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) 2006 Support the -a (use_resolved) option for TARGET_arm.
10 * Shaun Jackman <sjackman@gmail.com>
11 * (c) 2004, Nios II support, Wentao Xu <wentao@microtronix.com>
12 * (c) 2003, H8 support, ktrace <davidm@snapgear.com>
13 * (c) 2003-2004, MicroBlaze support, John Williams <jwilliams@itee.uq.edu.au>
14 * (c) 2001-2003, arm/arm-pic/arm-big-endian support <davidm@snapgear.com>
15 * (c) 2001, v850 changes, Mile Bader <miles@lsi.nec.co.jp>
16 * (c) 2003, SuperH support, Paul Mundt <lethal@linux-sh.org>
17 * (c) 2001, zflat support <davidm@snapgear.com>
18 * (c) 2001, Changes for GOT entries Paul Dale <pauli@snapgear.com> and
19 * David McCullough <davidm@snapgear.com>
21 * Now supports PIC with GOT tables. This works by taking a '.elf' file
22 * and a fully linked elf executable (at address 0) and produces a flat
23 * file that can be loaded with some fixups. It still supports the old
24 * style fully relocatable elf format files.
26 * Originally obj-res.c
28 * (c) 1998, Kenneth Albanowski <kjahds@kjahds.com>
29 * (c) 1998, D. Jeff Dionne
30 * (c) 1998, The Silver Hammer Group Ltd.
31 * (c) 1996, 1997 Dionne & Associates <jeff@ryeham.ee.ryerson.ca>
33 * This is Free Software, under the GNU Public Licence v2 or greater.
35 * Relocation added March 1997, Kresten Krab Thorup
36 * krab@california.daimi.aau.dk
39 #include <stdio.h> /* Userland pieces of the ANSI C standard I/O package */
40 #include <stdlib.h> /* Userland prototypes of the ANSI C std lib functions */
41 #include <stdarg.h> /* Allows va_list to exist in the these namespaces */
42 #include <string.h> /* Userland prototypes of the string handling funcs */
44 #include <unistd.h> /* Userland prototypes of the Unix std system calls */
45 #include <fcntl.h> /* Flag value for file handling functions */
48 #include <netinet/in.h> /* Consts and structs defined by the internet system */
49 #define BINARY_FILE_OPTS
52 #define BINARY_FILE_OPTS "b"
55 /* from $(INSTALLDIR)/include */
56 #include <bfd.h> /* Main header file for the BFD library */
57 #include <libiberty.h>
59 #if defined(TARGET_h8300)
60 #include <elf/h8.h> /* TARGET_* ELF support for the BFD library */
61 #elif defined(__CYGWIN__) || defined(__MINGW32__) || defined(TARGET_nios) || defined(TARGET_nios2)
62 #include "cygwin-elf.h" /* Cygwin uses a local copy */
63 #elif defined(TARGET_microblaze)
64 #include <elf/microblaze.h> /* TARGET_* ELF support for the BFD library */
65 #elif defined(TARGET_bfin)
68 #include <elf.h> /* TARGET_* ELF support for the BFD library */
71 #if defined(__MINGW32__)
75 /* from uClinux-x.x.x/include/linux */
76 #include "flat.h" /* Binary flat header description */
87 #if defined(TARGET_m68k)
88 #define ARCH "m68k/coldfire"
89 #elif defined(TARGET_arm)
91 #elif defined(TARGET_sparc)
93 #elif defined(TARGET_v850)
95 #elif defined(TARGET_sh)
97 #elif defined(TARGET_h8300)
99 #elif defined(TARGET_microblaze)
100 #define ARCH "microblaze"
101 #elif defined(TARGET_e1)
102 #define ARCH "e1-coff"
103 #elif defined(TARGET_bfin)
105 #define FLAT_RELOC_TYPE_TEXT 0
106 #define FLAT_RELOC_TYPE_DATA 1
107 #define FLAT_RELOC_TYPE_BSS 2
108 #define FLAT_RELOC_TYPE_STACK 3
109 #define FLAT_RELOC_PART_LO 0
110 #define FLAT_RELOC_PART_HI 1
111 #define PCREL24_MAGIC_OFFSET -1
112 #elif defined(TARGET_nios)
114 #elif defined(TARGET_nios2)
117 #error "Don't know how to support your CPU architecture??"
120 #if defined(TARGET_m68k) || defined(TARGET_h8300) || defined(TARGET_bfin)
122 * Define a maximum number of bytes allowed in the offset table.
123 * We'll fail if the table is larger than this.
125 * This limit may be different for platforms other than m68k, but
126 * 8000 entries is a lot, trust me :-) (davidm)
128 #define GOT_LIMIT 32767
130 * we have to mask out the shared library id here and there, this gives
131 * us the real address bits when needed
133 #define real_address_bits(x) (pic_with_got ? ((x) & 0xffffff) : (x))
135 #define real_address_bits(x) (x)
143 int verbose = 0; /* extra output when running */
144 int pic_with_got = 0; /* do elf/got processing with PIC code */
145 int load_to_ram = 0; /* instruct loader to allocate everything into RAM */
146 int ktrace = 0; /* instruct loader output kernel trace on load */
147 int docompress = 0; /* 1 = compress everything, 2 = compress data only */
148 int use_resolved = 0; /* If true, get the value of symbol references from */
149 /* the program contents, not from the relocation table. */
150 /* In this case, the input ELF file must be already */
151 /* fully resolved (using the `-q' flag with recent */
152 /* versions of GNU ld will give you a fully resolved */
153 /* output file with relocation entries). */
155 const char *progname, *filename;
161 static char where[200];
164 /* Use exactly one of these: */
165 E_NOFILE = 0, /* "progname: " */
166 E_FILE = 1, /* "filename: " */
167 E_FILELINE = 2, /* "filename:lineno: " */
168 E_FILEWHERE = 3, /* "filename:%s: " -- set %s with ewhere() */
170 /* Add in any of these with |': */
175 void ewhere (const char *format, ...);
176 void einfo (int type, const char *format, ...);
180 ewhere (const char *format, ...) {
182 va_start (args, format);
183 vsprintf (where, format, args);
189 einfo (int type, const char *format, ...) {
192 switch (type & 0x0f) {
194 fprintf (stderr, "%s: ", progname);
197 fprintf (stderr, "%s: ", filename);
200 ewhere ("%d", lineno);
203 fprintf (stderr, "%s:%s: ", filename, where);
207 if (type & E_WARNING) {
208 fprintf (stderr, "warning: ");
214 va_start (args, format);
215 vfprintf (stderr, format, args);
221 fprintf (stderr, "\n");
226 get_symbols (bfd *abfd, long *num)
229 asymbol **symbol_table;
230 long number_of_symbols;
232 storage_needed = bfd_get_symtab_upper_bound (abfd);
234 if (storage_needed < 0)
237 if (storage_needed == 0)
240 symbol_table = xmalloc (storage_needed);
242 number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
244 if (number_of_symbols < 0)
247 *num = number_of_symbols;
254 dump_symbols(asymbol **symbol_table, long number_of_symbols)
257 printf("SYMBOL TABLE:\n");
258 for (i=0; i<number_of_symbols; i++) {
259 printf(" NAME=%s VALUE=0x%x\n", symbol_table[i]->name,
260 symbol_table[i]->value);
269 get_symbol_offset(char *name, asection *sec, asymbol **symbol_table, long number_of_symbols)
272 for (i=0; i<number_of_symbols; i++) {
273 if (symbol_table[i]->section == sec) {
274 if (!strcmp(symbol_table[i]->name, name)) {
275 return symbol_table[i]->value;
285 get_gp_value(asymbol **symbol_table, long number_of_symbols)
288 for (i=0; i<number_of_symbols; i++) {
289 if (!strcmp(symbol_table[i]->name, "_gp"))
290 return symbol_table[i]->value;
298 add_com_to_bss(asymbol **symbol_table, long number_of_symbols, long bss_len)
304 for (i=0; i<number_of_symbols; i++) {
305 if (strcmp("*COM*", symbol_table[i]->section->name) == 0) {
306 offset = bss_len + comsize;
307 comsize += symbol_table[i]->value;
308 symbol_table[i]->value = offset;
315 /* FUNCTION : weak_und_symbol
316 ABSTRACT : return true if symbol is weak and undefined.
319 weak_und_symbol(const char *reloc_section_name,
320 struct bfd_symbol *symbol)
322 if (!(strstr (reloc_section_name, "text")
323 || strstr (reloc_section_name, "data")
324 || strstr (reloc_section_name, "bss"))) {
325 if (symbol->flags & BSF_WEAK) {
327 fprintf(stderr, "found weak undefined symbol %s\n", symbol->name);
336 bfin_set_reloc (uint32_t *reloc,
337 const char *reloc_section_name,
338 const char *sym_name,
339 struct bfd_symbol *symbol,
340 int sp, int hilo, int32_t offset)
345 if (strstr (reloc_section_name, "text"))
346 type = FLAT_RELOC_TYPE_TEXT;
347 else if (strstr (reloc_section_name, "data"))
348 type = FLAT_RELOC_TYPE_DATA;
349 else if (strstr (reloc_section_name, "bss"))
350 type = FLAT_RELOC_TYPE_BSS;
351 else if (strstr (reloc_section_name, "stack"))
352 type = FLAT_RELOC_TYPE_STACK;
353 else if (symbol->flags & BSF_WEAK){
354 /* weak symbol support ... if a weak symbol is undefined at the
355 end of a final link, it should return 0 rather than error
356 We will assume text section for the moment.
358 type = FLAT_RELOC_TYPE_TEXT;
359 } else if (strstr (reloc_section_name, "*ABS*")){
360 /* (A data section initialization of something in the shared libc's text section
361 does not resolve - i.e. a global pointer to function initialized with
363 The text section here is appropriate as the section information
364 of the shared library is lost. The loader will do some calcs.
366 type = FLAT_RELOC_TYPE_TEXT;
368 printf ("Unknown Type - relocation for %s in bad section - %s\n", sym_name, reloc_section_name);
372 val = (offset & ((1 << 26) - 1)) << 6;
373 val |= (sp & (1 << 3) - 1) << 3;
374 val |= (hilo & 1) << 2;
375 val |= (type & (1 << 2) - 1);
386 int number_of_symbols,
387 unsigned long *n_relocs,
388 unsigned char *text, int text_len, unsigned long text_vma,
389 unsigned char *data, int data_len, unsigned long data_vma,
392 uint32_t *flat_relocs;
393 asection *a, *sym_section, *r;
394 arelent **relpp, **p, *q;
395 const char *sym_name, *section_name;
396 unsigned char *sectionp;
397 unsigned long pflags;
399 long sym_addr, sym_vma, section_vma;
400 int relsize, relcount;
401 int flat_reloc_count;
402 int sym_reloc_size, rc;
409 printf("%s(%d): output_relocs(abs_bfd=%d,synbols=0x%x,number_of_symbols=%d"
410 "n_relocs=0x%x,text=0x%x,text_len=%d,data=0x%x,data_len=%d)\n",
411 __FILE__, __LINE__, abs_bfd, symbols, number_of_symbols, n_relocs,
412 text, text_len, data, data_len);
416 dump_symbols(symbols, number_of_symbols);
421 flat_reloc_count = 0;
425 /* Determine how big our offset table is in bytes.
426 * This isn't too difficult as we've terminated the table with -1.
427 * Also note that both the relocatable and absolute versions have this
428 * terminator even though the relocatable one doesn't have the GOT!
430 if (pic_with_got && !use_resolved) {
431 unsigned long *lp = (unsigned long *)data;
432 /* Should call ntohl(*lp) here but is isn't going to matter */
433 while (*lp != 0xffffffff) lp++;
434 got_size = ((unsigned char *)lp) - data;
436 printf("GOT table contains %d entries (%d bytes)\n",
437 got_size/sizeof(unsigned long), got_size);
439 if (got_size > GOT_LIMIT) {
440 fprintf(stderr, "GOT too large: %d bytes (limit = %d bytes)\n",
441 got_size, GOT_LIMIT);
447 for (a = abs_bfd->sections; (a != (asection *) NULL); a = a->next) {
448 section_vma = bfd_section_vma(abs_bfd, a);
451 printf("SECTION: %s [0x%x]: flags=0x%x vma=0x%x\n", a->name, a,
452 a->flags, section_vma);
454 // if (bfd_is_abs_section(a))
456 if (bfd_is_und_section(a))
458 if (bfd_is_com_section(a))
460 // if ((a->flags & SEC_RELOC) == 0)
464 * Only relocate things in the data sections if we are PIC/GOT.
465 * otherwise do text as well
467 if (!pic_with_got && (a->flags & SEC_CODE))
468 sectionp = text + (a->vma - text_vma);
469 else if (a->flags & SEC_DATA)
470 sectionp = data + (a->vma - data_vma);
474 /* Now search for the equivalent section in the relocation binary
475 * and use that relocation information to build reloc entries
478 for (r=rel_bfd->sections; r != NULL; r=r->next)
479 if (strcmp(a->name, r->name) == 0)
484 printf(" RELOCS: %s [0x%x]: flags=0x%x vma=0x%x\n", r->name, r,
485 r->flags, bfd_section_vma(abs_bfd, r));
486 if ((r->flags & SEC_RELOC) == 0)
488 relsize = bfd_get_reloc_upper_bound(rel_bfd, r);
491 printf("%s(%d): no relocation entries section=0x%x\n",
492 __FILE__, __LINE__, r->name);
496 symb = get_symbols(rel_bfd, &nsymb);
497 relpp = xmalloc(relsize);
499 relcount = bfd_canonicalize_reloc(rel_bfd, r, relpp, symb);
502 printf("%s(%d): no relocation entries section=%s\n",
503 __FILE__, __LINE__, r->name);
506 for (p = relpp; (relcount && (*p != NULL)); p++, relcount--) {
507 unsigned char *r_mem;
508 int relocation_needed = 0;
510 #ifdef TARGET_microblaze
511 /* The MICROBLAZE_XX_NONE relocs can be skipped.
512 They represent PC relative branches that the
513 linker has already resolved */
515 switch ((*p)->howto->type)
517 case R_MICROBLAZE_NONE:
518 case R_MICROBLAZE_64_NONE:
521 #endif /* TARGET_microblaze */
524 /* Skip this relocation entirely if possible (we
525 do this early, before doing any other
526 processing on it). */
527 switch ((*p)->howto->type) {
528 #ifdef R_V850_9_PCREL
531 #ifdef R_V850_22_PCREL
532 case R_V850_22_PCREL:
534 #ifdef R_V850_SDA_16_16_OFFSET
535 case R_V850_SDA_16_16_OFFSET:
537 #ifdef R_V850_SDA_15_16_OFFSET
538 case R_V850_SDA_15_16_OFFSET:
540 #ifdef R_V850_ZDA_15_16_OFFSET
541 case R_V850_ZDA_15_16_OFFSET:
543 #ifdef R_V850_TDA_6_8_OFFSET
544 case R_V850_TDA_6_8_OFFSET:
546 #ifdef R_V850_TDA_7_8_OFFSET
547 case R_V850_TDA_7_8_OFFSET:
549 #ifdef R_V850_TDA_7_7_OFFSET
550 case R_V850_TDA_7_7_OFFSET:
552 #ifdef R_V850_TDA_16_16_OFFSET
553 case R_V850_TDA_16_16_OFFSET:
555 #ifdef R_V850_TDA_4_5_OFFSET
556 case R_V850_TDA_4_5_OFFSET:
558 #ifdef R_V850_TDA_4_4_OFFSET
559 case R_V850_TDA_4_4_OFFSET:
561 #ifdef R_V850_SDA_16_16_SPLIT_OFFSET
562 case R_V850_SDA_16_16_SPLIT_OFFSET:
564 #ifdef R_V850_CALLT_6_7_OFFSET
565 case R_V850_CALLT_6_7_OFFSET:
567 #ifdef R_V850_CALLT_16_16_OFFSET
568 case R_V850_CALLT_16_16_OFFSET:
570 /* These are relative relocations, which
571 have already been fixed up by the
572 linker at this point, so just ignore
576 #endif /* USE_V850_RELOCS */
579 if (q->sym_ptr_ptr && *q->sym_ptr_ptr) {
580 sym_name = (*(q->sym_ptr_ptr))->name;
581 sym_section = (*(q->sym_ptr_ptr))->section;
582 section_name=(*(q->sym_ptr_ptr))->section->name;
584 printf("ERROR: undefined relocation entry\n");
589 /* Adjust the address to account for the GOT table which wasn't
590 * present in the relative file link.
592 if (pic_with_got && !use_resolved)
593 q->address += got_size;
596 /* A pointer to what's being relocated, used often
598 r_mem = sectionp + q->address;
601 * Fixup offset in the actual section.
605 if ((sym_addr = get_symbol_offset((char *) sym_name,
606 sym_section, symbols, number_of_symbols)) == -1) {
610 sym_addr = (*(q->sym_ptr_ptr))->value;
613 /* Use the address of the symbol already in
614 the program text. How this is handled may
615 still depend on the particular relocation
617 switch (q->howto->type) {
621 /* We specially handle adjacent
622 HI16_S/ZDA_15_16_OFFSET and
623 HI16_S/LO16 pairs that reference the
624 same address (these are usually
625 movhi/ld and movhi/movea pairs,
628 r2_type = R_V850_NONE;
630 r2_type = p[1]->howto->type;
631 if ((r2_type == R_V850_ZDA_15_16_OFFSET
632 || r2_type == R_V850_LO16)
633 && (p[0]->sym_ptr_ptr
634 == p[1]->sym_ptr_ptr)
635 && (p[0]->addend == p[1]->addend))
637 relocation_needed = 1;
640 case R_V850_ZDA_15_16_OFFSET:
648 /* We don't really need the
649 actual value -- the bits
650 produced by the linker are
651 what we want in the final
652 flat file -- but get it
656 unsigned char *r2_mem =
664 /* Sign extend LO. */
668 /* Maybe ignore the LSB
672 if (r2_type != R_V850_LO16)
680 goto bad_resolved_reloc;
684 /* See if this is actually the
685 2nd half of a pair. */
687 && (p[-1]->howto->type
689 && (p[-1]->sym_ptr_ptr
690 == p[0]->sym_ptr_ptr)
691 && (p[-1]->addend == p[0]->addend))
692 break; /* not an error */
694 goto bad_resolved_reloc;
697 goto bad_resolved_reloc;
699 goto good_32bit_resolved_reloc;
700 #elif defined(TARGET_arm)
702 relocation_needed = 1;
707 relocation_needed = 0;
710 goto bad_resolved_reloc;
711 #elif defined(TARGET_m68k)
713 goto good_32bit_resolved_reloc;
716 /* The linker has already resolved
717 PC relocs for us. In PIC links,
718 the symbol must be in the data
723 goto bad_resolved_reloc;
726 /* The default is to assume that the
727 relocation is relative and has
728 already been fixed up by the
729 linker (perhaps we ought to make
730 give an error by default, and
731 require `safe' relocations to be
732 enumberated explicitly?). */
733 goto good_32bit_resolved_reloc;
735 good_32bit_resolved_reloc:
736 if (bfd_big_endian (abs_bfd))
748 relocation_needed = 1;
752 printf("ERROR: reloc type %s unsupported in this context\n",
758 /* Calculate the sym address ourselves. */
759 sym_reloc_size = bfd_get_reloc_size(q->howto);
761 #if !defined(TARGET_h8300) && !defined(TARGET_e1) && !defined(TARGET_bfin) && !defined(TARGET_m68k)
762 if (sym_reloc_size != 4) {
763 printf("ERROR: bad reloc type %d size=%d for symbol=%s\n",
764 (*p)->howto->type, sym_reloc_size, sym_name);
771 switch ((*p)->howto->type) {
773 #if defined(TARGET_m68k)
775 relocation_needed = 1;
776 sym_vma = bfd_section_vma(abs_bfd, sym_section);
777 sym_addr += sym_vma + q->addend;
782 sym_addr += sym_vma + q->addend;
783 sym_addr -= q->address;
787 #if defined(TARGET_arm)
789 relocation_needed = 1;
792 "%s vma=0x%x, value=0x%x, address=0x%x "
793 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
795 sym_vma, (*(q->sym_ptr_ptr))->value,
796 q->address, sym_addr,
797 (*p)->howto->rightshift,
798 *(unsigned long *)r_mem);
799 sym_vma = bfd_section_vma(abs_bfd, sym_section);
800 sym_addr += sym_vma + q->addend;
804 /* Should be fine as is */
809 "%s vma=0x%x, value=0x%x, address=0x%x "
810 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
812 sym_vma, (*(q->sym_ptr_ptr))->value,
813 q->address, sym_addr,
814 (*p)->howto->rightshift,
815 *(unsigned long *)r_mem);
818 sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift;
824 relocation_needed = 1;
825 sym_vma = bfd_section_vma(abs_bfd, sym_section);
826 sym_addr += sym_vma + q->addend;
828 #if defined(R_V850_ZDA_16_16_OFFSET) || defined(R_V850_ZDA_16_16_SPLIT_OFFSET)
829 #ifdef R_V850_ZDA_16_16_OFFSET
830 case R_V850_ZDA_16_16_OFFSET:
832 #ifdef R_V850_ZDA_16_16_SPLIT_OFFSET
833 case R_V850_ZDA_16_16_SPLIT_OFFSET:
835 /* Can't support zero-relocations. */
836 printf ("ERROR: %s+0x%x: zero relocations not supported\n",
837 sym_name, q->addend);
839 #endif /* R_V850_ZDA_16_16_OFFSET || R_V850_ZDA_16_16_SPLIT_OFFSET */
840 #endif /* TARGET_v850 */
844 if (sym_reloc_size != 4) {
845 printf("R_H8_DIR24R8 size %d\n", sym_reloc_size);
849 relocation_needed = 1;
850 sym_addr = (*(q->sym_ptr_ptr))->value;
852 r_mem -= 1; /* tracks q->address */
853 sym_vma = bfd_section_vma(abs_bfd, sym_section);
854 sym_addr += sym_vma + q->addend;
855 sym_addr |= (*(unsigned char *)r_mem<<24);
858 if (sym_reloc_size != 4) {
859 printf("R_H8_DIR24A8 size %d\n", sym_reloc_size);
863 /* Absolute symbol done not relocation */
864 relocation_needed = !bfd_is_abs_section(sym_section);
865 sym_addr = (*(q->sym_ptr_ptr))->value;
866 sym_vma = bfd_section_vma(abs_bfd, sym_section);
867 sym_addr += sym_vma + q->addend;
870 case R_H8_DIR32A16: /* currently 32, could be made 16 */
871 if (sym_reloc_size != 4) {
872 printf("R_H8_DIR32 size %d\n", sym_reloc_size);
876 relocation_needed = 1;
877 sym_addr = (*(q->sym_ptr_ptr))->value;
878 sym_vma = bfd_section_vma(abs_bfd, sym_section);
879 sym_addr += sym_vma + q->addend;
883 sym_addr = (*(q->sym_ptr_ptr))->value;
884 sym_addr += sym_vma + q->addend;
885 sym_addr -= (q->address + 2);
886 if (bfd_big_endian(abs_bfd))
887 *(unsigned short *)r_mem =
888 bfd_big_endian(abs_bfd) ? htons(sym_addr) : sym_addr;
892 sym_addr = (*(q->sym_ptr_ptr))->value;
893 sym_addr += sym_vma + q->addend;
894 sym_addr -= (q->address + 1);
895 *(unsigned char *)r_mem = sym_addr;
899 #ifdef TARGET_microblaze
900 case R_MICROBLAZE_64:
901 /* The symbol is split over two consecutive instructions.
902 Flag this to the flat loader by setting the high bit of
903 the relocation symbol. */
905 unsigned char *p = r_mem;
906 unsigned long offset;
909 /* work out the relocation */
910 sym_vma = bfd_section_vma(abs_bfd, sym_section);
911 /* grab any offset from the text */
912 offset = (p[2]<<24) + (p[3] << 16) + (p[6] << 8) + (p[7]);
913 /* Update the address */
914 sym_addr += offset + sym_vma + q->addend;
915 /* Write relocated pointer back */
916 p[2] = (sym_addr >> 24) & 0xff;
917 p[3] = (sym_addr >> 16) & 0xff;
918 p[6] = (sym_addr >> 8) & 0xff;
919 p[7] = sym_addr & 0xff;
921 /* create a new reloc entry */
922 flat_relocs = realloc(flat_relocs,
923 (flat_reloc_count + 1) * sizeof(uint32_t));
924 flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address);
926 relocation_needed = 0;
928 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
929 bfd_section_vma(abs_bfd, sym_section));
931 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
932 "section=%s size=%d "
933 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
934 q->address, sym_name, addstr,
935 section_name, sym_reloc_size,
936 sym_addr, section_vma + q->address);
938 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
939 section_vma + q->address);
943 case R_MICROBLAZE_32:
945 unsigned char *p = r_mem;
946 unsigned long offset;
948 /* grab any offset from the text */
949 offset = (p[0]<<24) + (p[1] << 16) + (p[2] << 8) + (p[3]);
950 sym_vma = bfd_section_vma(abs_bfd, sym_section);
951 /* This is a horrible kludge. For some
952 reason, *sometimes* the offset is in
953 both addend and the code. Detect
954 it, and cancel the effect. Otherwise
955 the offset gets added twice - ouch.
956 There should be a better test
957 for this condition, based on the
958 BFD data structures */
959 if(offset==q->addend)
962 sym_addr += offset + sym_vma + q->addend;
963 relocation_needed = 1;
966 case R_MICROBLAZE_64_PCREL:
968 //sym_addr = (*(q->sym_ptr_ptr))->value;
969 sym_addr += sym_vma + q->addend;
970 sym_addr -= (q->address + 4);
971 sym_addr = htonl(sym_addr);
973 * ((unsigned short *) (r_mem+2)) |= (sym_addr) & 0xFFFF;
975 * ((unsigned short *) (r_mem+6)) |= (sym_addr >> 16) & 0xFFFF;
976 /* We've done all the work, so continue
977 to next reloc instead of break */
980 #endif /* TARGET_microblaze */
983 #define htoniosl(x) (x)
984 #define niostohl(x) (x)
985 case R_NIOS2_BFD_RELOC_32:
986 relocation_needed = 1;
987 pflags = (FLAT_NIOS2_R_32 << 28);
988 sym_vma = bfd_section_vma(abs_bfd, sym_section);
989 sym_addr += sym_vma + q->addend;
990 /* modify target, in target order */
991 *(unsigned long *)r_mem = htoniosl(sym_addr);
995 unsigned long exist_val;
996 relocation_needed = 1;
997 pflags = (FLAT_NIOS2_R_CALL26 << 28);
998 sym_vma = bfd_section_vma(abs_bfd, sym_section);
999 sym_addr += sym_vma + q->addend;
1001 /* modify target, in target order */
1002 // exist_val = niostohl(*(unsigned long *)r_mem);
1003 exist_val = ((sym_addr >> 2) << 6);
1004 *(unsigned long *)r_mem = htoniosl(exist_val);
1007 case R_NIOS2_HIADJ16:
1010 unsigned long exist_val;
1012 /* handle the adjacent HI/LO pairs */
1014 r2_type = R_NIOS2_NONE;
1016 r2_type = p[1]->howto->type;
1017 if ((r2_type == R_NIOS2_LO16)
1018 && (p[0]->sym_ptr_ptr == p[1]->sym_ptr_ptr)
1019 && (p[0]->addend == p[1]->addend))
1021 unsigned char * r2_mem = sectionp + p[1]->address;
1022 if (p[1]->address - q->address!=4)
1023 printf("Err: HI/LO not adjacent %d\n", p[1]->address - q->address);
1024 relocation_needed = 1;
1025 pflags = (q->howto->type == R_NIOS2_HIADJ16)
1026 ? FLAT_NIOS2_R_HIADJ_LO : FLAT_NIOS2_R_HI_LO;
1029 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1030 sym_addr += sym_vma + q->addend;
1032 /* modify high 16 bits, in target order */
1033 exist_val = niostohl(*(unsigned long *)r_mem);
1034 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1035 if (q->howto->type == R_NIOS2_HIADJ16)
1036 exist_val |= ((((sym_addr >> 16) + ((sym_addr >> 15) & 1)) & 0xFFFF) << 6);
1038 exist_val |= (((sym_addr >> 16) & 0xFFFF) << 6);
1039 *(unsigned long *)r_mem = htoniosl(exist_val);
1041 /* modify low 16 bits, in target order */
1042 exist_val = niostohl(*(unsigned long *)r2_mem);
1043 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1044 exist_val |= ((sym_addr & 0xFFFF) << 6);
1045 *(unsigned long *)r2_mem = htoniosl(exist_val);
1048 goto NIOS2_RELOC_ERR;
1054 unsigned long exist_val, temp;
1055 //long gp = get_symbol_offset("_gp", sym_section, symbols, number_of_symbols);
1056 long gp = get_gp_value(symbols, number_of_symbols);
1058 printf("Err: unresolved symbol _gp when relocating %s\n", sym_name);
1059 goto NIOS2_RELOC_ERR;
1061 /* _gp holds a absolute value, otherwise the ld cannot generate correct code */
1062 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1063 //printf("sym=%x, %d, _gp=%x, %d\n", sym_addr+sym_vma, sym_addr+sym_vma, gp, gp);
1064 sym_addr += sym_vma + q->addend;
1066 //printf("sym - _gp=%x, %d\n", sym_addr, sym_addr);
1067 /* modify the target, in target order (little_endian) */
1068 exist_val = niostohl(*(unsigned long *)r_mem);
1069 temp = ((exist_val >> 6) & 0x3ff0000) | (sym_addr & 0xffff);
1071 temp |= (exist_val & 0x3f);
1072 *(unsigned long *)r_mem = htoniosl(temp);
1074 printf("omit: offset=0x%x symbol=%s%s "
1075 "section=%s size=%d "
1076 "fixup=0x%x (reloc=0x%x) GPREL\n",
1077 q->address, sym_name, addstr,
1078 section_name, sym_reloc_size,
1079 sym_addr, section_vma + q->address);
1082 case R_NIOS2_PCREL16:
1084 unsigned long exist_val;
1086 sym_addr += sym_vma + q->addend;
1087 sym_addr -= (q->address + 4);
1088 /* modify the target, in target order (little_endian) */
1089 exist_val = niostohl(*(unsigned long *)r_mem);
1090 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1091 exist_val |= ((sym_addr & 0xFFFF) << 6);
1092 *(unsigned long *)r_mem = htoniosl(exist_val);
1094 printf("omit: offset=0x%x symbol=%s%s "
1095 "section=%s size=%d "
1096 "fixup=0x%x (reloc=0x%x) PCREL\n",
1097 q->address, sym_name, addstr,
1098 section_name, sym_reloc_size,
1099 sym_addr, section_vma + q->address);
1104 /* check if this is actually the 2nd half of a pair */
1106 && ((p[-1]->howto->type == R_NIOS2_HIADJ16)
1107 || (p[-1]->howto->type == R_NIOS2_HI16))
1108 && (p[-1]->sym_ptr_ptr == p[0]->sym_ptr_ptr)
1109 && (p[-1]->addend == p[0]->addend)) {
1111 printf("omit: offset=0x%x symbol=%s%s "
1112 "section=%s size=%d LO16\n",
1113 q->address, sym_name, addstr,
1114 section_name, sym_reloc_size);
1118 /* error, fall through */
1122 case R_NIOS2_CACHE_OPX:
1126 case R_NIOS2_BFD_RELOC_16:
1127 case R_NIOS2_BFD_RELOC_8:
1128 case R_NIOS2_GNU_VTINHERIT:
1129 case R_NIOS2_GNU_VTENTRY:
1134 printf("Err: unexpected reloc type %s(%d)\n", q->howto->name, q->howto->type);
1137 #endif /* TARGET_nios2 */
1142 relocation_needed = 1;
1143 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1144 sym_addr += sym_vma + q->addend;
1148 sym_addr += sym_vma + q->addend;
1149 sym_addr -= q->address;
1151 case R_SPARC_WDISP30:
1152 sym_addr = (((*(q->sym_ptr_ptr))->value-
1153 q->address) >> 2) & 0x3fffffff;
1155 ntohl(*(unsigned long *)r_mem)
1160 relocation_needed = 1;
1161 pflags = 0x80000000;
1162 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1163 sym_addr += sym_vma + q->addend;
1165 htonl(*(unsigned long *)r_mem)
1170 relocation_needed = 1;
1171 pflags = 0x40000000;
1172 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1173 sym_addr += sym_vma + q->addend;
1174 sym_addr &= 0x000003ff;
1176 htonl(*(unsigned long *)r_mem)
1180 #endif /* TARGET_sparc */
1183 case R_pcrel12_jump:
1184 case R_pcrel12_jump_s:
1186 case R_pcrel24_jump_l:
1187 case R_pcrel24_jump_x:
1188 case R_pcrel24_call_x:
1192 sym_addr += q->addend;// get the symbol addr
1193 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1194 sym_addr -= q->address; // make it PC relative
1195 // implicitly assumes code section and symbol section are same
1202 sym_addr += q->addend;
1203 if(weak_und_symbol(sym_section->name, (*(q->sym_ptr_ptr))))
1205 if(0xFFFF0000 & sym_addr){
1206 fprintf (stderr, "Relocation overflow for rN = %s\n",sym_name);
1209 flat_relocs = (uint32_t *)
1210 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1211 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1212 sym_section->name, sym_name,
1213 (*(q->sym_ptr_ptr)),
1214 0, FLAT_RELOC_PART_LO,
1215 section_vma + q->address))
1224 unsigned int reloc_count_incr;
1227 if (q->howto->type == R_luimm16)
1228 hi_lo = FLAT_RELOC_PART_LO;
1230 hi_lo = FLAT_RELOC_PART_HI;
1232 sym_addr += q->addend;
1234 flat_relocs = (uint32_t *)
1235 (realloc (flat_relocs, (flat_reloc_count + 2) * sizeof (uint32_t)));
1236 reloc_count_incr = 1;
1237 if (weak_und_symbol (sym_section->name, (*(q->sym_ptr_ptr))))
1239 if (0xFFFF0000 & sym_addr) {
1240 /* value is > 16 bits - use an extra field */
1241 /* see if we have already output that symbol */
1242 /* reloc may be addend from symbol and */
1243 /* we can only store 16 bit offsets */
1245 if ((*(q->sym_ptr_ptr))->udata.i == 0
1246 || flat_relocs[(*(q->sym_ptr_ptr))->udata.i] != sym_addr
1247 || ((*(q->sym_ptr_ptr))->udata.i & 0xFFFF0000))
1249 reloc_count_incr = 2;
1250 flat_relocs[flat_reloc_count + 1] = sym_addr;
1251 (*(q->sym_ptr_ptr))->udata.i = flat_reloc_count + 1;
1252 sym_addr = 0; // indication to loader to read next
1254 sym_addr = (*(q->sym_ptr_ptr))->udata.i;
1260 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1261 sym_section->name, sym_name,
1262 (*(q->sym_ptr_ptr)),
1264 section_vma + q->address))
1266 flat_reloc_count += reloc_count_incr;
1270 sym_addr += q->addend;
1272 if (weak_und_symbol (sym_section->name, *q->sym_ptr_ptr))
1275 flat_relocs = (uint32_t *)
1276 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1277 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1278 sym_section->name, sym_name,
1279 (*(q->sym_ptr_ptr)),
1280 2, FLAT_RELOC_PART_LO,
1281 section_vma + q->address))
1287 #endif //TARGET_bfin
1291 relocation_needed = 1;
1292 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1293 sym_addr += sym_vma + q->addend;
1297 sym_addr += sym_vma + q->addend;
1298 sym_addr -= q->address;
1300 #endif /* TARGET_sh */
1303 #define htoe1l(x) htonl(x)
1310 #define DBG_E1 printf
1312 #define DBG_E1(x, ... )
1315 #define _32BITS_RELOC 0x00000000
1316 #define _30BITS_RELOC 0x80000000
1317 #define _28BITS_RELOC 0x40000000
1320 unsigned long sec_vma, exist_val, S;
1322 relocation_needed = 1;
1323 DBG_E1("Handling Reloc <CONST31>\n");
1324 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1325 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1326 sec_vma, sym_addr, q->address);
1327 sym_addr = sec_vma + sym_addr;
1328 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1329 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1330 exist_val = htoe1l(exist_val);
1331 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1332 sym_addr += exist_val;
1333 pflags = _30BITS_RELOC;
1335 case R_E1_CONST31_PCREL:
1336 relocation_needed = 0;
1337 DBG_E1("Handling Reloc <CONST31_PCREL>\n");
1338 DBG_E1("DONT RELOCATE AT LOADING\n");
1339 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1340 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1341 sec_vma, sym_addr, q->address);
1342 sym_addr = sec_vma + sym_addr;
1343 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1345 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1347 q->address = q->address + section_vma;
1348 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1350 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1351 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1352 DBG_E1( "sym_addr := sym_addr - q->address - "
1353 "sizeof(CONST31_PCREL): [0x%x]\n",
1355 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1356 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1357 exist_val = htoe1l(exist_val);
1358 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1359 sym_addr |= exist_val;
1360 DBG_E1("sym_addr |= exist_val) : [0x%x]\n", sym_addr );
1362 case R_E1_DIS29W_PCREL:
1363 relocation_needed = 0;
1364 DBG_E1("Handling Reloc <DIS29W_PCREL>\n");
1365 DBG_E1("DONT RELOCATE AT LOADING\n");
1366 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1367 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1368 sec_vma, sym_addr, q->address);
1369 sym_addr = sec_vma + sym_addr;
1370 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1372 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1374 q->address = q->address + section_vma;
1375 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1377 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1378 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1379 DBG_E1( "sym_addr := sym_addr - q->address - "
1380 "sizeof(CONST31_PCREL): [0x%x]\n",
1382 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1383 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1384 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1385 exist_val = htoe1l(exist_val);
1386 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1387 sym_addr += exist_val;
1390 DBG_E1("Handling Reloc <DIS29W>\n");
1391 goto DIS29_RELOCATION;
1393 DBG_E1("Handling Reloc <DIS29H>\n");
1394 goto DIS29_RELOCATION;
1396 DBG_E1("Handling Reloc <DIS29B>\n");
1398 relocation_needed = 1;
1399 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1400 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%08x]\n",
1402 sym_addr = sec_vma + sym_addr;
1403 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%08x]\n", sym_addr);
1404 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1405 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1406 exist_val = htoe1l(exist_val);
1407 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1408 sym_addr += exist_val;
1409 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1410 pflags = _28BITS_RELOC;
1412 case R_E1_IMM32_PCREL:
1413 relocation_needed = 0;
1414 DBG_E1("Handling Reloc <IMM32_PCREL>\n");
1415 DBG_E1("DONT RELOCATE AT LOADING\n");
1416 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1417 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1419 sym_addr = sec_vma + sym_addr;
1421 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1422 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1424 q->address = q->address + section_vma;
1425 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1427 if( (sym_addr = (sym_addr - q->address - 6 )) < 0 )
1428 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1429 DBG_E1( "sym_addr := sym_addr - q->address - "
1430 "sizeof(CONST31_PCREL): [0x%x]\n",
1432 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1433 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1434 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1435 exist_val = htoe1l(exist_val);
1436 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1437 sym_addr += exist_val;
1440 relocation_needed = 1;
1441 DBG_E1("Handling Reloc <IMM32>\n");
1442 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1443 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1445 sym_addr = sec_vma + sym_addr;
1446 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1447 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1448 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1449 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1450 exist_val = htoe1l(exist_val);
1451 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1452 sym_addr += exist_val;
1453 pflags = _32BITS_RELOC;
1456 relocation_needed = 1;
1457 DBG_E1("Handling Reloc <WORD>\n");
1458 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1459 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1461 sym_addr = sec_vma + sym_addr;
1462 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1463 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address );
1464 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1465 exist_val = htoe1l(exist_val);
1466 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1467 sym_addr += exist_val;
1468 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1469 pflags = _32BITS_RELOC;
1472 #undef _32BITS_RELOC
1473 #undef _30BITS_RELOC
1474 #undef _28BITS_RELOC
1477 /* missing support for other types of relocs */
1478 printf("ERROR: bad reloc type %d\n", (*p)->howto->type);
1484 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
1485 bfd_section_vma(abs_bfd, sym_section));
1489 * for full elf relocation we have to write back the
1490 * start_code relative value to use.
1492 if (!pic_with_got) {
1493 #if defined(TARGET_arm)
1502 * horrible nasty hack to support different endianess
1504 if (!bfd_big_endian(abs_bfd)) {
1516 tmp.l = *(unsigned long *)r_mem;
1517 hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16);
1519 (((*p)->howto->type != R_ARM_PC24) &&
1520 ((*p)->howto->type != R_ARM_PLT32)))
1521 hl |= (tmp.c[i3] << 24);
1522 else if (tmp.c[i2] & 0x80)
1523 hl |= 0xff000000; /* sign extend */
1526 tmp.c[i0] = hl & 0xff;
1527 tmp.c[i1] = (hl >> 8) & 0xff;
1528 tmp.c[i2] = (hl >> 16) & 0xff;
1530 (((*p)->howto->type != R_ARM_PC24) &&
1531 ((*p)->howto->type != R_ARM_PLT32)))
1532 tmp.c[i3] = (hl >> 24) & 0xff;
1533 if ((*p)->howto->type == R_ARM_ABS32)
1534 *(unsigned long *)r_mem = htonl(hl);
1536 *(unsigned long *)r_mem = tmp.l;
1538 #elif defined(TARGET_bfin)
1539 if ((*p)->howto->type == R_pcrel24
1540 || (*p)->howto->type == R_pcrel24_jump_l
1541 || (*p)->howto->type == R_pcrel24_jump_x
1542 || (*p)->howto->type == R_pcrel24_call_x)
1544 sym_addr += 2*-1*PCREL24_MAGIC_OFFSET;
1545 *((unsigned short *)(sectionp + q->address) + 1 + PCREL24_MAGIC_OFFSET)
1546 = (sym_addr >> 1) & 0xffff;
1547 *((unsigned short *)(sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1548 = (0xff00 & *((unsigned short *) (sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1549 | ((sym_addr >> 17) & 0xff));
1550 } else if ((*p)->howto->type == R_byte4_data) {
1551 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1552 } else if ((*p)->howto->type == R_pcrel12_jump
1553 || (*p)->howto->type == R_pcrel12_jump_s) {
1554 *((unsigned short *)(sectionp + q->address))
1555 = (0xf000 & *((unsigned short *)(sectionp + q->address))
1556 | ((sym_addr >> 1) & 0xfff));
1557 } else if ((*p)->howto->type == R_pcrel10) {
1558 *((unsigned short *)(sectionp + q->address))
1559 = (~0x3ff & *((unsigned short *)(sectionp + q->address))
1560 | ((sym_addr >> 1) & 0x3ff));
1561 } else if ((*p)->howto->type == R_rimm16
1562 || (*p)->howto->type == R_huimm16
1563 || (*p)->howto->type == R_luimm16) {
1564 /* for l and h we set the lower 16 bits which is only when it will be used */
1565 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1566 } else if ((*p)->howto->type == R_pcrel5m2) {
1567 *((unsigned short *)(sectionp + q->address))
1568 = (0xfff0 & *((unsigned short *)(sectionp + q->address))
1569 | ((sym_addr >> 1) & 0xf));
1570 } else if ((*p)->howto->type == R_pcrel11){
1571 *((unsigned short *)(sectionp + q->address))
1572 = (0xfc00 & *((unsigned short *)(sectionp + q->address))
1573 | ((sym_addr >> 1) & 0x3ff));
1574 } else if (0xE0 <= (*p)->howto->type && 0xF3 >= (*p)->howto->type) {
1575 //arith relocs dont generate a real relocation
1577 printf("Blackfin relocation fail for reloc type: 0x%x\n", (*p)->howto->type);
1579 #elif defined(TARGET_e1)
1580 #define OPCODE_SIZE 2 /* Add 2 bytes, counting the opcode size*/
1581 switch ((*p)->howto->type) {
1583 case R_E1_CONST31_PCREL:
1584 case R_E1_DIS29W_PCREL:
1588 case R_E1_IMM32_PCREL:
1590 DBG_E1("In addr + 2:[0x%x] <- write [0x%x]\n",
1591 (sectionp + q->address + 2), sym_addr );
1592 *((unsigned long *) (sectionp + q->address + OPCODE_SIZE)) =
1596 DBG_E1("In addr : [0x%x] <- write [0x%x]\n",
1597 (sectionp + q->address), sym_addr );
1598 *((unsigned long *) (sectionp + q->address )) = htonl(sym_addr);
1601 printf("ERROR:Unhandled Relocation. Exiting...\n");
1605 #else /* ! TARGET_arm && ! TARGET_e1 */
1607 switch (q->howto->type) {
1612 /* Do nothing -- for cases we handle,
1613 the bits produced by the linker are
1614 what we want in the final flat file
1615 (and other cases are errors). Note
1616 that unlike most relocated values,
1617 it is stored in little-endian order,
1618 but this is necessary to avoid
1619 trashing the low-bit, and the float
1620 loaders knows about it. */
1622 #endif /* TARGET_V850 */
1625 case R_NIOS2_BFD_RELOC_32:
1626 case R_NIOS2_CALL26:
1627 case R_NIOS2_HIADJ16:
1631 #endif /* TARGET_nios2 */
1633 #if defined(TARGET_m68k)
1635 if (sym_addr < -0x8000 || sym_addr > 0x7fff) {
1636 fprintf (stderr, "Relocation overflow for R_68K_PC16 relocation against %s\n", sym_name);
1639 r_mem[0] = (sym_addr >> 8) & 0xff;
1640 r_mem[1] = sym_addr & 0xff;
1646 /* The alignment of the build host
1647 might be stricter than that of the
1648 target, so be careful. We store in
1649 network byte order. */
1650 r_mem[0] = (sym_addr >> 24) & 0xff;
1651 r_mem[1] = (sym_addr >> 16) & 0xff;
1652 r_mem[2] = (sym_addr >> 8) & 0xff;
1653 r_mem[3] = sym_addr & 0xff;
1655 #endif /* !TARGET_arm */
1660 if ((*p)->howto->type == R_rimm16
1661 || (*p)->howto->type == R_huimm16
1662 || (*p)->howto->type == R_luimm16)
1664 /* for l and h we set the lower 16 bits which is only when it will be used */
1665 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1666 } else if ((*p)->howto->type == R_byte4_data) {
1667 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1672 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
1673 "section=%s size=%d "
1674 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
1675 q->address, sym_name, addstr,
1676 section_name, sym_reloc_size,
1677 sym_addr, section_vma + q->address);
1680 * Create relocation entry (PC relative doesn't need this).
1682 if (relocation_needed) {
1684 flat_relocs = realloc(flat_relocs,
1685 (flat_reloc_count + 1) * sizeof(uint32_t));
1687 flat_relocs[flat_reloc_count] = pflags |
1688 (section_vma + q->address);
1691 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
1692 section_vma + q->address);
1694 switch ((*p)->howto->type) {
1696 case R_E1_CONST31_PCREL:
1697 case R_E1_DIS29W_PCREL:
1701 case R_E1_IMM32_PCREL:
1703 flat_relocs[flat_reloc_count] = pflags |
1704 (section_vma + q->address + OPCODE_SIZE);
1706 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1707 flat_relocs[flat_reloc_count] );
1710 flat_relocs[flat_reloc_count] = pflags |
1711 (section_vma + q->address);
1713 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1714 flat_relocs[flat_reloc_count] );
1720 relocation_needed = 0;
1725 printf("%s(%d): symbol name=%s address=0x%x section=%s -> RELOC=0x%x\n",
1726 __FILE__, __LINE__, sym_name, q->address, section_name,
1727 flat_relocs[flat_reloc_count]);
1734 printf("%d bad relocs\n", bad_relocs);
1741 *n_relocs = flat_reloc_count;
1747 static char * program;
1749 static void usage(void)
1751 fprintf(stderr, "Usage: %s [vrzd] [-p <abs-pic-file>] [-s stack-size] "
1752 "[-o <output-file>] <elf-file>\n\n"
1753 " -v : verbose operation\n"
1754 " -r : force load to RAM\n"
1755 " -k : enable kernel trace on load (for debug)\n"
1756 " -z : compress code/data/relocs\n"
1757 " -d : compress data/relocs\n"
1758 " -a : use existing symbol references\n"
1759 " instead of recalculating from\n"
1760 " relocation info\n"
1761 " -R reloc-file : read relocations from a separate file\n"
1762 " -p abs-pic-file : GOT/PIC processing with files\n"
1763 " -s stacksize : set application stack size\n"
1764 " -o output-file : output file name\n\n",
1766 fprintf(stderr, "Compiled for " ARCH " architecture\n\n");
1771 /* Write NUM zeroes to STREAM. */
1772 static void write_zeroes (unsigned long num, stream *stream)
1776 /* It'd be nice if we could just use fseek, but that doesn't seem to
1777 work for stdio output files. */
1778 memset(zeroes, 0x00, 1024);
1779 while (num > sizeof(zeroes)) {
1780 fwrite_stream(zeroes, sizeof(zeroes), 1, stream);
1781 num -= sizeof(zeroes);
1784 fwrite_stream(zeroes, num, 1, stream);
1789 int main(int argc, char *argv[])
1792 bfd *rel_bfd, *abs_bfd;
1794 char *ofile=NULL, *pfile=NULL, *abs_file = NULL, *rel_file = NULL;
1801 asymbol **symbol_table;
1802 long number_of_symbols;
1804 unsigned long data_len = 0;
1805 unsigned long bss_len = 0;
1806 unsigned long text_len = 0;
1807 unsigned long reloc_len;
1809 unsigned long data_vma = ~0;
1810 unsigned long bss_vma = ~0;
1811 unsigned long text_vma = ~0;
1813 unsigned long text_offs;
1819 struct flat_hdr hdr;
1823 xmalloc_set_program_name(program);
1828 if (sizeof(hdr) != 64) {
1830 "Potential flat header incompatibility detected\n"
1831 "header size should be 64 but is %d\n",
1838 #else /* We need plenty of stack for both of them (Aggregate and Register) */
1842 while ((opt = getopt(argc, argv, "avzdrkp:s:o:R:")) != -1) {
1869 if (sscanf(optarg, "%i", &stack) != 1) {
1870 fprintf(stderr, "%s invalid stack size %s\n", argv[0], optarg);
1878 fprintf(stderr, "%s Unknown option\n", argv[0]);
1885 * if neither the -r or -p options was given, default to
1886 * a RAM load as that is the only option that makes sense.
1888 if (!load_to_ram && !pfile)
1891 filename = fname = argv[argc-1];
1902 if (!(rel_bfd = bfd_openr(rel_file, 0))) {
1903 fprintf(stderr, "Can't open %s\n", rel_file);
1907 if (bfd_check_format (rel_bfd, bfd_object) == 0) {
1908 fprintf(stderr, "File is not an object file\n");
1912 if (abs_file == rel_file)
1913 abs_bfd = rel_bfd; /* one file does all */
1915 if (!(abs_bfd = bfd_openr(abs_file, 0))) {
1916 fprintf(stderr, "Can't open %s\n", abs_file);
1920 if (bfd_check_format (abs_bfd, bfd_object) == 0) {
1921 fprintf(stderr, "File is not an object file\n");
1926 if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC)) {
1927 fprintf (stderr, "%s: Input file contains no relocation info\n", rel_file);
1931 if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P)) {
1932 /* `Absolute' file is not absolute, so neither are address
1933 contained therein. */
1935 "%s: `-a' option specified with non-fully-resolved input file\n",
1936 bfd_get_filename (abs_bfd));
1940 symbol_table = get_symbols(abs_bfd, &number_of_symbols);
1942 /* Group output sections into text, data, and bss, and calc their sizes. */
1943 for (s = abs_bfd->sections; s != NULL; s = s->next) {
1944 unsigned long *vma, *len;
1945 bfd_size_type sec_size;
1948 if (s->flags & SEC_CODE) {
1951 } else if (s->flags & SEC_DATA) {
1954 } else if (s->flags & SEC_ALLOC) {
1960 sec_size = bfd_section_size(abs_bfd, s);
1961 sec_vma = bfd_section_vma(abs_bfd, s);
1963 if (sec_vma < *vma) {
1965 *len += sec_vma - *vma;
1969 } else if (sec_vma + sec_size > *vma + *len)
1970 *len = sec_vma + sec_size - *vma;
1973 if (text_len == 0) {
1974 fprintf (stderr, "%s: no .text section", abs_file);
1978 text = xmalloc(text_len);
1981 printf("TEXT -> vma=0x%x len=0x%x\n", text_vma, text_len);
1983 /* Read in all text sections. */
1984 for (s = abs_bfd->sections; s != NULL; s = s->next)
1985 if (s->flags & SEC_CODE)
1986 if (!bfd_get_section_contents(abs_bfd, s,
1987 text + (s->vma - text_vma), 0,
1988 bfd_section_size(abs_bfd, s)))
1990 fprintf(stderr, "read error section %s\n", s->name);
1994 if (data_len == 0) {
1995 fprintf (stderr, "%s: no .data section", abs_file);
1998 data = xmalloc(data_len);
2001 printf("DATA -> vma=0x%x len=0x%x\n", data_vma, data_len);
2003 if ((text_vma + text_len) != data_vma) {
2004 if ((text_vma + text_len) > data_vma) {
2005 printf("ERROR: text=0x%x overlaps data=0x%x ?\n", text_len, data_vma);
2009 printf("WARNING: data=0x%x does not directly follow text=0x%x\n",
2010 data_vma, text_len);
2011 text_len = data_vma - text_vma;
2014 /* Read in all data sections. */
2015 for (s = abs_bfd->sections; s != NULL; s = s->next)
2016 if (s->flags & SEC_DATA)
2017 if (!bfd_get_section_contents(abs_bfd, s,
2018 data + (s->vma - data_vma), 0,
2019 bfd_section_size(abs_bfd, s)))
2021 fprintf(stderr, "read error section %s\n", s->name);
2025 /* Put common symbols in bss. */
2026 bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len);
2029 printf("BSS -> vma=0x%x len=0x%x\n", bss_vma, bss_len);
2031 if ((data_vma + data_len) != bss_vma) {
2032 if ((data_vma + data_len) > bss_vma) {
2033 printf("ERROR: text=0x%x + data=0x%x overlaps bss=0x%x ?\n", text_len,
2038 printf("WARNING: bss=0x%x does not directly follow text=0x%x + data=0x%x(0x%x)\n",
2039 bss_vma, text_len, data_len, text_len + data_len);
2040 data_len = bss_vma - data_vma;
2043 reloc = output_relocs(abs_bfd, symbol_table, number_of_symbols, &reloc_len,
2044 text, text_len, text_vma, data, data_len, data_vma,
2048 printf("No relocations in code!\n");
2050 text_offs = real_address_bits(text_vma);
2052 /* Fill in the binflt_flat header */
2053 memcpy(hdr.magic,"bFLT",4);
2054 hdr.rev = htonl(FLAT_VERSION);
2055 hdr.entry = htonl(sizeof(hdr) + bfd_get_start_address(abs_bfd));
2056 hdr.data_start = htonl(sizeof(hdr) + text_offs + text_len);
2057 hdr.data_end = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2058 hdr.bss_end = htonl(sizeof(hdr) + text_offs + text_len +data_len+bss_len);
2059 hdr.stack_size = htonl(stack); /* FIXME */
2060 hdr.reloc_start = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2061 hdr.reloc_count = htonl(reloc_len);
2063 | (load_to_ram ? FLAT_FLAG_RAM : 0)
2064 | (ktrace ? FLAT_FLAG_KTRACE : 0)
2065 | (pic_with_got ? FLAT_FLAG_GOTPIC : 0)
2066 | (docompress ? (docompress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
2068 hdr.build_date = htonl((unsigned long)time(NULL));
2069 memset(hdr.filler, 0x00, sizeof(hdr.filler));
2071 for (i=0; i<reloc_len; i++) reloc[i] = htonl(reloc[i]);
2074 printf("SIZE: .text=0x%04x, .data=0x%04x, .bss=0x%04x",
2075 text_len, data_len, bss_len);
2077 printf(", relocs=0x%04x", reloc_len);
2082 ofile = xmalloc(strlen(fname) + 5 + 1); /* 5 to add suffix */
2083 strcpy(ofile, fname);
2084 strcat(ofile, ".bflt");
2087 if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0) {
2088 fprintf (stderr, "Can't open output file %s\n", ofile);
2092 write(fd, &hdr, sizeof(hdr));
2095 if (fopen_stream_u(&gf, ofile, "a" BINARY_FILE_OPTS)) {
2096 fprintf(stderr, "Can't open file %s for writing\n", ofile);
2100 if (docompress == 1)
2101 reopen_stream_compressed(&gf);
2103 /* Fill in any hole at the beginning of the text segment. */
2105 printf("ZERO before text len=0x%x\n", text_offs);
2106 write_zeroes(text_offs, &gf);
2108 /* Write the text segment. */
2109 fwrite_stream(text, text_len, 1, &gf);
2111 if (docompress == 2)
2112 reopen_stream_compressed(&gf);
2114 /* Write the data segment. */
2115 fwrite_stream(data, data_len, 1, &gf);
2118 fwrite_stream(reloc, reloc_len * 4, 1, &gf);
2127 * this __MUST__ be at the VERY end of the file - do NOT move!!
2133 * vi: tabstop=8 shiftwidth=4 textwidth=79 noexpandtab