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;
706 relocation_needed = 0;
709 printf("ERROR: reloc type %s unsupported in this context\n",
715 /* The default is to assume that the
716 relocation is relative and has
717 already been fixed up by the
718 linker (perhaps we ought to make
719 give an error by default, and
720 require `safe' relocations to be
721 enumberated explicitly?). */
722 if (bfd_big_endian (abs_bfd))
734 relocation_needed = 1;
738 /* Calculate the sym address ourselves. */
739 sym_reloc_size = bfd_get_reloc_size(q->howto);
741 #if !defined(TARGET_h8300) && !defined(TARGET_e1) && !defined(TARGET_bfin) && !defined(TARGET_m68k)
742 if (sym_reloc_size != 4) {
743 printf("ERROR: bad reloc type %d size=%d for symbol=%s\n",
744 (*p)->howto->type, sym_reloc_size, sym_name);
751 switch ((*p)->howto->type) {
753 #if defined(TARGET_m68k)
755 relocation_needed = 1;
756 sym_vma = bfd_section_vma(abs_bfd, sym_section);
757 sym_addr += sym_vma + q->addend;
762 sym_addr += sym_vma + q->addend;
763 sym_addr -= q->address;
767 #if defined(TARGET_arm)
769 relocation_needed = 1;
772 "%s vma=0x%x, value=0x%x, address=0x%x "
773 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
775 sym_vma, (*(q->sym_ptr_ptr))->value,
776 q->address, sym_addr,
777 (*p)->howto->rightshift,
778 *(unsigned long *)r_mem);
779 sym_vma = bfd_section_vma(abs_bfd, sym_section);
780 sym_addr += sym_vma + q->addend;
784 /* Should be fine as is */
789 "%s vma=0x%x, value=0x%x, address=0x%x "
790 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
792 sym_vma, (*(q->sym_ptr_ptr))->value,
793 q->address, sym_addr,
794 (*p)->howto->rightshift,
795 *(unsigned long *)r_mem);
798 sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift;
804 relocation_needed = 1;
805 sym_vma = bfd_section_vma(abs_bfd, sym_section);
806 sym_addr += sym_vma + q->addend;
808 #if defined(R_V850_ZDA_16_16_OFFSET) || defined(R_V850_ZDA_16_16_SPLIT_OFFSET)
809 #ifdef R_V850_ZDA_16_16_OFFSET
810 case R_V850_ZDA_16_16_OFFSET:
812 #ifdef R_V850_ZDA_16_16_SPLIT_OFFSET
813 case R_V850_ZDA_16_16_SPLIT_OFFSET:
815 /* Can't support zero-relocations. */
816 printf ("ERROR: %s+0x%x: zero relocations not supported\n",
817 sym_name, q->addend);
819 #endif /* R_V850_ZDA_16_16_OFFSET || R_V850_ZDA_16_16_SPLIT_OFFSET */
820 #endif /* TARGET_v850 */
824 if (sym_reloc_size != 4) {
825 printf("R_H8_DIR24R8 size %d\n", sym_reloc_size);
829 relocation_needed = 1;
830 sym_addr = (*(q->sym_ptr_ptr))->value;
832 r_mem -= 1; /* tracks q->address */
833 sym_vma = bfd_section_vma(abs_bfd, sym_section);
834 sym_addr += sym_vma + q->addend;
835 sym_addr |= (*(unsigned char *)r_mem<<24);
838 if (sym_reloc_size != 4) {
839 printf("R_H8_DIR24A8 size %d\n", sym_reloc_size);
843 /* Absolute symbol done not relocation */
844 relocation_needed = !bfd_is_abs_section(sym_section);
845 sym_addr = (*(q->sym_ptr_ptr))->value;
846 sym_vma = bfd_section_vma(abs_bfd, sym_section);
847 sym_addr += sym_vma + q->addend;
850 case R_H8_DIR32A16: /* currently 32, could be made 16 */
851 if (sym_reloc_size != 4) {
852 printf("R_H8_DIR32 size %d\n", sym_reloc_size);
856 relocation_needed = 1;
857 sym_addr = (*(q->sym_ptr_ptr))->value;
858 sym_vma = bfd_section_vma(abs_bfd, sym_section);
859 sym_addr += sym_vma + q->addend;
863 sym_addr = (*(q->sym_ptr_ptr))->value;
864 sym_addr += sym_vma + q->addend;
865 sym_addr -= (q->address + 2);
866 if (bfd_big_endian(abs_bfd))
867 *(unsigned short *)r_mem =
868 bfd_big_endian(abs_bfd) ? htons(sym_addr) : sym_addr;
872 sym_addr = (*(q->sym_ptr_ptr))->value;
873 sym_addr += sym_vma + q->addend;
874 sym_addr -= (q->address + 1);
875 *(unsigned char *)r_mem = sym_addr;
879 #ifdef TARGET_microblaze
880 case R_MICROBLAZE_64:
881 /* The symbol is split over two consecutive instructions.
882 Flag this to the flat loader by setting the high bit of
883 the relocation symbol. */
885 unsigned char *p = r_mem;
886 unsigned long offset;
889 /* work out the relocation */
890 sym_vma = bfd_section_vma(abs_bfd, sym_section);
891 /* grab any offset from the text */
892 offset = (p[2]<<24) + (p[3] << 16) + (p[6] << 8) + (p[7]);
893 /* Update the address */
894 sym_addr += offset + sym_vma + q->addend;
895 /* Write relocated pointer back */
896 p[2] = (sym_addr >> 24) & 0xff;
897 p[3] = (sym_addr >> 16) & 0xff;
898 p[6] = (sym_addr >> 8) & 0xff;
899 p[7] = sym_addr & 0xff;
901 /* create a new reloc entry */
902 flat_relocs = realloc(flat_relocs,
903 (flat_reloc_count + 1) * sizeof(uint32_t));
904 flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address);
906 relocation_needed = 0;
908 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
909 bfd_section_vma(abs_bfd, sym_section));
911 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
912 "section=%s size=%d "
913 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
914 q->address, sym_name, addstr,
915 section_name, sym_reloc_size,
916 sym_addr, section_vma + q->address);
918 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
919 section_vma + q->address);
923 case R_MICROBLAZE_32:
925 unsigned char *p = r_mem;
926 unsigned long offset;
928 /* grab any offset from the text */
929 offset = (p[0]<<24) + (p[1] << 16) + (p[2] << 8) + (p[3]);
930 sym_vma = bfd_section_vma(abs_bfd, sym_section);
931 /* This is a horrible kludge. For some
932 reason, *sometimes* the offset is in
933 both addend and the code. Detect
934 it, and cancel the effect. Otherwise
935 the offset gets added twice - ouch.
936 There should be a better test
937 for this condition, based on the
938 BFD data structures */
939 if(offset==q->addend)
942 sym_addr += offset + sym_vma + q->addend;
943 relocation_needed = 1;
946 case R_MICROBLAZE_64_PCREL:
948 //sym_addr = (*(q->sym_ptr_ptr))->value;
949 sym_addr += sym_vma + q->addend;
950 sym_addr -= (q->address + 4);
951 sym_addr = htonl(sym_addr);
953 * ((unsigned short *) (r_mem+2)) |= (sym_addr) & 0xFFFF;
955 * ((unsigned short *) (r_mem+6)) |= (sym_addr >> 16) & 0xFFFF;
956 /* We've done all the work, so continue
957 to next reloc instead of break */
960 #endif /* TARGET_microblaze */
963 #define htoniosl(x) (x)
964 #define niostohl(x) (x)
965 switch ((*p)->howto->type)
967 case R_NIOS2_BFD_RELOC_32:
968 relocation_needed = 1;
969 pflags = (FLAT_NIOS2_R_32 << 28);
970 sym_vma = bfd_section_vma(abs_bfd, sym_section);
971 sym_addr += sym_vma + q->addend;
972 /* modify target, in target order */
973 *(unsigned long *)r_mem = htoniosl(sym_addr);
977 unsigned long exist_val;
978 relocation_needed = 1;
979 pflags = (FLAT_NIOS2_R_CALL26 << 28);
980 sym_vma = bfd_section_vma(abs_bfd, sym_section);
981 sym_addr += sym_vma + q->addend;
983 /* modify target, in target order */
984 // exist_val = niostohl(*(unsigned long *)r_mem);
985 exist_val = ((sym_addr >> 2) << 6);
986 *(unsigned long *)r_mem = htoniosl(exist_val);
989 case R_NIOS2_HIADJ16:
992 unsigned long exist_val;
994 /* handle the adjacent HI/LO pairs */
996 r2_type = R_NIOS2_NONE;
998 r2_type = p[1]->howto->type;
999 if ((r2_type == R_NIOS2_LO16)
1000 && (p[0]->sym_ptr_ptr == p[1]->sym_ptr_ptr)
1001 && (p[0]->addend == p[1]->addend))
1003 unsigned char * r2_mem = sectionp + p[1]->address;
1004 if (p[1]->address - q->address!=4)
1005 printf("Err: HI/LO not adjacent %d\n", p[1]->address - q->address);
1006 relocation_needed = 1;
1007 pflags = (q->howto->type == R_NIOS2_HIADJ16)
1008 ? FLAT_NIOS2_R_HIADJ_LO : FLAT_NIOS2_R_HI_LO;
1011 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1012 sym_addr += sym_vma + q->addend;
1014 /* modify high 16 bits, in target order */
1015 exist_val = niostohl(*(unsigned long *)r_mem);
1016 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1017 if (q->howto->type == R_NIOS2_HIADJ16)
1018 exist_val |= ((((sym_addr >> 16) + ((sym_addr >> 15) & 1)) & 0xFFFF) << 6);
1020 exist_val |= (((sym_addr >> 16) & 0xFFFF) << 6);
1021 *(unsigned long *)r_mem = htoniosl(exist_val);
1023 /* modify low 16 bits, in target order */
1024 exist_val = niostohl(*(unsigned long *)r2_mem);
1025 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1026 exist_val |= ((sym_addr & 0xFFFF) << 6);
1027 *(unsigned long *)r2_mem = htoniosl(exist_val);
1030 goto NIOS2_RELOC_ERR;
1036 unsigned long exist_val, temp;
1037 //long gp = get_symbol_offset("_gp", sym_section, symbols, number_of_symbols);
1038 long gp = get_gp_value(symbols, number_of_symbols);
1040 printf("Err: unresolved symbol _gp when relocating %s\n", sym_name);
1041 goto NIOS2_RELOC_ERR;
1043 /* _gp holds a absolute value, otherwise the ld cannot generate correct code */
1044 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1045 //printf("sym=%x, %d, _gp=%x, %d\n", sym_addr+sym_vma, sym_addr+sym_vma, gp, gp);
1046 sym_addr += sym_vma + q->addend;
1048 //printf("sym - _gp=%x, %d\n", sym_addr, sym_addr);
1049 /* modify the target, in target order (little_endian) */
1050 exist_val = niostohl(*(unsigned long *)r_mem);
1051 temp = ((exist_val >> 6) & 0x3ff0000) | (sym_addr & 0xffff);
1053 temp |= (exist_val & 0x3f);
1054 *(unsigned long *)r_mem = htoniosl(temp);
1056 printf("omit: offset=0x%x symbol=%s%s "
1057 "section=%s size=%d "
1058 "fixup=0x%x (reloc=0x%x) GPREL\n",
1059 q->address, sym_name, addstr,
1060 section_name, sym_reloc_size,
1061 sym_addr, section_vma + q->address);
1064 case R_NIOS2_PCREL16:
1066 unsigned long exist_val;
1068 sym_addr += sym_vma + q->addend;
1069 sym_addr -= (q->address + 4);
1070 /* modify the target, in target order (little_endian) */
1071 exist_val = niostohl(*(unsigned long *)r_mem);
1072 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1073 exist_val |= ((sym_addr & 0xFFFF) << 6);
1074 *(unsigned long *)r_mem = htoniosl(exist_val);
1076 printf("omit: offset=0x%x symbol=%s%s "
1077 "section=%s size=%d "
1078 "fixup=0x%x (reloc=0x%x) PCREL\n",
1079 q->address, sym_name, addstr,
1080 section_name, sym_reloc_size,
1081 sym_addr, section_vma + q->address);
1086 /* check if this is actually the 2nd half of a pair */
1088 && ((p[-1]->howto->type == R_NIOS2_HIADJ16)
1089 || (p[-1]->howto->type == R_NIOS2_HI16))
1090 && (p[-1]->sym_ptr_ptr == p[0]->sym_ptr_ptr)
1091 && (p[-1]->addend == p[0]->addend)) {
1093 printf("omit: offset=0x%x symbol=%s%s "
1094 "section=%s size=%d LO16\n",
1095 q->address, sym_name, addstr,
1096 section_name, sym_reloc_size);
1100 /* error, fall through */
1104 case R_NIOS2_CACHE_OPX:
1108 case R_NIOS2_BFD_RELOC_16:
1109 case R_NIOS2_BFD_RELOC_8:
1110 case R_NIOS2_GNU_VTINHERIT:
1111 case R_NIOS2_GNU_VTENTRY:
1116 printf("Err: unexpected reloc type %s(%d)\n", q->howto->name, q->howto->type);
1120 #endif /* TARGET_nios2 */
1125 relocation_needed = 1;
1126 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1127 sym_addr += sym_vma + q->addend;
1131 sym_addr += sym_vma + q->addend;
1132 sym_addr -= q->address;
1134 case R_SPARC_WDISP30:
1135 sym_addr = (((*(q->sym_ptr_ptr))->value-
1136 q->address) >> 2) & 0x3fffffff;
1138 ntohl(*(unsigned long *)r_mem)
1143 relocation_needed = 1;
1144 pflags = 0x80000000;
1145 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1146 sym_addr += sym_vma + q->addend;
1148 htonl(*(unsigned long *)r_mem)
1153 relocation_needed = 1;
1154 pflags = 0x40000000;
1155 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1156 sym_addr += sym_vma + q->addend;
1157 sym_addr &= 0x000003ff;
1159 htonl(*(unsigned long *)r_mem)
1163 #endif /* TARGET_sparc */
1166 case R_pcrel12_jump:
1167 case R_pcrel12_jump_s:
1169 case R_pcrel24_jump_l:
1170 case R_pcrel24_jump_x:
1171 case R_pcrel24_call_x:
1175 sym_addr += q->addend;// get the symbol addr
1176 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1177 sym_addr -= q->address; // make it PC relative
1178 // implicitly assumes code section and symbol section are same
1185 sym_addr += q->addend;
1186 if(weak_und_symbol(sym_section->name, (*(q->sym_ptr_ptr))))
1188 if(0xFFFF0000 & sym_addr){
1189 fprintf (stderr, "Relocation overflow for rN = %s\n",sym_name);
1192 flat_relocs = (uint32_t *)
1193 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1194 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1195 sym_section->name, sym_name,
1196 (*(q->sym_ptr_ptr)),
1197 0, FLAT_RELOC_PART_LO,
1198 section_vma + q->address))
1207 unsigned int reloc_count_incr;
1210 if (q->howto->type == R_luimm16)
1211 hi_lo = FLAT_RELOC_PART_LO;
1213 hi_lo = FLAT_RELOC_PART_HI;
1215 sym_addr += q->addend;
1217 flat_relocs = (uint32_t *)
1218 (realloc (flat_relocs, (flat_reloc_count + 2) * sizeof (uint32_t)));
1219 reloc_count_incr = 1;
1220 if (weak_und_symbol (sym_section->name, (*(q->sym_ptr_ptr))))
1222 if (0xFFFF0000 & sym_addr) {
1223 /* value is > 16 bits - use an extra field */
1224 /* see if we have already output that symbol */
1225 /* reloc may be addend from symbol and */
1226 /* we can only store 16 bit offsets */
1228 if ((*(q->sym_ptr_ptr))->udata.i == 0
1229 || flat_relocs[(*(q->sym_ptr_ptr))->udata.i] != sym_addr
1230 || ((*(q->sym_ptr_ptr))->udata.i & 0xFFFF0000))
1232 reloc_count_incr = 2;
1233 flat_relocs[flat_reloc_count + 1] = sym_addr;
1234 (*(q->sym_ptr_ptr))->udata.i = flat_reloc_count + 1;
1235 sym_addr = 0; // indication to loader to read next
1237 sym_addr = (*(q->sym_ptr_ptr))->udata.i;
1243 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1244 sym_section->name, sym_name,
1245 (*(q->sym_ptr_ptr)),
1247 section_vma + q->address))
1249 flat_reloc_count += reloc_count_incr;
1253 sym_addr += q->addend;
1255 if (weak_und_symbol (sym_section->name, *q->sym_ptr_ptr))
1258 flat_relocs = (uint32_t *)
1259 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1260 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1261 sym_section->name, sym_name,
1262 (*(q->sym_ptr_ptr)),
1263 2, FLAT_RELOC_PART_LO,
1264 section_vma + q->address))
1270 #endif //TARGET_bfin
1274 relocation_needed = 1;
1275 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1276 sym_addr += sym_vma + q->addend;
1280 sym_addr += sym_vma + q->addend;
1281 sym_addr -= q->address;
1283 #endif /* TARGET_sh */
1286 #define htoe1l(x) htonl(x)
1293 #define DBG_E1 printf
1295 #define DBG_E1(x, ... )
1298 #define _32BITS_RELOC 0x00000000
1299 #define _30BITS_RELOC 0x80000000
1300 #define _28BITS_RELOC 0x40000000
1303 unsigned long sec_vma, exist_val, S;
1305 relocation_needed = 1;
1306 DBG_E1("Handling Reloc <CONST31>\n");
1307 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1308 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1309 sec_vma, sym_addr, q->address);
1310 sym_addr = sec_vma + sym_addr;
1311 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1312 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1313 exist_val = htoe1l(exist_val);
1314 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1315 sym_addr += exist_val;
1316 pflags = _30BITS_RELOC;
1318 case R_E1_CONST31_PCREL:
1319 relocation_needed = 0;
1320 DBG_E1("Handling Reloc <CONST31_PCREL>\n");
1321 DBG_E1("DONT RELOCATE AT LOADING\n");
1322 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1323 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1324 sec_vma, sym_addr, q->address);
1325 sym_addr = sec_vma + sym_addr;
1326 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1328 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1330 q->address = q->address + section_vma;
1331 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1333 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1334 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1335 DBG_E1( "sym_addr := sym_addr - q->address - "
1336 "sizeof(CONST31_PCREL): [0x%x]\n",
1338 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1339 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1340 exist_val = htoe1l(exist_val);
1341 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1342 sym_addr |= exist_val;
1343 DBG_E1("sym_addr |= exist_val) : [0x%x]\n", sym_addr );
1345 case R_E1_DIS29W_PCREL:
1346 relocation_needed = 0;
1347 DBG_E1("Handling Reloc <DIS29W_PCREL>\n");
1348 DBG_E1("DONT RELOCATE AT LOADING\n");
1349 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1350 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1351 sec_vma, sym_addr, q->address);
1352 sym_addr = sec_vma + sym_addr;
1353 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1355 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1357 q->address = q->address + section_vma;
1358 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1360 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1361 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1362 DBG_E1( "sym_addr := sym_addr - q->address - "
1363 "sizeof(CONST31_PCREL): [0x%x]\n",
1365 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1366 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1367 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1368 exist_val = htoe1l(exist_val);
1369 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1370 sym_addr += exist_val;
1373 DBG_E1("Handling Reloc <DIS29W>\n");
1374 goto DIS29_RELOCATION;
1376 DBG_E1("Handling Reloc <DIS29H>\n");
1377 goto DIS29_RELOCATION;
1379 DBG_E1("Handling Reloc <DIS29B>\n");
1381 relocation_needed = 1;
1382 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1383 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%08x]\n",
1385 sym_addr = sec_vma + sym_addr;
1386 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%08x]\n", sym_addr);
1387 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1388 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1389 exist_val = htoe1l(exist_val);
1390 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1391 sym_addr += exist_val;
1392 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1393 pflags = _28BITS_RELOC;
1395 case R_E1_IMM32_PCREL:
1396 relocation_needed = 0;
1397 DBG_E1("Handling Reloc <IMM32_PCREL>\n");
1398 DBG_E1("DONT RELOCATE AT LOADING\n");
1399 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1400 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1402 sym_addr = sec_vma + sym_addr;
1404 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1405 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1407 q->address = q->address + section_vma;
1408 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1410 if( (sym_addr = (sym_addr - q->address - 6 )) < 0 )
1411 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1412 DBG_E1( "sym_addr := sym_addr - q->address - "
1413 "sizeof(CONST31_PCREL): [0x%x]\n",
1415 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1416 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1417 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1418 exist_val = htoe1l(exist_val);
1419 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1420 sym_addr += exist_val;
1423 relocation_needed = 1;
1424 DBG_E1("Handling Reloc <IMM32>\n");
1425 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1426 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1428 sym_addr = sec_vma + sym_addr;
1429 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1430 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1431 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1432 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1433 exist_val = htoe1l(exist_val);
1434 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1435 sym_addr += exist_val;
1436 pflags = _32BITS_RELOC;
1439 relocation_needed = 1;
1440 DBG_E1("Handling Reloc <WORD>\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 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address );
1447 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1448 exist_val = htoe1l(exist_val);
1449 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1450 sym_addr += exist_val;
1451 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1452 pflags = _32BITS_RELOC;
1455 #undef _32BITS_RELOC
1456 #undef _30BITS_RELOC
1457 #undef _28BITS_RELOC
1460 /* missing support for other types of relocs */
1461 printf("ERROR: bad reloc type %d\n", (*p)->howto->type);
1467 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
1468 bfd_section_vma(abs_bfd, sym_section));
1472 * for full elf relocation we have to write back the
1473 * start_code relative value to use.
1475 if (!pic_with_got) {
1476 #if defined(TARGET_arm)
1485 * horrible nasty hack to support different endianess
1487 if (!bfd_big_endian(abs_bfd)) {
1499 tmp.l = *(unsigned long *)r_mem;
1500 hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16);
1502 (((*p)->howto->type != R_ARM_PC24) &&
1503 ((*p)->howto->type != R_ARM_PLT32)))
1504 hl |= (tmp.c[i3] << 24);
1505 else if (tmp.c[i2] & 0x80)
1506 hl |= 0xff000000; /* sign extend */
1509 tmp.c[i0] = hl & 0xff;
1510 tmp.c[i1] = (hl >> 8) & 0xff;
1511 tmp.c[i2] = (hl >> 16) & 0xff;
1513 (((*p)->howto->type != R_ARM_PC24) &&
1514 ((*p)->howto->type != R_ARM_PLT32)))
1515 tmp.c[i3] = (hl >> 24) & 0xff;
1516 if ((*p)->howto->type == R_ARM_ABS32)
1517 *(unsigned long *)r_mem = htonl(hl);
1519 *(unsigned long *)r_mem = tmp.l;
1521 #elif defined(TARGET_bfin)
1522 if ((*p)->howto->type == R_pcrel24
1523 || (*p)->howto->type == R_pcrel24_jump_l
1524 || (*p)->howto->type == R_pcrel24_jump_x
1525 || (*p)->howto->type == R_pcrel24_call_x)
1527 sym_addr += 2*-1*PCREL24_MAGIC_OFFSET;
1528 *((unsigned short *)(sectionp + q->address) + 1 + PCREL24_MAGIC_OFFSET)
1529 = (sym_addr >> 1) & 0xffff;
1530 *((unsigned short *)(sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1531 = (0xff00 & *((unsigned short *) (sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1532 | ((sym_addr >> 17) & 0xff));
1533 } else if ((*p)->howto->type == R_byte4_data) {
1534 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1535 } else if ((*p)->howto->type == R_pcrel12_jump
1536 || (*p)->howto->type == R_pcrel12_jump_s) {
1537 *((unsigned short *)(sectionp + q->address))
1538 = (0xf000 & *((unsigned short *)(sectionp + q->address))
1539 | ((sym_addr >> 1) & 0xfff));
1540 } else if ((*p)->howto->type == R_pcrel10) {
1541 *((unsigned short *)(sectionp + q->address))
1542 = (~0x3ff & *((unsigned short *)(sectionp + q->address))
1543 | ((sym_addr >> 1) & 0x3ff));
1544 } else if ((*p)->howto->type == R_rimm16
1545 || (*p)->howto->type == R_huimm16
1546 || (*p)->howto->type == R_luimm16) {
1547 /* for l and h we set the lower 16 bits which is only when it will be used */
1548 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1549 } else if ((*p)->howto->type == R_pcrel5m2) {
1550 *((unsigned short *)(sectionp + q->address))
1551 = (0xfff0 & *((unsigned short *)(sectionp + q->address))
1552 | ((sym_addr >> 1) & 0xf));
1553 } else if ((*p)->howto->type == R_pcrel11){
1554 *((unsigned short *)(sectionp + q->address))
1555 = (0xfc00 & *((unsigned short *)(sectionp + q->address))
1556 | ((sym_addr >> 1) & 0x3ff));
1557 } else if (0xE0 <= (*p)->howto->type && 0xF3 >= (*p)->howto->type) {
1558 //arith relocs dont generate a real relocation
1560 printf("Blackfin relocation fail for reloc type: 0x%x\n", (*p)->howto->type);
1562 #elif defined(TARGET_e1)
1563 #define OPCODE_SIZE 2 /* Add 2 bytes, counting the opcode size*/
1564 switch ((*p)->howto->type) {
1566 case R_E1_CONST31_PCREL:
1567 case R_E1_DIS29W_PCREL:
1571 case R_E1_IMM32_PCREL:
1573 DBG_E1("In addr + 2:[0x%x] <- write [0x%x]\n",
1574 (sectionp + q->address + 2), sym_addr );
1575 *((unsigned long *) (sectionp + q->address + OPCODE_SIZE)) =
1579 DBG_E1("In addr : [0x%x] <- write [0x%x]\n",
1580 (sectionp + q->address), sym_addr );
1581 *((unsigned long *) (sectionp + q->address )) = htonl(sym_addr);
1584 printf("ERROR:Unhandled Relocation. Exiting...\n");
1588 #else /* ! TARGET_arm && ! TARGET_e1 */
1590 switch (q->howto->type) {
1595 /* Do nothing -- for cases we handle,
1596 the bits produced by the linker are
1597 what we want in the final flat file
1598 (and other cases are errors). Note
1599 that unlike most relocated values,
1600 it is stored in little-endian order,
1601 but this is necessary to avoid
1602 trashing the low-bit, and the float
1603 loaders knows about it. */
1605 #endif /* TARGET_V850 */
1608 case R_NIOS2_BFD_RELOC_32:
1609 case R_NIOS2_CALL26:
1610 case R_NIOS2_HIADJ16:
1614 #endif /* TARGET_nios2 */
1616 #if defined(TARGET_m68k)
1618 if (sym_addr < -0x8000 || sym_addr > 0x7fff) {
1619 fprintf (stderr, "Relocation overflow for R_68K_PC16 relocation against %s\n", sym_name);
1622 r_mem[0] = (sym_addr >> 8) & 0xff;
1623 r_mem[1] = sym_addr & 0xff;
1629 /* The alignment of the build host
1630 might be stricter than that of the
1631 target, so be careful. We store in
1632 network byte order. */
1633 r_mem[0] = (sym_addr >> 24) & 0xff;
1634 r_mem[1] = (sym_addr >> 16) & 0xff;
1635 r_mem[2] = (sym_addr >> 8) & 0xff;
1636 r_mem[3] = sym_addr & 0xff;
1638 #endif /* !TARGET_arm */
1643 if ((*p)->howto->type == R_rimm16
1644 || (*p)->howto->type == R_huimm16
1645 || (*p)->howto->type == R_luimm16)
1647 /* for l and h we set the lower 16 bits which is only when it will be used */
1648 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1649 } else if ((*p)->howto->type == R_byte4_data) {
1650 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1655 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
1656 "section=%s size=%d "
1657 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
1658 q->address, sym_name, addstr,
1659 section_name, sym_reloc_size,
1660 sym_addr, section_vma + q->address);
1663 * Create relocation entry (PC relative doesn't need this).
1665 if (relocation_needed) {
1667 flat_relocs = realloc(flat_relocs,
1668 (flat_reloc_count + 1) * sizeof(uint32_t));
1670 flat_relocs[flat_reloc_count] = pflags |
1671 (section_vma + q->address);
1674 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
1675 section_vma + q->address);
1677 switch ((*p)->howto->type) {
1679 case R_E1_CONST31_PCREL:
1680 case R_E1_DIS29W_PCREL:
1684 case R_E1_IMM32_PCREL:
1686 flat_relocs[flat_reloc_count] = pflags |
1687 (section_vma + q->address + OPCODE_SIZE);
1689 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1690 flat_relocs[flat_reloc_count] );
1693 flat_relocs[flat_reloc_count] = pflags |
1694 (section_vma + q->address);
1696 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1697 flat_relocs[flat_reloc_count] );
1703 relocation_needed = 0;
1708 printf("%s(%d): symbol name=%s address=0x%x section=%s -> RELOC=0x%x\n",
1709 __FILE__, __LINE__, sym_name, q->address, section_name,
1710 flat_relocs[flat_reloc_count]);
1717 printf("%d bad relocs\n", bad_relocs);
1724 *n_relocs = flat_reloc_count;
1730 static char * program;
1732 static void usage(void)
1734 fprintf(stderr, "Usage: %s [vrzd] [-p <abs-pic-file>] [-s stack-size] "
1735 "[-o <output-file>] <elf-file>\n\n"
1736 " -v : verbose operation\n"
1737 " -r : force load to RAM\n"
1738 " -k : enable kernel trace on load (for debug)\n"
1739 " -z : compress code/data/relocs\n"
1740 " -d : compress data/relocs\n"
1741 " -a : use existing symbol references\n"
1742 " instead of recalculating from\n"
1743 " relocation info\n"
1744 " -R reloc-file : read relocations from a separate file\n"
1745 " -p abs-pic-file : GOT/PIC processing with files\n"
1746 " -s stacksize : set application stack size\n"
1747 " -o output-file : output file name\n\n",
1749 fprintf(stderr, "Compiled for " ARCH " architecture\n\n");
1754 /* Write NUM zeroes to STREAM. */
1755 static void write_zeroes (unsigned long num, FILE *stream)
1759 /* It'd be nice if we could just use fseek, but that doesn't seem to
1760 work for stdio output files. */
1761 bzero(zeroes, 1024);
1762 while (num > sizeof(zeroes)) {
1763 fwrite(zeroes, sizeof(zeroes), 1, stream);
1764 num -= sizeof(zeroes);
1767 fwrite(zeroes, num, 1, stream);
1772 int main(int argc, char *argv[])
1775 bfd *rel_bfd, *abs_bfd;
1777 char *ofile=NULL, *pfile=NULL, *abs_file = NULL, *rel_file = NULL;
1785 asymbol **symbol_table;
1786 long number_of_symbols;
1788 unsigned long data_len = 0;
1789 unsigned long bss_len = 0;
1790 unsigned long text_len = 0;
1791 unsigned long reloc_len;
1793 unsigned long data_vma = ~0;
1794 unsigned long bss_vma = ~0;
1795 unsigned long text_vma = ~0;
1797 unsigned long text_offs;
1803 struct flat_hdr hdr;
1813 if (sizeof(hdr) != 64) {
1815 "Potential flat header incompatibility detected\n"
1816 "header size should be 64 but is %d\n",
1823 #else /* We need plenty of stack for both of them (Aggregate and Register) */
1827 while ((opt = getopt(argc, argv, "avzdrkp:s:o:R:")) != -1) {
1854 stack = atoi(optarg);
1860 fprintf(stderr, "%s Unknown option\n", argv[0]);
1867 * if neither the -r or -p options was given, default to
1868 * a RAM load as that is the only option that makes sense.
1870 if (!load_to_ram && !pfile)
1873 filename = fname = argv[argc-1];
1884 if (!(rel_bfd = bfd_openr(rel_file, 0))) {
1885 fprintf(stderr, "Can't open %s\n", rel_file);
1889 if (bfd_check_format (rel_bfd, bfd_object) == 0) {
1890 fprintf(stderr, "File is not an object file\n");
1894 if (abs_file == rel_file)
1895 abs_bfd = rel_bfd; /* one file does all */
1897 if (!(abs_bfd = bfd_openr(abs_file, 0))) {
1898 fprintf(stderr, "Can't open %s\n", abs_file);
1902 if (bfd_check_format (abs_bfd, bfd_object) == 0) {
1903 fprintf(stderr, "File is not an object file\n");
1908 if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC)) {
1909 fprintf (stderr, "%s: Input file contains no relocation info\n", rel_file);
1913 if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P)) {
1914 /* `Absolute' file is not absolute, so neither are address
1915 contained therein. */
1917 "%s: `-a' option specified with non-fully-resolved input file\n",
1918 bfd_get_filename (abs_bfd));
1922 symbol_table = get_symbols(abs_bfd, &number_of_symbols);
1924 /* Group output sections into text, data, and bss, and calc their sizes. */
1925 for (s = abs_bfd->sections; s != NULL; s = s->next) {
1926 unsigned long *vma, *len;
1927 bfd_size_type sec_size;
1930 if (s->flags & SEC_CODE) {
1933 } else if (s->flags & SEC_DATA) {
1936 } else if (s->flags & SEC_ALLOC) {
1942 sec_size = bfd_section_size(abs_bfd, s);
1943 sec_vma = bfd_section_vma(abs_bfd, s);
1945 if (sec_vma < *vma) {
1947 *len += sec_vma - *vma;
1951 } else if (sec_vma + sec_size > *vma + *len)
1952 *len = sec_vma + sec_size - *vma;
1955 if (text_len == 0) {
1956 fprintf (stderr, "%s: no .text section", abs_file);
1960 text = malloc(text_len);
1963 printf("TEXT -> vma=0x%x len=0x%x\n", text_vma, text_len);
1965 /* Read in all text sections. */
1966 for (s = abs_bfd->sections; s != NULL; s = s->next)
1967 if (s->flags & SEC_CODE)
1968 if (!bfd_get_section_contents(abs_bfd, s,
1969 text + (s->vma - text_vma), 0,
1970 bfd_section_size(abs_bfd, s)))
1972 fprintf(stderr, "read error section %s\n", s->name);
1976 if (data_len == 0) {
1977 fprintf (stderr, "%s: no .data section", abs_file);
1980 data = malloc(data_len);
1983 printf("DATA -> vma=0x%x len=0x%x\n", data_vma, data_len);
1985 if ((text_vma + text_len) != data_vma) {
1986 if ((text_vma + text_len) > data_vma) {
1987 printf("ERROR: text=0x%x overlaps data=0x%x ?\n", text_len, data_vma);
1991 printf("WARNING: data=0x%x does not directly follow text=0x%x\n",
1992 data_vma, text_len);
1993 text_len = data_vma - text_vma;
1996 /* Read in all data sections. */
1997 for (s = abs_bfd->sections; s != NULL; s = s->next)
1998 if (s->flags & SEC_DATA)
1999 if (!bfd_get_section_contents(abs_bfd, s,
2000 data + (s->vma - data_vma), 0,
2001 bfd_section_size(abs_bfd, s)))
2003 fprintf(stderr, "read error section %s\n", s->name);
2007 /* Put common symbols in bss. */
2008 bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len);
2011 printf("BSS -> vma=0x%x len=0x%x\n", bss_vma, bss_len);
2013 if ((data_vma + data_len) != bss_vma) {
2014 if ((data_vma + data_len) > bss_vma) {
2015 printf("ERROR: text=0x%x + data=0x%x overlaps bss=0x%x ?\n", text_len,
2020 printf("WARNING: bss=0x%x does not directly follow text=0x%x + data=0x%x(0x%x)\n",
2021 bss_vma, text_len, data_len, text_len + data_len);
2022 data_len = bss_vma - data_vma;
2025 reloc = output_relocs(abs_bfd, symbol_table, number_of_symbols, &reloc_len,
2026 text, text_len, text_vma, data, data_len, data_vma,
2030 printf("No relocations in code!\n");
2032 text_offs = real_address_bits(text_vma);
2034 /* Fill in the binflt_flat header */
2035 memcpy(hdr.magic,"bFLT",4);
2036 hdr.rev = htonl(FLAT_VERSION);
2037 hdr.entry = htonl(sizeof(hdr) + bfd_get_start_address(abs_bfd));
2038 hdr.data_start = htonl(sizeof(hdr) + text_offs + text_len);
2039 hdr.data_end = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2040 hdr.bss_end = htonl(sizeof(hdr) + text_offs + text_len +data_len+bss_len);
2041 hdr.stack_size = htonl(stack); /* FIXME */
2042 hdr.reloc_start = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2043 hdr.reloc_count = htonl(reloc_len);
2045 | (load_to_ram ? FLAT_FLAG_RAM : 0)
2046 | (ktrace ? FLAT_FLAG_KTRACE : 0)
2047 | (pic_with_got ? FLAT_FLAG_GOTPIC : 0)
2048 | (compress ? (compress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
2050 hdr.build_date = htonl((unsigned long)time(NULL));
2051 bzero(hdr.filler, sizeof(hdr.filler));
2053 for (i=0; i<reloc_len; i++) reloc[i] = htonl(reloc[i]);
2056 printf("SIZE: .text=0x%04x, .data=0x%04x, .bss=0x%04x",
2057 text_len, data_len, bss_len);
2059 printf(", relocs=0x%04x", reloc_len);
2064 ofile = malloc(strlen(fname) + 5 + 1); /* 5 to add suffix */
2065 strcpy(ofile, fname);
2066 strcat(ofile, ".bflt");
2069 if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0) {
2070 fprintf (stderr, "Can't open output file %s\n", ofile);
2074 write(fd, &hdr, sizeof(hdr));
2078 * get the compression command ready
2080 sprintf(cmd, "gzip -f -9 >> %s", ofile);
2082 #define START_COMPRESSOR do { \
2088 if (!(gf = popen(cmd, "w" BINARY_FILE_OPTS))) { \
2089 fprintf(stderr, "Can't run cmd %s\n", cmd); \
2095 gf = fopen(ofile, "ab"); /* Add 'b' to support non-posix (ie windows) */
2097 fprintf(stderr, "Can't open file %s for writing\n", ofile); \
2104 /* Fill in any hole at the beginning of the text segment. */
2106 printf("ZERO before text len=0x%x\n", text_offs);
2107 write_zeroes(text_offs, gf);
2109 /* Write the text segment. */
2110 fwrite(text, text_len, 1, gf);
2115 /* Write the data segment. */
2116 fwrite(data, data_len, 1, gf);
2119 fwrite(reloc, reloc_len * 4, 1, gf);
2131 * this __MUST__ be at the VERY end of the file - do NOT move!!
2137 * vi: tabstop=8 shiftwidth=4 textwidth=79 noexpandtab