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 = (asymbol **) malloc (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 = (arelent **) xmalloc(relsize);
496 relcount = bfd_canonicalize_reloc(rel_bfd, r, relpp, symb);
499 printf("%s(%d): no relocation entries section=%s\n",
500 __FILE__, __LINE__, r->name);
503 for (p = relpp; (relcount && (*p != NULL)); p++, relcount--) {
504 unsigned char *r_mem;
505 int relocation_needed = 0;
507 #ifdef TARGET_microblaze
508 /* The MICROBLAZE_XX_NONE relocs can be skipped.
509 They represent PC relative branches that the
510 linker has already resolved */
512 switch ((*p)->howto->type)
514 case R_MICROBLAZE_NONE:
515 case R_MICROBLAZE_64_NONE:
518 #endif /* TARGET_microblaze */
521 /* Skip this relocation entirely if possible (we
522 do this early, before doing any other
523 processing on it). */
524 switch ((*p)->howto->type) {
525 #ifdef R_V850_9_PCREL
528 #ifdef R_V850_22_PCREL
529 case R_V850_22_PCREL:
531 #ifdef R_V850_SDA_16_16_OFFSET
532 case R_V850_SDA_16_16_OFFSET:
534 #ifdef R_V850_SDA_15_16_OFFSET
535 case R_V850_SDA_15_16_OFFSET:
537 #ifdef R_V850_ZDA_15_16_OFFSET
538 case R_V850_ZDA_15_16_OFFSET:
540 #ifdef R_V850_TDA_6_8_OFFSET
541 case R_V850_TDA_6_8_OFFSET:
543 #ifdef R_V850_TDA_7_8_OFFSET
544 case R_V850_TDA_7_8_OFFSET:
546 #ifdef R_V850_TDA_7_7_OFFSET
547 case R_V850_TDA_7_7_OFFSET:
549 #ifdef R_V850_TDA_16_16_OFFSET
550 case R_V850_TDA_16_16_OFFSET:
552 #ifdef R_V850_TDA_4_5_OFFSET
553 case R_V850_TDA_4_5_OFFSET:
555 #ifdef R_V850_TDA_4_4_OFFSET
556 case R_V850_TDA_4_4_OFFSET:
558 #ifdef R_V850_SDA_16_16_SPLIT_OFFSET
559 case R_V850_SDA_16_16_SPLIT_OFFSET:
561 #ifdef R_V850_CALLT_6_7_OFFSET
562 case R_V850_CALLT_6_7_OFFSET:
564 #ifdef R_V850_CALLT_16_16_OFFSET
565 case R_V850_CALLT_16_16_OFFSET:
567 /* These are relative relocations, which
568 have already been fixed up by the
569 linker at this point, so just ignore
573 #endif /* USE_V850_RELOCS */
576 if (q->sym_ptr_ptr && *q->sym_ptr_ptr) {
577 sym_name = (*(q->sym_ptr_ptr))->name;
578 sym_section = (*(q->sym_ptr_ptr))->section;
579 section_name=(*(q->sym_ptr_ptr))->section->name;
581 printf("ERROR: undefined relocation entry\n");
586 /* Adjust the address to account for the GOT table which wasn't
587 * present in the relative file link.
589 if (pic_with_got && !use_resolved)
590 q->address += got_size;
593 /* A pointer to what's being relocated, used often
595 r_mem = sectionp + q->address;
598 * Fixup offset in the actual section.
602 if ((sym_addr = get_symbol_offset((char *) sym_name,
603 sym_section, symbols, number_of_symbols)) == -1) {
607 sym_addr = (*(q->sym_ptr_ptr))->value;
610 /* Use the address of the symbol already in
611 the program text. How this is handled may
612 still depend on the particular relocation
614 switch (q->howto->type) {
618 /* We specially handle adjacent
619 HI16_S/ZDA_15_16_OFFSET and
620 HI16_S/LO16 pairs that reference the
621 same address (these are usually
622 movhi/ld and movhi/movea pairs,
625 r2_type = R_V850_NONE;
627 r2_type = p[1]->howto->type;
628 if ((r2_type == R_V850_ZDA_15_16_OFFSET
629 || r2_type == R_V850_LO16)
630 && (p[0]->sym_ptr_ptr
631 == p[1]->sym_ptr_ptr)
632 && (p[0]->addend == p[1]->addend))
634 relocation_needed = 1;
637 case R_V850_ZDA_15_16_OFFSET:
645 /* We don't really need the
646 actual value -- the bits
647 produced by the linker are
648 what we want in the final
649 flat file -- but get it
653 unsigned char *r2_mem =
661 /* Sign extend LO. */
665 /* Maybe ignore the LSB
669 if (r2_type != R_V850_LO16)
677 goto bad_resolved_reloc;
681 /* See if this is actually the
682 2nd half of a pair. */
684 && (p[-1]->howto->type
686 && (p[-1]->sym_ptr_ptr
687 == p[0]->sym_ptr_ptr)
688 && (p[-1]->addend == p[0]->addend))
689 break; /* not an error */
691 goto bad_resolved_reloc;
694 goto bad_resolved_reloc;
696 goto good_32bit_resolved_reloc;
697 #elif defined(TARGET_arm)
699 relocation_needed = 1;
703 relocation_needed = 0;
706 goto bad_resolved_reloc;
707 #elif defined(TARGET_m68k)
709 goto good_32bit_resolved_reloc;
712 /* The linker has already resolved
713 PC relocs for us. In PIC links,
714 the symbol must be in the data
719 goto bad_resolved_reloc;
722 /* The default is to assume that the
723 relocation is relative and has
724 already been fixed up by the
725 linker (perhaps we ought to make
726 give an error by default, and
727 require `safe' relocations to be
728 enumberated explicitly?). */
729 goto good_32bit_resolve_reloc;
731 good_32bit_resolved_reloc:
732 if (bfd_big_endian (abs_bfd))
744 relocation_needed = 1;
748 printf("ERROR: reloc type %s unsupported in this context\n",
754 /* Calculate the sym address ourselves. */
755 sym_reloc_size = bfd_get_reloc_size(q->howto);
757 #if !defined(TARGET_h8300) && !defined(TARGET_e1) && !defined(TARGET_bfin) && !defined(TARGET_m68k)
758 if (sym_reloc_size != 4) {
759 printf("ERROR: bad reloc type %d size=%d for symbol=%s\n",
760 (*p)->howto->type, sym_reloc_size, sym_name);
767 switch ((*p)->howto->type) {
769 #if defined(TARGET_m68k)
771 relocation_needed = 1;
772 sym_vma = bfd_section_vma(abs_bfd, sym_section);
773 sym_addr += sym_vma + q->addend;
778 sym_addr += sym_vma + q->addend;
779 sym_addr -= q->address;
783 #if defined(TARGET_arm)
785 relocation_needed = 1;
788 "%s vma=0x%x, value=0x%x, address=0x%x "
789 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
791 sym_vma, (*(q->sym_ptr_ptr))->value,
792 q->address, sym_addr,
793 (*p)->howto->rightshift,
794 *(unsigned long *)r_mem);
795 sym_vma = bfd_section_vma(abs_bfd, sym_section);
796 sym_addr += sym_vma + q->addend;
800 /* Should be fine as is */
805 "%s vma=0x%x, value=0x%x, address=0x%x "
806 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
808 sym_vma, (*(q->sym_ptr_ptr))->value,
809 q->address, sym_addr,
810 (*p)->howto->rightshift,
811 *(unsigned long *)r_mem);
814 sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift;
820 relocation_needed = 1;
821 sym_vma = bfd_section_vma(abs_bfd, sym_section);
822 sym_addr += sym_vma + q->addend;
824 #if defined(R_V850_ZDA_16_16_OFFSET) || defined(R_V850_ZDA_16_16_SPLIT_OFFSET)
825 #ifdef R_V850_ZDA_16_16_OFFSET
826 case R_V850_ZDA_16_16_OFFSET:
828 #ifdef R_V850_ZDA_16_16_SPLIT_OFFSET
829 case R_V850_ZDA_16_16_SPLIT_OFFSET:
831 /* Can't support zero-relocations. */
832 printf ("ERROR: %s+0x%x: zero relocations not supported\n",
833 sym_name, q->addend);
835 #endif /* R_V850_ZDA_16_16_OFFSET || R_V850_ZDA_16_16_SPLIT_OFFSET */
836 #endif /* TARGET_v850 */
840 if (sym_reloc_size != 4) {
841 printf("R_H8_DIR24R8 size %d\n", sym_reloc_size);
845 relocation_needed = 1;
846 sym_addr = (*(q->sym_ptr_ptr))->value;
848 r_mem -= 1; /* tracks q->address */
849 sym_vma = bfd_section_vma(abs_bfd, sym_section);
850 sym_addr += sym_vma + q->addend;
851 sym_addr |= (*(unsigned char *)r_mem<<24);
854 if (sym_reloc_size != 4) {
855 printf("R_H8_DIR24A8 size %d\n", sym_reloc_size);
859 /* Absolute symbol done not relocation */
860 relocation_needed = !bfd_is_abs_section(sym_section);
861 sym_addr = (*(q->sym_ptr_ptr))->value;
862 sym_vma = bfd_section_vma(abs_bfd, sym_section);
863 sym_addr += sym_vma + q->addend;
866 case R_H8_DIR32A16: /* currently 32, could be made 16 */
867 if (sym_reloc_size != 4) {
868 printf("R_H8_DIR32 size %d\n", sym_reloc_size);
872 relocation_needed = 1;
873 sym_addr = (*(q->sym_ptr_ptr))->value;
874 sym_vma = bfd_section_vma(abs_bfd, sym_section);
875 sym_addr += sym_vma + q->addend;
879 sym_addr = (*(q->sym_ptr_ptr))->value;
880 sym_addr += sym_vma + q->addend;
881 sym_addr -= (q->address + 2);
882 if (bfd_big_endian(abs_bfd))
883 *(unsigned short *)r_mem =
884 bfd_big_endian(abs_bfd) ? htons(sym_addr) : sym_addr;
888 sym_addr = (*(q->sym_ptr_ptr))->value;
889 sym_addr += sym_vma + q->addend;
890 sym_addr -= (q->address + 1);
891 *(unsigned char *)r_mem = sym_addr;
895 #ifdef TARGET_microblaze
896 case R_MICROBLAZE_64:
897 /* The symbol is split over two consecutive instructions.
898 Flag this to the flat loader by setting the high bit of
899 the relocation symbol. */
901 unsigned char *p = r_mem;
902 unsigned long offset;
905 /* work out the relocation */
906 sym_vma = bfd_section_vma(abs_bfd, sym_section);
907 /* grab any offset from the text */
908 offset = (p[2]<<24) + (p[3] << 16) + (p[6] << 8) + (p[7]);
909 /* Update the address */
910 sym_addr += offset + sym_vma + q->addend;
911 /* Write relocated pointer back */
912 p[2] = (sym_addr >> 24) & 0xff;
913 p[3] = (sym_addr >> 16) & 0xff;
914 p[6] = (sym_addr >> 8) & 0xff;
915 p[7] = sym_addr & 0xff;
917 /* create a new reloc entry */
918 flat_relocs = realloc(flat_relocs,
919 (flat_reloc_count + 1) * sizeof(uint32_t));
920 flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address);
922 relocation_needed = 0;
924 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
925 bfd_section_vma(abs_bfd, sym_section));
927 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
928 "section=%s size=%d "
929 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
930 q->address, sym_name, addstr,
931 section_name, sym_reloc_size,
932 sym_addr, section_vma + q->address);
934 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
935 section_vma + q->address);
939 case R_MICROBLAZE_32:
941 unsigned char *p = r_mem;
942 unsigned long offset;
944 /* grab any offset from the text */
945 offset = (p[0]<<24) + (p[1] << 16) + (p[2] << 8) + (p[3]);
946 sym_vma = bfd_section_vma(abs_bfd, sym_section);
947 /* This is a horrible kludge. For some
948 reason, *sometimes* the offset is in
949 both addend and the code. Detect
950 it, and cancel the effect. Otherwise
951 the offset gets added twice - ouch.
952 There should be a better test
953 for this condition, based on the
954 BFD data structures */
955 if(offset==q->addend)
958 sym_addr += offset + sym_vma + q->addend;
959 relocation_needed = 1;
962 case R_MICROBLAZE_64_PCREL:
964 //sym_addr = (*(q->sym_ptr_ptr))->value;
965 sym_addr += sym_vma + q->addend;
966 sym_addr -= (q->address + 4);
967 sym_addr = htonl(sym_addr);
969 * ((unsigned short *) (r_mem+2)) |= (sym_addr) & 0xFFFF;
971 * ((unsigned short *) (r_mem+6)) |= (sym_addr >> 16) & 0xFFFF;
972 /* We've done all the work, so continue
973 to next reloc instead of break */
976 #endif /* TARGET_microblaze */
979 #define htoniosl(x) (x)
980 #define niostohl(x) (x)
981 switch ((*p)->howto->type)
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);
1136 #endif /* TARGET_nios2 */
1141 relocation_needed = 1;
1142 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1143 sym_addr += sym_vma + q->addend;
1147 sym_addr += sym_vma + q->addend;
1148 sym_addr -= q->address;
1150 case R_SPARC_WDISP30:
1151 sym_addr = (((*(q->sym_ptr_ptr))->value-
1152 q->address) >> 2) & 0x3fffffff;
1154 ntohl(*(unsigned long *)r_mem)
1159 relocation_needed = 1;
1160 pflags = 0x80000000;
1161 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1162 sym_addr += sym_vma + q->addend;
1164 htonl(*(unsigned long *)r_mem)
1169 relocation_needed = 1;
1170 pflags = 0x40000000;
1171 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1172 sym_addr += sym_vma + q->addend;
1173 sym_addr &= 0x000003ff;
1175 htonl(*(unsigned long *)r_mem)
1179 #endif /* TARGET_sparc */
1182 case R_pcrel12_jump:
1183 case R_pcrel12_jump_s:
1185 case R_pcrel24_jump_l:
1186 case R_pcrel24_jump_x:
1187 case R_pcrel24_call_x:
1191 sym_addr += q->addend;// get the symbol addr
1192 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1193 sym_addr -= q->address; // make it PC relative
1194 // implicitly assumes code section and symbol section are same
1201 sym_addr += q->addend;
1202 if(weak_und_symbol(sym_section->name, (*(q->sym_ptr_ptr))))
1204 if(0xFFFF0000 & sym_addr){
1205 fprintf (stderr, "Relocation overflow for rN = %s\n",sym_name);
1208 flat_relocs = (uint32_t *)
1209 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1210 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1211 sym_section->name, sym_name,
1212 (*(q->sym_ptr_ptr)),
1213 0, FLAT_RELOC_PART_LO,
1214 section_vma + q->address))
1223 unsigned int reloc_count_incr;
1226 if (q->howto->type == R_luimm16)
1227 hi_lo = FLAT_RELOC_PART_LO;
1229 hi_lo = FLAT_RELOC_PART_HI;
1231 sym_addr += q->addend;
1233 flat_relocs = (uint32_t *)
1234 (realloc (flat_relocs, (flat_reloc_count + 2) * sizeof (uint32_t)));
1235 reloc_count_incr = 1;
1236 if (weak_und_symbol (sym_section->name, (*(q->sym_ptr_ptr))))
1238 if (0xFFFF0000 & sym_addr) {
1239 /* value is > 16 bits - use an extra field */
1240 /* see if we have already output that symbol */
1241 /* reloc may be addend from symbol and */
1242 /* we can only store 16 bit offsets */
1244 if ((*(q->sym_ptr_ptr))->udata.i == 0
1245 || flat_relocs[(*(q->sym_ptr_ptr))->udata.i] != sym_addr
1246 || ((*(q->sym_ptr_ptr))->udata.i & 0xFFFF0000))
1248 reloc_count_incr = 2;
1249 flat_relocs[flat_reloc_count + 1] = sym_addr;
1250 (*(q->sym_ptr_ptr))->udata.i = flat_reloc_count + 1;
1251 sym_addr = 0; // indication to loader to read next
1253 sym_addr = (*(q->sym_ptr_ptr))->udata.i;
1259 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1260 sym_section->name, sym_name,
1261 (*(q->sym_ptr_ptr)),
1263 section_vma + q->address))
1265 flat_reloc_count += reloc_count_incr;
1269 sym_addr += q->addend;
1271 if (weak_und_symbol (sym_section->name, *q->sym_ptr_ptr))
1274 flat_relocs = (uint32_t *)
1275 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1276 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1277 sym_section->name, sym_name,
1278 (*(q->sym_ptr_ptr)),
1279 2, FLAT_RELOC_PART_LO,
1280 section_vma + q->address))
1286 #endif //TARGET_bfin
1290 relocation_needed = 1;
1291 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1292 sym_addr += sym_vma + q->addend;
1296 sym_addr += sym_vma + q->addend;
1297 sym_addr -= q->address;
1299 #endif /* TARGET_sh */
1302 #define htoe1l(x) htonl(x)
1309 #define DBG_E1 printf
1311 #define DBG_E1(x, ... )
1314 #define _32BITS_RELOC 0x00000000
1315 #define _30BITS_RELOC 0x80000000
1316 #define _28BITS_RELOC 0x40000000
1319 unsigned long sec_vma, exist_val, S;
1321 relocation_needed = 1;
1322 DBG_E1("Handling Reloc <CONST31>\n");
1323 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1324 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1325 sec_vma, sym_addr, q->address);
1326 sym_addr = sec_vma + sym_addr;
1327 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1328 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1329 exist_val = htoe1l(exist_val);
1330 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1331 sym_addr += exist_val;
1332 pflags = _30BITS_RELOC;
1334 case R_E1_CONST31_PCREL:
1335 relocation_needed = 0;
1336 DBG_E1("Handling Reloc <CONST31_PCREL>\n");
1337 DBG_E1("DONT RELOCATE AT LOADING\n");
1338 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1339 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1340 sec_vma, sym_addr, q->address);
1341 sym_addr = sec_vma + sym_addr;
1342 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1344 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1346 q->address = q->address + section_vma;
1347 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1349 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1350 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1351 DBG_E1( "sym_addr := sym_addr - q->address - "
1352 "sizeof(CONST31_PCREL): [0x%x]\n",
1354 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1355 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1356 exist_val = htoe1l(exist_val);
1357 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1358 sym_addr |= exist_val;
1359 DBG_E1("sym_addr |= exist_val) : [0x%x]\n", sym_addr );
1361 case R_E1_DIS29W_PCREL:
1362 relocation_needed = 0;
1363 DBG_E1("Handling Reloc <DIS29W_PCREL>\n");
1364 DBG_E1("DONT RELOCATE AT LOADING\n");
1365 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1366 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1367 sec_vma, sym_addr, q->address);
1368 sym_addr = sec_vma + sym_addr;
1369 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1371 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1373 q->address = q->address + section_vma;
1374 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1376 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1377 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1378 DBG_E1( "sym_addr := sym_addr - q->address - "
1379 "sizeof(CONST31_PCREL): [0x%x]\n",
1381 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1382 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1383 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1384 exist_val = htoe1l(exist_val);
1385 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1386 sym_addr += exist_val;
1389 DBG_E1("Handling Reloc <DIS29W>\n");
1390 goto DIS29_RELOCATION;
1392 DBG_E1("Handling Reloc <DIS29H>\n");
1393 goto DIS29_RELOCATION;
1395 DBG_E1("Handling Reloc <DIS29B>\n");
1397 relocation_needed = 1;
1398 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1399 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%08x]\n",
1401 sym_addr = sec_vma + sym_addr;
1402 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%08x]\n", sym_addr);
1403 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1404 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1405 exist_val = htoe1l(exist_val);
1406 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1407 sym_addr += exist_val;
1408 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1409 pflags = _28BITS_RELOC;
1411 case R_E1_IMM32_PCREL:
1412 relocation_needed = 0;
1413 DBG_E1("Handling Reloc <IMM32_PCREL>\n");
1414 DBG_E1("DONT RELOCATE AT LOADING\n");
1415 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1416 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1418 sym_addr = sec_vma + sym_addr;
1420 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1421 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1423 q->address = q->address + section_vma;
1424 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1426 if( (sym_addr = (sym_addr - q->address - 6 )) < 0 )
1427 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1428 DBG_E1( "sym_addr := sym_addr - q->address - "
1429 "sizeof(CONST31_PCREL): [0x%x]\n",
1431 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1432 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1433 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1434 exist_val = htoe1l(exist_val);
1435 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1436 sym_addr += exist_val;
1439 relocation_needed = 1;
1440 DBG_E1("Handling Reloc <IMM32>\n");
1441 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1442 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1444 sym_addr = sec_vma + sym_addr;
1445 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1446 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1447 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1448 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1449 exist_val = htoe1l(exist_val);
1450 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1451 sym_addr += exist_val;
1452 pflags = _32BITS_RELOC;
1455 relocation_needed = 1;
1456 DBG_E1("Handling Reloc <WORD>\n");
1457 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1458 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1460 sym_addr = sec_vma + sym_addr;
1461 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1462 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address );
1463 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1464 exist_val = htoe1l(exist_val);
1465 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1466 sym_addr += exist_val;
1467 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1468 pflags = _32BITS_RELOC;
1471 #undef _32BITS_RELOC
1472 #undef _30BITS_RELOC
1473 #undef _28BITS_RELOC
1476 /* missing support for other types of relocs */
1477 printf("ERROR: bad reloc type %d\n", (*p)->howto->type);
1483 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
1484 bfd_section_vma(abs_bfd, sym_section));
1488 * for full elf relocation we have to write back the
1489 * start_code relative value to use.
1491 if (!pic_with_got) {
1492 #if defined(TARGET_arm)
1501 * horrible nasty hack to support different endianess
1503 if (!bfd_big_endian(abs_bfd)) {
1515 tmp.l = *(unsigned long *)r_mem;
1516 hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16);
1518 (((*p)->howto->type != R_ARM_PC24) &&
1519 ((*p)->howto->type != R_ARM_PLT32)))
1520 hl |= (tmp.c[i3] << 24);
1521 else if (tmp.c[i2] & 0x80)
1522 hl |= 0xff000000; /* sign extend */
1525 tmp.c[i0] = hl & 0xff;
1526 tmp.c[i1] = (hl >> 8) & 0xff;
1527 tmp.c[i2] = (hl >> 16) & 0xff;
1529 (((*p)->howto->type != R_ARM_PC24) &&
1530 ((*p)->howto->type != R_ARM_PLT32)))
1531 tmp.c[i3] = (hl >> 24) & 0xff;
1532 if ((*p)->howto->type == R_ARM_ABS32)
1533 *(unsigned long *)r_mem = htonl(hl);
1535 *(unsigned long *)r_mem = tmp.l;
1537 #elif defined(TARGET_bfin)
1538 if ((*p)->howto->type == R_pcrel24
1539 || (*p)->howto->type == R_pcrel24_jump_l
1540 || (*p)->howto->type == R_pcrel24_jump_x
1541 || (*p)->howto->type == R_pcrel24_call_x)
1543 sym_addr += 2*-1*PCREL24_MAGIC_OFFSET;
1544 *((unsigned short *)(sectionp + q->address) + 1 + PCREL24_MAGIC_OFFSET)
1545 = (sym_addr >> 1) & 0xffff;
1546 *((unsigned short *)(sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1547 = (0xff00 & *((unsigned short *) (sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1548 | ((sym_addr >> 17) & 0xff));
1549 } else if ((*p)->howto->type == R_byte4_data) {
1550 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1551 } else if ((*p)->howto->type == R_pcrel12_jump
1552 || (*p)->howto->type == R_pcrel12_jump_s) {
1553 *((unsigned short *)(sectionp + q->address))
1554 = (0xf000 & *((unsigned short *)(sectionp + q->address))
1555 | ((sym_addr >> 1) & 0xfff));
1556 } else if ((*p)->howto->type == R_pcrel10) {
1557 *((unsigned short *)(sectionp + q->address))
1558 = (~0x3ff & *((unsigned short *)(sectionp + q->address))
1559 | ((sym_addr >> 1) & 0x3ff));
1560 } else if ((*p)->howto->type == R_rimm16
1561 || (*p)->howto->type == R_huimm16
1562 || (*p)->howto->type == R_luimm16) {
1563 /* for l and h we set the lower 16 bits which is only when it will be used */
1564 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1565 } else if ((*p)->howto->type == R_pcrel5m2) {
1566 *((unsigned short *)(sectionp + q->address))
1567 = (0xfff0 & *((unsigned short *)(sectionp + q->address))
1568 | ((sym_addr >> 1) & 0xf));
1569 } else if ((*p)->howto->type == R_pcrel11){
1570 *((unsigned short *)(sectionp + q->address))
1571 = (0xfc00 & *((unsigned short *)(sectionp + q->address))
1572 | ((sym_addr >> 1) & 0x3ff));
1573 } else if (0xE0 <= (*p)->howto->type && 0xF3 >= (*p)->howto->type) {
1574 //arith relocs dont generate a real relocation
1576 printf("Blackfin relocation fail for reloc type: 0x%x\n", (*p)->howto->type);
1578 #elif defined(TARGET_e1)
1579 #define OPCODE_SIZE 2 /* Add 2 bytes, counting the opcode size*/
1580 switch ((*p)->howto->type) {
1582 case R_E1_CONST31_PCREL:
1583 case R_E1_DIS29W_PCREL:
1587 case R_E1_IMM32_PCREL:
1589 DBG_E1("In addr + 2:[0x%x] <- write [0x%x]\n",
1590 (sectionp + q->address + 2), sym_addr );
1591 *((unsigned long *) (sectionp + q->address + OPCODE_SIZE)) =
1595 DBG_E1("In addr : [0x%x] <- write [0x%x]\n",
1596 (sectionp + q->address), sym_addr );
1597 *((unsigned long *) (sectionp + q->address )) = htonl(sym_addr);
1600 printf("ERROR:Unhandled Relocation. Exiting...\n");
1604 #else /* ! TARGET_arm && ! TARGET_e1 */
1606 switch (q->howto->type) {
1611 /* Do nothing -- for cases we handle,
1612 the bits produced by the linker are
1613 what we want in the final flat file
1614 (and other cases are errors). Note
1615 that unlike most relocated values,
1616 it is stored in little-endian order,
1617 but this is necessary to avoid
1618 trashing the low-bit, and the float
1619 loaders knows about it. */
1621 #endif /* TARGET_V850 */
1624 case R_NIOS2_BFD_RELOC_32:
1625 case R_NIOS2_CALL26:
1626 case R_NIOS2_HIADJ16:
1630 #endif /* TARGET_nios2 */
1632 #if defined(TARGET_m68k)
1634 if (sym_addr < -0x8000 || sym_addr > 0x7fff) {
1635 fprintf (stderr, "Relocation overflow for R_68K_PC16 relocation against %s\n", sym_name);
1638 r_mem[0] = (sym_addr >> 8) & 0xff;
1639 r_mem[1] = sym_addr & 0xff;
1645 /* The alignment of the build host
1646 might be stricter than that of the
1647 target, so be careful. We store in
1648 network byte order. */
1649 r_mem[0] = (sym_addr >> 24) & 0xff;
1650 r_mem[1] = (sym_addr >> 16) & 0xff;
1651 r_mem[2] = (sym_addr >> 8) & 0xff;
1652 r_mem[3] = sym_addr & 0xff;
1654 #endif /* !TARGET_arm */
1659 if ((*p)->howto->type == R_rimm16
1660 || (*p)->howto->type == R_huimm16
1661 || (*p)->howto->type == R_luimm16)
1663 /* for l and h we set the lower 16 bits which is only when it will be used */
1664 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1665 } else if ((*p)->howto->type == R_byte4_data) {
1666 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1671 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
1672 "section=%s size=%d "
1673 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
1674 q->address, sym_name, addstr,
1675 section_name, sym_reloc_size,
1676 sym_addr, section_vma + q->address);
1679 * Create relocation entry (PC relative doesn't need this).
1681 if (relocation_needed) {
1683 flat_relocs = realloc(flat_relocs,
1684 (flat_reloc_count + 1) * sizeof(uint32_t));
1686 flat_relocs[flat_reloc_count] = pflags |
1687 (section_vma + q->address);
1690 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
1691 section_vma + q->address);
1693 switch ((*p)->howto->type) {
1695 case R_E1_CONST31_PCREL:
1696 case R_E1_DIS29W_PCREL:
1700 case R_E1_IMM32_PCREL:
1702 flat_relocs[flat_reloc_count] = pflags |
1703 (section_vma + q->address + OPCODE_SIZE);
1705 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1706 flat_relocs[flat_reloc_count] );
1709 flat_relocs[flat_reloc_count] = pflags |
1710 (section_vma + q->address);
1712 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1713 flat_relocs[flat_reloc_count] );
1719 relocation_needed = 0;
1724 printf("%s(%d): symbol name=%s address=0x%x section=%s -> RELOC=0x%x\n",
1725 __FILE__, __LINE__, sym_name, q->address, section_name,
1726 flat_relocs[flat_reloc_count]);
1733 printf("%d bad relocs\n", bad_relocs);
1740 *n_relocs = flat_reloc_count;
1746 static char * program;
1748 static void usage(void)
1750 fprintf(stderr, "Usage: %s [vrzd] [-p <abs-pic-file>] [-s stack-size] "
1751 "[-o <output-file>] <elf-file>\n\n"
1752 " -v : verbose operation\n"
1753 " -r : force load to RAM\n"
1754 " -k : enable kernel trace on load (for debug)\n"
1755 " -z : compress code/data/relocs\n"
1756 " -d : compress data/relocs\n"
1757 " -a : use existing symbol references\n"
1758 " instead of recalculating from\n"
1759 " relocation info\n"
1760 " -R reloc-file : read relocations from a separate file\n"
1761 " -p abs-pic-file : GOT/PIC processing with files\n"
1762 " -s stacksize : set application stack size\n"
1763 " -o output-file : output file name\n\n",
1765 fprintf(stderr, "Compiled for " ARCH " architecture\n\n");
1770 /* Write NUM zeroes to STREAM. */
1771 static void write_zeroes (unsigned long num, FILE *stream)
1775 /* It'd be nice if we could just use fseek, but that doesn't seem to
1776 work for stdio output files. */
1777 bzero(zeroes, 1024);
1778 while (num > sizeof(zeroes)) {
1779 fwrite(zeroes, sizeof(zeroes), 1, stream);
1780 num -= sizeof(zeroes);
1783 fwrite(zeroes, num, 1, stream);
1788 int main(int argc, char *argv[])
1791 bfd *rel_bfd, *abs_bfd;
1793 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;
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 stack = atoi(optarg);
1876 fprintf(stderr, "%s Unknown option\n", argv[0]);
1883 * if neither the -r or -p options was given, default to
1884 * a RAM load as that is the only option that makes sense.
1886 if (!load_to_ram && !pfile)
1889 filename = fname = argv[argc-1];
1900 if (!(rel_bfd = bfd_openr(rel_file, 0))) {
1901 fprintf(stderr, "Can't open %s\n", rel_file);
1905 if (bfd_check_format (rel_bfd, bfd_object) == 0) {
1906 fprintf(stderr, "File is not an object file\n");
1910 if (abs_file == rel_file)
1911 abs_bfd = rel_bfd; /* one file does all */
1913 if (!(abs_bfd = bfd_openr(abs_file, 0))) {
1914 fprintf(stderr, "Can't open %s\n", abs_file);
1918 if (bfd_check_format (abs_bfd, bfd_object) == 0) {
1919 fprintf(stderr, "File is not an object file\n");
1924 if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC)) {
1925 fprintf (stderr, "%s: Input file contains no relocation info\n", rel_file);
1929 if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P)) {
1930 /* `Absolute' file is not absolute, so neither are address
1931 contained therein. */
1933 "%s: `-a' option specified with non-fully-resolved input file\n",
1934 bfd_get_filename (abs_bfd));
1938 symbol_table = get_symbols(abs_bfd, &number_of_symbols);
1940 /* Group output sections into text, data, and bss, and calc their sizes. */
1941 for (s = abs_bfd->sections; s != NULL; s = s->next) {
1942 unsigned long *vma, *len;
1943 bfd_size_type sec_size;
1946 if (s->flags & SEC_CODE) {
1949 } else if (s->flags & SEC_DATA) {
1952 } else if (s->flags & SEC_ALLOC) {
1958 sec_size = bfd_section_size(abs_bfd, s);
1959 sec_vma = bfd_section_vma(abs_bfd, s);
1961 if (sec_vma < *vma) {
1963 *len += sec_vma - *vma;
1967 } else if (sec_vma + sec_size > *vma + *len)
1968 *len = sec_vma + sec_size - *vma;
1971 if (text_len == 0) {
1972 fprintf (stderr, "%s: no .text section", abs_file);
1976 text = malloc(text_len);
1979 printf("TEXT -> vma=0x%x len=0x%x\n", text_vma, text_len);
1981 /* Read in all text sections. */
1982 for (s = abs_bfd->sections; s != NULL; s = s->next)
1983 if (s->flags & SEC_CODE)
1984 if (!bfd_get_section_contents(abs_bfd, s,
1985 text + (s->vma - text_vma), 0,
1986 bfd_section_size(abs_bfd, s)))
1988 fprintf(stderr, "read error section %s\n", s->name);
1992 if (data_len == 0) {
1993 fprintf (stderr, "%s: no .data section", abs_file);
1996 data = malloc(data_len);
1999 printf("DATA -> vma=0x%x len=0x%x\n", data_vma, data_len);
2001 if ((text_vma + text_len) != data_vma) {
2002 if ((text_vma + text_len) > data_vma) {
2003 printf("ERROR: text=0x%x overlaps data=0x%x ?\n", text_len, data_vma);
2007 printf("WARNING: data=0x%x does not directly follow text=0x%x\n",
2008 data_vma, text_len);
2009 text_len = data_vma - text_vma;
2012 /* Read in all data sections. */
2013 for (s = abs_bfd->sections; s != NULL; s = s->next)
2014 if (s->flags & SEC_DATA)
2015 if (!bfd_get_section_contents(abs_bfd, s,
2016 data + (s->vma - data_vma), 0,
2017 bfd_section_size(abs_bfd, s)))
2019 fprintf(stderr, "read error section %s\n", s->name);
2023 /* Put common symbols in bss. */
2024 bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len);
2027 printf("BSS -> vma=0x%x len=0x%x\n", bss_vma, bss_len);
2029 if ((data_vma + data_len) != bss_vma) {
2030 if ((data_vma + data_len) > bss_vma) {
2031 printf("ERROR: text=0x%x + data=0x%x overlaps bss=0x%x ?\n", text_len,
2036 printf("WARNING: bss=0x%x does not directly follow text=0x%x + data=0x%x(0x%x)\n",
2037 bss_vma, text_len, data_len, text_len + data_len);
2038 data_len = bss_vma - data_vma;
2041 reloc = output_relocs(abs_bfd, symbol_table, number_of_symbols, &reloc_len,
2042 text, text_len, text_vma, data, data_len, data_vma,
2046 printf("No relocations in code!\n");
2048 text_offs = real_address_bits(text_vma);
2050 /* Fill in the binflt_flat header */
2051 memcpy(hdr.magic,"bFLT",4);
2052 hdr.rev = htonl(FLAT_VERSION);
2053 hdr.entry = htonl(sizeof(hdr) + bfd_get_start_address(abs_bfd));
2054 hdr.data_start = htonl(sizeof(hdr) + text_offs + text_len);
2055 hdr.data_end = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2056 hdr.bss_end = htonl(sizeof(hdr) + text_offs + text_len +data_len+bss_len);
2057 hdr.stack_size = htonl(stack); /* FIXME */
2058 hdr.reloc_start = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2059 hdr.reloc_count = htonl(reloc_len);
2061 | (load_to_ram ? FLAT_FLAG_RAM : 0)
2062 | (ktrace ? FLAT_FLAG_KTRACE : 0)
2063 | (pic_with_got ? FLAT_FLAG_GOTPIC : 0)
2064 | (compress ? (compress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
2066 hdr.build_date = htonl((unsigned long)time(NULL));
2067 bzero(hdr.filler, sizeof(hdr.filler));
2069 for (i=0; i<reloc_len; i++) reloc[i] = htonl(reloc[i]);
2072 printf("SIZE: .text=0x%04x, .data=0x%04x, .bss=0x%04x",
2073 text_len, data_len, bss_len);
2075 printf(", relocs=0x%04x", reloc_len);
2080 ofile = malloc(strlen(fname) + 5 + 1); /* 5 to add suffix */
2081 strcpy(ofile, fname);
2082 strcat(ofile, ".bflt");
2085 if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0) {
2086 fprintf (stderr, "Can't open output file %s\n", ofile);
2090 write(fd, &hdr, sizeof(hdr));
2094 * get the compression command ready
2096 sprintf(cmd, "gzip -f -9 >> %s", ofile);
2098 #define START_COMPRESSOR do { \
2104 if (!(gf = popen(cmd, "w" BINARY_FILE_OPTS))) { \
2105 fprintf(stderr, "Can't run cmd %s\n", cmd); \
2111 gf = fopen(ofile, "ab"); /* Add 'b' to support non-posix (ie windows) */
2113 fprintf(stderr, "Can't open file %s for writing\n", ofile); \
2120 /* Fill in any hole at the beginning of the text segment. */
2122 printf("ZERO before text len=0x%x\n", text_offs);
2123 write_zeroes(text_offs, gf);
2125 /* Write the text segment. */
2126 fwrite(text, text_len, 1, gf);
2131 /* Write the data segment. */
2132 fwrite(data, data_len, 1, gf);
2135 fwrite(reloc, reloc_len * 4, 1, gf);
2147 * this __MUST__ be at the VERY end of the file - do NOT move!!
2153 * vi: tabstop=8 shiftwidth=4 textwidth=79 noexpandtab