2 * elf2flt.c: Convert ELF (or any BFD format) to FLAT binary format
4 * (c) 1999-2002, Greg Ungerer <gerg@snapgear.com>
5 * Created elf2flt from coff2flt (see copyrights below). Added all the
6 * ELF format file handling. Extended relocation support for all of
9 * (c) 2003, H8 support, ktrace <davidm@snapgear.com>
10 * (c) 2003-2004, MicroBlaze support, John Williams <jwilliams@itee.uq.edu.au>
11 * (c) 2001-2003, arm/arm-pic/arm-big-endian support <davidm@snapgear.com>
12 * (c) 2001, v850 changes, Mile Bader <miles@lsi.nec.co.jp>
13 * (c) 2003, SuperH support, Paul Mundt <lethal@linux-sh.org>
14 * (c) 2001, zflat support <davidm@snapgear.com>
15 * (c) 2001, Changes for GOT entries Paul Dale <pauli@snapgear.com> and
16 * David McCullough <davidm@snapgear.com>
18 * Now supports PIC with GOT tables. This works by taking a '.elf' file
19 * and a fully linked elf executable (at address 0) and produces a flat
20 * file that can be loaded with some fixups. It still supports the old
21 * style fully relocatable elf format files.
23 * Originally obj-res.c
25 * (c) 1998, Kenneth Albanowski <kjahds@kjahds.com>
26 * (c) 1998, D. Jeff Dionne
27 * (c) 1998, The Silver Hammer Group Ltd.
28 * (c) 1996, 1997 Dionne & Associates <jeff@ryeham.ee.ryerson.ca>
30 * This is Free Software, under the GNU Public Licence v2 or greater.
32 * Relocation added March 1997, Kresten Krab Thorup
33 * krab@california.daimi.aau.dk
36 #include <stdio.h> /* Userland pieces of the ANSI C standard I/O package */
37 #include <stdlib.h> /* Userland prototypes of the ANSI C std lib functions */
38 #include <stdarg.h> /* Allows va_list to exist in the these namespaces */
39 #include <string.h> /* Userland prototypes of the string handling funcs */
41 #include <unistd.h> /* Userland prototypes of the Unix std system calls */
42 #include <fcntl.h> /* Flag value for file handling functions */
45 #include <netinet/in.h> /* Consts and structs defined by the internet system */
50 /* from $(INSTALLDIR)/include */
51 #include <bfd.h> /* Main header file for the BFD library */
53 #if defined(TARGET_h8300)
54 #include <elf/h8.h> /* TARGET_* ELF support for the BFD library */
55 #elif defined(__CYGWIN__)
56 #include "cygwin-elf.h" /* Cygwin uses a local copy */
57 #elif defined(TARGET_microblaze)
58 #include <elf/microblaze.h> /* TARGET_* ELF support for the BFD library */
60 #include <elf.h> /* TARGET_* ELF support for the BFD library */
63 /* from uClinux-x.x.x/include/linux */
64 #include "flat.h" /* Binary flat header description */
74 #if defined(TARGET_m68k)
75 #define ARCH "m68k/coldfire"
76 #elif defined(TARGET_arm)
78 #elif defined(TARGET_sparc)
80 #elif defined(TARGET_v850)
82 #elif defined(TARGET_sh)
84 #elif defined(TARGET_h8300)
86 #elif defined(TARGET_microblaze)
87 #define ARCH "microblaze"
88 #elif defined(TARGET_e1)
89 #define ARCH "e1-coff"
91 #error "Don't know how to support your CPU architecture??"
94 #if defined(TARGET_m68k) || defined(TARGET_h8300)
96 * Define a maximum number of bytes allowed in the offset table.
97 * We'll fail if the table is larger than this.
99 * This limit may be different for platforms other than m68k, but
100 * 8000 entries is a lot, trust me :-) (davidm)
102 #define GOT_LIMIT 32767
104 * we have to mask out the shared library id here and there, this gives
105 * us the real address bits when needed
107 #define real_address_bits(x) (pic_with_got ? ((x) & 0xffffff) : (x))
109 #define real_address_bits(x) (x)
117 int verbose = 0; /* extra output when running */
118 int pic_with_got = 0; /* do elf/got processing with PIC code */
119 int load_to_ram = 0; /* instruct loader to allocate everything into RAM */
120 int ktrace = 0; /* instruct loader output kernel trace on load */
121 int compress = 0; /* 1 = compress everything, 2 = compress data only */
122 int use_resolved = 0; /* If true, get the value of symbol references from */
123 /* the program contents, not from the relocation table. */
124 /* In this case, the input ELF file must be already */
125 /* fully resolved (using the `-q' flag with recent */
126 /* versions of GNU ld will give you a fully resolved */
127 /* output file with relocation entries). */
129 const char *progname, *filename;
135 static char where[200];
138 /* Use exactly one of these: */
139 E_NOFILE = 0, /* "progname: " */
140 E_FILE = 1, /* "filename: " */
141 E_FILELINE = 2, /* "filename:lineno: " */
142 E_FILEWHERE = 3, /* "filename:%s: " -- set %s with ewhere() */
144 /* Add in any of these with |': */
149 void ewhere (const char *format, ...);
150 void einfo (int type, const char *format, ...);
154 ewhere (const char *format, ...) {
156 va_start (args, format);
157 vsprintf (where, format, args);
163 einfo (int type, const char *format, ...) {
166 switch (type & 0x0f) {
168 fprintf (stderr, "%s: ", progname);
171 fprintf (stderr, "%s: ", filename);
174 ewhere ("%d", lineno);
177 fprintf (stderr, "%s:%s: ", filename, where);
181 if (type & E_WARNING) {
182 fprintf (stderr, "warning: ");
188 va_start (args, format);
189 vfprintf (stderr, format, args);
195 fprintf (stderr, "\n");
200 get_symbols (bfd *abfd, long *num)
203 asymbol **symbol_table;
204 long number_of_symbols;
206 storage_needed = bfd_get_symtab_upper_bound (abfd);
208 if (storage_needed < 0)
211 if (storage_needed == 0)
214 symbol_table = (asymbol **) malloc (storage_needed);
216 number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
218 if (number_of_symbols < 0)
221 *num = number_of_symbols;
228 dump_symbols(asymbol **symbol_table, long number_of_symbols)
231 printf("SYMBOL TABLE:\n");
232 for (i=0; i<number_of_symbols; i++) {
233 printf(" NAME=%s VALUE=0x%x\n", symbol_table[i]->name,
234 symbol_table[i]->value);
243 get_symbol_offset(char *name, asection *sec, asymbol **symbol_table, long number_of_symbols)
246 for (i=0; i<number_of_symbols; i++) {
247 if (symbol_table[i]->section == sec) {
248 if (!strcmp(symbol_table[i]->name, name)) {
249 return symbol_table[i]->value;
259 add_com_to_bss(asymbol **symbol_table, long number_of_symbols, long bss_len)
265 for (i=0; i<number_of_symbols; i++) {
266 if (strcmp("*COM*", symbol_table[i]->section->name) == 0) {
267 offset = bss_len + comsize;
268 comsize += symbol_table[i]->value;
269 symbol_table[i]->value = offset;
281 int number_of_symbols,
282 unsigned long *n_relocs,
283 unsigned char *text, int text_len, unsigned long text_vma,
284 unsigned char *data, int data_len, unsigned long data_vma,
287 unsigned long *flat_relocs;
288 asection *a, *sym_section, *r;
289 arelent **relpp, **p, *q;
290 const char *sym_name, *section_name;
291 unsigned char *sectionp;
292 unsigned long pflags;
294 long sym_addr, sym_vma, section_vma;
295 int relsize, relcount;
296 int flat_reloc_count;
297 int sym_reloc_size, rc;
304 printf("%s(%d): output_relocs(abs_bfd=%d,synbols=0x%x,number_of_symbols=%d"
305 "n_relocs=0x%x,text=0x%x,text_len=%d,data=0x%x,data_len=%d)\n",
306 __FILE__, __LINE__, abs_bfd, symbols, number_of_symbols, n_relocs,
307 text, text_len, data, data_len);
311 dump_symbols(symbols, number_of_symbols);
316 flat_reloc_count = 0;
320 /* Determine how big our offset table is in bytes.
321 * This isn't too difficult as we've terminated the table with -1.
322 * Also note that both the relocatable and absolute versions have this
323 * terminator even though the relocatable one doesn't have the GOT!
326 unsigned long *lp = (unsigned long *)data;
327 /* Should call ntohl(*lp) here but is isn't going to matter */
328 while (*lp != 0xffffffff) lp++;
329 got_size = ((unsigned char *)lp) - data;
331 printf("GOT table contains %d entries (%d bytes)\n",
332 got_size/sizeof(unsigned long), got_size);
334 if (got_size > GOT_LIMIT) {
335 fprintf(stderr, "GOT too large: %d bytes (limit = %d bytes)\n",
336 got_size, GOT_LIMIT);
342 for (a = abs_bfd->sections; (a != (asection *) NULL); a = a->next) {
343 section_vma = bfd_section_vma(abs_bfd, a);
346 printf("SECTION: %s [0x%x]: flags=0x%x vma=0x%x\n", a->name, a,
347 a->flags, section_vma);
349 // if (bfd_is_abs_section(a))
351 if (bfd_is_und_section(a))
353 if (bfd_is_com_section(a))
355 // if ((a->flags & SEC_RELOC) == 0)
359 * Only relocate things in the data sections if we are PIC/GOT.
360 * otherwise do text as well
362 if (!pic_with_got && (a->flags & SEC_CODE))
363 sectionp = text + (a->vma - text_vma);
364 else if (a->flags & SEC_DATA)
365 sectionp = data + (a->vma - data_vma);
369 /* Now search for the equivalent section in the relocation binary
370 * and use that relocation information to build reloc entries
373 for (r=rel_bfd->sections; r != NULL; r=r->next)
374 if (strcmp(a->name, r->name) == 0)
379 printf(" RELOCS: %s [0x%x]: flags=0x%x vma=0x%x\n", r->name, r,
380 r->flags, bfd_section_vma(abs_bfd, r));
381 if ((r->flags & SEC_RELOC) == 0)
383 relsize = bfd_get_reloc_upper_bound(rel_bfd, r);
386 printf("%s(%d): no relocation entries section=0x%x\n",
387 __FILE__, __LINE__, r->name);
391 symb = get_symbols(rel_bfd, &nsymb);
392 relpp = (arelent **) xmalloc(relsize);
393 relcount = bfd_canonicalize_reloc(rel_bfd, r, relpp, symb);
396 printf("%s(%d): no relocation entries section=%s\n",
397 __FILE__, __LINE__, r->name);
400 for (p = relpp; (relcount && (*p != NULL)); p++, relcount--) {
401 unsigned char *r_mem;
402 int relocation_needed = 0;
404 #ifdef TARGET_microblaze
405 /* The MICROBLAZE_XX_NONE relocs can be skipped.
406 They represent PC relative branches that the
407 linker has already resolved */
409 switch ((*p)->howto->type)
411 case R_MICROBLAZE_NONE:
412 case R_MICROBLAZE_64_NONE:
415 #endif /* TARGET_microblaze */
418 /* Skip this relocation entirely if possible (we
419 do this early, before doing any other
420 processing on it). */
421 switch ((*p)->howto->type) {
422 #ifdef R_V850_9_PCREL
425 #ifdef R_V850_22_PCREL
426 case R_V850_22_PCREL:
428 #ifdef R_V850_SDA_16_16_OFFSET
429 case R_V850_SDA_16_16_OFFSET:
431 #ifdef R_V850_SDA_15_16_OFFSET
432 case R_V850_SDA_15_16_OFFSET:
434 #ifdef R_V850_ZDA_15_16_OFFSET
435 case R_V850_ZDA_15_16_OFFSET:
437 #ifdef R_V850_TDA_6_8_OFFSET
438 case R_V850_TDA_6_8_OFFSET:
440 #ifdef R_V850_TDA_7_8_OFFSET
441 case R_V850_TDA_7_8_OFFSET:
443 #ifdef R_V850_TDA_7_7_OFFSET
444 case R_V850_TDA_7_7_OFFSET:
446 #ifdef R_V850_TDA_16_16_OFFSET
447 case R_V850_TDA_16_16_OFFSET:
449 #ifdef R_V850_TDA_4_5_OFFSET
450 case R_V850_TDA_4_5_OFFSET:
452 #ifdef R_V850_TDA_4_4_OFFSET
453 case R_V850_TDA_4_4_OFFSET:
455 #ifdef R_V850_SDA_16_16_SPLIT_OFFSET
456 case R_V850_SDA_16_16_SPLIT_OFFSET:
458 #ifdef R_V850_CALLT_6_7_OFFSET
459 case R_V850_CALLT_6_7_OFFSET:
461 #ifdef R_V850_CALLT_16_16_OFFSET
462 case R_V850_CALLT_16_16_OFFSET:
464 /* These are relative relocations, which
465 have already been fixed up by the
466 linker at this point, so just ignore
470 #endif /* USE_V850_RELOCS */
473 if (q->sym_ptr_ptr && *q->sym_ptr_ptr) {
474 sym_name = (*(q->sym_ptr_ptr))->name;
475 sym_section = (*(q->sym_ptr_ptr))->section;
476 section_name=(*(q->sym_ptr_ptr))->section->name;
478 printf("ERROR: undefined relocation entry\n");
482 /* Adjust the address to account for the GOT table which wasn't
483 * present in the relative file link.
486 q->address += got_size;
488 /* A pointer to what's being relocated, used often
490 r_mem = sectionp + q->address;
493 * Fixup offset in the actual section.
497 if ((sym_addr = get_symbol_offset((char *) sym_name,
498 sym_section, symbols, number_of_symbols)) == -1) {
502 sym_addr = (*(q->sym_ptr_ptr))->value;
505 /* Use the address of the symbol already in
506 the program text. How this is handled may
507 still depend on the particular relocation
509 switch (q->howto->type) {
513 /* We specially handle adjacent
514 HI16_S/ZDA_15_16_OFFSET and
515 HI16_S/LO16 pairs that reference the
516 same address (these are usually
517 movhi/ld and movhi/movea pairs,
520 r2_type = R_V850_NONE;
522 r2_type = p[1]->howto->type;
523 if ((r2_type == R_V850_ZDA_15_16_OFFSET
524 || r2_type == R_V850_LO16)
525 && (p[0]->sym_ptr_ptr
526 == p[1]->sym_ptr_ptr)
527 && (p[0]->addend == p[1]->addend))
529 relocation_needed = 1;
532 case R_V850_ZDA_15_16_OFFSET:
540 /* We don't really need the
541 actual value -- the bits
542 produced by the linker are
543 what we want in the final
544 flat file -- but get it
548 unsigned char *r2_mem =
556 /* Sign extend LO. */
560 /* Maybe ignore the LSB
564 if (r2_type != R_V850_LO16)
572 goto bad_v850_reloc_err;
576 /* See if this is actually the
577 2nd half of a pair. */
579 && (p[-1]->howto->type
581 && (p[-1]->sym_ptr_ptr
582 == p[0]->sym_ptr_ptr)
583 && (p[-1]->addend == p[0]->addend))
584 break; /* not an error */
586 goto bad_v850_reloc_err;
590 printf("ERROR: reloc type %s unsupported in this context\n",
594 #endif /* TARGET_V850 */
597 /* The default is to assume that the
598 relocation is relative and has
599 already been fixed up by the
600 linker (perhaps we ought to make
601 give an error by default, and
602 require `safe' relocations to be
603 enumberated explicitly?). */
604 if (bfd_big_endian (abs_bfd))
616 relocation_needed = 1;
619 /* Calculate the sym address ourselves. */
620 sym_reloc_size = bfd_get_reloc_size(q->howto);
622 #if !defined(TARGET_h8300) && !defined(TARGET_e1)
623 if (sym_reloc_size != 4) {
624 printf("ERROR: bad reloc type %d size=%d for symbol=%s\n",
625 (*p)->howto->type, sym_reloc_size, sym_name);
632 switch ((*p)->howto->type) {
634 #if defined(TARGET_m68k)
636 relocation_needed = 1;
637 sym_vma = bfd_section_vma(abs_bfd, sym_section);
638 sym_addr += sym_vma + q->addend;
642 sym_addr += sym_vma + q->addend;
643 sym_addr -= q->address;
647 #if defined(TARGET_arm)
649 relocation_needed = 1;
652 "%s vma=0x%x, value=0x%x, address=0x%x "
653 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
655 sym_vma, (*(q->sym_ptr_ptr))->value,
656 q->address, sym_addr,
657 (*p)->howto->rightshift,
658 *(unsigned long *)r_mem);
659 sym_vma = bfd_section_vma(abs_bfd, sym_section);
660 sym_addr += sym_vma + q->addend;
664 /* Should be fine as is */
669 "%s vma=0x%x, value=0x%x, address=0x%x "
670 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
672 sym_vma, (*(q->sym_ptr_ptr))->value,
673 q->address, sym_addr,
674 (*p)->howto->rightshift,
675 *(unsigned long *)r_mem);
678 sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift;
684 relocation_needed = 1;
685 sym_vma = bfd_section_vma(abs_bfd, sym_section);
686 sym_addr += sym_vma + q->addend;
688 #if defined(R_V850_ZDA_16_16_OFFSET) || defined(R_V850_ZDA_16_16_SPLIT_OFFSET)
689 #ifdef R_V850_ZDA_16_16_OFFSET
690 case R_V850_ZDA_16_16_OFFSET:
692 #ifdef R_V850_ZDA_16_16_SPLIT_OFFSET
693 case R_V850_ZDA_16_16_SPLIT_OFFSET:
695 /* Can't support zero-relocations. */
696 printf ("ERROR: %s+0x%x: zero relocations not supported\n",
697 sym_name, q->addend);
699 #endif /* R_V850_ZDA_16_16_OFFSET || R_V850_ZDA_16_16_SPLIT_OFFSET */
700 #endif /* TARGET_v850 */
704 if (sym_reloc_size != 4) {
705 printf("R_H8_DIR24R8 size %d\n", sym_reloc_size);
709 relocation_needed = 1;
710 sym_addr = (*(q->sym_ptr_ptr))->value;
712 r_mem -= 1; /* tracks q->address */
713 sym_vma = bfd_section_vma(abs_bfd, sym_section);
714 sym_addr += sym_vma + q->addend;
715 sym_addr |= (*(unsigned char *)r_mem<<24);
718 if (sym_reloc_size != 4) {
719 printf("R_H8_DIR24A8 size %d\n", sym_reloc_size);
723 /* Absolute symbol done not relocation */
724 relocation_needed = !bfd_is_abs_section(sym_section);
725 sym_addr = (*(q->sym_ptr_ptr))->value;
726 sym_vma = bfd_section_vma(abs_bfd, sym_section);
727 sym_addr += sym_vma + q->addend;
730 case R_H8_DIR32A16: /* currently 32, could be made 16 */
731 if (sym_reloc_size != 4) {
732 printf("R_H8_DIR32 size %d\n", sym_reloc_size);
736 relocation_needed = 1;
737 sym_addr = (*(q->sym_ptr_ptr))->value;
738 sym_vma = bfd_section_vma(abs_bfd, sym_section);
739 sym_addr += sym_vma + q->addend;
743 sym_addr = (*(q->sym_ptr_ptr))->value;
744 sym_addr += sym_vma + q->addend;
745 sym_addr -= (q->address + 2);
746 if (bfd_big_endian(abs_bfd))
747 *(unsigned short *)r_mem =
748 bfd_big_endian(abs_bfd) ? htons(sym_addr) : sym_addr;
752 sym_addr = (*(q->sym_ptr_ptr))->value;
753 sym_addr += sym_vma + q->addend;
754 sym_addr -= (q->address + 1);
755 *(unsigned char *)r_mem = sym_addr;
759 #ifdef TARGET_microblaze
760 case R_MICROBLAZE_64:
761 /* The symbol is split over two consecutive instructions.
762 Flag this to the flat loader by setting the high bit of
763 the relocation symbol. */
765 unsigned char *p = r_mem;
766 unsigned long offset;
769 /* work out the relocation */
770 sym_vma = bfd_section_vma(abs_bfd, sym_section);
771 /* grab any offset from the text */
772 offset = (p[2]<<24) + (p[3] << 16) + (p[6] << 8) + (p[7]);
773 /* Update the address */
774 sym_addr += offset + sym_vma + q->addend;
775 /* Write relocated pointer back */
776 p[2] = (sym_addr >> 24) & 0xff;
777 p[3] = (sym_addr >> 16) & 0xff;
778 p[6] = (sym_addr >> 8) & 0xff;
779 p[7] = sym_addr & 0xff;
781 /* create a new reloc entry */
782 flat_relocs = realloc(flat_relocs,
783 (flat_reloc_count + 1) * sizeof(unsigned long));
784 flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address);
786 relocation_needed = 0;
788 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
789 bfd_section_vma(abs_bfd, sym_section));
791 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
792 "section=%s size=%d "
793 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
794 q->address, sym_name, addstr,
795 section_name, sym_reloc_size,
796 sym_addr, section_vma + q->address);
798 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
799 section_vma + q->address);
803 case R_MICROBLAZE_32:
805 unsigned char *p = r_mem;
806 unsigned long offset;
808 /* grab any offset from the text */
809 offset = (p[0]<<24) + (p[1] << 16) + (p[2] << 8) + (p[3]);
810 sym_vma = bfd_section_vma(abs_bfd, sym_section);
811 /* This is a horrible kludge. For some
812 reason, *sometimes* the offset is in
813 both addend and the code. Detect
814 it, and cancel the effect. Otherwise
815 the offset gets added twice - ouch.
816 There should be a better test
817 for this condition, based on the
818 BFD data structures */
819 if(offset==q->addend)
822 sym_addr += offset + sym_vma + q->addend;
823 relocation_needed = 1;
826 case R_MICROBLAZE_64_PCREL:
828 //sym_addr = (*(q->sym_ptr_ptr))->value;
829 sym_addr += sym_vma + q->addend;
830 sym_addr -= (q->address + 4);
831 sym_addr = htonl(sym_addr);
833 * ((unsigned short *) (r_mem+2)) |= (sym_addr) & 0xFFFF;
835 * ((unsigned short *) (r_mem+6)) |= (sym_addr >> 16) & 0xFFFF;
836 /* We've done all the work, so continue
837 to next reloc instead of break */
840 #endif /* TARGET_microblaze */
845 relocation_needed = 1;
846 sym_vma = bfd_section_vma(abs_bfd, sym_section);
847 sym_addr += sym_vma + q->addend;
851 sym_addr += sym_vma + q->addend;
852 sym_addr -= q->address;
854 case R_SPARC_WDISP30:
855 sym_addr = (((*(q->sym_ptr_ptr))->value-
856 q->address) >> 2) & 0x3fffffff;
858 ntohl(*(unsigned long *)r_mem)
863 relocation_needed = 1;
865 sym_vma = bfd_section_vma(abs_bfd, sym_section);
866 sym_addr += sym_vma + q->addend;
868 htonl(*(unsigned long *)r_mem)
873 relocation_needed = 1;
875 sym_vma = bfd_section_vma(abs_bfd, sym_section);
876 sym_addr += sym_vma + q->addend;
877 sym_addr &= 0x000003ff;
879 htonl(*(unsigned long *)r_mem)
883 #endif /* TARGET_sparc */
887 relocation_needed = 1;
888 sym_vma = bfd_section_vma(abs_bfd, sym_section);
889 sym_addr += sym_vma + q->addend;
893 sym_addr += sym_vma + q->addend;
894 sym_addr -= q->address;
896 #endif /* TARGET_sh */
899 #define htoe1l(x) htonl(x)
906 #define DBG_E1 printf
908 #define DBG_E1(x, ... )
911 #define _32BITS_RELOC 0x00000000
912 #define _30BITS_RELOC 0x80000000
913 #define _28BITS_RELOC 0x40000000
916 unsigned long sec_vma, exist_val, S;
918 relocation_needed = 1;
919 DBG_E1("Handling Reloc <CONST31>\n");
920 sec_vma = bfd_section_vma(abs_bfd, sym_section);
921 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
922 sec_vma, sym_addr, q->address);
923 sym_addr = sec_vma + sym_addr;
924 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
925 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
926 exist_val = htoe1l(exist_val);
927 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
928 sym_addr += exist_val;
929 pflags = _30BITS_RELOC;
931 case R_E1_CONST31_PCREL:
932 relocation_needed = 0;
933 DBG_E1("Handling Reloc <CONST31_PCREL>\n");
934 DBG_E1("DONT RELOCATE AT LOADING\n");
935 sec_vma = bfd_section_vma(abs_bfd, sym_section);
936 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
937 sec_vma, sym_addr, q->address);
938 sym_addr = sec_vma + sym_addr;
939 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
941 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
943 q->address = q->address + section_vma;
944 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
946 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
947 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
948 DBG_E1( "sym_addr := sym_addr - q->address - "
949 "sizeof(CONST31_PCREL): [0x%x]\n",
951 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
952 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
953 exist_val = htoe1l(exist_val);
954 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
955 sym_addr |= exist_val;
956 DBG_E1("sym_addr |= exist_val) : [0x%x]\n", sym_addr );
958 case R_E1_DIS29W_PCREL:
959 relocation_needed = 0;
960 DBG_E1("Handling Reloc <DIS29W_PCREL>\n");
961 DBG_E1("DONT RELOCATE AT LOADING\n");
962 sec_vma = bfd_section_vma(abs_bfd, sym_section);
963 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
964 sec_vma, sym_addr, q->address);
965 sym_addr = sec_vma + sym_addr;
966 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
968 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
970 q->address = q->address + section_vma;
971 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
973 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
974 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
975 DBG_E1( "sym_addr := sym_addr - q->address - "
976 "sizeof(CONST31_PCREL): [0x%x]\n",
978 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
979 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
980 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
981 exist_val = htoe1l(exist_val);
982 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
983 sym_addr += exist_val;
986 DBG_E1("Handling Reloc <DIS29W>\n");
987 goto DIS29_RELOCATION;
989 DBG_E1("Handling Reloc <DIS29H>\n");
990 goto DIS29_RELOCATION;
992 DBG_E1("Handling Reloc <DIS29B>\n");
994 relocation_needed = 1;
995 sec_vma = bfd_section_vma(abs_bfd, sym_section);
996 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%08x]\n",
998 sym_addr = sec_vma + sym_addr;
999 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%08x]\n", sym_addr);
1000 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1001 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1002 exist_val = htoe1l(exist_val);
1003 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1004 sym_addr += exist_val;
1005 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1006 pflags = _28BITS_RELOC;
1008 case R_E1_IMM32_PCREL:
1009 relocation_needed = 0;
1010 DBG_E1("Handling Reloc <IMM32_PCREL>\n");
1011 DBG_E1("DONT RELOCATE AT LOADING\n");
1012 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1013 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1015 sym_addr = sec_vma + sym_addr;
1017 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1018 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1020 q->address = q->address + section_vma;
1021 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1023 if( (sym_addr = (sym_addr - q->address - 6 )) < 0 )
1024 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1025 DBG_E1( "sym_addr := sym_addr - q->address - "
1026 "sizeof(CONST31_PCREL): [0x%x]\n",
1028 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1029 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1030 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1031 exist_val = htoe1l(exist_val);
1032 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1033 sym_addr += exist_val;
1036 relocation_needed = 1;
1037 DBG_E1("Handling Reloc <IMM32>\n");
1038 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1039 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1041 sym_addr = sec_vma + sym_addr;
1042 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1043 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1044 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1045 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1046 exist_val = htoe1l(exist_val);
1047 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1048 sym_addr += exist_val;
1049 pflags = _32BITS_RELOC;
1052 relocation_needed = 1;
1053 DBG_E1("Handling Reloc <WORD>\n");
1054 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1055 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1057 sym_addr = sec_vma + sym_addr;
1058 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1059 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address );
1060 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1061 exist_val = htoe1l(exist_val);
1062 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1063 sym_addr += exist_val;
1064 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1065 pflags = _32BITS_RELOC;
1068 #undef _32BITS_RELOC
1069 #undef _30BITS_RELOC
1070 #undef _28BITS_RELOC
1073 /* missing support for other types of relocs */
1074 printf("ERROR: bad reloc type %d\n", (*p)->howto->type);
1080 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
1081 bfd_section_vma(abs_bfd, sym_section));
1085 * for full elf relocation we have to write back the
1086 * start_code relative value to use.
1088 if (!pic_with_got) {
1089 #if defined(TARGET_arm)
1098 * horrible nasty hack to support different endianess
1100 if (!bfd_big_endian(abs_bfd)) {
1112 tmp.l = *(unsigned long *)r_mem;
1113 hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16);
1114 if (((*p)->howto->type != R_ARM_PC24) &&
1115 ((*p)->howto->type != R_ARM_PLT32))
1116 hl |= (tmp.c[i3] << 24);
1117 else if (tmp.c[i2] & 0x80)
1118 hl |= 0xff000000; /* sign extend */
1120 tmp.c[i0] = hl & 0xff;
1121 tmp.c[i1] = (hl >> 8) & 0xff;
1122 tmp.c[i2] = (hl >> 16) & 0xff;
1123 if (((*p)->howto->type != R_ARM_PC24) &&
1124 ((*p)->howto->type != R_ARM_PLT32))
1125 tmp.c[i3] = (hl >> 24) & 0xff;
1126 if ((*p)->howto->type == R_ARM_ABS32)
1127 *(unsigned long *)r_mem = htonl(hl);
1129 *(unsigned long *)r_mem = tmp.l;
1131 #elif defined(TARGET_e1)
1132 #define OPCODE_SIZE 2 /* Add 2 bytes, counting the opcode size*/
1133 switch ((*p)->howto->type) {
1135 case R_E1_CONST31_PCREL:
1136 case R_E1_DIS29W_PCREL:
1140 case R_E1_IMM32_PCREL:
1142 DBG_E1("In addr + 2:[0x%x] <- write [0x%x]\n",
1143 (sectionp + q->address + 2), sym_addr );
1144 *((unsigned long *) (sectionp + q->address + OPCODE_SIZE)) =
1148 DBG_E1("In addr : [0x%x] <- write [0x%x]\n",
1149 (sectionp + q->address), sym_addr );
1150 *((unsigned long *) (sectionp + q->address )) = htonl(sym_addr);
1153 printf("ERROR:Unhandled Relocation. Exiting...\n");
1157 #else /* ! TARGET_arm && ! TARGET_e1 */
1159 switch (q->howto->type) {
1164 /* Do nothing -- for cases we handle,
1165 the bits produced by the linker are
1166 what we want in the final flat file
1167 (and other cases are errors). Note
1168 that unlike most relocated values,
1169 it is stored in little-endian order,
1170 but this is necessary to avoid
1171 trashing the low-bit, and the float
1172 loaders knows about it. */
1174 #endif /* TARGET_V850 */
1176 /* The alignment of the build host
1177 might be stricter than that of the
1178 target, so be careful. We store in
1179 network byte order. */
1180 r_mem[0] = (sym_addr >> 24) & 0xff;
1181 r_mem[1] = (sym_addr >> 16) & 0xff;
1182 r_mem[2] = (sym_addr >> 8) & 0xff;
1183 r_mem[3] = sym_addr & 0xff;
1185 #endif /* !TARGET_arm */
1189 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
1190 "section=%s size=%d "
1191 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
1192 q->address, sym_name, addstr,
1193 section_name, sym_reloc_size,
1194 sym_addr, section_vma + q->address);
1197 * Create relocation entry (PC relative doesn't need this).
1199 if (relocation_needed) {
1200 flat_relocs = realloc(flat_relocs,
1201 (flat_reloc_count + 1) * sizeof(unsigned long));
1203 flat_relocs[flat_reloc_count] = pflags |
1204 (section_vma + q->address);
1207 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
1208 section_vma + q->address);
1210 switch ((*p)->howto->type) {
1212 case R_E1_CONST31_PCREL:
1213 case R_E1_DIS29W_PCREL:
1217 case R_E1_IMM32_PCREL:
1219 flat_relocs[flat_reloc_count] = pflags |
1220 (section_vma + q->address + OPCODE_SIZE);
1222 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1223 flat_relocs[flat_reloc_count] );
1226 flat_relocs[flat_reloc_count] = pflags |
1227 (section_vma + q->address);
1229 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1230 flat_relocs[flat_reloc_count] );
1235 relocation_needed = 0;
1240 printf("%s(%d): symbol name=%s address=0x%x section=%s -> RELOC=0x%x\n",
1241 __FILE__, __LINE__, sym_name, q->address, section_name,
1242 flat_relocs[flat_reloc_count]);
1249 printf("%d bad relocs\n", bad_relocs);
1256 *n_relocs = flat_reloc_count;
1263 /* shared lib symbols stuff */
1266 get_symbol(char *name, asection *sec, asymbol **symbol_table, long number_of_symbols)
1269 for (i=0; i<number_of_symbols; i++) {
1270 if (symbol_table[i]->section == sec) {
1271 if (!strcmp(symbol_table[i]->name, name)) {
1272 return symbol_table[i]->value;
1280 output_offset_table(int fd, char *ename, bfd *abfd, asymbol **symbol_table, long number_of_symbols)
1291 signed short *tab = malloc(32768); /* we don't know how many yet*/
1293 asection *text_section = bfd_get_section_by_name (abfd, ".text");
1295 if (!(ef = fopen(ename, "rb"))) {
1296 fprintf (stderr,"Can't open %s\n",ename);
1300 fgets(libname, 80, ef);
1302 if (number_of_symbols < 0) {
1303 fprintf (stderr,"Corrupt symbol table!\n");
1307 if ((etext_addr = get_symbol("etext",
1310 number_of_symbols)) == -1) {
1311 fprintf (stderr,"Can't find the symbol etext\n");
1317 buf[strlen(buf)-1] = 0; /* Arrrgh! linefeeds */
1319 if ((sym_addr = get_symbol(buf,
1322 number_of_symbols)) == -1) {
1323 fprintf (stderr,"Can't find the symbol %s\n",buf);
1326 tab[++count] = htons(sym_addr - etext_addr);
1334 fprintf (stderr,"*** %d symbols not found\n",foobar);
1338 strcpy((char *)&tab[++count],libname);
1339 tab[0] = htons(count * 2);
1340 write(fd, tab, count * 2 + strlen(libname) + 2);
1346 static char * program;
1348 static void usage(void)
1350 fprintf(stderr, "Usage: %s [vrzd] [-p <abs-pic-file>] [-s stack-size] "
1351 "[-o <output-file>] <elf-file>\n\n"
1352 " -v : verbose operation\n"
1353 " -r : force load to RAM\n"
1354 " -k : enable kernel trace on load (for debug)\n"
1355 " -z : compress code/data/relocs\n"
1356 " -d : compress data/relocs\n"
1357 " -a : use existing symbol references\n"
1358 " instead of recalculating from\n"
1359 " relocation info\n"
1360 " -R reloc-file : read relocations from a separate file\n"
1361 " -p abs-pic-file : GOT/PIC processing with files\n"
1362 " -s stacksize : set application stack size\n"
1363 " -o output-file : output file name\n\n",
1365 fprintf(stderr, "Compiled for " ARCH " architecture\n\n");
1370 /* Write NUM zeroes to STREAM. */
1371 static void write_zeroes (unsigned long num, FILE *stream)
1375 /* It'd be nice if we could just use fseek, but that doesn't seem to
1376 work for stdio output files. */
1377 bzero(zeroes, 1024);
1378 while (num > sizeof(zeroes)) {
1379 fwrite(zeroes, sizeof(zeroes), 1, stream);
1380 num -= sizeof(zeroes);
1383 fwrite(zeroes, num, 1, stream);
1388 int main(int argc, char *argv[])
1391 bfd *rel_bfd, *abs_bfd;
1393 char *ofile=NULL, *pfile=NULL, *abs_file = NULL, *rel_file = NULL;
1402 asymbol **symbol_table;
1403 long number_of_symbols;
1405 unsigned long data_len = 0;
1406 unsigned long bss_len = 0;
1407 unsigned long text_len = 0;
1408 unsigned long reloc_len;
1410 unsigned long data_vma = ~0;
1411 unsigned long bss_vma = ~0;
1412 unsigned long text_vma = ~0;
1414 unsigned long text_offs;
1418 unsigned long *reloc;
1420 struct flat_hdr hdr;
1432 #else /* We need plenty of stack for both of them (Aggregate and Register) */
1436 while ((opt = getopt(argc, argv, "avzdrkp:s:o:R:")) != -1) {
1463 stack = atoi(optarg);
1469 fprintf(stderr, "%s Unknown option\n", argv[0]);
1476 * if neither the -r or -p options was given, default to
1477 * a RAM load as that is the only option that makes sense.
1479 if (!load_to_ram && !pfile)
1482 filename = fname = argv[argc-1];
1493 if (!(rel_bfd = bfd_openr(rel_file, 0))) {
1494 fprintf(stderr, "Can't open %s\n", rel_file);
1498 if (bfd_check_format (rel_bfd, bfd_object) == 0) {
1499 fprintf(stderr, "File is not an object file\n");
1503 if (abs_file == rel_file)
1504 abs_bfd = rel_bfd; /* one file does all */
1506 if (!(abs_bfd = bfd_openr(abs_file, 0))) {
1507 fprintf(stderr, "Can't open %s\n", abs_file);
1511 if (bfd_check_format (abs_bfd, bfd_object) == 0) {
1512 fprintf(stderr, "File is not an object file\n");
1517 if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC)) {
1518 fprintf (stderr, "%s: Input file contains no relocation info\n", rel_file);
1522 if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P)) {
1523 /* `Absolute' file is not absolute, so neither are address
1524 contained therein. */
1526 "%s: `-a' option specified with non-fully-resolved input file\n",
1527 bfd_get_filename (abs_bfd));
1531 symbol_table = get_symbols(abs_bfd, &number_of_symbols);
1533 /* Group output sections into text, data, and bss, and calc their sizes. */
1534 for (s = abs_bfd->sections; s != NULL; s = s->next) {
1535 unsigned long *vma, *len;
1536 bfd_size_type sec_size;
1539 if (s->flags & SEC_CODE) {
1542 } else if (s->flags & SEC_DATA) {
1545 } else if (s->flags & SEC_ALLOC) {
1551 sec_size = bfd_section_size(abs_bfd, s);
1552 sec_vma = bfd_section_vma(abs_bfd, s);
1554 if (sec_vma < *vma) {
1556 *len += sec_vma - *vma;
1560 } else if (sec_vma + sec_size > *vma + *len)
1561 *len = sec_vma + sec_size - *vma;
1564 if (text_len == 0) {
1565 fprintf (stderr, "%s: no .text section", abs_file);
1569 text = malloc(text_len);
1572 printf("TEXT -> vma=0x%x len=0x%x\n", text_vma, text_len);
1574 /* Read in all text sections. */
1575 for (s = abs_bfd->sections; s != NULL; s = s->next)
1576 if (s->flags & SEC_CODE)
1577 if (!bfd_get_section_contents(abs_bfd, s,
1578 text + (s->vma - text_vma), 0,
1579 bfd_section_size(abs_bfd, s)))
1581 fprintf(stderr, "read error section %s\n", s->name);
1585 if (data_len == 0) {
1586 fprintf (stderr, "%s: no .data section", abs_file);
1589 data = malloc(data_len);
1592 printf("DATA -> vma=0x%x len=0x%x\n", data_vma, data_len);
1594 if ((text_vma + text_len) != data_vma) {
1595 if ((text_vma + text_len) > data_vma) {
1596 printf("ERROR: text=0x%x overlaps data=0x%x ?\n", text_len, data_vma);
1600 printf("WARNING: data=0x%x does not directly follow text=0x%x\n",
1601 data_vma, text_len);
1602 text_len = data_vma - text_vma;
1605 /* Read in all data sections. */
1606 for (s = abs_bfd->sections; s != NULL; s = s->next)
1607 if (s->flags & SEC_DATA)
1608 if (!bfd_get_section_contents(abs_bfd, s,
1609 data + (s->vma - data_vma), 0,
1610 bfd_section_size(abs_bfd, s)))
1612 fprintf(stderr, "read error section %s\n", s->name);
1616 /* Put common symbols in bss. */
1617 bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len);
1620 printf("BSS -> vma=0x%x len=0x%x\n", bss_vma, bss_len);
1622 if ((data_vma + data_len) != bss_vma) {
1623 if ((data_vma + data_len) > bss_vma) {
1624 printf("ERROR: text=0x%x + data=0x%x overlaps bss=0x%x ?\n", text_len,
1629 printf("WARNING: bss=0x%x does not directly follow text=0x%x + data=0x%x(0x%x)\n",
1630 bss_vma, text_len, data_len, text_len + data_len);
1631 data_len = bss_vma - data_vma;
1634 reloc = (unsigned long *)
1635 output_relocs(abs_bfd, symbol_table, number_of_symbols, &reloc_len,
1636 text, text_len, text_vma, data, data_len, data_vma, rel_bfd);
1639 printf("No relocations in code!\n");
1641 text_offs = real_address_bits(text_vma);
1643 /* Fill in the binflt_flat header */
1644 memcpy(hdr.magic,"bFLT",4);
1645 hdr.rev = htonl(FLAT_VERSION);
1646 hdr.entry = htonl(16 * 4 + bfd_get_start_address(abs_bfd));
1647 hdr.data_start = htonl(16 * 4 + text_offs + text_len);
1648 hdr.data_end = htonl(16 * 4 + text_offs + text_len + data_len);
1649 hdr.bss_end = htonl(16 * 4 + text_offs + text_len + data_len + bss_len);
1650 hdr.stack_size = htonl(stack); /* FIXME */
1651 hdr.reloc_start = htonl(16 * 4 + text_offs + text_len + data_len);
1652 hdr.reloc_count = htonl(reloc_len);
1654 | (load_to_ram ? FLAT_FLAG_RAM : 0)
1655 | (ktrace ? FLAT_FLAG_KTRACE : 0)
1656 | (pic_with_got ? FLAT_FLAG_GOTPIC : 0)
1657 | (compress ? (compress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
1659 hdr.build_date = htonl((unsigned long)time(NULL));
1660 bzero(hdr.filler, sizeof(hdr.filler));
1662 for (i=0; i<reloc_len; i++) reloc[i] = htonl(reloc[i]);
1665 printf("SIZE: .text=0x%04x, .data=0x%04x, .bss=0x%04x",
1666 text_len, data_len, bss_len);
1668 printf(", relocs=0x%04x", reloc_len);
1673 ofile = malloc(strlen(fname) + 5 + 1); /* 5 to add suffix */
1674 strcpy(ofile, fname);
1675 strcat(ofile, ".bflt");
1678 if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0) {
1679 fprintf (stderr, "Can't open output file %s\n", ofile);
1683 write(fd, &hdr, sizeof(hdr));
1687 * get the compression command ready
1689 sprintf(cmd, "gzip -f -9 >> %s", ofile);
1691 #define START_COMPRESSOR do { \
1697 if (!(gf = popen(cmd, "wb"))) { \
1698 fprintf(stderr, "Can't run cmd %s\n", cmd); \
1704 gf = fopen(ofile, "ab"); /* Add 'b' to support non-posix (ie windows) */
1706 fprintf(stderr, "Can't open file %s for writing\n", ofile); \
1713 /* Fill in any hole at the beginning of the text segment. */
1715 printf("ZERO before text len=0x%x\n", text_offs);
1716 write_zeroes(text_offs, gf);
1718 /* Write the text segment. */
1719 fwrite(text, text_len, 1, gf);
1724 /* Write the data segment. */
1725 fwrite(data, data_len, 1, gf);
1728 fwrite(reloc, reloc_len * 4, 1, gf);