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!
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_v850_reloc_err;
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_v850_reloc_err;
695 printf("ERROR: reloc type %s unsupported in this context\n",
699 #endif /* TARGET_V850 */
701 #if defined(TARGET_arm)
703 relocation_needed = 1;
707 relocation_needed = 0;
710 printf("ERROR: reloc type %s unsupported in this context\n",
716 /* The default is to assume that the
717 relocation is relative and has
718 already been fixed up by the
719 linker (perhaps we ought to make
720 give an error by default, and
721 require `safe' relocations to be
722 enumberated explicitly?). */
723 if (bfd_big_endian (abs_bfd))
735 relocation_needed = 1;
739 /* Calculate the sym address ourselves. */
740 sym_reloc_size = bfd_get_reloc_size(q->howto);
742 #if !defined(TARGET_h8300) && !defined(TARGET_e1) && !defined(TARGET_bfin) && !defined(TARGET_m68k)
743 if (sym_reloc_size != 4) {
744 printf("ERROR: bad reloc type %d size=%d for symbol=%s\n",
745 (*p)->howto->type, sym_reloc_size, sym_name);
752 switch ((*p)->howto->type) {
754 #if defined(TARGET_m68k)
756 relocation_needed = 1;
757 sym_vma = bfd_section_vma(abs_bfd, sym_section);
758 sym_addr += sym_vma + q->addend;
763 sym_addr += sym_vma + q->addend;
764 sym_addr -= q->address;
768 #if defined(TARGET_arm)
770 relocation_needed = 1;
773 "%s vma=0x%x, value=0x%x, address=0x%x "
774 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
776 sym_vma, (*(q->sym_ptr_ptr))->value,
777 q->address, sym_addr,
778 (*p)->howto->rightshift,
779 *(unsigned long *)r_mem);
780 sym_vma = bfd_section_vma(abs_bfd, sym_section);
781 sym_addr += sym_vma + q->addend;
785 /* Should be fine as is */
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);
799 sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift;
805 relocation_needed = 1;
806 sym_vma = bfd_section_vma(abs_bfd, sym_section);
807 sym_addr += sym_vma + q->addend;
809 #if defined(R_V850_ZDA_16_16_OFFSET) || defined(R_V850_ZDA_16_16_SPLIT_OFFSET)
810 #ifdef R_V850_ZDA_16_16_OFFSET
811 case R_V850_ZDA_16_16_OFFSET:
813 #ifdef R_V850_ZDA_16_16_SPLIT_OFFSET
814 case R_V850_ZDA_16_16_SPLIT_OFFSET:
816 /* Can't support zero-relocations. */
817 printf ("ERROR: %s+0x%x: zero relocations not supported\n",
818 sym_name, q->addend);
820 #endif /* R_V850_ZDA_16_16_OFFSET || R_V850_ZDA_16_16_SPLIT_OFFSET */
821 #endif /* TARGET_v850 */
825 if (sym_reloc_size != 4) {
826 printf("R_H8_DIR24R8 size %d\n", sym_reloc_size);
830 relocation_needed = 1;
831 sym_addr = (*(q->sym_ptr_ptr))->value;
833 r_mem -= 1; /* tracks q->address */
834 sym_vma = bfd_section_vma(abs_bfd, sym_section);
835 sym_addr += sym_vma + q->addend;
836 sym_addr |= (*(unsigned char *)r_mem<<24);
839 if (sym_reloc_size != 4) {
840 printf("R_H8_DIR24A8 size %d\n", sym_reloc_size);
844 /* Absolute symbol done not relocation */
845 relocation_needed = !bfd_is_abs_section(sym_section);
846 sym_addr = (*(q->sym_ptr_ptr))->value;
847 sym_vma = bfd_section_vma(abs_bfd, sym_section);
848 sym_addr += sym_vma + q->addend;
851 case R_H8_DIR32A16: /* currently 32, could be made 16 */
852 if (sym_reloc_size != 4) {
853 printf("R_H8_DIR32 size %d\n", sym_reloc_size);
857 relocation_needed = 1;
858 sym_addr = (*(q->sym_ptr_ptr))->value;
859 sym_vma = bfd_section_vma(abs_bfd, sym_section);
860 sym_addr += sym_vma + q->addend;
864 sym_addr = (*(q->sym_ptr_ptr))->value;
865 sym_addr += sym_vma + q->addend;
866 sym_addr -= (q->address + 2);
867 if (bfd_big_endian(abs_bfd))
868 *(unsigned short *)r_mem =
869 bfd_big_endian(abs_bfd) ? htons(sym_addr) : sym_addr;
873 sym_addr = (*(q->sym_ptr_ptr))->value;
874 sym_addr += sym_vma + q->addend;
875 sym_addr -= (q->address + 1);
876 *(unsigned char *)r_mem = sym_addr;
880 #ifdef TARGET_microblaze
881 case R_MICROBLAZE_64:
882 /* The symbol is split over two consecutive instructions.
883 Flag this to the flat loader by setting the high bit of
884 the relocation symbol. */
886 unsigned char *p = r_mem;
887 unsigned long offset;
890 /* work out the relocation */
891 sym_vma = bfd_section_vma(abs_bfd, sym_section);
892 /* grab any offset from the text */
893 offset = (p[2]<<24) + (p[3] << 16) + (p[6] << 8) + (p[7]);
894 /* Update the address */
895 sym_addr += offset + sym_vma + q->addend;
896 /* Write relocated pointer back */
897 p[2] = (sym_addr >> 24) & 0xff;
898 p[3] = (sym_addr >> 16) & 0xff;
899 p[6] = (sym_addr >> 8) & 0xff;
900 p[7] = sym_addr & 0xff;
902 /* create a new reloc entry */
903 flat_relocs = realloc(flat_relocs,
904 (flat_reloc_count + 1) * sizeof(uint32_t));
905 flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address);
907 relocation_needed = 0;
909 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
910 bfd_section_vma(abs_bfd, sym_section));
912 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
913 "section=%s size=%d "
914 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
915 q->address, sym_name, addstr,
916 section_name, sym_reloc_size,
917 sym_addr, section_vma + q->address);
919 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
920 section_vma + q->address);
924 case R_MICROBLAZE_32:
926 unsigned char *p = r_mem;
927 unsigned long offset;
929 /* grab any offset from the text */
930 offset = (p[0]<<24) + (p[1] << 16) + (p[2] << 8) + (p[3]);
931 sym_vma = bfd_section_vma(abs_bfd, sym_section);
932 /* This is a horrible kludge. For some
933 reason, *sometimes* the offset is in
934 both addend and the code. Detect
935 it, and cancel the effect. Otherwise
936 the offset gets added twice - ouch.
937 There should be a better test
938 for this condition, based on the
939 BFD data structures */
940 if(offset==q->addend)
943 sym_addr += offset + sym_vma + q->addend;
944 relocation_needed = 1;
947 case R_MICROBLAZE_64_PCREL:
949 //sym_addr = (*(q->sym_ptr_ptr))->value;
950 sym_addr += sym_vma + q->addend;
951 sym_addr -= (q->address + 4);
952 sym_addr = htonl(sym_addr);
954 * ((unsigned short *) (r_mem+2)) |= (sym_addr) & 0xFFFF;
956 * ((unsigned short *) (r_mem+6)) |= (sym_addr >> 16) & 0xFFFF;
957 /* We've done all the work, so continue
958 to next reloc instead of break */
961 #endif /* TARGET_microblaze */
964 #define htoniosl(x) (x)
965 #define niostohl(x) (x)
966 switch ((*p)->howto->type)
968 case R_NIOS2_BFD_RELOC_32:
969 relocation_needed = 1;
970 pflags = (FLAT_NIOS2_R_32 << 28);
971 sym_vma = bfd_section_vma(abs_bfd, sym_section);
972 sym_addr += sym_vma + q->addend;
973 /* modify target, in target order */
974 *(unsigned long *)r_mem = htoniosl(sym_addr);
978 unsigned long exist_val;
979 relocation_needed = 1;
980 pflags = (FLAT_NIOS2_R_CALL26 << 28);
981 sym_vma = bfd_section_vma(abs_bfd, sym_section);
982 sym_addr += sym_vma + q->addend;
984 /* modify target, in target order */
985 // exist_val = niostohl(*(unsigned long *)r_mem);
986 exist_val = ((sym_addr >> 2) << 6);
987 *(unsigned long *)r_mem = htoniosl(exist_val);
990 case R_NIOS2_HIADJ16:
993 unsigned long exist_val;
995 /* handle the adjacent HI/LO pairs */
997 r2_type = R_NIOS2_NONE;
999 r2_type = p[1]->howto->type;
1000 if ((r2_type == R_NIOS2_LO16)
1001 && (p[0]->sym_ptr_ptr == p[1]->sym_ptr_ptr)
1002 && (p[0]->addend == p[1]->addend))
1004 unsigned char * r2_mem = sectionp + p[1]->address;
1005 if (p[1]->address - q->address!=4)
1006 printf("Err: HI/LO not adjacent %d\n", p[1]->address - q->address);
1007 relocation_needed = 1;
1008 pflags = (q->howto->type == R_NIOS2_HIADJ16)
1009 ? FLAT_NIOS2_R_HIADJ_LO : FLAT_NIOS2_R_HI_LO;
1012 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1013 sym_addr += sym_vma + q->addend;
1015 /* modify high 16 bits, in target order */
1016 exist_val = niostohl(*(unsigned long *)r_mem);
1017 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1018 if (q->howto->type == R_NIOS2_HIADJ16)
1019 exist_val |= ((((sym_addr >> 16) + ((sym_addr >> 15) & 1)) & 0xFFFF) << 6);
1021 exist_val |= (((sym_addr >> 16) & 0xFFFF) << 6);
1022 *(unsigned long *)r_mem = htoniosl(exist_val);
1024 /* modify low 16 bits, in target order */
1025 exist_val = niostohl(*(unsigned long *)r2_mem);
1026 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1027 exist_val |= ((sym_addr & 0xFFFF) << 6);
1028 *(unsigned long *)r2_mem = htoniosl(exist_val);
1031 goto NIOS2_RELOC_ERR;
1037 unsigned long exist_val, temp;
1038 //long gp = get_symbol_offset("_gp", sym_section, symbols, number_of_symbols);
1039 long gp = get_gp_value(symbols, number_of_symbols);
1041 printf("Err: unresolved symbol _gp when relocating %s\n", sym_name);
1042 goto NIOS2_RELOC_ERR;
1044 /* _gp holds a absolute value, otherwise the ld cannot generate correct code */
1045 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1046 //printf("sym=%x, %d, _gp=%x, %d\n", sym_addr+sym_vma, sym_addr+sym_vma, gp, gp);
1047 sym_addr += sym_vma + q->addend;
1049 //printf("sym - _gp=%x, %d\n", sym_addr, sym_addr);
1050 /* modify the target, in target order (little_endian) */
1051 exist_val = niostohl(*(unsigned long *)r_mem);
1052 temp = ((exist_val >> 6) & 0x3ff0000) | (sym_addr & 0xffff);
1054 temp |= (exist_val & 0x3f);
1055 *(unsigned long *)r_mem = htoniosl(temp);
1057 printf("omit: offset=0x%x symbol=%s%s "
1058 "section=%s size=%d "
1059 "fixup=0x%x (reloc=0x%x) GPREL\n",
1060 q->address, sym_name, addstr,
1061 section_name, sym_reloc_size,
1062 sym_addr, section_vma + q->address);
1065 case R_NIOS2_PCREL16:
1067 unsigned long exist_val;
1069 sym_addr += sym_vma + q->addend;
1070 sym_addr -= (q->address + 4);
1071 /* modify the target, in target order (little_endian) */
1072 exist_val = niostohl(*(unsigned long *)r_mem);
1073 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1074 exist_val |= ((sym_addr & 0xFFFF) << 6);
1075 *(unsigned long *)r_mem = htoniosl(exist_val);
1077 printf("omit: offset=0x%x symbol=%s%s "
1078 "section=%s size=%d "
1079 "fixup=0x%x (reloc=0x%x) PCREL\n",
1080 q->address, sym_name, addstr,
1081 section_name, sym_reloc_size,
1082 sym_addr, section_vma + q->address);
1087 /* check if this is actually the 2nd half of a pair */
1089 && ((p[-1]->howto->type == R_NIOS2_HIADJ16)
1090 || (p[-1]->howto->type == R_NIOS2_HI16))
1091 && (p[-1]->sym_ptr_ptr == p[0]->sym_ptr_ptr)
1092 && (p[-1]->addend == p[0]->addend)) {
1094 printf("omit: offset=0x%x symbol=%s%s "
1095 "section=%s size=%d LO16\n",
1096 q->address, sym_name, addstr,
1097 section_name, sym_reloc_size);
1101 /* error, fall through */
1105 case R_NIOS2_CACHE_OPX:
1109 case R_NIOS2_BFD_RELOC_16:
1110 case R_NIOS2_BFD_RELOC_8:
1111 case R_NIOS2_GNU_VTINHERIT:
1112 case R_NIOS2_GNU_VTENTRY:
1117 printf("Err: unexpected reloc type %s(%d)\n", q->howto->name, q->howto->type);
1121 #endif /* TARGET_nios2 */
1126 relocation_needed = 1;
1127 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1128 sym_addr += sym_vma + q->addend;
1132 sym_addr += sym_vma + q->addend;
1133 sym_addr -= q->address;
1135 case R_SPARC_WDISP30:
1136 sym_addr = (((*(q->sym_ptr_ptr))->value-
1137 q->address) >> 2) & 0x3fffffff;
1139 ntohl(*(unsigned long *)r_mem)
1144 relocation_needed = 1;
1145 pflags = 0x80000000;
1146 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1147 sym_addr += sym_vma + q->addend;
1149 htonl(*(unsigned long *)r_mem)
1154 relocation_needed = 1;
1155 pflags = 0x40000000;
1156 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1157 sym_addr += sym_vma + q->addend;
1158 sym_addr &= 0x000003ff;
1160 htonl(*(unsigned long *)r_mem)
1164 #endif /* TARGET_sparc */
1167 case R_pcrel12_jump:
1168 case R_pcrel12_jump_s:
1170 case R_pcrel24_jump_l:
1171 case R_pcrel24_jump_x:
1172 case R_pcrel24_call_x:
1176 sym_addr += q->addend;// get the symbol addr
1177 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1178 sym_addr -= q->address; // make it PC relative
1179 // implicitly assumes code section and symbol section are same
1186 sym_addr += q->addend;
1187 if(weak_und_symbol(sym_section->name, (*(q->sym_ptr_ptr))))
1189 if(0xFFFF0000 & sym_addr){
1190 fprintf (stderr, "Relocation overflow for rN = %s\n",sym_name);
1193 flat_relocs = (uint32_t *)
1194 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1195 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1196 sym_section->name, sym_name,
1197 (*(q->sym_ptr_ptr)),
1198 0, FLAT_RELOC_PART_LO,
1199 section_vma + q->address))
1208 unsigned int reloc_count_incr;
1211 if (q->howto->type == R_luimm16)
1212 hi_lo = FLAT_RELOC_PART_LO;
1214 hi_lo = FLAT_RELOC_PART_HI;
1216 sym_addr += q->addend;
1218 flat_relocs = (uint32_t *)
1219 (realloc (flat_relocs, (flat_reloc_count + 2) * sizeof (uint32_t)));
1220 reloc_count_incr = 1;
1221 if (weak_und_symbol (sym_section->name, (*(q->sym_ptr_ptr))))
1223 if (0xFFFF0000 & sym_addr) {
1224 /* value is > 16 bits - use an extra field */
1225 /* see if we have already output that symbol */
1226 /* reloc may be addend from symbol and */
1227 /* we can only store 16 bit offsets */
1229 if ((*(q->sym_ptr_ptr))->udata.i == 0
1230 || flat_relocs[(*(q->sym_ptr_ptr))->udata.i] != sym_addr
1231 || ((*(q->sym_ptr_ptr))->udata.i & 0xFFFF0000))
1233 reloc_count_incr = 2;
1234 flat_relocs[flat_reloc_count + 1] = sym_addr;
1235 (*(q->sym_ptr_ptr))->udata.i = flat_reloc_count + 1;
1236 sym_addr = 0; // indication to loader to read next
1238 sym_addr = (*(q->sym_ptr_ptr))->udata.i;
1244 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1245 sym_section->name, sym_name,
1246 (*(q->sym_ptr_ptr)),
1248 section_vma + q->address))
1250 flat_reloc_count += reloc_count_incr;
1254 sym_addr += q->addend;
1256 if (weak_und_symbol (sym_section->name, *q->sym_ptr_ptr))
1259 flat_relocs = (uint32_t *)
1260 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1261 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1262 sym_section->name, sym_name,
1263 (*(q->sym_ptr_ptr)),
1264 2, FLAT_RELOC_PART_LO,
1265 section_vma + q->address))
1271 #endif //TARGET_bfin
1275 relocation_needed = 1;
1276 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1277 sym_addr += sym_vma + q->addend;
1281 sym_addr += sym_vma + q->addend;
1282 sym_addr -= q->address;
1284 #endif /* TARGET_sh */
1287 #define htoe1l(x) htonl(x)
1294 #define DBG_E1 printf
1296 #define DBG_E1(x, ... )
1299 #define _32BITS_RELOC 0x00000000
1300 #define _30BITS_RELOC 0x80000000
1301 #define _28BITS_RELOC 0x40000000
1304 unsigned long sec_vma, exist_val, S;
1306 relocation_needed = 1;
1307 DBG_E1("Handling Reloc <CONST31>\n");
1308 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1309 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1310 sec_vma, sym_addr, q->address);
1311 sym_addr = sec_vma + sym_addr;
1312 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1313 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1314 exist_val = htoe1l(exist_val);
1315 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1316 sym_addr += exist_val;
1317 pflags = _30BITS_RELOC;
1319 case R_E1_CONST31_PCREL:
1320 relocation_needed = 0;
1321 DBG_E1("Handling Reloc <CONST31_PCREL>\n");
1322 DBG_E1("DONT RELOCATE AT LOADING\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 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1329 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1331 q->address = q->address + section_vma;
1332 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1334 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1335 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1336 DBG_E1( "sym_addr := sym_addr - q->address - "
1337 "sizeof(CONST31_PCREL): [0x%x]\n",
1339 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1340 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1341 exist_val = htoe1l(exist_val);
1342 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1343 sym_addr |= exist_val;
1344 DBG_E1("sym_addr |= exist_val) : [0x%x]\n", sym_addr );
1346 case R_E1_DIS29W_PCREL:
1347 relocation_needed = 0;
1348 DBG_E1("Handling Reloc <DIS29W_PCREL>\n");
1349 DBG_E1("DONT RELOCATE AT LOADING\n");
1350 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1351 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1352 sec_vma, sym_addr, q->address);
1353 sym_addr = sec_vma + sym_addr;
1354 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1356 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1358 q->address = q->address + section_vma;
1359 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1361 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1362 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1363 DBG_E1( "sym_addr := sym_addr - q->address - "
1364 "sizeof(CONST31_PCREL): [0x%x]\n",
1366 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1367 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1368 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1369 exist_val = htoe1l(exist_val);
1370 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1371 sym_addr += exist_val;
1374 DBG_E1("Handling Reloc <DIS29W>\n");
1375 goto DIS29_RELOCATION;
1377 DBG_E1("Handling Reloc <DIS29H>\n");
1378 goto DIS29_RELOCATION;
1380 DBG_E1("Handling Reloc <DIS29B>\n");
1382 relocation_needed = 1;
1383 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1384 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%08x]\n",
1386 sym_addr = sec_vma + sym_addr;
1387 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%08x]\n", sym_addr);
1388 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1389 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1390 exist_val = htoe1l(exist_val);
1391 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1392 sym_addr += exist_val;
1393 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1394 pflags = _28BITS_RELOC;
1396 case R_E1_IMM32_PCREL:
1397 relocation_needed = 0;
1398 DBG_E1("Handling Reloc <IMM32_PCREL>\n");
1399 DBG_E1("DONT RELOCATE AT LOADING\n");
1400 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1401 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1403 sym_addr = sec_vma + sym_addr;
1405 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1406 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1408 q->address = q->address + section_vma;
1409 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1411 if( (sym_addr = (sym_addr - q->address - 6 )) < 0 )
1412 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1413 DBG_E1( "sym_addr := sym_addr - q->address - "
1414 "sizeof(CONST31_PCREL): [0x%x]\n",
1416 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1417 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1418 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1419 exist_val = htoe1l(exist_val);
1420 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1421 sym_addr += exist_val;
1424 relocation_needed = 1;
1425 DBG_E1("Handling Reloc <IMM32>\n");
1426 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1427 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1429 sym_addr = sec_vma + sym_addr;
1430 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
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;
1437 pflags = _32BITS_RELOC;
1440 relocation_needed = 1;
1441 DBG_E1("Handling Reloc <WORD>\n");
1442 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1443 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1445 sym_addr = sec_vma + sym_addr;
1446 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1447 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address );
1448 DBG_E1("Orig: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 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1453 pflags = _32BITS_RELOC;
1456 #undef _32BITS_RELOC
1457 #undef _30BITS_RELOC
1458 #undef _28BITS_RELOC
1461 /* missing support for other types of relocs */
1462 printf("ERROR: bad reloc type %d\n", (*p)->howto->type);
1468 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
1469 bfd_section_vma(abs_bfd, sym_section));
1473 * for full elf relocation we have to write back the
1474 * start_code relative value to use.
1476 if (!pic_with_got) {
1477 #if defined(TARGET_arm)
1486 * horrible nasty hack to support different endianess
1488 if (!bfd_big_endian(abs_bfd)) {
1500 tmp.l = *(unsigned long *)r_mem;
1501 hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16);
1503 (((*p)->howto->type != R_ARM_PC24) &&
1504 ((*p)->howto->type != R_ARM_PLT32)))
1505 hl |= (tmp.c[i3] << 24);
1506 else if (tmp.c[i2] & 0x80)
1507 hl |= 0xff000000; /* sign extend */
1510 tmp.c[i0] = hl & 0xff;
1511 tmp.c[i1] = (hl >> 8) & 0xff;
1512 tmp.c[i2] = (hl >> 16) & 0xff;
1514 (((*p)->howto->type != R_ARM_PC24) &&
1515 ((*p)->howto->type != R_ARM_PLT32)))
1516 tmp.c[i3] = (hl >> 24) & 0xff;
1517 if ((*p)->howto->type == R_ARM_ABS32)
1518 *(unsigned long *)r_mem = htonl(hl);
1520 *(unsigned long *)r_mem = tmp.l;
1522 #elif defined(TARGET_bfin)
1523 if ((*p)->howto->type == R_pcrel24
1524 || (*p)->howto->type == R_pcrel24_jump_l
1525 || (*p)->howto->type == R_pcrel24_jump_x
1526 || (*p)->howto->type == R_pcrel24_call_x)
1528 sym_addr += 2*-1*PCREL24_MAGIC_OFFSET;
1529 *((unsigned short *)(sectionp + q->address) + 1 + PCREL24_MAGIC_OFFSET)
1530 = (sym_addr >> 1) & 0xffff;
1531 *((unsigned short *)(sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1532 = (0xff00 & *((unsigned short *) (sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1533 | ((sym_addr >> 17) & 0xff));
1534 } else if ((*p)->howto->type == R_byte4_data) {
1535 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1536 } else if ((*p)->howto->type == R_pcrel12_jump
1537 || (*p)->howto->type == R_pcrel12_jump_s) {
1538 *((unsigned short *)(sectionp + q->address))
1539 = (0xf000 & *((unsigned short *)(sectionp + q->address))
1540 | ((sym_addr >> 1) & 0xfff));
1541 } else if ((*p)->howto->type == R_pcrel10) {
1542 *((unsigned short *)(sectionp + q->address))
1543 = (~0x3ff & *((unsigned short *)(sectionp + q->address))
1544 | ((sym_addr >> 1) & 0x3ff));
1545 } else if ((*p)->howto->type == R_rimm16
1546 || (*p)->howto->type == R_huimm16
1547 || (*p)->howto->type == R_luimm16) {
1548 /* for l and h we set the lower 16 bits which is only when it will be used */
1549 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1550 } else if ((*p)->howto->type == R_pcrel5m2) {
1551 *((unsigned short *)(sectionp + q->address))
1552 = (0xfff0 & *((unsigned short *)(sectionp + q->address))
1553 | ((sym_addr >> 1) & 0xf));
1554 } else if ((*p)->howto->type == R_pcrel11){
1555 *((unsigned short *)(sectionp + q->address))
1556 = (0xfc00 & *((unsigned short *)(sectionp + q->address))
1557 | ((sym_addr >> 1) & 0x3ff));
1558 } else if (0xE0 <= (*p)->howto->type && 0xF3 >= (*p)->howto->type) {
1559 //arith relocs dont generate a real relocation
1561 printf("Blackfin relocation fail for reloc type: 0x%x\n", (*p)->howto->type);
1563 #elif defined(TARGET_e1)
1564 #define OPCODE_SIZE 2 /* Add 2 bytes, counting the opcode size*/
1565 switch ((*p)->howto->type) {
1567 case R_E1_CONST31_PCREL:
1568 case R_E1_DIS29W_PCREL:
1572 case R_E1_IMM32_PCREL:
1574 DBG_E1("In addr + 2:[0x%x] <- write [0x%x]\n",
1575 (sectionp + q->address + 2), sym_addr );
1576 *((unsigned long *) (sectionp + q->address + OPCODE_SIZE)) =
1580 DBG_E1("In addr : [0x%x] <- write [0x%x]\n",
1581 (sectionp + q->address), sym_addr );
1582 *((unsigned long *) (sectionp + q->address )) = htonl(sym_addr);
1585 printf("ERROR:Unhandled Relocation. Exiting...\n");
1589 #else /* ! TARGET_arm && ! TARGET_e1 */
1591 switch (q->howto->type) {
1596 /* Do nothing -- for cases we handle,
1597 the bits produced by the linker are
1598 what we want in the final flat file
1599 (and other cases are errors). Note
1600 that unlike most relocated values,
1601 it is stored in little-endian order,
1602 but this is necessary to avoid
1603 trashing the low-bit, and the float
1604 loaders knows about it. */
1606 #endif /* TARGET_V850 */
1609 case R_NIOS2_BFD_RELOC_32:
1610 case R_NIOS2_CALL26:
1611 case R_NIOS2_HIADJ16:
1615 #endif /* TARGET_nios2 */
1617 #if defined(TARGET_m68k)
1619 if (sym_addr < -0x8000 || sym_addr > 0x7fff) {
1620 fprintf (stderr, "Relocation overflow for R_68K_PC16 relocation against %s\n", sym_name);
1623 r_mem[0] = (sym_addr >> 8) & 0xff;
1624 r_mem[1] = sym_addr & 0xff;
1630 /* The alignment of the build host
1631 might be stricter than that of the
1632 target, so be careful. We store in
1633 network byte order. */
1634 r_mem[0] = (sym_addr >> 24) & 0xff;
1635 r_mem[1] = (sym_addr >> 16) & 0xff;
1636 r_mem[2] = (sym_addr >> 8) & 0xff;
1637 r_mem[3] = sym_addr & 0xff;
1639 #endif /* !TARGET_arm */
1644 if ((*p)->howto->type == R_rimm16
1645 || (*p)->howto->type == R_huimm16
1646 || (*p)->howto->type == R_luimm16)
1648 /* for l and h we set the lower 16 bits which is only when it will be used */
1649 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1650 } else if ((*p)->howto->type == R_byte4_data) {
1651 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1656 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
1657 "section=%s size=%d "
1658 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
1659 q->address, sym_name, addstr,
1660 section_name, sym_reloc_size,
1661 sym_addr, section_vma + q->address);
1664 * Create relocation entry (PC relative doesn't need this).
1666 if (relocation_needed) {
1668 flat_relocs = realloc(flat_relocs,
1669 (flat_reloc_count + 1) * sizeof(uint32_t));
1671 flat_relocs[flat_reloc_count] = pflags |
1672 (section_vma + q->address);
1675 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
1676 section_vma + q->address);
1678 switch ((*p)->howto->type) {
1680 case R_E1_CONST31_PCREL:
1681 case R_E1_DIS29W_PCREL:
1685 case R_E1_IMM32_PCREL:
1687 flat_relocs[flat_reloc_count] = pflags |
1688 (section_vma + q->address + OPCODE_SIZE);
1690 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1691 flat_relocs[flat_reloc_count] );
1694 flat_relocs[flat_reloc_count] = pflags |
1695 (section_vma + q->address);
1697 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1698 flat_relocs[flat_reloc_count] );
1704 relocation_needed = 0;
1709 printf("%s(%d): symbol name=%s address=0x%x section=%s -> RELOC=0x%x\n",
1710 __FILE__, __LINE__, sym_name, q->address, section_name,
1711 flat_relocs[flat_reloc_count]);
1718 printf("%d bad relocs\n", bad_relocs);
1725 *n_relocs = flat_reloc_count;
1731 static char * program;
1733 static void usage(void)
1735 fprintf(stderr, "Usage: %s [vrzd] [-p <abs-pic-file>] [-s stack-size] "
1736 "[-o <output-file>] <elf-file>\n\n"
1737 " -v : verbose operation\n"
1738 " -r : force load to RAM\n"
1739 " -k : enable kernel trace on load (for debug)\n"
1740 " -z : compress code/data/relocs\n"
1741 " -d : compress data/relocs\n"
1742 " -a : use existing symbol references\n"
1743 " instead of recalculating from\n"
1744 " relocation info\n"
1745 " -R reloc-file : read relocations from a separate file\n"
1746 " -p abs-pic-file : GOT/PIC processing with files\n"
1747 " -s stacksize : set application stack size\n"
1748 " -o output-file : output file name\n\n",
1750 fprintf(stderr, "Compiled for " ARCH " architecture\n\n");
1755 /* Write NUM zeroes to STREAM. */
1756 static void write_zeroes (unsigned long num, FILE *stream)
1760 /* It'd be nice if we could just use fseek, but that doesn't seem to
1761 work for stdio output files. */
1762 bzero(zeroes, 1024);
1763 while (num > sizeof(zeroes)) {
1764 fwrite(zeroes, sizeof(zeroes), 1, stream);
1765 num -= sizeof(zeroes);
1768 fwrite(zeroes, num, 1, stream);
1773 int main(int argc, char *argv[])
1776 bfd *rel_bfd, *abs_bfd;
1778 char *ofile=NULL, *pfile=NULL, *abs_file = NULL, *rel_file = NULL;
1786 asymbol **symbol_table;
1787 long number_of_symbols;
1789 unsigned long data_len = 0;
1790 unsigned long bss_len = 0;
1791 unsigned long text_len = 0;
1792 unsigned long reloc_len;
1794 unsigned long data_vma = ~0;
1795 unsigned long bss_vma = ~0;
1796 unsigned long text_vma = ~0;
1798 unsigned long text_offs;
1804 struct flat_hdr hdr;
1814 if (sizeof(hdr) != 64) {
1816 "Potential flat header incompatibility detected\n"
1817 "header size should be 64 but is %d\n",
1824 #else /* We need plenty of stack for both of them (Aggregate and Register) */
1828 while ((opt = getopt(argc, argv, "avzdrkp:s:o:R:")) != -1) {
1855 stack = atoi(optarg);
1861 fprintf(stderr, "%s Unknown option\n", argv[0]);
1868 * if neither the -r or -p options was given, default to
1869 * a RAM load as that is the only option that makes sense.
1871 if (!load_to_ram && !pfile)
1874 filename = fname = argv[argc-1];
1885 if (!(rel_bfd = bfd_openr(rel_file, 0))) {
1886 fprintf(stderr, "Can't open %s\n", rel_file);
1890 if (bfd_check_format (rel_bfd, bfd_object) == 0) {
1891 fprintf(stderr, "File is not an object file\n");
1895 if (abs_file == rel_file)
1896 abs_bfd = rel_bfd; /* one file does all */
1898 if (!(abs_bfd = bfd_openr(abs_file, 0))) {
1899 fprintf(stderr, "Can't open %s\n", abs_file);
1903 if (bfd_check_format (abs_bfd, bfd_object) == 0) {
1904 fprintf(stderr, "File is not an object file\n");
1909 if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC)) {
1910 fprintf (stderr, "%s: Input file contains no relocation info\n", rel_file);
1914 if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P)) {
1915 /* `Absolute' file is not absolute, so neither are address
1916 contained therein. */
1918 "%s: `-a' option specified with non-fully-resolved input file\n",
1919 bfd_get_filename (abs_bfd));
1923 symbol_table = get_symbols(abs_bfd, &number_of_symbols);
1925 /* Group output sections into text, data, and bss, and calc their sizes. */
1926 for (s = abs_bfd->sections; s != NULL; s = s->next) {
1927 unsigned long *vma, *len;
1928 bfd_size_type sec_size;
1931 if (s->flags & SEC_CODE) {
1934 } else if (s->flags & SEC_DATA) {
1937 } else if (s->flags & SEC_ALLOC) {
1943 sec_size = bfd_section_size(abs_bfd, s);
1944 sec_vma = bfd_section_vma(abs_bfd, s);
1946 if (sec_vma < *vma) {
1948 *len += sec_vma - *vma;
1952 } else if (sec_vma + sec_size > *vma + *len)
1953 *len = sec_vma + sec_size - *vma;
1956 if (text_len == 0) {
1957 fprintf (stderr, "%s: no .text section", abs_file);
1961 text = malloc(text_len);
1964 printf("TEXT -> vma=0x%x len=0x%x\n", text_vma, text_len);
1966 /* Read in all text sections. */
1967 for (s = abs_bfd->sections; s != NULL; s = s->next)
1968 if (s->flags & SEC_CODE)
1969 if (!bfd_get_section_contents(abs_bfd, s,
1970 text + (s->vma - text_vma), 0,
1971 bfd_section_size(abs_bfd, s)))
1973 fprintf(stderr, "read error section %s\n", s->name);
1977 if (data_len == 0) {
1978 fprintf (stderr, "%s: no .data section", abs_file);
1981 data = malloc(data_len);
1984 printf("DATA -> vma=0x%x len=0x%x\n", data_vma, data_len);
1986 if ((text_vma + text_len) != data_vma) {
1987 if ((text_vma + text_len) > data_vma) {
1988 printf("ERROR: text=0x%x overlaps data=0x%x ?\n", text_len, data_vma);
1992 printf("WARNING: data=0x%x does not directly follow text=0x%x\n",
1993 data_vma, text_len);
1994 text_len = data_vma - text_vma;
1997 /* Read in all data sections. */
1998 for (s = abs_bfd->sections; s != NULL; s = s->next)
1999 if (s->flags & SEC_DATA)
2000 if (!bfd_get_section_contents(abs_bfd, s,
2001 data + (s->vma - data_vma), 0,
2002 bfd_section_size(abs_bfd, s)))
2004 fprintf(stderr, "read error section %s\n", s->name);
2008 /* Put common symbols in bss. */
2009 bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len);
2012 printf("BSS -> vma=0x%x len=0x%x\n", bss_vma, bss_len);
2014 if ((data_vma + data_len) != bss_vma) {
2015 if ((data_vma + data_len) > bss_vma) {
2016 printf("ERROR: text=0x%x + data=0x%x overlaps bss=0x%x ?\n", text_len,
2021 printf("WARNING: bss=0x%x does not directly follow text=0x%x + data=0x%x(0x%x)\n",
2022 bss_vma, text_len, data_len, text_len + data_len);
2023 data_len = bss_vma - data_vma;
2026 reloc = output_relocs(abs_bfd, symbol_table, number_of_symbols, &reloc_len,
2027 text, text_len, text_vma, data, data_len, data_vma,
2031 printf("No relocations in code!\n");
2033 text_offs = real_address_bits(text_vma);
2035 /* Fill in the binflt_flat header */
2036 memcpy(hdr.magic,"bFLT",4);
2037 hdr.rev = htonl(FLAT_VERSION);
2038 hdr.entry = htonl(sizeof(hdr) + bfd_get_start_address(abs_bfd));
2039 hdr.data_start = htonl(sizeof(hdr) + text_offs + text_len);
2040 hdr.data_end = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2041 hdr.bss_end = htonl(sizeof(hdr) + text_offs + text_len +data_len+bss_len);
2042 hdr.stack_size = htonl(stack); /* FIXME */
2043 hdr.reloc_start = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2044 hdr.reloc_count = htonl(reloc_len);
2046 | (load_to_ram ? FLAT_FLAG_RAM : 0)
2047 | (ktrace ? FLAT_FLAG_KTRACE : 0)
2048 | (pic_with_got ? FLAT_FLAG_GOTPIC : 0)
2049 | (compress ? (compress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
2051 hdr.build_date = htonl((unsigned long)time(NULL));
2052 bzero(hdr.filler, sizeof(hdr.filler));
2054 for (i=0; i<reloc_len; i++) reloc[i] = htonl(reloc[i]);
2057 printf("SIZE: .text=0x%04x, .data=0x%04x, .bss=0x%04x",
2058 text_len, data_len, bss_len);
2060 printf(", relocs=0x%04x", reloc_len);
2065 ofile = malloc(strlen(fname) + 5 + 1); /* 5 to add suffix */
2066 strcpy(ofile, fname);
2067 strcat(ofile, ".bflt");
2070 if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0) {
2071 fprintf (stderr, "Can't open output file %s\n", ofile);
2075 write(fd, &hdr, sizeof(hdr));
2079 * get the compression command ready
2081 sprintf(cmd, "gzip -f -9 >> %s", ofile);
2083 #define START_COMPRESSOR do { \
2089 if (!(gf = popen(cmd, "w" BINARY_FILE_OPTS))) { \
2090 fprintf(stderr, "Can't run cmd %s\n", cmd); \
2096 gf = fopen(ofile, "ab"); /* Add 'b' to support non-posix (ie windows) */
2098 fprintf(stderr, "Can't open file %s for writing\n", ofile); \
2105 /* Fill in any hole at the beginning of the text segment. */
2107 printf("ZERO before text len=0x%x\n", text_offs);
2108 write_zeroes(text_offs, gf);
2110 /* Write the text segment. */
2111 fwrite(text, text_len, 1, gf);
2116 /* Write the data segment. */
2117 fwrite(data, data_len, 1, gf);
2120 fwrite(reloc, reloc_len * 4, 1, gf);
2132 * this __MUST__ be at the VERY end of the file - do NOT move!!
2138 * vi: tabstop=8 shiftwidth=4 textwidth=79 noexpandtab