From dc6cb8c74a248f7eecfd2a13d6e14d4a3db6ba3d Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 11 Nov 2003 07:23:04 +0000 Subject: [PATCH] Find attached the patch for the elf2flt utility. Except the elf2flt.c file, I have slightly modified the Makefile.in. The reason for this is to check the target architecture and if it is set to "e1", another linker script is installed. The reason for this alchemy is that our linker needs some sections that are included in the e1-elf2flt.ld script. Patch submitted by Yannis Mitsos . --- Makefile.in | 10 ++- config.sub | 4 +- e1-elf2flt.ld | 161 +++++++++++++++++++++++++++++++++ elf2flt.c | 244 +++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 413 insertions(+), 6 deletions(-) create mode 100644 e1-elf2flt.ld diff --git a/Makefile.in b/Makefile.in index 506365f..4f54438 100644 --- a/Makefile.in +++ b/Makefile.in @@ -22,6 +22,13 @@ OBJEXT = @OBJEXT@ CCFLAGS = $(CFLAGS) $(DEFS) $(INCLUDES) +LDFILE= elf2flt.ld +ifeq ($(strip $(CPU)),e1) +SRC_LDFILE= $(CPU)-elf2flt.ld +else +SRC_LDFILE= elf2flt.ld +endif + target_bindir = $(prefix)/$(TARGET)/bin target_libdir = $(prefix)/$(TARGET)/lib @@ -55,5 +62,6 @@ install: mv $(target_bindir)/ld$(EXEEXT) $(target_bindir)/ld.real$(EXEEXT) $(INSTALL) -m 755 ld-elf2flt $(bindir)/$(TARGET)-ld $(INSTALL) -m 755 ld-elf2flt $(target_bindir)/ld - $(INSTALL) -m 644 $(srcdir)/elf2flt.ld $(target_libdir) + $(INSTALL) -m 644 $(srcdir)/$(SRC_LDFILE) $(target_libdir)/$(LDFILE) + diff --git a/config.sub b/config.sub index ba0a36c..f124aa9 100755 --- a/config.sub +++ b/config.sub @@ -232,7 +232,7 @@ case $basic_machine in | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \ | mips64vr5000 | miprs64vr5000el | mcore | s390 | s390x \ | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | v850e | c4x \ - | microblaze \ + | microblaze | e1 \ | thumb | d10v | d30v | fr30 | avr | openrisc | tic80 \ | pj | pjl | h8500) basic_machine=$basic_machine-unknown @@ -280,7 +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-* \ + | microblaze-* | e1-* \ | bs2000-* | tic54x-* | c54x-* | x86_64-* | pj-* | pjl-*) ;; # Recognize the various machine names and aliases which stand diff --git a/e1-elf2flt.ld b/e1-elf2flt.ld new file mode 100644 index 0000000..a88fc4f --- /dev/null +++ b/e1-elf2flt.ld @@ -0,0 +1,161 @@ + +ENTRY (__start) + +MEMORY { + flatmem : ORIGIN = 0x0, LENGTH = 0xfffffff +} + +SECTIONS { + .G6 (DEFINED(G6Base) ? G6Base : 0x0) : { + *(.G6) + } + .G7 (DEFINED(G7Base) ? G7Base : 0x0) : { + *(.G7) + } + .G8 (DEFINED(G8Base) ? G8Base : 0x0) : { + *(.G8) + } + .G9 (DEFINED(G9Base) ? G9Base : 0) : { + *(.G9) + } + .G10 (DEFINED(G10Base) ? G10Base : 0) : { + *(.G10) + } + .G11 (DEFINED(G11Base) ? G11Base : 0) : { + *(.G11) + } + .G12 (DEFINED(G12Base) ? G12Base : 0) : { + *(.G12) + } + .G13 (DEFINED(G13Base) ? G13Base : 0) : { + *(.G13) + } + .text 0x0 : { + . = . + 4; + . = ALIGN(0x4) ; + _stext = . ; + *(.text) + *(.text.*) + *(.gnu.warning) + *(.stub) + *(.gnu.linkonce.t*) + *(.glue_7t) + *(.glue_7) + *(.jcr) + *(.init) + *(.fini) + +W_RODAT *(.rodata) +W_RODAT *(.rodata1) +W_RODAT *(.rodata.*) + + /* This is special code area at the end of the normal + text section. It contains a small lookup table at + the start followed by the code pointed to by entries + in the lookup table. */ + . = ALIGN (4) ; + PROVIDE(__ctbp = .); + *(.call_table_data) + *(.call_table_text) + + . = ALIGN(0x20) ; + _etext = . ; + } > flatmem + .data : { + . = ALIGN(0x4) ; + _sdata = . ; + __data_start = . ; + data_start = . ; + *(.got.plt) + *(.got) + FILL(0) ; + . = ALIGN(0x20) ; + LONG(-1) + . = ALIGN(0x20) ; +R_RODAT *(.rodata) +R_RODAT *(.rodata1) +R_RODAT *(.rodata.*) + *(.gnu.linkonce.r*) + *(.data) + *(.data1) + *(.data.*) + *(.gnu.linkonce.d*) + *(.data1) + *(.eh_frame) + *(.gcc_except_table) + + /* Microblaze has .sdata and .sbss (small bss). They must + be contiguous, so please don't move any of this. JW */ + _ssrw = . ; + *(.sdata) + *(.sdata.*) + *(.sbss) /* Don't move this! */ + _essrw = . ; + + _ssrw_size = _essrw - _ssrw; + PROVIDE(_SDA_BASE_ = _ssrw + (_ssrw_size / 2)); + + *(.gnu.linkonce.s.*) + *(__libc_atexit) + *(__libc_subinit) + *(__libc_subfreeres) + *(.note.ABI-tag) + + /* microblaze-specific read-only small data area + and associated locating symbols */ + _ssro = . ; + *(.sdata2) + _essro = . ; + _ssro_size = _essro - _ssro; + PROVIDE(_SDA2_BASE_ = _ssro + (_ssro_size / 2)); + + . = ALIGN(4) ; + __CTOR_LIST__ = .; + LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) + *(.ctors) + LONG(0) + __CTOR_END__ = .; + __DTOR_LIST__ = .; + LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) + *(.dtors) + LONG(0) + __DTOR_END__ = .; + + . = ALIGN(0x10) ; + _edata = . ; + } > flatmem + .bss : { + . = ALIGN(0x4) ; + _sbss = ALIGN(0x4) ; + __bss_start = . ; + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.scommon) + *(.dynbss) + *(.bss) + *(.bss.*) + *(.bss*) + *(.gnu.linkonce.b*) + *(COMMON) + . = ALIGN(0x10) ; + _ebss = . ; + _end = . ; + end = . ; + } > flatmem + + .junk 0 : { *(.rel*) *(.rela*) } + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/elf2flt.c b/elf2flt.c index f661d36..4161d10 100644 --- a/elf2flt.c +++ b/elf2flt.c @@ -57,6 +57,9 @@ /* from uClinux-x.x.x/include/linux */ #include "flat.h" /* Binary flat header description */ +#ifdef TARGET_e1 +#include +#endif #ifdef TARGET_v850e #define TARGET_v850 @@ -76,6 +79,8 @@ #define ARCH "h8300" #elif defined(TARGET_microblaze) #define ARCH "microblaze" +#elif defined(TARGET_e1) +#define ARCH "e1-coff" #else #error "Don't know how to support your CPU architecture??" #endif @@ -482,11 +487,14 @@ dump_symbols(symbols, number_of_symbols); * Fixup offset in the actual section. */ addstr[0] = 0; +#ifndef TARGET_e1 if ((sym_addr = get_symbol_offset((char *) sym_name, sym_section, symbols, number_of_symbols)) == -1) { sym_addr = 0; } - +#else + sym_addr = (*(q->sym_ptr_ptr))->value; +#endif if (use_resolved) { /* Use the address of the symbol already in the program text. How this is handled may @@ -605,7 +613,7 @@ dump_symbols(symbols, number_of_symbols); /* Calculate the sym address ourselves. */ sym_reloc_size = bfd_get_reloc_size(q->howto); -#ifndef TARGET_h8300 +#if !defined(TARGET_h8300) && !defined(TARGET_e1) if (sym_reloc_size != 4) { printf("ERROR: bad reloc type %d size=%d for symbol=%s\n", (*p)->howto->type, sym_reloc_size, sym_name); @@ -871,6 +879,180 @@ dump_symbols(symbols, number_of_symbols); break; #endif /* TARGET_sh */ +#ifdef TARGET_e1 +#define htoe1l(x) htonl(x) + +#if 0 +#define DEBUG_E1 +#endif + +#ifdef DEBUG_E1 +#define DBG_E1 printf +#else +#define DBG_E1(x, ... ) +#endif + +#define _32BITS_RELOC 0x00000000 +#define _30BITS_RELOC 0x80000000 +#define _28BITS_RELOC 0x40000000 + { + char *p; + unsigned long sec_vma, exist_val, S; + case R_E1_CONST31: + relocation_needed = 1; + DBG_E1("Handling Reloc \n"); + sec_vma = bfd_section_vma(abs_bfd, sym_section); + DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n", + sec_vma, sym_addr, q->address); + sym_addr = sec_vma + sym_addr; + exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2); + DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val); + exist_val = htoe1l(exist_val); + DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val); + sym_addr += exist_val; + pflags = _30BITS_RELOC; + break; + case R_E1_CONST31_PCREL: + relocation_needed = 0; + DBG_E1("Handling Reloc \n"); + DBG_E1("DONT RELOCATE AT LOADING\n"); + sec_vma = bfd_section_vma(abs_bfd, sym_section); + DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n", + sec_vma, sym_addr, q->address); + sym_addr = sec_vma + sym_addr; + DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr ); + + DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address, + section_vma ); + q->address = q->address + section_vma; + DBG_E1("q->address += section_vma : 0x%x\n", q->address ); + + if( (sym_addr = (sym_addr - q->address - 6)) < 0 ) + DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n"); + DBG_E1( "sym_addr := sym_addr - q->address - " + "sizeof(CONST31_PCREL): [0x%x]\n", + sym_addr ); + exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2); + DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val); + exist_val = htoe1l(exist_val); + DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val); + sym_addr |= exist_val; + DBG_E1("sym_addr |= exist_val) : [0x%x]\n", sym_addr ); + break; + case R_E1_DIS29W_PCREL: + relocation_needed = 0; + DBG_E1("Handling Reloc \n"); + DBG_E1("DONT RELOCATE AT LOADING\n"); + sec_vma = bfd_section_vma(abs_bfd, sym_section); + DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n", + sec_vma, sym_addr, q->address); + sym_addr = sec_vma + sym_addr; + DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr ); + + DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address, + section_vma ); + q->address = q->address + section_vma; + DBG_E1("q->address += section_vma : 0x%x\n", q->address ); + + if( (sym_addr = (sym_addr - q->address - 6)) < 0 ) + DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n"); + DBG_E1( "sym_addr := sym_addr - q->address - " + "sizeof(CONST31_PCREL): [0x%x]\n", + sym_addr ); + DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address ); + exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2); + DBG_E1("Original:exist_val : [0x%08x]\n",exist_val); + exist_val = htoe1l(exist_val); + DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val); + sym_addr += exist_val; + break; + case R_E1_DIS29W: + DBG_E1("Handling Reloc \n"); + goto DIS29_RELOCATION; + case R_E1_DIS29H: + DBG_E1("Handling Reloc \n"); + goto DIS29_RELOCATION; + case R_E1_DIS29B: + DBG_E1("Handling Reloc \n"); +DIS29_RELOCATION: + relocation_needed = 1; + sec_vma = bfd_section_vma(abs_bfd, sym_section); + DBG_E1("sec_vma : [0x%x], sym_addr : [0x%08x]\n", + sec_vma, sym_addr); + sym_addr = sec_vma + sym_addr; + DBG_E1("sym_addr = sec_vma + sym_addr : [0x%08x]\n", sym_addr); + exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2); + DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val); + exist_val = htoe1l(exist_val); + DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val); + sym_addr += exist_val; + DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr); + pflags = _28BITS_RELOC; + break; + case R_E1_IMM32_PCREL: + relocation_needed = 0; + DBG_E1("Handling Reloc \n"); + DBG_E1("DONT RELOCATE AT LOADING\n"); + sec_vma = bfd_section_vma(abs_bfd, sym_section); + DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n", + sec_vma, sym_addr); + sym_addr = sec_vma + sym_addr; + + DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr ); + DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address, + section_vma ); + q->address = q->address + section_vma; + DBG_E1("q->address += section_vma : 0x%x\n", q->address ); + + if( (sym_addr = (sym_addr - q->address - 6 )) < 0 ) + DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n"); + DBG_E1( "sym_addr := sym_addr - q->address - " + "sizeof(CONST31_PCREL): [0x%x]\n", + sym_addr ); + DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address ); + exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2); + DBG_E1("Original:exist_val : [0x%08x]\n",exist_val); + exist_val = htoe1l(exist_val); + DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val); + sym_addr += exist_val; + break; + case R_E1_IMM32: + relocation_needed = 1; + DBG_E1("Handling Reloc \n"); + sec_vma = bfd_section_vma(abs_bfd, sym_section); + DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n", + sec_vma, sym_addr); + sym_addr = sec_vma + sym_addr; + DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr ); + DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address ); + exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2); + DBG_E1("Original:exist_val : [0x%08x]\n",exist_val); + exist_val = htoe1l(exist_val); + DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val); + sym_addr += exist_val; + pflags = _32BITS_RELOC; + break; + case R_E1_WORD: + relocation_needed = 1; + DBG_E1("Handling Reloc \n"); + sec_vma = bfd_section_vma(abs_bfd, sym_section); + DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n", + sec_vma, sym_addr); + sym_addr = sec_vma + sym_addr; + DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr ); + exist_val = *(unsigned long*)((unsigned long)sectionp + q->address ); + DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val); + exist_val = htoe1l(exist_val); + DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val); + sym_addr += exist_val; + DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr); + pflags = _32BITS_RELOC; + break; + } +#undef _32BITS_RELOC +#undef _30BITS_RELOC +#undef _28BITS_RELOC +#endif default: /* missing support for other types of relocs */ printf("ERROR: bad reloc type %d\n", (*p)->howto->type); @@ -930,7 +1112,33 @@ dump_symbols(symbols, number_of_symbols); else *(unsigned long *)r_mem = tmp.l; -#else /* ! TARGET_arm */ +#elif defined(TARGET_e1) +#define OPCODE_SIZE 2 /* Add 2 bytes, counting the opcode size*/ + switch ((*p)->howto->type) { + case R_E1_CONST31: + case R_E1_CONST31_PCREL: + case R_E1_DIS29W_PCREL: + case R_E1_DIS29W: + case R_E1_DIS29H: + case R_E1_DIS29B: + case R_E1_IMM32_PCREL: + case R_E1_IMM32: + DBG_E1("In addr + 2:[0x%x] <- write [0x%x]\n", + (sectionp + q->address + 2), sym_addr ); + *((unsigned long *) (sectionp + q->address + OPCODE_SIZE)) = + htonl(sym_addr); + break; + case R_E1_WORD: + DBG_E1("In addr : [0x%x] <- write [0x%x]\n", + (sectionp + q->address), sym_addr ); + *((unsigned long *) (sectionp + q->address )) = htonl(sym_addr); + break; + default: + printf("ERROR:Unhandled Relocation. Exiting...\n"); + exit(0); + break; + } +#else /* ! TARGET_arm && ! TARGET_e1 */ switch (q->howto->type) { #ifdef TARGET_v850 @@ -975,12 +1183,38 @@ dump_symbols(symbols, number_of_symbols); if (relocation_needed) { flat_relocs = realloc(flat_relocs, (flat_reloc_count + 1) * sizeof(unsigned long)); +#ifndef TARGET_e1 flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address); if (verbose) printf("reloc[%d] = 0x%x\n", flat_reloc_count, section_vma + q->address); +#else + switch ((*p)->howto->type) { + case R_E1_CONST31: + case R_E1_CONST31_PCREL: + case R_E1_DIS29W_PCREL: + case R_E1_DIS29W: + case R_E1_DIS29H: + case R_E1_DIS29B: + case R_E1_IMM32_PCREL: + case R_E1_IMM32: + flat_relocs[flat_reloc_count] = pflags | + (section_vma + q->address + OPCODE_SIZE); + if (verbose) + printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count, + flat_relocs[flat_reloc_count] ); + break; + case R_E1_WORD: + flat_relocs[flat_reloc_count] = pflags | + (section_vma + q->address); + if (verbose) + printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count, + flat_relocs[flat_reloc_count] ); + break; + } +#endif flat_reloc_count++; relocation_needed = 0; pflags = 0; @@ -1176,7 +1410,11 @@ int main(int argc, char *argv[]) if (argc < 2) usage(); +#ifndef TARGET_e1 stack = 4096; +#else /* We need plenty of stack for both of them (Aggregate and Register) */ + stack = 0x2020; +#endif while ((opt = getopt(argc, argv, "avzdrkp:s:o:R:")) != -1) { switch (opt) { -- 2.39.5