From 9898df037a428f9e0ab67e1c988affdd073b734c Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Thu, 22 May 2003 05:42:19 +0000 Subject: [PATCH] Added support for the Microblaze archiecture. 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 . --- config.sub | 2 ++ elf2flt.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ elf2flt.ld | 1 + 3 files changed, 85 insertions(+) diff --git a/config.sub b/config.sub index 23e6803..ba0a36c 100755 --- a/config.sub +++ b/config.sub @@ -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 diff --git a/elf2flt.c b/elf2flt.c index f90e48b..8b1c401 100644 --- 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: diff --git a/elf2flt.ld b/elf2flt.ld index 2aeb560..acb893c 100644 --- a/elf2flt.ld +++ b/elf2flt.ld @@ -93,6 +93,7 @@ R_RODAT *(.rodata.*) *(.dynbss) *(.bss) *(.bss.*) + *(.bss*) *(COMMON) . = ALIGN(0x10) ; _ebss = . ; -- 2.39.5