]> git.wh0rd.org Git - elf2flt.git/commitdiff
Added support for the Microblaze archiecture.
authorGreg Ungerer <gerg@snapgear.com>
Thu, 22 May 2003 05:42:19 +0000 (05:42 +0000)
committerGreg Ungerer <gerg@snapgear.com>
Thu, 22 May 2003 05:42:19 +0000 (05:42 +0000)
The only mod outside the #ifdef TARGET_microblaze stuff in elf2flt.c is a new
entry in config.sub so it knows about the target, and a new entry in the
elf2flt.ld because the microblaze gnu tools create sections called (.bss.*).

Patch from John Williams <jwilliams@itee.uq.edu.au>.

config.sub
elf2flt.c
elf2flt.ld

index 23e6803df1436a91c3377958e82c2f663e113dda..ba0a36cb12b51ccffe3cc2d0bea0f43414ba8705 100755 (executable)
@@ -232,6 +232,7 @@ case $basic_machine in
                | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
                | mips64vr5000 | miprs64vr5000el | mcore | s390 | s390x \
                | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | v850e | c4x \
+               | microblaze \
                | thumb | d10v | d30v | fr30 | avr | openrisc | tic80 \
                | pj | pjl | h8500)
                basic_machine=$basic_machine-unknown
@@ -279,6 +280,7 @@ case $basic_machine in
              | [cjt]90-* \
              | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
              | thumb-* | v850-* | v850e-* | d30v-* | tic30-* | tic80-* | c30-* | fr30-* \
+             | microblaze-* \
              | bs2000-* | tic54x-* | c54x-* | x86_64-* | pj-* | pjl-*)
                ;;
        # Recognize the various machine names and aliases which stand
index f90e48bc70599a28890726d9fb41be197e1f67e1..8b1c401919603c04667aa657f0daf5abd7ed7e77 100644 (file)
--- a/elf2flt.c
+++ b/elf2flt.c
@@ -72,6 +72,8 @@
 #define        ARCH    "sh"
 #elif defined(TARGET_h8300)
 #define        ARCH    "h8300"
+#elif defined(TARGET_microblaze)
+#define ARCH   "microblaze"
 #else
 #error "Don't know how to support your CPU architecture??"
 #endif
@@ -374,6 +376,19 @@ dump_symbols(symbols, number_of_symbols);
                for (p = relpp; (relcount && (*p != NULL)); p++, relcount--) {
                        int relocation_needed = 0;
 
+#ifdef TARGET_microblaze
+                       /* The MICROBLAZE_XX_NONE relocs can be skipped.
+                          They represent PC relative branches that the
+                          linker has already resolved */
+                               
+                       switch ((*p)->howto->type) 
+                       {
+                       case R_MICROBLAZE_NONE:
+                       case R_MICROBLAZE_64_NONE:
+                               continue;
+                       }
+#endif /* TARGET_microblaze */
+                          
 #ifdef TARGET_v850
                        /* Skip this relocation entirely if possible (we
                           do this early, before doing any other
@@ -609,6 +624,73 @@ dump_symbols(symbols, number_of_symbols);
                                        continue;
 #endif
 
+#ifdef TARGET_microblaze
+                               case R_MICROBLAZE_64:
+               /* The symbol is split over two consecutive instructions.  
+                  Flag this to the flat loader by setting the high bit of 
+                  the relocation symbol. */
+                               {
+                                       unsigned char *p = sectionp + q->address;
+                                       unsigned long offset;
+                                       pflags=0x80000000;
+
+                                       /* work out the relocation */
+                                       sym_vma = bfd_section_vma(abs_bfd, sym_section);
+                                       /* grab any offset from the text */
+                                       offset = (p[2]<<24) + (p[3] << 16) + (p[6] << 8) + (p[7]);
+                                       /* Update the address */
+                                       sym_addr += offset + sym_vma + q->addend;
+                                       /* Write relocated pointer back */
+                                       p[2] = (sym_addr >> 24) & 0xff;
+                                       p[3] = (sym_addr >> 16) & 0xff;
+                                       p[6] = (sym_addr >>  8) & 0xff;
+                                       p[7] =  sym_addr        & 0xff;
+
+                                       /* create a new reloc entry */
+                                       flat_relocs = realloc(flat_relocs,
+                                               (flat_reloc_count + 1) * sizeof(unsigned long));
+                                       flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address);
+                                       flat_reloc_count++;
+                                       relocation_needed = 0;
+                                       pflags = 0;
+                       sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
+                                        bfd_section_vma(abs_bfd, sym_section));
+                       if (verbose)
+                               printf("  RELOC[%d]: offset=%x symbol=%s%s "
+                                       "section=%s size=%d "
+                                       "fixup=%x (reloc=0x%x)\n", flat_reloc_count,
+                                       q->address, sym_name, addstr,
+                                       section_name, sym_reloc_size,
+                                       sym_addr, section_vma + q->address);
+                       if (verbose)
+                               printf("reloc[%d] = 0x%x\n", flat_reloc_count,
+                                        section_vma + q->address);
+
+                                       continue;
+                               }
+                               case R_MICROBLAZE_32:
+                                       relocation_needed = 1;
+                                       //sym_addr = (*(q->sym_ptr_ptr))->value;
+                                       sym_vma = bfd_section_vma(abs_bfd, sym_section);
+                                       sym_addr += sym_vma + q->addend;
+                                       break;
+
+                               case R_MICROBLAZE_64_PCREL:
+                                       sym_vma = 0;
+                                       //sym_addr = (*(q->sym_ptr_ptr))->value;
+                                       sym_addr += sym_vma + q->addend;
+                                       sym_addr -= (q->address + 4);
+                                       sym_addr = htonl(sym_addr);
+                                       /* insert 16 MSB */
+                                       * ((unsigned short *) (sectionp + q->address+2)) |= (sym_addr) & 0xFFFF;
+                                       /* then 16 LSB */
+                                       * ((unsigned short *) (sectionp + q->address+6)) |= (sym_addr >> 16) & 0xFFFF;
+                                       /* We've done all the work, so continue
+                                          to next reloc instead of break */
+                                       continue;
+
+#endif /* TARGET_microblaze */
+                                       
 #ifdef TARGET_sparc
                                case R_SPARC_32:
                                case R_SPARC_UA32:
index 2aeb56064f9de3adadeaba0c2083a4f4726d7299..acb893c116dcdbfb83e1a9e502348ab84c29ceb7 100644 (file)
@@ -93,6 +93,7 @@ R_RODAT               *(.rodata.*)
                *(.dynbss)
                *(.bss)
                *(.bss.*)
+               *(.bss*)
                *(COMMON)
                . = ALIGN(0x10) ;
                _ebss = . ;