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 */
58 #if defined(TARGET_h8300)
59 #include <elf/h8.h> /* TARGET_* ELF support for the BFD library */
60 #elif defined(__CYGWIN__) || defined(__MINGW32__) || defined(TARGET_nios) || defined(TARGET_nios2)
61 #include "cygwin-elf.h" /* Cygwin uses a local copy */
62 #elif defined(TARGET_microblaze)
63 #include <elf/microblaze.h> /* TARGET_* ELF support for the BFD library */
64 #elif defined(TARGET_bfin)
67 #include <elf.h> /* TARGET_* ELF support for the BFD library */
70 #if defined(__MINGW32__)
74 /* from uClinux-x.x.x/include/linux */
75 #include "flat.h" /* Binary flat header description */
85 #if defined(TARGET_m68k)
86 #define ARCH "m68k/coldfire"
87 #elif defined(TARGET_arm)
89 #elif defined(TARGET_sparc)
91 #elif defined(TARGET_v850)
93 #elif defined(TARGET_sh)
95 #elif defined(TARGET_h8300)
97 #elif defined(TARGET_microblaze)
98 #define ARCH "microblaze"
99 #elif defined(TARGET_e1)
100 #define ARCH "e1-coff"
101 #elif defined(TARGET_bfin)
103 #define FLAT_RELOC_TYPE_TEXT 0
104 #define FLAT_RELOC_TYPE_DATA 1
105 #define FLAT_RELOC_TYPE_BSS 2
106 #define FLAT_RELOC_TYPE_STACK 3
107 #define FLAT_RELOC_PART_LO 0
108 #define FLAT_RELOC_PART_HI 1
109 #define PCREL24_MAGIC_OFFSET -1
110 #elif defined(TARGET_nios)
112 #elif defined(TARGET_nios2)
115 #error "Don't know how to support your CPU architecture??"
118 #if defined(TARGET_m68k) || defined(TARGET_h8300) || defined(TARGET_bfin)
120 * Define a maximum number of bytes allowed in the offset table.
121 * We'll fail if the table is larger than this.
123 * This limit may be different for platforms other than m68k, but
124 * 8000 entries is a lot, trust me :-) (davidm)
126 #define GOT_LIMIT 32767
128 * we have to mask out the shared library id here and there, this gives
129 * us the real address bits when needed
131 #define real_address_bits(x) (pic_with_got ? ((x) & 0xffffff) : (x))
133 #define real_address_bits(x) (x)
141 int verbose = 0; /* extra output when running */
142 int pic_with_got = 0; /* do elf/got processing with PIC code */
143 int load_to_ram = 0; /* instruct loader to allocate everything into RAM */
144 int ktrace = 0; /* instruct loader output kernel trace on load */
145 int compress = 0; /* 1 = compress everything, 2 = compress data only */
146 int use_resolved = 0; /* If true, get the value of symbol references from */
147 /* the program contents, not from the relocation table. */
148 /* In this case, the input ELF file must be already */
149 /* fully resolved (using the `-q' flag with recent */
150 /* versions of GNU ld will give you a fully resolved */
151 /* output file with relocation entries). */
153 const char *progname, *filename;
159 static char where[200];
162 /* Use exactly one of these: */
163 E_NOFILE = 0, /* "progname: " */
164 E_FILE = 1, /* "filename: " */
165 E_FILELINE = 2, /* "filename:lineno: " */
166 E_FILEWHERE = 3, /* "filename:%s: " -- set %s with ewhere() */
168 /* Add in any of these with |': */
173 void ewhere (const char *format, ...);
174 void einfo (int type, const char *format, ...);
178 ewhere (const char *format, ...) {
180 va_start (args, format);
181 vsprintf (where, format, args);
187 einfo (int type, const char *format, ...) {
190 switch (type & 0x0f) {
192 fprintf (stderr, "%s: ", progname);
195 fprintf (stderr, "%s: ", filename);
198 ewhere ("%d", lineno);
201 fprintf (stderr, "%s:%s: ", filename, where);
205 if (type & E_WARNING) {
206 fprintf (stderr, "warning: ");
212 va_start (args, format);
213 vfprintf (stderr, format, args);
219 fprintf (stderr, "\n");
224 get_symbols (bfd *abfd, long *num)
227 asymbol **symbol_table;
228 long number_of_symbols;
230 storage_needed = bfd_get_symtab_upper_bound (abfd);
232 if (storage_needed < 0)
235 if (storage_needed == 0)
238 symbol_table = xmalloc (storage_needed);
240 number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
242 if (number_of_symbols < 0)
245 *num = number_of_symbols;
252 dump_symbols(asymbol **symbol_table, long number_of_symbols)
255 printf("SYMBOL TABLE:\n");
256 for (i=0; i<number_of_symbols; i++) {
257 printf(" NAME=%s VALUE=0x%x\n", symbol_table[i]->name,
258 symbol_table[i]->value);
267 get_symbol_offset(char *name, asection *sec, asymbol **symbol_table, long number_of_symbols)
270 for (i=0; i<number_of_symbols; i++) {
271 if (symbol_table[i]->section == sec) {
272 if (!strcmp(symbol_table[i]->name, name)) {
273 return symbol_table[i]->value;
283 get_gp_value(asymbol **symbol_table, long number_of_symbols)
286 for (i=0; i<number_of_symbols; i++) {
287 if (!strcmp(symbol_table[i]->name, "_gp"))
288 return symbol_table[i]->value;
296 add_com_to_bss(asymbol **symbol_table, long number_of_symbols, long bss_len)
302 for (i=0; i<number_of_symbols; i++) {
303 if (strcmp("*COM*", symbol_table[i]->section->name) == 0) {
304 offset = bss_len + comsize;
305 comsize += symbol_table[i]->value;
306 symbol_table[i]->value = offset;
313 /* FUNCTION : weak_und_symbol
314 ABSTRACT : return true if symbol is weak and undefined.
317 weak_und_symbol(const char *reloc_section_name,
318 struct bfd_symbol *symbol)
320 if (!(strstr (reloc_section_name, "text")
321 || strstr (reloc_section_name, "data")
322 || strstr (reloc_section_name, "bss"))) {
323 if (symbol->flags & BSF_WEAK) {
325 fprintf(stderr, "found weak undefined symbol %s\n", symbol->name);
334 bfin_set_reloc (uint32_t *reloc,
335 const char *reloc_section_name,
336 const char *sym_name,
337 struct bfd_symbol *symbol,
338 int sp, int hilo, int32_t offset)
343 if (strstr (reloc_section_name, "text"))
344 type = FLAT_RELOC_TYPE_TEXT;
345 else if (strstr (reloc_section_name, "data"))
346 type = FLAT_RELOC_TYPE_DATA;
347 else if (strstr (reloc_section_name, "bss"))
348 type = FLAT_RELOC_TYPE_BSS;
349 else if (strstr (reloc_section_name, "stack"))
350 type = FLAT_RELOC_TYPE_STACK;
351 else if (symbol->flags & BSF_WEAK){
352 /* weak symbol support ... if a weak symbol is undefined at the
353 end of a final link, it should return 0 rather than error
354 We will assume text section for the moment.
356 type = FLAT_RELOC_TYPE_TEXT;
357 } else if (strstr (reloc_section_name, "*ABS*")){
358 /* (A data section initialization of something in the shared libc's text section
359 does not resolve - i.e. a global pointer to function initialized with
361 The text section here is appropriate as the section information
362 of the shared library is lost. The loader will do some calcs.
364 type = FLAT_RELOC_TYPE_TEXT;
366 printf ("Unknown Type - relocation for %s in bad section - %s\n", sym_name, reloc_section_name);
370 val = (offset & ((1 << 26) - 1)) << 6;
371 val |= (sp & (1 << 3) - 1) << 3;
372 val |= (hilo & 1) << 2;
373 val |= (type & (1 << 2) - 1);
384 int number_of_symbols,
385 unsigned long *n_relocs,
386 unsigned char *text, int text_len, unsigned long text_vma,
387 unsigned char *data, int data_len, unsigned long data_vma,
390 uint32_t *flat_relocs;
391 asection *a, *sym_section, *r;
392 arelent **relpp, **p, *q;
393 const char *sym_name, *section_name;
394 unsigned char *sectionp;
395 unsigned long pflags;
397 long sym_addr, sym_vma, section_vma;
398 int relsize, relcount;
399 int flat_reloc_count;
400 int sym_reloc_size, rc;
407 printf("%s(%d): output_relocs(abs_bfd=%d,synbols=0x%x,number_of_symbols=%d"
408 "n_relocs=0x%x,text=0x%x,text_len=%d,data=0x%x,data_len=%d)\n",
409 __FILE__, __LINE__, abs_bfd, symbols, number_of_symbols, n_relocs,
410 text, text_len, data, data_len);
414 dump_symbols(symbols, number_of_symbols);
419 flat_reloc_count = 0;
423 /* Determine how big our offset table is in bytes.
424 * This isn't too difficult as we've terminated the table with -1.
425 * Also note that both the relocatable and absolute versions have this
426 * terminator even though the relocatable one doesn't have the GOT!
428 if (pic_with_got && !use_resolved) {
429 unsigned long *lp = (unsigned long *)data;
430 /* Should call ntohl(*lp) here but is isn't going to matter */
431 while (*lp != 0xffffffff) lp++;
432 got_size = ((unsigned char *)lp) - data;
434 printf("GOT table contains %d entries (%d bytes)\n",
435 got_size/sizeof(unsigned long), got_size);
437 if (got_size > GOT_LIMIT) {
438 fprintf(stderr, "GOT too large: %d bytes (limit = %d bytes)\n",
439 got_size, GOT_LIMIT);
445 for (a = abs_bfd->sections; (a != (asection *) NULL); a = a->next) {
446 section_vma = bfd_section_vma(abs_bfd, a);
449 printf("SECTION: %s [0x%x]: flags=0x%x vma=0x%x\n", a->name, a,
450 a->flags, section_vma);
452 // if (bfd_is_abs_section(a))
454 if (bfd_is_und_section(a))
456 if (bfd_is_com_section(a))
458 // if ((a->flags & SEC_RELOC) == 0)
462 * Only relocate things in the data sections if we are PIC/GOT.
463 * otherwise do text as well
465 if (!pic_with_got && (a->flags & SEC_CODE))
466 sectionp = text + (a->vma - text_vma);
467 else if (a->flags & SEC_DATA)
468 sectionp = data + (a->vma - data_vma);
472 /* Now search for the equivalent section in the relocation binary
473 * and use that relocation information to build reloc entries
476 for (r=rel_bfd->sections; r != NULL; r=r->next)
477 if (strcmp(a->name, r->name) == 0)
482 printf(" RELOCS: %s [0x%x]: flags=0x%x vma=0x%x\n", r->name, r,
483 r->flags, bfd_section_vma(abs_bfd, r));
484 if ((r->flags & SEC_RELOC) == 0)
486 relsize = bfd_get_reloc_upper_bound(rel_bfd, r);
489 printf("%s(%d): no relocation entries section=0x%x\n",
490 __FILE__, __LINE__, r->name);
494 symb = get_symbols(rel_bfd, &nsymb);
495 relpp = xmalloc(relsize);
497 relcount = bfd_canonicalize_reloc(rel_bfd, r, relpp, symb);
500 printf("%s(%d): no relocation entries section=%s\n",
501 __FILE__, __LINE__, r->name);
504 for (p = relpp; (relcount && (*p != NULL)); p++, relcount--) {
505 unsigned char *r_mem;
506 int relocation_needed = 0;
508 #ifdef TARGET_microblaze
509 /* The MICROBLAZE_XX_NONE relocs can be skipped.
510 They represent PC relative branches that the
511 linker has already resolved */
513 switch ((*p)->howto->type)
515 case R_MICROBLAZE_NONE:
516 case R_MICROBLAZE_64_NONE:
519 #endif /* TARGET_microblaze */
522 /* Skip this relocation entirely if possible (we
523 do this early, before doing any other
524 processing on it). */
525 switch ((*p)->howto->type) {
526 #ifdef R_V850_9_PCREL
529 #ifdef R_V850_22_PCREL
530 case R_V850_22_PCREL:
532 #ifdef R_V850_SDA_16_16_OFFSET
533 case R_V850_SDA_16_16_OFFSET:
535 #ifdef R_V850_SDA_15_16_OFFSET
536 case R_V850_SDA_15_16_OFFSET:
538 #ifdef R_V850_ZDA_15_16_OFFSET
539 case R_V850_ZDA_15_16_OFFSET:
541 #ifdef R_V850_TDA_6_8_OFFSET
542 case R_V850_TDA_6_8_OFFSET:
544 #ifdef R_V850_TDA_7_8_OFFSET
545 case R_V850_TDA_7_8_OFFSET:
547 #ifdef R_V850_TDA_7_7_OFFSET
548 case R_V850_TDA_7_7_OFFSET:
550 #ifdef R_V850_TDA_16_16_OFFSET
551 case R_V850_TDA_16_16_OFFSET:
553 #ifdef R_V850_TDA_4_5_OFFSET
554 case R_V850_TDA_4_5_OFFSET:
556 #ifdef R_V850_TDA_4_4_OFFSET
557 case R_V850_TDA_4_4_OFFSET:
559 #ifdef R_V850_SDA_16_16_SPLIT_OFFSET
560 case R_V850_SDA_16_16_SPLIT_OFFSET:
562 #ifdef R_V850_CALLT_6_7_OFFSET
563 case R_V850_CALLT_6_7_OFFSET:
565 #ifdef R_V850_CALLT_16_16_OFFSET
566 case R_V850_CALLT_16_16_OFFSET:
568 /* These are relative relocations, which
569 have already been fixed up by the
570 linker at this point, so just ignore
574 #endif /* USE_V850_RELOCS */
577 if (q->sym_ptr_ptr && *q->sym_ptr_ptr) {
578 sym_name = (*(q->sym_ptr_ptr))->name;
579 sym_section = (*(q->sym_ptr_ptr))->section;
580 section_name=(*(q->sym_ptr_ptr))->section->name;
582 printf("ERROR: undefined relocation entry\n");
587 /* Adjust the address to account for the GOT table which wasn't
588 * present in the relative file link.
590 if (pic_with_got && !use_resolved)
591 q->address += got_size;
594 /* A pointer to what's being relocated, used often
596 r_mem = sectionp + q->address;
599 * Fixup offset in the actual section.
603 if ((sym_addr = get_symbol_offset((char *) sym_name,
604 sym_section, symbols, number_of_symbols)) == -1) {
608 sym_addr = (*(q->sym_ptr_ptr))->value;
611 /* Use the address of the symbol already in
612 the program text. How this is handled may
613 still depend on the particular relocation
615 switch (q->howto->type) {
619 /* We specially handle adjacent
620 HI16_S/ZDA_15_16_OFFSET and
621 HI16_S/LO16 pairs that reference the
622 same address (these are usually
623 movhi/ld and movhi/movea pairs,
626 r2_type = R_V850_NONE;
628 r2_type = p[1]->howto->type;
629 if ((r2_type == R_V850_ZDA_15_16_OFFSET
630 || r2_type == R_V850_LO16)
631 && (p[0]->sym_ptr_ptr
632 == p[1]->sym_ptr_ptr)
633 && (p[0]->addend == p[1]->addend))
635 relocation_needed = 1;
638 case R_V850_ZDA_15_16_OFFSET:
646 /* We don't really need the
647 actual value -- the bits
648 produced by the linker are
649 what we want in the final
650 flat file -- but get it
654 unsigned char *r2_mem =
662 /* Sign extend LO. */
666 /* Maybe ignore the LSB
670 if (r2_type != R_V850_LO16)
678 goto bad_resolved_reloc;
682 /* See if this is actually the
683 2nd half of a pair. */
685 && (p[-1]->howto->type
687 && (p[-1]->sym_ptr_ptr
688 == p[0]->sym_ptr_ptr)
689 && (p[-1]->addend == p[0]->addend))
690 break; /* not an error */
692 goto bad_resolved_reloc;
695 goto bad_resolved_reloc;
697 goto good_32bit_resolved_reloc;
698 #elif defined(TARGET_arm)
700 relocation_needed = 1;
705 relocation_needed = 0;
708 goto bad_resolved_reloc;
709 #elif defined(TARGET_m68k)
711 goto good_32bit_resolved_reloc;
714 /* The linker has already resolved
715 PC relocs for us. In PIC links,
716 the symbol must be in the data
721 goto bad_resolved_reloc;
724 /* The default is to assume that the
725 relocation is relative and has
726 already been fixed up by the
727 linker (perhaps we ought to make
728 give an error by default, and
729 require `safe' relocations to be
730 enumberated explicitly?). */
731 goto good_32bit_resolved_reloc;
733 good_32bit_resolved_reloc:
734 if (bfd_big_endian (abs_bfd))
746 relocation_needed = 1;
750 printf("ERROR: reloc type %s unsupported in this context\n",
756 /* Calculate the sym address ourselves. */
757 sym_reloc_size = bfd_get_reloc_size(q->howto);
759 #if !defined(TARGET_h8300) && !defined(TARGET_e1) && !defined(TARGET_bfin) && !defined(TARGET_m68k)
760 if (sym_reloc_size != 4) {
761 printf("ERROR: bad reloc type %d size=%d for symbol=%s\n",
762 (*p)->howto->type, sym_reloc_size, sym_name);
769 switch ((*p)->howto->type) {
771 #if defined(TARGET_m68k)
773 relocation_needed = 1;
774 sym_vma = bfd_section_vma(abs_bfd, sym_section);
775 sym_addr += sym_vma + q->addend;
780 sym_addr += sym_vma + q->addend;
781 sym_addr -= q->address;
785 #if defined(TARGET_arm)
787 relocation_needed = 1;
790 "%s vma=0x%x, value=0x%x, address=0x%x "
791 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
793 sym_vma, (*(q->sym_ptr_ptr))->value,
794 q->address, sym_addr,
795 (*p)->howto->rightshift,
796 *(unsigned long *)r_mem);
797 sym_vma = bfd_section_vma(abs_bfd, sym_section);
798 sym_addr += sym_vma + q->addend;
802 /* Should be fine as is */
807 "%s vma=0x%x, value=0x%x, address=0x%x "
808 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
810 sym_vma, (*(q->sym_ptr_ptr))->value,
811 q->address, sym_addr,
812 (*p)->howto->rightshift,
813 *(unsigned long *)r_mem);
816 sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift;
822 relocation_needed = 1;
823 sym_vma = bfd_section_vma(abs_bfd, sym_section);
824 sym_addr += sym_vma + q->addend;
826 #if defined(R_V850_ZDA_16_16_OFFSET) || defined(R_V850_ZDA_16_16_SPLIT_OFFSET)
827 #ifdef R_V850_ZDA_16_16_OFFSET
828 case R_V850_ZDA_16_16_OFFSET:
830 #ifdef R_V850_ZDA_16_16_SPLIT_OFFSET
831 case R_V850_ZDA_16_16_SPLIT_OFFSET:
833 /* Can't support zero-relocations. */
834 printf ("ERROR: %s+0x%x: zero relocations not supported\n",
835 sym_name, q->addend);
837 #endif /* R_V850_ZDA_16_16_OFFSET || R_V850_ZDA_16_16_SPLIT_OFFSET */
838 #endif /* TARGET_v850 */
842 if (sym_reloc_size != 4) {
843 printf("R_H8_DIR24R8 size %d\n", sym_reloc_size);
847 relocation_needed = 1;
848 sym_addr = (*(q->sym_ptr_ptr))->value;
850 r_mem -= 1; /* tracks q->address */
851 sym_vma = bfd_section_vma(abs_bfd, sym_section);
852 sym_addr += sym_vma + q->addend;
853 sym_addr |= (*(unsigned char *)r_mem<<24);
856 if (sym_reloc_size != 4) {
857 printf("R_H8_DIR24A8 size %d\n", sym_reloc_size);
861 /* Absolute symbol done not relocation */
862 relocation_needed = !bfd_is_abs_section(sym_section);
863 sym_addr = (*(q->sym_ptr_ptr))->value;
864 sym_vma = bfd_section_vma(abs_bfd, sym_section);
865 sym_addr += sym_vma + q->addend;
868 case R_H8_DIR32A16: /* currently 32, could be made 16 */
869 if (sym_reloc_size != 4) {
870 printf("R_H8_DIR32 size %d\n", sym_reloc_size);
874 relocation_needed = 1;
875 sym_addr = (*(q->sym_ptr_ptr))->value;
876 sym_vma = bfd_section_vma(abs_bfd, sym_section);
877 sym_addr += sym_vma + q->addend;
881 sym_addr = (*(q->sym_ptr_ptr))->value;
882 sym_addr += sym_vma + q->addend;
883 sym_addr -= (q->address + 2);
884 if (bfd_big_endian(abs_bfd))
885 *(unsigned short *)r_mem =
886 bfd_big_endian(abs_bfd) ? htons(sym_addr) : sym_addr;
890 sym_addr = (*(q->sym_ptr_ptr))->value;
891 sym_addr += sym_vma + q->addend;
892 sym_addr -= (q->address + 1);
893 *(unsigned char *)r_mem = sym_addr;
897 #ifdef TARGET_microblaze
898 case R_MICROBLAZE_64:
899 /* The symbol is split over two consecutive instructions.
900 Flag this to the flat loader by setting the high bit of
901 the relocation symbol. */
903 unsigned char *p = r_mem;
904 unsigned long offset;
907 /* work out the relocation */
908 sym_vma = bfd_section_vma(abs_bfd, sym_section);
909 /* grab any offset from the text */
910 offset = (p[2]<<24) + (p[3] << 16) + (p[6] << 8) + (p[7]);
911 /* Update the address */
912 sym_addr += offset + sym_vma + q->addend;
913 /* Write relocated pointer back */
914 p[2] = (sym_addr >> 24) & 0xff;
915 p[3] = (sym_addr >> 16) & 0xff;
916 p[6] = (sym_addr >> 8) & 0xff;
917 p[7] = sym_addr & 0xff;
919 /* create a new reloc entry */
920 flat_relocs = realloc(flat_relocs,
921 (flat_reloc_count + 1) * sizeof(uint32_t));
922 flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address);
924 relocation_needed = 0;
926 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
927 bfd_section_vma(abs_bfd, sym_section));
929 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
930 "section=%s size=%d "
931 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
932 q->address, sym_name, addstr,
933 section_name, sym_reloc_size,
934 sym_addr, section_vma + q->address);
936 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
937 section_vma + q->address);
941 case R_MICROBLAZE_32:
943 unsigned char *p = r_mem;
944 unsigned long offset;
946 /* grab any offset from the text */
947 offset = (p[0]<<24) + (p[1] << 16) + (p[2] << 8) + (p[3]);
948 sym_vma = bfd_section_vma(abs_bfd, sym_section);
949 /* This is a horrible kludge. For some
950 reason, *sometimes* the offset is in
951 both addend and the code. Detect
952 it, and cancel the effect. Otherwise
953 the offset gets added twice - ouch.
954 There should be a better test
955 for this condition, based on the
956 BFD data structures */
957 if(offset==q->addend)
960 sym_addr += offset + sym_vma + q->addend;
961 relocation_needed = 1;
964 case R_MICROBLAZE_64_PCREL:
966 //sym_addr = (*(q->sym_ptr_ptr))->value;
967 sym_addr += sym_vma + q->addend;
968 sym_addr -= (q->address + 4);
969 sym_addr = htonl(sym_addr);
971 * ((unsigned short *) (r_mem+2)) |= (sym_addr) & 0xFFFF;
973 * ((unsigned short *) (r_mem+6)) |= (sym_addr >> 16) & 0xFFFF;
974 /* We've done all the work, so continue
975 to next reloc instead of break */
978 #endif /* TARGET_microblaze */
981 #define htoniosl(x) (x)
982 #define niostohl(x) (x)
983 case R_NIOS2_BFD_RELOC_32:
984 relocation_needed = 1;
985 pflags = (FLAT_NIOS2_R_32 << 28);
986 sym_vma = bfd_section_vma(abs_bfd, sym_section);
987 sym_addr += sym_vma + q->addend;
988 /* modify target, in target order */
989 *(unsigned long *)r_mem = htoniosl(sym_addr);
993 unsigned long exist_val;
994 relocation_needed = 1;
995 pflags = (FLAT_NIOS2_R_CALL26 << 28);
996 sym_vma = bfd_section_vma(abs_bfd, sym_section);
997 sym_addr += sym_vma + q->addend;
999 /* modify target, in target order */
1000 // exist_val = niostohl(*(unsigned long *)r_mem);
1001 exist_val = ((sym_addr >> 2) << 6);
1002 *(unsigned long *)r_mem = htoniosl(exist_val);
1005 case R_NIOS2_HIADJ16:
1008 unsigned long exist_val;
1010 /* handle the adjacent HI/LO pairs */
1012 r2_type = R_NIOS2_NONE;
1014 r2_type = p[1]->howto->type;
1015 if ((r2_type == R_NIOS2_LO16)
1016 && (p[0]->sym_ptr_ptr == p[1]->sym_ptr_ptr)
1017 && (p[0]->addend == p[1]->addend))
1019 unsigned char * r2_mem = sectionp + p[1]->address;
1020 if (p[1]->address - q->address!=4)
1021 printf("Err: HI/LO not adjacent %d\n", p[1]->address - q->address);
1022 relocation_needed = 1;
1023 pflags = (q->howto->type == R_NIOS2_HIADJ16)
1024 ? FLAT_NIOS2_R_HIADJ_LO : FLAT_NIOS2_R_HI_LO;
1027 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1028 sym_addr += sym_vma + q->addend;
1030 /* modify high 16 bits, in target order */
1031 exist_val = niostohl(*(unsigned long *)r_mem);
1032 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1033 if (q->howto->type == R_NIOS2_HIADJ16)
1034 exist_val |= ((((sym_addr >> 16) + ((sym_addr >> 15) & 1)) & 0xFFFF) << 6);
1036 exist_val |= (((sym_addr >> 16) & 0xFFFF) << 6);
1037 *(unsigned long *)r_mem = htoniosl(exist_val);
1039 /* modify low 16 bits, in target order */
1040 exist_val = niostohl(*(unsigned long *)r2_mem);
1041 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1042 exist_val |= ((sym_addr & 0xFFFF) << 6);
1043 *(unsigned long *)r2_mem = htoniosl(exist_val);
1046 goto NIOS2_RELOC_ERR;
1052 unsigned long exist_val, temp;
1053 //long gp = get_symbol_offset("_gp", sym_section, symbols, number_of_symbols);
1054 long gp = get_gp_value(symbols, number_of_symbols);
1056 printf("Err: unresolved symbol _gp when relocating %s\n", sym_name);
1057 goto NIOS2_RELOC_ERR;
1059 /* _gp holds a absolute value, otherwise the ld cannot generate correct code */
1060 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1061 //printf("sym=%x, %d, _gp=%x, %d\n", sym_addr+sym_vma, sym_addr+sym_vma, gp, gp);
1062 sym_addr += sym_vma + q->addend;
1064 //printf("sym - _gp=%x, %d\n", sym_addr, sym_addr);
1065 /* modify the target, in target order (little_endian) */
1066 exist_val = niostohl(*(unsigned long *)r_mem);
1067 temp = ((exist_val >> 6) & 0x3ff0000) | (sym_addr & 0xffff);
1069 temp |= (exist_val & 0x3f);
1070 *(unsigned long *)r_mem = htoniosl(temp);
1072 printf("omit: offset=0x%x symbol=%s%s "
1073 "section=%s size=%d "
1074 "fixup=0x%x (reloc=0x%x) GPREL\n",
1075 q->address, sym_name, addstr,
1076 section_name, sym_reloc_size,
1077 sym_addr, section_vma + q->address);
1080 case R_NIOS2_PCREL16:
1082 unsigned long exist_val;
1084 sym_addr += sym_vma + q->addend;
1085 sym_addr -= (q->address + 4);
1086 /* modify the target, in target order (little_endian) */
1087 exist_val = niostohl(*(unsigned long *)r_mem);
1088 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1089 exist_val |= ((sym_addr & 0xFFFF) << 6);
1090 *(unsigned long *)r_mem = htoniosl(exist_val);
1092 printf("omit: offset=0x%x symbol=%s%s "
1093 "section=%s size=%d "
1094 "fixup=0x%x (reloc=0x%x) PCREL\n",
1095 q->address, sym_name, addstr,
1096 section_name, sym_reloc_size,
1097 sym_addr, section_vma + q->address);
1102 /* check if this is actually the 2nd half of a pair */
1104 && ((p[-1]->howto->type == R_NIOS2_HIADJ16)
1105 || (p[-1]->howto->type == R_NIOS2_HI16))
1106 && (p[-1]->sym_ptr_ptr == p[0]->sym_ptr_ptr)
1107 && (p[-1]->addend == p[0]->addend)) {
1109 printf("omit: offset=0x%x symbol=%s%s "
1110 "section=%s size=%d LO16\n",
1111 q->address, sym_name, addstr,
1112 section_name, sym_reloc_size);
1116 /* error, fall through */
1120 case R_NIOS2_CACHE_OPX:
1124 case R_NIOS2_BFD_RELOC_16:
1125 case R_NIOS2_BFD_RELOC_8:
1126 case R_NIOS2_GNU_VTINHERIT:
1127 case R_NIOS2_GNU_VTENTRY:
1132 printf("Err: unexpected reloc type %s(%d)\n", q->howto->name, q->howto->type);
1135 #endif /* TARGET_nios2 */
1140 relocation_needed = 1;
1141 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1142 sym_addr += sym_vma + q->addend;
1146 sym_addr += sym_vma + q->addend;
1147 sym_addr -= q->address;
1149 case R_SPARC_WDISP30:
1150 sym_addr = (((*(q->sym_ptr_ptr))->value-
1151 q->address) >> 2) & 0x3fffffff;
1153 ntohl(*(unsigned long *)r_mem)
1158 relocation_needed = 1;
1159 pflags = 0x80000000;
1160 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1161 sym_addr += sym_vma + q->addend;
1163 htonl(*(unsigned long *)r_mem)
1168 relocation_needed = 1;
1169 pflags = 0x40000000;
1170 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1171 sym_addr += sym_vma + q->addend;
1172 sym_addr &= 0x000003ff;
1174 htonl(*(unsigned long *)r_mem)
1178 #endif /* TARGET_sparc */
1181 case R_pcrel12_jump:
1182 case R_pcrel12_jump_s:
1184 case R_pcrel24_jump_l:
1185 case R_pcrel24_jump_x:
1186 case R_pcrel24_call_x:
1190 sym_addr += q->addend;// get the symbol addr
1191 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1192 sym_addr -= q->address; // make it PC relative
1193 // implicitly assumes code section and symbol section are same
1200 sym_addr += q->addend;
1201 if(weak_und_symbol(sym_section->name, (*(q->sym_ptr_ptr))))
1203 if(0xFFFF0000 & sym_addr){
1204 fprintf (stderr, "Relocation overflow for rN = %s\n",sym_name);
1207 flat_relocs = (uint32_t *)
1208 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1209 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1210 sym_section->name, sym_name,
1211 (*(q->sym_ptr_ptr)),
1212 0, FLAT_RELOC_PART_LO,
1213 section_vma + q->address))
1222 unsigned int reloc_count_incr;
1225 if (q->howto->type == R_luimm16)
1226 hi_lo = FLAT_RELOC_PART_LO;
1228 hi_lo = FLAT_RELOC_PART_HI;
1230 sym_addr += q->addend;
1232 flat_relocs = (uint32_t *)
1233 (realloc (flat_relocs, (flat_reloc_count + 2) * sizeof (uint32_t)));
1234 reloc_count_incr = 1;
1235 if (weak_und_symbol (sym_section->name, (*(q->sym_ptr_ptr))))
1237 if (0xFFFF0000 & sym_addr) {
1238 /* value is > 16 bits - use an extra field */
1239 /* see if we have already output that symbol */
1240 /* reloc may be addend from symbol and */
1241 /* we can only store 16 bit offsets */
1243 if ((*(q->sym_ptr_ptr))->udata.i == 0
1244 || flat_relocs[(*(q->sym_ptr_ptr))->udata.i] != sym_addr
1245 || ((*(q->sym_ptr_ptr))->udata.i & 0xFFFF0000))
1247 reloc_count_incr = 2;
1248 flat_relocs[flat_reloc_count + 1] = sym_addr;
1249 (*(q->sym_ptr_ptr))->udata.i = flat_reloc_count + 1;
1250 sym_addr = 0; // indication to loader to read next
1252 sym_addr = (*(q->sym_ptr_ptr))->udata.i;
1258 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1259 sym_section->name, sym_name,
1260 (*(q->sym_ptr_ptr)),
1262 section_vma + q->address))
1264 flat_reloc_count += reloc_count_incr;
1268 sym_addr += q->addend;
1270 if (weak_und_symbol (sym_section->name, *q->sym_ptr_ptr))
1273 flat_relocs = (uint32_t *)
1274 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1275 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1276 sym_section->name, sym_name,
1277 (*(q->sym_ptr_ptr)),
1278 2, FLAT_RELOC_PART_LO,
1279 section_vma + q->address))
1285 #endif //TARGET_bfin
1289 relocation_needed = 1;
1290 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1291 sym_addr += sym_vma + q->addend;
1295 sym_addr += sym_vma + q->addend;
1296 sym_addr -= q->address;
1298 #endif /* TARGET_sh */
1301 #define htoe1l(x) htonl(x)
1308 #define DBG_E1 printf
1310 #define DBG_E1(x, ... )
1313 #define _32BITS_RELOC 0x00000000
1314 #define _30BITS_RELOC 0x80000000
1315 #define _28BITS_RELOC 0x40000000
1318 unsigned long sec_vma, exist_val, S;
1320 relocation_needed = 1;
1321 DBG_E1("Handling Reloc <CONST31>\n");
1322 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1323 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1324 sec_vma, sym_addr, q->address);
1325 sym_addr = sec_vma + sym_addr;
1326 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1327 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1328 exist_val = htoe1l(exist_val);
1329 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1330 sym_addr += exist_val;
1331 pflags = _30BITS_RELOC;
1333 case R_E1_CONST31_PCREL:
1334 relocation_needed = 0;
1335 DBG_E1("Handling Reloc <CONST31_PCREL>\n");
1336 DBG_E1("DONT RELOCATE AT LOADING\n");
1337 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1338 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1339 sec_vma, sym_addr, q->address);
1340 sym_addr = sec_vma + sym_addr;
1341 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1343 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1345 q->address = q->address + section_vma;
1346 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1348 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1349 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1350 DBG_E1( "sym_addr := sym_addr - q->address - "
1351 "sizeof(CONST31_PCREL): [0x%x]\n",
1353 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1354 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1355 exist_val = htoe1l(exist_val);
1356 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1357 sym_addr |= exist_val;
1358 DBG_E1("sym_addr |= exist_val) : [0x%x]\n", sym_addr );
1360 case R_E1_DIS29W_PCREL:
1361 relocation_needed = 0;
1362 DBG_E1("Handling Reloc <DIS29W_PCREL>\n");
1363 DBG_E1("DONT RELOCATE AT LOADING\n");
1364 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1365 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1366 sec_vma, sym_addr, q->address);
1367 sym_addr = sec_vma + sym_addr;
1368 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1370 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1372 q->address = q->address + section_vma;
1373 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1375 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1376 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1377 DBG_E1( "sym_addr := sym_addr - q->address - "
1378 "sizeof(CONST31_PCREL): [0x%x]\n",
1380 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1381 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1382 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1383 exist_val = htoe1l(exist_val);
1384 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1385 sym_addr += exist_val;
1388 DBG_E1("Handling Reloc <DIS29W>\n");
1389 goto DIS29_RELOCATION;
1391 DBG_E1("Handling Reloc <DIS29H>\n");
1392 goto DIS29_RELOCATION;
1394 DBG_E1("Handling Reloc <DIS29B>\n");
1396 relocation_needed = 1;
1397 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1398 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%08x]\n",
1400 sym_addr = sec_vma + sym_addr;
1401 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%08x]\n", sym_addr);
1402 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1403 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1404 exist_val = htoe1l(exist_val);
1405 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1406 sym_addr += exist_val;
1407 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1408 pflags = _28BITS_RELOC;
1410 case R_E1_IMM32_PCREL:
1411 relocation_needed = 0;
1412 DBG_E1("Handling Reloc <IMM32_PCREL>\n");
1413 DBG_E1("DONT RELOCATE AT LOADING\n");
1414 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1415 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1417 sym_addr = sec_vma + sym_addr;
1419 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1420 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1422 q->address = q->address + section_vma;
1423 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1425 if( (sym_addr = (sym_addr - q->address - 6 )) < 0 )
1426 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1427 DBG_E1( "sym_addr := sym_addr - q->address - "
1428 "sizeof(CONST31_PCREL): [0x%x]\n",
1430 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1431 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1432 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1433 exist_val = htoe1l(exist_val);
1434 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1435 sym_addr += exist_val;
1438 relocation_needed = 1;
1439 DBG_E1("Handling Reloc <IMM32>\n");
1440 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1441 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1443 sym_addr = sec_vma + sym_addr;
1444 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1445 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1446 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1447 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1448 exist_val = htoe1l(exist_val);
1449 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1450 sym_addr += exist_val;
1451 pflags = _32BITS_RELOC;
1454 relocation_needed = 1;
1455 DBG_E1("Handling Reloc <WORD>\n");
1456 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1457 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1459 sym_addr = sec_vma + sym_addr;
1460 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1461 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address );
1462 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1463 exist_val = htoe1l(exist_val);
1464 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1465 sym_addr += exist_val;
1466 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1467 pflags = _32BITS_RELOC;
1470 #undef _32BITS_RELOC
1471 #undef _30BITS_RELOC
1472 #undef _28BITS_RELOC
1475 /* missing support for other types of relocs */
1476 printf("ERROR: bad reloc type %d\n", (*p)->howto->type);
1482 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
1483 bfd_section_vma(abs_bfd, sym_section));
1487 * for full elf relocation we have to write back the
1488 * start_code relative value to use.
1490 if (!pic_with_got) {
1491 #if defined(TARGET_arm)
1500 * horrible nasty hack to support different endianess
1502 if (!bfd_big_endian(abs_bfd)) {
1514 tmp.l = *(unsigned long *)r_mem;
1515 hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16);
1517 (((*p)->howto->type != R_ARM_PC24) &&
1518 ((*p)->howto->type != R_ARM_PLT32)))
1519 hl |= (tmp.c[i3] << 24);
1520 else if (tmp.c[i2] & 0x80)
1521 hl |= 0xff000000; /* sign extend */
1524 tmp.c[i0] = hl & 0xff;
1525 tmp.c[i1] = (hl >> 8) & 0xff;
1526 tmp.c[i2] = (hl >> 16) & 0xff;
1528 (((*p)->howto->type != R_ARM_PC24) &&
1529 ((*p)->howto->type != R_ARM_PLT32)))
1530 tmp.c[i3] = (hl >> 24) & 0xff;
1531 if ((*p)->howto->type == R_ARM_ABS32)
1532 *(unsigned long *)r_mem = htonl(hl);
1534 *(unsigned long *)r_mem = tmp.l;
1536 #elif defined(TARGET_bfin)
1537 if ((*p)->howto->type == R_pcrel24
1538 || (*p)->howto->type == R_pcrel24_jump_l
1539 || (*p)->howto->type == R_pcrel24_jump_x
1540 || (*p)->howto->type == R_pcrel24_call_x)
1542 sym_addr += 2*-1*PCREL24_MAGIC_OFFSET;
1543 *((unsigned short *)(sectionp + q->address) + 1 + PCREL24_MAGIC_OFFSET)
1544 = (sym_addr >> 1) & 0xffff;
1545 *((unsigned short *)(sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1546 = (0xff00 & *((unsigned short *) (sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1547 | ((sym_addr >> 17) & 0xff));
1548 } else if ((*p)->howto->type == R_byte4_data) {
1549 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1550 } else if ((*p)->howto->type == R_pcrel12_jump
1551 || (*p)->howto->type == R_pcrel12_jump_s) {
1552 *((unsigned short *)(sectionp + q->address))
1553 = (0xf000 & *((unsigned short *)(sectionp + q->address))
1554 | ((sym_addr >> 1) & 0xfff));
1555 } else if ((*p)->howto->type == R_pcrel10) {
1556 *((unsigned short *)(sectionp + q->address))
1557 = (~0x3ff & *((unsigned short *)(sectionp + q->address))
1558 | ((sym_addr >> 1) & 0x3ff));
1559 } else if ((*p)->howto->type == R_rimm16
1560 || (*p)->howto->type == R_huimm16
1561 || (*p)->howto->type == R_luimm16) {
1562 /* for l and h we set the lower 16 bits which is only when it will be used */
1563 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1564 } else if ((*p)->howto->type == R_pcrel5m2) {
1565 *((unsigned short *)(sectionp + q->address))
1566 = (0xfff0 & *((unsigned short *)(sectionp + q->address))
1567 | ((sym_addr >> 1) & 0xf));
1568 } else if ((*p)->howto->type == R_pcrel11){
1569 *((unsigned short *)(sectionp + q->address))
1570 = (0xfc00 & *((unsigned short *)(sectionp + q->address))
1571 | ((sym_addr >> 1) & 0x3ff));
1572 } else if (0xE0 <= (*p)->howto->type && 0xF3 >= (*p)->howto->type) {
1573 //arith relocs dont generate a real relocation
1575 printf("Blackfin relocation fail for reloc type: 0x%x\n", (*p)->howto->type);
1577 #elif defined(TARGET_e1)
1578 #define OPCODE_SIZE 2 /* Add 2 bytes, counting the opcode size*/
1579 switch ((*p)->howto->type) {
1581 case R_E1_CONST31_PCREL:
1582 case R_E1_DIS29W_PCREL:
1586 case R_E1_IMM32_PCREL:
1588 DBG_E1("In addr + 2:[0x%x] <- write [0x%x]\n",
1589 (sectionp + q->address + 2), sym_addr );
1590 *((unsigned long *) (sectionp + q->address + OPCODE_SIZE)) =
1594 DBG_E1("In addr : [0x%x] <- write [0x%x]\n",
1595 (sectionp + q->address), sym_addr );
1596 *((unsigned long *) (sectionp + q->address )) = htonl(sym_addr);
1599 printf("ERROR:Unhandled Relocation. Exiting...\n");
1603 #else /* ! TARGET_arm && ! TARGET_e1 */
1605 switch (q->howto->type) {
1610 /* Do nothing -- for cases we handle,
1611 the bits produced by the linker are
1612 what we want in the final flat file
1613 (and other cases are errors). Note
1614 that unlike most relocated values,
1615 it is stored in little-endian order,
1616 but this is necessary to avoid
1617 trashing the low-bit, and the float
1618 loaders knows about it. */
1620 #endif /* TARGET_V850 */
1623 case R_NIOS2_BFD_RELOC_32:
1624 case R_NIOS2_CALL26:
1625 case R_NIOS2_HIADJ16:
1629 #endif /* TARGET_nios2 */
1631 #if defined(TARGET_m68k)
1633 if (sym_addr < -0x8000 || sym_addr > 0x7fff) {
1634 fprintf (stderr, "Relocation overflow for R_68K_PC16 relocation against %s\n", sym_name);
1637 r_mem[0] = (sym_addr >> 8) & 0xff;
1638 r_mem[1] = sym_addr & 0xff;
1644 /* The alignment of the build host
1645 might be stricter than that of the
1646 target, so be careful. We store in
1647 network byte order. */
1648 r_mem[0] = (sym_addr >> 24) & 0xff;
1649 r_mem[1] = (sym_addr >> 16) & 0xff;
1650 r_mem[2] = (sym_addr >> 8) & 0xff;
1651 r_mem[3] = sym_addr & 0xff;
1653 #endif /* !TARGET_arm */
1658 if ((*p)->howto->type == R_rimm16
1659 || (*p)->howto->type == R_huimm16
1660 || (*p)->howto->type == R_luimm16)
1662 /* for l and h we set the lower 16 bits which is only when it will be used */
1663 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1664 } else if ((*p)->howto->type == R_byte4_data) {
1665 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1670 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
1671 "section=%s size=%d "
1672 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
1673 q->address, sym_name, addstr,
1674 section_name, sym_reloc_size,
1675 sym_addr, section_vma + q->address);
1678 * Create relocation entry (PC relative doesn't need this).
1680 if (relocation_needed) {
1682 flat_relocs = realloc(flat_relocs,
1683 (flat_reloc_count + 1) * sizeof(uint32_t));
1685 flat_relocs[flat_reloc_count] = pflags |
1686 (section_vma + q->address);
1689 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
1690 section_vma + q->address);
1692 switch ((*p)->howto->type) {
1694 case R_E1_CONST31_PCREL:
1695 case R_E1_DIS29W_PCREL:
1699 case R_E1_IMM32_PCREL:
1701 flat_relocs[flat_reloc_count] = pflags |
1702 (section_vma + q->address + OPCODE_SIZE);
1704 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1705 flat_relocs[flat_reloc_count] );
1708 flat_relocs[flat_reloc_count] = pflags |
1709 (section_vma + q->address);
1711 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1712 flat_relocs[flat_reloc_count] );
1718 relocation_needed = 0;
1723 printf("%s(%d): symbol name=%s address=0x%x section=%s -> RELOC=0x%x\n",
1724 __FILE__, __LINE__, sym_name, q->address, section_name,
1725 flat_relocs[flat_reloc_count]);
1732 printf("%d bad relocs\n", bad_relocs);
1739 *n_relocs = flat_reloc_count;
1745 static char * program;
1747 static void usage(void)
1749 fprintf(stderr, "Usage: %s [vrzd] [-p <abs-pic-file>] [-s stack-size] "
1750 "[-o <output-file>] <elf-file>\n\n"
1751 " -v : verbose operation\n"
1752 " -r : force load to RAM\n"
1753 " -k : enable kernel trace on load (for debug)\n"
1754 " -z : compress code/data/relocs\n"
1755 " -d : compress data/relocs\n"
1756 " -a : use existing symbol references\n"
1757 " instead of recalculating from\n"
1758 " relocation info\n"
1759 " -R reloc-file : read relocations from a separate file\n"
1760 " -p abs-pic-file : GOT/PIC processing with files\n"
1761 " -s stacksize : set application stack size\n"
1762 " -o output-file : output file name\n\n",
1764 fprintf(stderr, "Compiled for " ARCH " architecture\n\n");
1769 /* Write NUM zeroes to STREAM. */
1770 static void write_zeroes (unsigned long num, FILE *stream)
1774 /* It'd be nice if we could just use fseek, but that doesn't seem to
1775 work for stdio output files. */
1776 memset(zeroes, 0x00, 1024);
1777 while (num > sizeof(zeroes)) {
1778 fwrite(zeroes, sizeof(zeroes), 1, stream);
1779 num -= sizeof(zeroes);
1782 fwrite(zeroes, num, 1, stream);
1787 int main(int argc, char *argv[])
1790 bfd *rel_bfd, *abs_bfd;
1792 char *ofile=NULL, *pfile=NULL, *abs_file = NULL, *rel_file = NULL;
1800 asymbol **symbol_table;
1801 long number_of_symbols;
1803 unsigned long data_len = 0;
1804 unsigned long bss_len = 0;
1805 unsigned long text_len = 0;
1806 unsigned long reloc_len;
1808 unsigned long data_vma = ~0;
1809 unsigned long bss_vma = ~0;
1810 unsigned long text_vma = ~0;
1812 unsigned long text_offs;
1818 struct flat_hdr hdr;
1824 xmalloc_set_program_name(program);
1829 if (sizeof(hdr) != 64) {
1831 "Potential flat header incompatibility detected\n"
1832 "header size should be 64 but is %d\n",
1839 #else /* We need plenty of stack for both of them (Aggregate and Register) */
1843 while ((opt = getopt(argc, argv, "avzdrkp:s:o:R:")) != -1) {
1870 if (sscanf(optarg, "%i", &stack) != 1) {
1871 fprintf(stderr, "%s invalid stack size %s\n", argv[0], optarg);
1879 fprintf(stderr, "%s Unknown option\n", argv[0]);
1886 * if neither the -r or -p options was given, default to
1887 * a RAM load as that is the only option that makes sense.
1889 if (!load_to_ram && !pfile)
1892 filename = fname = argv[argc-1];
1903 if (!(rel_bfd = bfd_openr(rel_file, 0))) {
1904 fprintf(stderr, "Can't open %s\n", rel_file);
1908 if (bfd_check_format (rel_bfd, bfd_object) == 0) {
1909 fprintf(stderr, "File is not an object file\n");
1913 if (abs_file == rel_file)
1914 abs_bfd = rel_bfd; /* one file does all */
1916 if (!(abs_bfd = bfd_openr(abs_file, 0))) {
1917 fprintf(stderr, "Can't open %s\n", abs_file);
1921 if (bfd_check_format (abs_bfd, bfd_object) == 0) {
1922 fprintf(stderr, "File is not an object file\n");
1927 if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC)) {
1928 fprintf (stderr, "%s: Input file contains no relocation info\n", rel_file);
1932 if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P)) {
1933 /* `Absolute' file is not absolute, so neither are address
1934 contained therein. */
1936 "%s: `-a' option specified with non-fully-resolved input file\n",
1937 bfd_get_filename (abs_bfd));
1941 symbol_table = get_symbols(abs_bfd, &number_of_symbols);
1943 /* Group output sections into text, data, and bss, and calc their sizes. */
1944 for (s = abs_bfd->sections; s != NULL; s = s->next) {
1945 unsigned long *vma, *len;
1946 bfd_size_type sec_size;
1949 if (s->flags & SEC_CODE) {
1952 } else if (s->flags & SEC_DATA) {
1955 } else if (s->flags & SEC_ALLOC) {
1961 sec_size = bfd_section_size(abs_bfd, s);
1962 sec_vma = bfd_section_vma(abs_bfd, s);
1964 if (sec_vma < *vma) {
1966 *len += sec_vma - *vma;
1970 } else if (sec_vma + sec_size > *vma + *len)
1971 *len = sec_vma + sec_size - *vma;
1974 if (text_len == 0) {
1975 fprintf (stderr, "%s: no .text section", abs_file);
1979 text = xmalloc(text_len);
1982 printf("TEXT -> vma=0x%x len=0x%x\n", text_vma, text_len);
1984 /* Read in all text sections. */
1985 for (s = abs_bfd->sections; s != NULL; s = s->next)
1986 if (s->flags & SEC_CODE)
1987 if (!bfd_get_section_contents(abs_bfd, s,
1988 text + (s->vma - text_vma), 0,
1989 bfd_section_size(abs_bfd, s)))
1991 fprintf(stderr, "read error section %s\n", s->name);
1995 if (data_len == 0) {
1996 fprintf (stderr, "%s: no .data section", abs_file);
1999 data = xmalloc(data_len);
2002 printf("DATA -> vma=0x%x len=0x%x\n", data_vma, data_len);
2004 if ((text_vma + text_len) != data_vma) {
2005 if ((text_vma + text_len) > data_vma) {
2006 printf("ERROR: text=0x%x overlaps data=0x%x ?\n", text_len, data_vma);
2010 printf("WARNING: data=0x%x does not directly follow text=0x%x\n",
2011 data_vma, text_len);
2012 text_len = data_vma - text_vma;
2015 /* Read in all data sections. */
2016 for (s = abs_bfd->sections; s != NULL; s = s->next)
2017 if (s->flags & SEC_DATA)
2018 if (!bfd_get_section_contents(abs_bfd, s,
2019 data + (s->vma - data_vma), 0,
2020 bfd_section_size(abs_bfd, s)))
2022 fprintf(stderr, "read error section %s\n", s->name);
2026 /* Put common symbols in bss. */
2027 bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len);
2030 printf("BSS -> vma=0x%x len=0x%x\n", bss_vma, bss_len);
2032 if ((data_vma + data_len) != bss_vma) {
2033 if ((data_vma + data_len) > bss_vma) {
2034 printf("ERROR: text=0x%x + data=0x%x overlaps bss=0x%x ?\n", text_len,
2039 printf("WARNING: bss=0x%x does not directly follow text=0x%x + data=0x%x(0x%x)\n",
2040 bss_vma, text_len, data_len, text_len + data_len);
2041 data_len = bss_vma - data_vma;
2044 reloc = output_relocs(abs_bfd, symbol_table, number_of_symbols, &reloc_len,
2045 text, text_len, text_vma, data, data_len, data_vma,
2049 printf("No relocations in code!\n");
2051 text_offs = real_address_bits(text_vma);
2053 /* Fill in the binflt_flat header */
2054 memcpy(hdr.magic,"bFLT",4);
2055 hdr.rev = htonl(FLAT_VERSION);
2056 hdr.entry = htonl(sizeof(hdr) + bfd_get_start_address(abs_bfd));
2057 hdr.data_start = htonl(sizeof(hdr) + text_offs + text_len);
2058 hdr.data_end = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2059 hdr.bss_end = htonl(sizeof(hdr) + text_offs + text_len +data_len+bss_len);
2060 hdr.stack_size = htonl(stack); /* FIXME */
2061 hdr.reloc_start = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2062 hdr.reloc_count = htonl(reloc_len);
2064 | (load_to_ram ? FLAT_FLAG_RAM : 0)
2065 | (ktrace ? FLAT_FLAG_KTRACE : 0)
2066 | (pic_with_got ? FLAT_FLAG_GOTPIC : 0)
2067 | (compress ? (compress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
2069 hdr.build_date = htonl((unsigned long)time(NULL));
2070 memset(hdr.filler, 0x00, sizeof(hdr.filler));
2072 for (i=0; i<reloc_len; i++) reloc[i] = htonl(reloc[i]);
2075 printf("SIZE: .text=0x%04x, .data=0x%04x, .bss=0x%04x",
2076 text_len, data_len, bss_len);
2078 printf(", relocs=0x%04x", reloc_len);
2083 ofile = xmalloc(strlen(fname) + 5 + 1); /* 5 to add suffix */
2084 strcpy(ofile, fname);
2085 strcat(ofile, ".bflt");
2088 if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0) {
2089 fprintf (stderr, "Can't open output file %s\n", ofile);
2093 write(fd, &hdr, sizeof(hdr));
2097 * get the compression command ready
2099 sprintf(cmd, "gzip -f -9 >> %s", ofile);
2101 #define START_COMPRESSOR do { \
2107 if (!(gf = popen(cmd, "w" BINARY_FILE_OPTS))) { \
2108 fprintf(stderr, "Can't run cmd %s\n", cmd); \
2114 gf = fopen(ofile, "ab"); /* Add 'b' to support non-posix (ie windows) */
2116 fprintf(stderr, "Can't open file %s for writing\n", ofile); \
2123 /* Fill in any hole at the beginning of the text segment. */
2125 printf("ZERO before text len=0x%x\n", text_offs);
2126 write_zeroes(text_offs, gf);
2128 /* Write the text segment. */
2129 fwrite(text, text_len, 1, gf);
2134 /* Write the data segment. */
2135 fwrite(data, data_len, 1, gf);
2138 fwrite(reloc, reloc_len * 4, 1, gf);
2150 * this __MUST__ be at the VERY end of the file - do NOT move!!
2156 * vi: tabstop=8 shiftwidth=4 textwidth=79 noexpandtab