diff -urP -Xcludes elf2flt-20010712.orig/elf2flt-v850.ld elf2flt-20010712/elf2flt-v850.ld --- elf2flt-20010712.orig/elf2flt-v850.ld Thu Jan 1 09:00:00 1970 +++ elf2flt-20010712/elf2flt-v850.ld Fri Sep 7 11:12:55 2001 @@ -0,0 +1,85 @@ +ENTRY (_start) + +MEMORY { + flatmem : ORIGIN = 0x0, LENGTH = 0x100000 +} + +SECTIONS { + .text 0 : { + /* Avoid address 0; binfmt_flat treats it specially. */ + . = . + 4 ; + + . = ALIGN(0x4) ; + _stext = . ; + + *(.text) + *(.text.*) + *(.gnu.warning) + *(.stub) + *(.gnu.linkonce.t*) + *(.init) + + /* 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(0x10) ; + _etext = . ; + } > flatmem + .data : { + . = ALIGN(0x4) ; + _sdata = . ; + __data_start = . ; + data_start = . ; + __gp = . ; + *(.rela.got) + *(.rel.got) + *(.got.plt) + *(.got) + LONG(-1) + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r*) + *(.rodata1) + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + *(.data1) + *(.eh_frame) + *(.gcc_except_table) + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(4) ; + *(.ctors.*) + *(.ctors) + LONG(0) + *(.dtors.*) + *(.dtors) + LONG(0) + . = ALIGN(0x10) ; + _edata = . ; + } > flatmem + .bss : { + . = ALIGN(0x4) ; + _sbss = ALIGN(0x4) ; + __bss_start = . ; + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.scommon) + *(.dynbss) + *(.bss) + *(.bss.*) + *(COMMON) + . = ALIGN(0x4) ; + _ebss = . ; + _end = . ; + end = . ; + } > flatmem +} diff -urP -Xcludes elf2flt-20010712.orig/elf2flt.c elf2flt-20010712/elf2flt.c --- elf2flt-20010712.orig/elf2flt.c Thu Jul 12 09:06:59 2001 +++ elf2flt-20010712/elf2flt.c Fri Aug 31 14:11:25 2001 @@ -55,6 +55,12 @@ int pic_with_got = 0; /* do elf/got processing with PIC code */ int load_to_ram = 0; /* instruct loader to allocate everything into RAM */ int compress = 0; +/* If true, get the value of symbol references from the program + contents, not from the relocation table. In this case, the input ELF + file must be already fully resolved (using the `-q' flag with recent + versions of GNU ld will give you a fully resolved output file with + relocation entries). */ +int use_resolved = 0; const char *progname, *filename; int lineno; @@ -354,6 +360,63 @@ continue; } else { for (p = relpp; (relcount && (*p != NULL)); p++, relcount--) { + int pc_rel = 0, ignore = 0; + +#ifdef USE_V850_RELOCS + /* Skip this relocation entirely if possible (we + do this early, before doing any other + processing on it). */ + switch ((*p)->howto->type) { +#ifdef R_V850_9_PCREL + case R_V850_9_PCREL: +#endif +#ifdef R_V850_22_PCREL + case R_V850_22_PCREL: +#endif +#ifdef R_V850_SDA_16_16_OFFSET + case R_V850_SDA_16_16_OFFSET: +#endif +#ifdef R_V850_SDA_15_16_OFFSET + case R_V850_SDA_15_16_OFFSET: +#endif +#ifdef R_V850_ZDA_15_16_OFFSET + case R_V850_ZDA_15_16_OFFSET: +#endif +#ifdef R_V850_TDA_6_8_OFFSET + case R_V850_TDA_6_8_OFFSET: +#endif +#ifdef R_V850_TDA_7_8_OFFSET + case R_V850_TDA_7_8_OFFSET: +#endif +#ifdef R_V850_TDA_7_7_OFFSET + case R_V850_TDA_7_7_OFFSET: +#endif +#ifdef R_V850_TDA_16_16_OFFSET + case R_V850_TDA_16_16_OFFSET: +#endif +#ifdef R_V850_TDA_4_5_OFFSET + case R_V850_TDA_4_5_OFFSET: +#endif +#ifdef R_V850_TDA_4_4_OFFSET + case R_V850_TDA_4_4_OFFSET: +#endif +#ifdef R_V850_SDA_16_16_SPLIT_OFFSET + case R_V850_SDA_16_16_SPLIT_OFFSET: +#endif +#ifdef R_V850_CALLT_6_7_OFFSET + case R_V850_CALLT_6_7_OFFSET: +#endif +#ifdef R_V850_CALLT_16_16_OFFSET + case R_V850_CALLT_16_16_OFFSET: +#endif + /* These are relative relocations, which + have already been fixed up by the + linker at this point, so just ignore + them. */ + continue; + } +#endif /* USE_V850_RELOCS */ + q = *p; if (q->sym_ptr_ptr && *q->sym_ptr_ptr) { sym_name = (*(q->sym_ptr_ptr))->name; @@ -364,8 +427,9 @@ rc = -1; continue; } - /* Adjust the address to account for the GOT table which wasn't - * present in the relative file link. + /* Adjust the address to account for the GOT + * table which wasn't present in the relative + * file link. */ if (pic_with_got) q->address += got_size; @@ -379,42 +443,86 @@ sym_addr = 0; } - sym_reloc_size = bfd_get_reloc_size(q->howto); - if (sym_reloc_size != 4) { - printf("ERROR: bad reloc size=%d for " - "symbol=%s\n", sym_reloc_size, - sym_name); - rc = -1; - continue; - } + if (use_resolved) { + /* Use the address of the symbol already in + the program text. */ + sym_addr = *((unsigned long *) + (sectionp + q->address)); + } else { + /* Calculate the sym address ourselves. */ - switch ((*p)->howto->type) { + sym_reloc_size = bfd_get_reloc_size(q->howto); + if (sym_reloc_size != 4) { + printf("ERROR: bad reloc size=%d for " + "symbol=%s\n", sym_reloc_size, + sym_name); + rc = -1; + continue; + } + + switch ((*p)->howto->type) { +#ifdef USE_68K_RELOCS #ifdef R_68K_32 - case R_68K_32: + case R_68K_32: +#endif #endif +#ifdef USE_ARM_RELOCS #ifdef R_ARM_ABS32 - case R_ARM_ABS32: + case R_ARM_ABS32: +#endif +#endif +#ifdef USE_V850_RELOCS +#ifdef R_V850_32 + case R_V850_32: #endif - sym_vma = bfd_section_vma(abs_bfd, sym_section); - sym_addr += sym_vma + q->addend; - break; +#endif + sym_vma = bfd_section_vma(abs_bfd, + sym_section); + sym_addr += sym_vma + q->addend; + break; +#ifdef USE_68K_RELOCS #ifdef R_68K_PC32 - case R_68K_PC32: + case R_68K_PC32: +#endif #endif +#ifdef USE_ARM_RELOCS #ifdef R_ARM_PLT32 - case R_ARM_PLT32: + case R_ARM_PLT32: #endif - sym_vma = 0; - sym_addr += sym_vma + q->addend; - sym_addr -= q->address; - break; - default: - /* missing support for other types of relocs */ - printf("ERROR: bad reloc type %d\n", (*p)->howto->type); - continue; +#endif + pc_rel = 1; + sym_vma = 0; + sym_addr += sym_vma + q->addend; + sym_addr -= q->address; + break; + +#ifdef USE_V850_RELOCS +#ifdef R_V850_ZDA_16_16_OFFSET + case R_V850_ZDA_16_16_OFFSET: +#endif +#ifdef R_V850_ZDA_16_16_SPLIT_OFFSET + case R_V850_ZDA_16_16_SPLIT_OFFSET: +#endif + /* Can't support zero-relocations. */ + printf ("ERROR: %s+0x%x: " + "zero relocations not supported\n", + sym_name, q->addend); + continue; +#endif /* USE_V850_RELOCS */ + + default: + /* missing support for other + types of relocs */ + printf("ERROR: bad reloc type %d\n", + (*p)->howto->type); + continue; + } } - sprintf(&addstr[0], "+0x%x", q->addend); + sprintf (&addstr[0], "+0x%x", + sym_addr + - (*(q->sym_ptr_ptr))->value + - bfd_section_vma(abs_bfd, sym_section)); #if 0 printf("%s(%d): patching offset=%x symbol=%s%s *%x=%x\n", __FILE__, __LINE__, @@ -422,27 +530,32 @@ #endif /* - * for full elf relocation we have to write back the start_code - * relative value to use. + * for full elf relocation we have to write back + * the start_code relative value to use. */ - if (!pic_with_got) - *((unsigned long *) (sectionp + q->address)) = htonl(sym_addr); + if (! pic_with_got) + *((unsigned long *) (sectionp + q->address)) + = htonl(sym_addr); 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); + "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); /* - * Create relocation entry (PC relative doesn't need this). + * Create relocation entry (PC relative doesn't + * need this). */ - if ((*p)->howto->type==R_68K_32) { + if (! pc_rel) { flat_relocs = realloc(flat_relocs, - (flat_reloc_count + 1) * sizeof(unsigned long)); - flat_relocs[flat_reloc_count] = section_vma + q->address; + (flat_reloc_count + 1) + * sizeof(unsigned long)); + flat_relocs[flat_reloc_count] + = section_vma + q->address; flat_reloc_count++; } @@ -558,6 +671,9 @@ fprintf(stderr, " -v : verbose operation\n"); fprintf(stderr, " -r : force load to RAM\n"); fprintf(stderr, " -z : compress code/data/relocs\n"); + fprintf(stderr, " -a : use existing symbol references\n" + " instead of recalculating from\n" + " relocation info\n"); fprintf(stderr, " -p abs-pic-file : GOT/PIC processing with files\n"); fprintf(stderr, " -s stacksize : set application stack size\n"); fprintf(stderr, " -o output-file : output file name\n"); @@ -605,7 +721,7 @@ stack = 4096; - while ((opt = getopt(argc, argv, "vzrp:s:o:")) != -1) { + while ((opt = getopt(argc, argv, "avzrp:s:o:")) != -1) { switch (opt) { case 'v': @@ -623,6 +739,9 @@ case 'o': ofile = optarg; break; + case 'a': + use_resolved = 1; + break; case 's': stack = atoi(optarg); break; @@ -665,7 +784,20 @@ exit(2); } } else - abs_bfd = rel_bfd; /* one file does all */ + abs_bfd = rel_bfd; /* one file does all */ + + if (! (bfd_get_file_flags (rel_bfd) & HAS_RELOC)) { + fprintf (stderr, "%s: Input file contains no relocation info\n", fname); + exit (2); + } + if (use_resolved && !(bfd_get_file_flags (abs_bfd) & EXEC_P)) { + /* `Absolute' file is not absolute, so neither are address + contained therein. */ + fprintf (stderr, + "%s: `-a' option specified with non-fully-resolved input file\n", + bfd_get_filename (abs_bfd)); + exit (2); + } symbol_table = get_symbols(abs_bfd, &number_of_symbols); @@ -754,7 +886,7 @@ /* Fill in the binflt_flat header */ memcpy(hdr.magic,"bFLT",4); hdr.rev = htonl(FLAT_VERSION); - hdr.entry = htonl(16 * 4); /* FIXME */ + hdr.entry = htonl(16 * 4 + bfd_get_start_address(abs_bfd)); hdr.data_start = htonl(16 * 4 + text_len); hdr.data_end = htonl(16 * 4 + text_len + data_len); hdr.bss_end = htonl(16 * 4 + text_len + data_len + bss_len); @@ -818,5 +950,3 @@ exit(0); } - -