2 * elf2flt.c: Convert ELF (or any BFD format) to FLAT binary format
4 * (c) 1999-2002, Greg Ungerer <gerg@snapgear.com>
5 * Created elf2flt from coff2flt (see copyrights below). Added all the
6 * ELF format file handling. Extended relocation support for all of
9 * (c) 2006 Support the -a (use_resolved) option for TARGET_arm.
10 * Shaun Jackman <sjackman@gmail.com>
11 * (c) 2004, Nios II support, Wentao Xu <wentao@microtronix.com>
12 * (c) 2003, H8 support, ktrace <davidm@snapgear.com>
13 * (c) 2003-2004, MicroBlaze support, John Williams <jwilliams@itee.uq.edu.au>
14 * (c) 2001-2003, arm/arm-pic/arm-big-endian support <davidm@snapgear.com>
15 * (c) 2001, v850 changes, Mile Bader <miles@lsi.nec.co.jp>
16 * (c) 2003, SuperH support, Paul Mundt <lethal@linux-sh.org>
17 * (c) 2001, zflat support <davidm@snapgear.com>
18 * (c) 2001, Changes for GOT entries Paul Dale <pauli@snapgear.com> and
19 * David McCullough <davidm@snapgear.com>
21 * Now supports PIC with GOT tables. This works by taking a '.elf' file
22 * and a fully linked elf executable (at address 0) and produces a flat
23 * file that can be loaded with some fixups. It still supports the old
24 * style fully relocatable elf format files.
26 * Originally obj-res.c
28 * (c) 1998, Kenneth Albanowski <kjahds@kjahds.com>
29 * (c) 1998, D. Jeff Dionne
30 * (c) 1998, The Silver Hammer Group Ltd.
31 * (c) 1996, 1997 Dionne & Associates <jeff@ryeham.ee.ryerson.ca>
33 * This is Free Software, under the GNU Public Licence v2 or greater.
35 * Relocation added March 1997, Kresten Krab Thorup
36 * krab@california.daimi.aau.dk
39 #include <stdio.h> /* Userland pieces of the ANSI C standard I/O package */
40 #include <stdlib.h> /* Userland prototypes of the ANSI C std lib functions */
41 #include <stdarg.h> /* Allows va_list to exist in the these namespaces */
42 #include <string.h> /* Userland prototypes of the string handling funcs */
44 #include <unistd.h> /* Userland prototypes of the Unix std system calls */
45 #include <fcntl.h> /* Flag value for file handling functions */
48 #include <netinet/in.h> /* Consts and structs defined by the internet system */
49 #define BINARY_FILE_OPTS
52 #define BINARY_FILE_OPTS "b"
55 /* from $(INSTALLDIR)/include */
56 #include <bfd.h> /* Main header file for the BFD library */
58 #if defined(TARGET_h8300)
59 #include <elf/h8.h> /* TARGET_* ELF support for the BFD library */
60 #elif defined(__CYGWIN__) || defined(__MINGW32__) || defined(TARGET_nios) || defined(TARGET_nios2)
61 #include "cygwin-elf.h" /* Cygwin uses a local copy */
62 #elif defined(TARGET_microblaze)
63 #include <elf/microblaze.h> /* TARGET_* ELF support for the BFD library */
64 #elif defined(TARGET_bfin)
67 #include <elf.h> /* TARGET_* ELF support for the BFD library */
70 #if defined(__MINGW32__)
74 /* from uClinux-x.x.x/include/linux */
75 #include "flat.h" /* Binary flat header description */
85 #if defined(TARGET_m68k)
86 #define ARCH "m68k/coldfire"
87 #elif defined(TARGET_arm)
89 #elif defined(TARGET_sparc)
91 #elif defined(TARGET_v850)
93 #elif defined(TARGET_sh)
95 #elif defined(TARGET_h8300)
97 #elif defined(TARGET_microblaze)
98 #define ARCH "microblaze"
99 #elif defined(TARGET_e1)
100 #define ARCH "e1-coff"
101 #elif defined(TARGET_bfin)
103 #define FLAT_RELOC_TYPE_TEXT 0
104 #define FLAT_RELOC_TYPE_DATA 1
105 #define FLAT_RELOC_TYPE_BSS 2
106 #define FLAT_RELOC_TYPE_STACK 3
107 #define FLAT_RELOC_PART_LO 0
108 #define FLAT_RELOC_PART_HI 1
109 #define PCREL24_MAGIC_OFFSET -1
110 #elif defined(TARGET_nios)
112 #elif defined(TARGET_nios2)
115 #error "Don't know how to support your CPU architecture??"
118 #if defined(TARGET_m68k) || defined(TARGET_h8300) || defined(TARGET_bfin)
120 * Define a maximum number of bytes allowed in the offset table.
121 * We'll fail if the table is larger than this.
123 * This limit may be different for platforms other than m68k, but
124 * 8000 entries is a lot, trust me :-) (davidm)
126 #define GOT_LIMIT 32767
128 * we have to mask out the shared library id here and there, this gives
129 * us the real address bits when needed
131 #define real_address_bits(x) (pic_with_got ? ((x) & 0xffffff) : (x))
133 #define real_address_bits(x) (x)
141 int verbose = 0; /* extra output when running */
142 int pic_with_got = 0; /* do elf/got processing with PIC code */
143 int load_to_ram = 0; /* instruct loader to allocate everything into RAM */
144 int ktrace = 0; /* instruct loader output kernel trace on load */
145 int compress = 0; /* 1 = compress everything, 2 = compress data only */
146 int use_resolved = 0; /* If true, get the value of symbol references from */
147 /* the program contents, not from the relocation table. */
148 /* In this case, the input ELF file must be already */
149 /* fully resolved (using the `-q' flag with recent */
150 /* versions of GNU ld will give you a fully resolved */
151 /* output file with relocation entries). */
153 const char *progname, *filename;
159 static char where[200];
162 /* Use exactly one of these: */
163 E_NOFILE = 0, /* "progname: " */
164 E_FILE = 1, /* "filename: " */
165 E_FILELINE = 2, /* "filename:lineno: " */
166 E_FILEWHERE = 3, /* "filename:%s: " -- set %s with ewhere() */
168 /* Add in any of these with |': */
173 void ewhere (const char *format, ...);
174 void einfo (int type, const char *format, ...);
178 ewhere (const char *format, ...) {
180 va_start (args, format);
181 vsprintf (where, format, args);
187 einfo (int type, const char *format, ...) {
190 switch (type & 0x0f) {
192 fprintf (stderr, "%s: ", progname);
195 fprintf (stderr, "%s: ", filename);
198 ewhere ("%d", lineno);
201 fprintf (stderr, "%s:%s: ", filename, where);
205 if (type & E_WARNING) {
206 fprintf (stderr, "warning: ");
212 va_start (args, format);
213 vfprintf (stderr, format, args);
219 fprintf (stderr, "\n");
224 get_symbols (bfd *abfd, long *num)
227 asymbol **symbol_table;
228 long number_of_symbols;
230 storage_needed = bfd_get_symtab_upper_bound (abfd);
232 if (storage_needed < 0)
235 if (storage_needed == 0)
238 symbol_table = (asymbol **) malloc (storage_needed);
240 number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
242 if (number_of_symbols < 0)
245 *num = number_of_symbols;
252 dump_symbols(asymbol **symbol_table, long number_of_symbols)
255 printf("SYMBOL TABLE:\n");
256 for (i=0; i<number_of_symbols; i++) {
257 printf(" NAME=%s VALUE=0x%x\n", symbol_table[i]->name,
258 symbol_table[i]->value);
267 get_symbol_offset(char *name, asection *sec, asymbol **symbol_table, long number_of_symbols)
270 for (i=0; i<number_of_symbols; i++) {
271 if (symbol_table[i]->section == sec) {
272 if (!strcmp(symbol_table[i]->name, name)) {
273 return symbol_table[i]->value;
283 get_gp_value(asymbol **symbol_table, long number_of_symbols)
286 for (i=0; i<number_of_symbols; i++) {
287 if (!strcmp(symbol_table[i]->name, "_gp"))
288 return symbol_table[i]->value;
296 add_com_to_bss(asymbol **symbol_table, long number_of_symbols, long bss_len)
302 for (i=0; i<number_of_symbols; i++) {
303 if (strcmp("*COM*", symbol_table[i]->section->name) == 0) {
304 offset = bss_len + comsize;
305 comsize += symbol_table[i]->value;
306 symbol_table[i]->value = offset;
313 /* FUNCTION : weak_und_symbol
314 ABSTRACT : return true if symbol is weak and undefined.
317 weak_und_symbol(const char *reloc_section_name,
318 struct bfd_symbol *symbol)
320 if (!(strstr (reloc_section_name, "text")
321 || strstr (reloc_section_name, "data")
322 || strstr (reloc_section_name, "bss"))) {
323 if (symbol->flags & BSF_WEAK) {
325 fprintf(stderr, "found weak undefined symbol %s\n", symbol->name);
334 bfin_set_reloc (uint32_t *reloc,
335 const char *reloc_section_name,
336 const char *sym_name,
337 struct bfd_symbol *symbol,
338 int sp, int hilo, int32_t offset)
343 if (strstr (reloc_section_name, "text"))
344 type = FLAT_RELOC_TYPE_TEXT;
345 else if (strstr (reloc_section_name, "data"))
346 type = FLAT_RELOC_TYPE_DATA;
347 else if (strstr (reloc_section_name, "bss"))
348 type = FLAT_RELOC_TYPE_BSS;
349 else if (strstr (reloc_section_name, "stack"))
350 type = FLAT_RELOC_TYPE_STACK;
351 else if (symbol->flags & BSF_WEAK){
352 /* weak symbol support ... if a weak symbol is undefined at the
353 end of a final link, it should return 0 rather than error
354 We will assume text section for the moment.
356 type = FLAT_RELOC_TYPE_TEXT;
357 } else if (strstr (reloc_section_name, "*ABS*")){
358 /* (A data section initialization of something in the shared libc's text section
359 does not resolve - i.e. a global pointer to function initialized with
361 The text section here is appropriate as the section information
362 of the shared library is lost. The loader will do some calcs.
364 type = FLAT_RELOC_TYPE_TEXT;
366 printf ("Unknown Type - relocation for %s in bad section - %s\n", sym_name, reloc_section_name);
370 val = (offset & ((1 << 26) - 1)) << 6;
371 val |= (sp & (1 << 3) - 1) << 3;
372 val |= (hilo & 1) << 2;
373 val |= (type & (1 << 2) - 1);
384 int number_of_symbols,
385 unsigned long *n_relocs,
386 unsigned char *text, int text_len, unsigned long text_vma,
387 unsigned char *data, int data_len, unsigned long data_vma,
390 uint32_t *flat_relocs;
391 asection *a, *sym_section, *r;
392 arelent **relpp, **p, *q;
393 const char *sym_name, *section_name;
394 unsigned char *sectionp;
395 unsigned long pflags;
397 long sym_addr, sym_vma, section_vma;
398 int relsize, relcount;
399 int flat_reloc_count;
400 int sym_reloc_size, rc;
407 printf("%s(%d): output_relocs(abs_bfd=%d,synbols=0x%x,number_of_symbols=%d"
408 "n_relocs=0x%x,text=0x%x,text_len=%d,data=0x%x,data_len=%d)\n",
409 __FILE__, __LINE__, abs_bfd, symbols, number_of_symbols, n_relocs,
410 text, text_len, data, data_len);
414 dump_symbols(symbols, number_of_symbols);
419 flat_reloc_count = 0;
423 /* Determine how big our offset table is in bytes.
424 * This isn't too difficult as we've terminated the table with -1.
425 * Also note that both the relocatable and absolute versions have this
426 * terminator even though the relocatable one doesn't have the GOT!
428 if (pic_with_got && !use_resolved) {
429 unsigned long *lp = (unsigned long *)data;
430 /* Should call ntohl(*lp) here but is isn't going to matter */
431 while (*lp != 0xffffffff) lp++;
432 got_size = ((unsigned char *)lp) - data;
434 printf("GOT table contains %d entries (%d bytes)\n",
435 got_size/sizeof(unsigned long), got_size);
437 if (got_size > GOT_LIMIT) {
438 fprintf(stderr, "GOT too large: %d bytes (limit = %d bytes)\n",
439 got_size, GOT_LIMIT);
445 for (a = abs_bfd->sections; (a != (asection *) NULL); a = a->next) {
446 section_vma = bfd_section_vma(abs_bfd, a);
449 printf("SECTION: %s [0x%x]: flags=0x%x vma=0x%x\n", a->name, a,
450 a->flags, section_vma);
452 // if (bfd_is_abs_section(a))
454 if (bfd_is_und_section(a))
456 if (bfd_is_com_section(a))
458 // if ((a->flags & SEC_RELOC) == 0)
462 * Only relocate things in the data sections if we are PIC/GOT.
463 * otherwise do text as well
465 if (!pic_with_got && (a->flags & SEC_CODE))
466 sectionp = text + (a->vma - text_vma);
467 else if (a->flags & SEC_DATA)
468 sectionp = data + (a->vma - data_vma);
472 /* Now search for the equivalent section in the relocation binary
473 * and use that relocation information to build reloc entries
476 for (r=rel_bfd->sections; r != NULL; r=r->next)
477 if (strcmp(a->name, r->name) == 0)
482 printf(" RELOCS: %s [0x%x]: flags=0x%x vma=0x%x\n", r->name, r,
483 r->flags, bfd_section_vma(abs_bfd, r));
484 if ((r->flags & SEC_RELOC) == 0)
486 relsize = bfd_get_reloc_upper_bound(rel_bfd, r);
489 printf("%s(%d): no relocation entries section=0x%x\n",
490 __FILE__, __LINE__, r->name);
494 symb = get_symbols(rel_bfd, &nsymb);
495 relpp = (arelent **) xmalloc(relsize);
496 relcount = bfd_canonicalize_reloc(rel_bfd, r, relpp, symb);
499 printf("%s(%d): no relocation entries section=%s\n",
500 __FILE__, __LINE__, r->name);
503 for (p = relpp; (relcount && (*p != NULL)); p++, relcount--) {
504 unsigned char *r_mem;
505 int relocation_needed = 0;
507 #ifdef TARGET_microblaze
508 /* The MICROBLAZE_XX_NONE relocs can be skipped.
509 They represent PC relative branches that the
510 linker has already resolved */
512 switch ((*p)->howto->type)
514 case R_MICROBLAZE_NONE:
515 case R_MICROBLAZE_64_NONE:
518 #endif /* TARGET_microblaze */
521 /* Skip this relocation entirely if possible (we
522 do this early, before doing any other
523 processing on it). */
524 switch ((*p)->howto->type) {
525 #ifdef R_V850_9_PCREL
528 #ifdef R_V850_22_PCREL
529 case R_V850_22_PCREL:
531 #ifdef R_V850_SDA_16_16_OFFSET
532 case R_V850_SDA_16_16_OFFSET:
534 #ifdef R_V850_SDA_15_16_OFFSET
535 case R_V850_SDA_15_16_OFFSET:
537 #ifdef R_V850_ZDA_15_16_OFFSET
538 case R_V850_ZDA_15_16_OFFSET:
540 #ifdef R_V850_TDA_6_8_OFFSET
541 case R_V850_TDA_6_8_OFFSET:
543 #ifdef R_V850_TDA_7_8_OFFSET
544 case R_V850_TDA_7_8_OFFSET:
546 #ifdef R_V850_TDA_7_7_OFFSET
547 case R_V850_TDA_7_7_OFFSET:
549 #ifdef R_V850_TDA_16_16_OFFSET
550 case R_V850_TDA_16_16_OFFSET:
552 #ifdef R_V850_TDA_4_5_OFFSET
553 case R_V850_TDA_4_5_OFFSET:
555 #ifdef R_V850_TDA_4_4_OFFSET
556 case R_V850_TDA_4_4_OFFSET:
558 #ifdef R_V850_SDA_16_16_SPLIT_OFFSET
559 case R_V850_SDA_16_16_SPLIT_OFFSET:
561 #ifdef R_V850_CALLT_6_7_OFFSET
562 case R_V850_CALLT_6_7_OFFSET:
564 #ifdef R_V850_CALLT_16_16_OFFSET
565 case R_V850_CALLT_16_16_OFFSET:
567 /* These are relative relocations, which
568 have already been fixed up by the
569 linker at this point, so just ignore
573 #endif /* USE_V850_RELOCS */
576 if (q->sym_ptr_ptr && *q->sym_ptr_ptr) {
577 sym_name = (*(q->sym_ptr_ptr))->name;
578 sym_section = (*(q->sym_ptr_ptr))->section;
579 section_name=(*(q->sym_ptr_ptr))->section->name;
581 printf("ERROR: undefined relocation entry\n");
586 /* Adjust the address to account for the GOT table which wasn't
587 * present in the relative file link.
589 if (pic_with_got && !use_resolved)
590 q->address += got_size;
593 /* A pointer to what's being relocated, used often
595 r_mem = sectionp + q->address;
598 * Fixup offset in the actual section.
602 if ((sym_addr = get_symbol_offset((char *) sym_name,
603 sym_section, symbols, number_of_symbols)) == -1) {
607 sym_addr = (*(q->sym_ptr_ptr))->value;
610 /* Use the address of the symbol already in
611 the program text. How this is handled may
612 still depend on the particular relocation
614 switch (q->howto->type) {
618 /* We specially handle adjacent
619 HI16_S/ZDA_15_16_OFFSET and
620 HI16_S/LO16 pairs that reference the
621 same address (these are usually
622 movhi/ld and movhi/movea pairs,
625 r2_type = R_V850_NONE;
627 r2_type = p[1]->howto->type;
628 if ((r2_type == R_V850_ZDA_15_16_OFFSET
629 || r2_type == R_V850_LO16)
630 && (p[0]->sym_ptr_ptr
631 == p[1]->sym_ptr_ptr)
632 && (p[0]->addend == p[1]->addend))
634 relocation_needed = 1;
637 case R_V850_ZDA_15_16_OFFSET:
645 /* We don't really need the
646 actual value -- the bits
647 produced by the linker are
648 what we want in the final
649 flat file -- but get it
653 unsigned char *r2_mem =
661 /* Sign extend LO. */
665 /* Maybe ignore the LSB
669 if (r2_type != R_V850_LO16)
677 goto bad_resolved_reloc;
681 /* See if this is actually the
682 2nd half of a pair. */
684 && (p[-1]->howto->type
686 && (p[-1]->sym_ptr_ptr
687 == p[0]->sym_ptr_ptr)
688 && (p[-1]->addend == p[0]->addend))
689 break; /* not an error */
691 goto bad_resolved_reloc;
694 goto bad_resolved_reloc;
696 goto good_32bit_resolved_reloc;
697 #elif defined(TARGET_arm)
699 relocation_needed = 1;
704 relocation_needed = 0;
707 goto bad_resolved_reloc;
708 #elif defined(TARGET_m68k)
710 goto good_32bit_resolved_reloc;
713 /* The linker has already resolved
714 PC relocs for us. In PIC links,
715 the symbol must be in the data
720 goto bad_resolved_reloc;
723 /* The default is to assume that the
724 relocation is relative and has
725 already been fixed up by the
726 linker (perhaps we ought to make
727 give an error by default, and
728 require `safe' relocations to be
729 enumberated explicitly?). */
730 goto good_32bit_resolve_reloc;
732 good_32bit_resolved_reloc:
733 if (bfd_big_endian (abs_bfd))
745 relocation_needed = 1;
749 printf("ERROR: reloc type %s unsupported in this context\n",
755 /* Calculate the sym address ourselves. */
756 sym_reloc_size = bfd_get_reloc_size(q->howto);
758 #if !defined(TARGET_h8300) && !defined(TARGET_e1) && !defined(TARGET_bfin) && !defined(TARGET_m68k)
759 if (sym_reloc_size != 4) {
760 printf("ERROR: bad reloc type %d size=%d for symbol=%s\n",
761 (*p)->howto->type, sym_reloc_size, sym_name);
768 switch ((*p)->howto->type) {
770 #if defined(TARGET_m68k)
772 relocation_needed = 1;
773 sym_vma = bfd_section_vma(abs_bfd, sym_section);
774 sym_addr += sym_vma + q->addend;
779 sym_addr += sym_vma + q->addend;
780 sym_addr -= q->address;
784 #if defined(TARGET_arm)
786 relocation_needed = 1;
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);
796 sym_vma = bfd_section_vma(abs_bfd, sym_section);
797 sym_addr += sym_vma + q->addend;
801 /* Should be fine as is */
806 "%s vma=0x%x, value=0x%x, address=0x%x "
807 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
809 sym_vma, (*(q->sym_ptr_ptr))->value,
810 q->address, sym_addr,
811 (*p)->howto->rightshift,
812 *(unsigned long *)r_mem);
815 sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift;
821 relocation_needed = 1;
822 sym_vma = bfd_section_vma(abs_bfd, sym_section);
823 sym_addr += sym_vma + q->addend;
825 #if defined(R_V850_ZDA_16_16_OFFSET) || defined(R_V850_ZDA_16_16_SPLIT_OFFSET)
826 #ifdef R_V850_ZDA_16_16_OFFSET
827 case R_V850_ZDA_16_16_OFFSET:
829 #ifdef R_V850_ZDA_16_16_SPLIT_OFFSET
830 case R_V850_ZDA_16_16_SPLIT_OFFSET:
832 /* Can't support zero-relocations. */
833 printf ("ERROR: %s+0x%x: zero relocations not supported\n",
834 sym_name, q->addend);
836 #endif /* R_V850_ZDA_16_16_OFFSET || R_V850_ZDA_16_16_SPLIT_OFFSET */
837 #endif /* TARGET_v850 */
841 if (sym_reloc_size != 4) {
842 printf("R_H8_DIR24R8 size %d\n", sym_reloc_size);
846 relocation_needed = 1;
847 sym_addr = (*(q->sym_ptr_ptr))->value;
849 r_mem -= 1; /* tracks q->address */
850 sym_vma = bfd_section_vma(abs_bfd, sym_section);
851 sym_addr += sym_vma + q->addend;
852 sym_addr |= (*(unsigned char *)r_mem<<24);
855 if (sym_reloc_size != 4) {
856 printf("R_H8_DIR24A8 size %d\n", sym_reloc_size);
860 /* Absolute symbol done not relocation */
861 relocation_needed = !bfd_is_abs_section(sym_section);
862 sym_addr = (*(q->sym_ptr_ptr))->value;
863 sym_vma = bfd_section_vma(abs_bfd, sym_section);
864 sym_addr += sym_vma + q->addend;
867 case R_H8_DIR32A16: /* currently 32, could be made 16 */
868 if (sym_reloc_size != 4) {
869 printf("R_H8_DIR32 size %d\n", sym_reloc_size);
873 relocation_needed = 1;
874 sym_addr = (*(q->sym_ptr_ptr))->value;
875 sym_vma = bfd_section_vma(abs_bfd, sym_section);
876 sym_addr += sym_vma + q->addend;
880 sym_addr = (*(q->sym_ptr_ptr))->value;
881 sym_addr += sym_vma + q->addend;
882 sym_addr -= (q->address + 2);
883 if (bfd_big_endian(abs_bfd))
884 *(unsigned short *)r_mem =
885 bfd_big_endian(abs_bfd) ? htons(sym_addr) : sym_addr;
889 sym_addr = (*(q->sym_ptr_ptr))->value;
890 sym_addr += sym_vma + q->addend;
891 sym_addr -= (q->address + 1);
892 *(unsigned char *)r_mem = sym_addr;
896 #ifdef TARGET_microblaze
897 case R_MICROBLAZE_64:
898 /* The symbol is split over two consecutive instructions.
899 Flag this to the flat loader by setting the high bit of
900 the relocation symbol. */
902 unsigned char *p = r_mem;
903 unsigned long offset;
906 /* work out the relocation */
907 sym_vma = bfd_section_vma(abs_bfd, sym_section);
908 /* grab any offset from the text */
909 offset = (p[2]<<24) + (p[3] << 16) + (p[6] << 8) + (p[7]);
910 /* Update the address */
911 sym_addr += offset + sym_vma + q->addend;
912 /* Write relocated pointer back */
913 p[2] = (sym_addr >> 24) & 0xff;
914 p[3] = (sym_addr >> 16) & 0xff;
915 p[6] = (sym_addr >> 8) & 0xff;
916 p[7] = sym_addr & 0xff;
918 /* create a new reloc entry */
919 flat_relocs = realloc(flat_relocs,
920 (flat_reloc_count + 1) * sizeof(uint32_t));
921 flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address);
923 relocation_needed = 0;
925 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
926 bfd_section_vma(abs_bfd, sym_section));
928 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
929 "section=%s size=%d "
930 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
931 q->address, sym_name, addstr,
932 section_name, sym_reloc_size,
933 sym_addr, section_vma + q->address);
935 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
936 section_vma + q->address);
940 case R_MICROBLAZE_32:
942 unsigned char *p = r_mem;
943 unsigned long offset;
945 /* grab any offset from the text */
946 offset = (p[0]<<24) + (p[1] << 16) + (p[2] << 8) + (p[3]);
947 sym_vma = bfd_section_vma(abs_bfd, sym_section);
948 /* This is a horrible kludge. For some
949 reason, *sometimes* the offset is in
950 both addend and the code. Detect
951 it, and cancel the effect. Otherwise
952 the offset gets added twice - ouch.
953 There should be a better test
954 for this condition, based on the
955 BFD data structures */
956 if(offset==q->addend)
959 sym_addr += offset + sym_vma + q->addend;
960 relocation_needed = 1;
963 case R_MICROBLAZE_64_PCREL:
965 //sym_addr = (*(q->sym_ptr_ptr))->value;
966 sym_addr += sym_vma + q->addend;
967 sym_addr -= (q->address + 4);
968 sym_addr = htonl(sym_addr);
970 * ((unsigned short *) (r_mem+2)) |= (sym_addr) & 0xFFFF;
972 * ((unsigned short *) (r_mem+6)) |= (sym_addr >> 16) & 0xFFFF;
973 /* We've done all the work, so continue
974 to next reloc instead of break */
977 #endif /* TARGET_microblaze */
980 #define htoniosl(x) (x)
981 #define niostohl(x) (x)
982 switch ((*p)->howto->type)
984 case R_NIOS2_BFD_RELOC_32:
985 relocation_needed = 1;
986 pflags = (FLAT_NIOS2_R_32 << 28);
987 sym_vma = bfd_section_vma(abs_bfd, sym_section);
988 sym_addr += sym_vma + q->addend;
989 /* modify target, in target order */
990 *(unsigned long *)r_mem = htoniosl(sym_addr);
994 unsigned long exist_val;
995 relocation_needed = 1;
996 pflags = (FLAT_NIOS2_R_CALL26 << 28);
997 sym_vma = bfd_section_vma(abs_bfd, sym_section);
998 sym_addr += sym_vma + q->addend;
1000 /* modify target, in target order */
1001 // exist_val = niostohl(*(unsigned long *)r_mem);
1002 exist_val = ((sym_addr >> 2) << 6);
1003 *(unsigned long *)r_mem = htoniosl(exist_val);
1006 case R_NIOS2_HIADJ16:
1009 unsigned long exist_val;
1011 /* handle the adjacent HI/LO pairs */
1013 r2_type = R_NIOS2_NONE;
1015 r2_type = p[1]->howto->type;
1016 if ((r2_type == R_NIOS2_LO16)
1017 && (p[0]->sym_ptr_ptr == p[1]->sym_ptr_ptr)
1018 && (p[0]->addend == p[1]->addend))
1020 unsigned char * r2_mem = sectionp + p[1]->address;
1021 if (p[1]->address - q->address!=4)
1022 printf("Err: HI/LO not adjacent %d\n", p[1]->address - q->address);
1023 relocation_needed = 1;
1024 pflags = (q->howto->type == R_NIOS2_HIADJ16)
1025 ? FLAT_NIOS2_R_HIADJ_LO : FLAT_NIOS2_R_HI_LO;
1028 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1029 sym_addr += sym_vma + q->addend;
1031 /* modify high 16 bits, in target order */
1032 exist_val = niostohl(*(unsigned long *)r_mem);
1033 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1034 if (q->howto->type == R_NIOS2_HIADJ16)
1035 exist_val |= ((((sym_addr >> 16) + ((sym_addr >> 15) & 1)) & 0xFFFF) << 6);
1037 exist_val |= (((sym_addr >> 16) & 0xFFFF) << 6);
1038 *(unsigned long *)r_mem = htoniosl(exist_val);
1040 /* modify low 16 bits, in target order */
1041 exist_val = niostohl(*(unsigned long *)r2_mem);
1042 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1043 exist_val |= ((sym_addr & 0xFFFF) << 6);
1044 *(unsigned long *)r2_mem = htoniosl(exist_val);
1047 goto NIOS2_RELOC_ERR;
1053 unsigned long exist_val, temp;
1054 //long gp = get_symbol_offset("_gp", sym_section, symbols, number_of_symbols);
1055 long gp = get_gp_value(symbols, number_of_symbols);
1057 printf("Err: unresolved symbol _gp when relocating %s\n", sym_name);
1058 goto NIOS2_RELOC_ERR;
1060 /* _gp holds a absolute value, otherwise the ld cannot generate correct code */
1061 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1062 //printf("sym=%x, %d, _gp=%x, %d\n", sym_addr+sym_vma, sym_addr+sym_vma, gp, gp);
1063 sym_addr += sym_vma + q->addend;
1065 //printf("sym - _gp=%x, %d\n", sym_addr, sym_addr);
1066 /* modify the target, in target order (little_endian) */
1067 exist_val = niostohl(*(unsigned long *)r_mem);
1068 temp = ((exist_val >> 6) & 0x3ff0000) | (sym_addr & 0xffff);
1070 temp |= (exist_val & 0x3f);
1071 *(unsigned long *)r_mem = htoniosl(temp);
1073 printf("omit: offset=0x%x symbol=%s%s "
1074 "section=%s size=%d "
1075 "fixup=0x%x (reloc=0x%x) GPREL\n",
1076 q->address, sym_name, addstr,
1077 section_name, sym_reloc_size,
1078 sym_addr, section_vma + q->address);
1081 case R_NIOS2_PCREL16:
1083 unsigned long exist_val;
1085 sym_addr += sym_vma + q->addend;
1086 sym_addr -= (q->address + 4);
1087 /* modify the target, in target order (little_endian) */
1088 exist_val = niostohl(*(unsigned long *)r_mem);
1089 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1090 exist_val |= ((sym_addr & 0xFFFF) << 6);
1091 *(unsigned long *)r_mem = htoniosl(exist_val);
1093 printf("omit: offset=0x%x symbol=%s%s "
1094 "section=%s size=%d "
1095 "fixup=0x%x (reloc=0x%x) PCREL\n",
1096 q->address, sym_name, addstr,
1097 section_name, sym_reloc_size,
1098 sym_addr, section_vma + q->address);
1103 /* check if this is actually the 2nd half of a pair */
1105 && ((p[-1]->howto->type == R_NIOS2_HIADJ16)
1106 || (p[-1]->howto->type == R_NIOS2_HI16))
1107 && (p[-1]->sym_ptr_ptr == p[0]->sym_ptr_ptr)
1108 && (p[-1]->addend == p[0]->addend)) {
1110 printf("omit: offset=0x%x symbol=%s%s "
1111 "section=%s size=%d LO16\n",
1112 q->address, sym_name, addstr,
1113 section_name, sym_reloc_size);
1117 /* error, fall through */
1121 case R_NIOS2_CACHE_OPX:
1125 case R_NIOS2_BFD_RELOC_16:
1126 case R_NIOS2_BFD_RELOC_8:
1127 case R_NIOS2_GNU_VTINHERIT:
1128 case R_NIOS2_GNU_VTENTRY:
1133 printf("Err: unexpected reloc type %s(%d)\n", q->howto->name, q->howto->type);
1137 #endif /* TARGET_nios2 */
1142 relocation_needed = 1;
1143 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1144 sym_addr += sym_vma + q->addend;
1148 sym_addr += sym_vma + q->addend;
1149 sym_addr -= q->address;
1151 case R_SPARC_WDISP30:
1152 sym_addr = (((*(q->sym_ptr_ptr))->value-
1153 q->address) >> 2) & 0x3fffffff;
1155 ntohl(*(unsigned long *)r_mem)
1160 relocation_needed = 1;
1161 pflags = 0x80000000;
1162 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1163 sym_addr += sym_vma + q->addend;
1165 htonl(*(unsigned long *)r_mem)
1170 relocation_needed = 1;
1171 pflags = 0x40000000;
1172 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1173 sym_addr += sym_vma + q->addend;
1174 sym_addr &= 0x000003ff;
1176 htonl(*(unsigned long *)r_mem)
1180 #endif /* TARGET_sparc */
1183 case R_pcrel12_jump:
1184 case R_pcrel12_jump_s:
1186 case R_pcrel24_jump_l:
1187 case R_pcrel24_jump_x:
1188 case R_pcrel24_call_x:
1192 sym_addr += q->addend;// get the symbol addr
1193 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1194 sym_addr -= q->address; // make it PC relative
1195 // implicitly assumes code section and symbol section are same
1202 sym_addr += q->addend;
1203 if(weak_und_symbol(sym_section->name, (*(q->sym_ptr_ptr))))
1205 if(0xFFFF0000 & sym_addr){
1206 fprintf (stderr, "Relocation overflow for rN = %s\n",sym_name);
1209 flat_relocs = (uint32_t *)
1210 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1211 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1212 sym_section->name, sym_name,
1213 (*(q->sym_ptr_ptr)),
1214 0, FLAT_RELOC_PART_LO,
1215 section_vma + q->address))
1224 unsigned int reloc_count_incr;
1227 if (q->howto->type == R_luimm16)
1228 hi_lo = FLAT_RELOC_PART_LO;
1230 hi_lo = FLAT_RELOC_PART_HI;
1232 sym_addr += q->addend;
1234 flat_relocs = (uint32_t *)
1235 (realloc (flat_relocs, (flat_reloc_count + 2) * sizeof (uint32_t)));
1236 reloc_count_incr = 1;
1237 if (weak_und_symbol (sym_section->name, (*(q->sym_ptr_ptr))))
1239 if (0xFFFF0000 & sym_addr) {
1240 /* value is > 16 bits - use an extra field */
1241 /* see if we have already output that symbol */
1242 /* reloc may be addend from symbol and */
1243 /* we can only store 16 bit offsets */
1245 if ((*(q->sym_ptr_ptr))->udata.i == 0
1246 || flat_relocs[(*(q->sym_ptr_ptr))->udata.i] != sym_addr
1247 || ((*(q->sym_ptr_ptr))->udata.i & 0xFFFF0000))
1249 reloc_count_incr = 2;
1250 flat_relocs[flat_reloc_count + 1] = sym_addr;
1251 (*(q->sym_ptr_ptr))->udata.i = flat_reloc_count + 1;
1252 sym_addr = 0; // indication to loader to read next
1254 sym_addr = (*(q->sym_ptr_ptr))->udata.i;
1260 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1261 sym_section->name, sym_name,
1262 (*(q->sym_ptr_ptr)),
1264 section_vma + q->address))
1266 flat_reloc_count += reloc_count_incr;
1270 sym_addr += q->addend;
1272 if (weak_und_symbol (sym_section->name, *q->sym_ptr_ptr))
1275 flat_relocs = (uint32_t *)
1276 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1277 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1278 sym_section->name, sym_name,
1279 (*(q->sym_ptr_ptr)),
1280 2, FLAT_RELOC_PART_LO,
1281 section_vma + q->address))
1287 #endif //TARGET_bfin
1291 relocation_needed = 1;
1292 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1293 sym_addr += sym_vma + q->addend;
1297 sym_addr += sym_vma + q->addend;
1298 sym_addr -= q->address;
1300 #endif /* TARGET_sh */
1303 #define htoe1l(x) htonl(x)
1310 #define DBG_E1 printf
1312 #define DBG_E1(x, ... )
1315 #define _32BITS_RELOC 0x00000000
1316 #define _30BITS_RELOC 0x80000000
1317 #define _28BITS_RELOC 0x40000000
1320 unsigned long sec_vma, exist_val, S;
1322 relocation_needed = 1;
1323 DBG_E1("Handling Reloc <CONST31>\n");
1324 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1325 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1326 sec_vma, sym_addr, q->address);
1327 sym_addr = sec_vma + sym_addr;
1328 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1329 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1330 exist_val = htoe1l(exist_val);
1331 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1332 sym_addr += exist_val;
1333 pflags = _30BITS_RELOC;
1335 case R_E1_CONST31_PCREL:
1336 relocation_needed = 0;
1337 DBG_E1("Handling Reloc <CONST31_PCREL>\n");
1338 DBG_E1("DONT RELOCATE AT LOADING\n");
1339 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1340 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1341 sec_vma, sym_addr, q->address);
1342 sym_addr = sec_vma + sym_addr;
1343 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1345 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1347 q->address = q->address + section_vma;
1348 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1350 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1351 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1352 DBG_E1( "sym_addr := sym_addr - q->address - "
1353 "sizeof(CONST31_PCREL): [0x%x]\n",
1355 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1356 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1357 exist_val = htoe1l(exist_val);
1358 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1359 sym_addr |= exist_val;
1360 DBG_E1("sym_addr |= exist_val) : [0x%x]\n", sym_addr );
1362 case R_E1_DIS29W_PCREL:
1363 relocation_needed = 0;
1364 DBG_E1("Handling Reloc <DIS29W_PCREL>\n");
1365 DBG_E1("DONT RELOCATE AT LOADING\n");
1366 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1367 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1368 sec_vma, sym_addr, q->address);
1369 sym_addr = sec_vma + sym_addr;
1370 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1372 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1374 q->address = q->address + section_vma;
1375 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1377 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1378 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1379 DBG_E1( "sym_addr := sym_addr - q->address - "
1380 "sizeof(CONST31_PCREL): [0x%x]\n",
1382 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1383 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1384 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1385 exist_val = htoe1l(exist_val);
1386 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1387 sym_addr += exist_val;
1390 DBG_E1("Handling Reloc <DIS29W>\n");
1391 goto DIS29_RELOCATION;
1393 DBG_E1("Handling Reloc <DIS29H>\n");
1394 goto DIS29_RELOCATION;
1396 DBG_E1("Handling Reloc <DIS29B>\n");
1398 relocation_needed = 1;
1399 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1400 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%08x]\n",
1402 sym_addr = sec_vma + sym_addr;
1403 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%08x]\n", sym_addr);
1404 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1405 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1406 exist_val = htoe1l(exist_val);
1407 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1408 sym_addr += exist_val;
1409 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1410 pflags = _28BITS_RELOC;
1412 case R_E1_IMM32_PCREL:
1413 relocation_needed = 0;
1414 DBG_E1("Handling Reloc <IMM32_PCREL>\n");
1415 DBG_E1("DONT RELOCATE AT LOADING\n");
1416 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1417 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1419 sym_addr = sec_vma + sym_addr;
1421 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1422 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1424 q->address = q->address + section_vma;
1425 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1427 if( (sym_addr = (sym_addr - q->address - 6 )) < 0 )
1428 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1429 DBG_E1( "sym_addr := sym_addr - q->address - "
1430 "sizeof(CONST31_PCREL): [0x%x]\n",
1432 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1433 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1434 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1435 exist_val = htoe1l(exist_val);
1436 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1437 sym_addr += exist_val;
1440 relocation_needed = 1;
1441 DBG_E1("Handling Reloc <IMM32>\n");
1442 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1443 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1445 sym_addr = sec_vma + sym_addr;
1446 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1447 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1448 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1449 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1450 exist_val = htoe1l(exist_val);
1451 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1452 sym_addr += exist_val;
1453 pflags = _32BITS_RELOC;
1456 relocation_needed = 1;
1457 DBG_E1("Handling Reloc <WORD>\n");
1458 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1459 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1461 sym_addr = sec_vma + sym_addr;
1462 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1463 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address );
1464 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1465 exist_val = htoe1l(exist_val);
1466 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1467 sym_addr += exist_val;
1468 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1469 pflags = _32BITS_RELOC;
1472 #undef _32BITS_RELOC
1473 #undef _30BITS_RELOC
1474 #undef _28BITS_RELOC
1477 /* missing support for other types of relocs */
1478 printf("ERROR: bad reloc type %d\n", (*p)->howto->type);
1484 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
1485 bfd_section_vma(abs_bfd, sym_section));
1489 * for full elf relocation we have to write back the
1490 * start_code relative value to use.
1492 if (!pic_with_got) {
1493 #if defined(TARGET_arm)
1502 * horrible nasty hack to support different endianess
1504 if (!bfd_big_endian(abs_bfd)) {
1516 tmp.l = *(unsigned long *)r_mem;
1517 hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16);
1519 (((*p)->howto->type != R_ARM_PC24) &&
1520 ((*p)->howto->type != R_ARM_PLT32)))
1521 hl |= (tmp.c[i3] << 24);
1522 else if (tmp.c[i2] & 0x80)
1523 hl |= 0xff000000; /* sign extend */
1526 tmp.c[i0] = hl & 0xff;
1527 tmp.c[i1] = (hl >> 8) & 0xff;
1528 tmp.c[i2] = (hl >> 16) & 0xff;
1530 (((*p)->howto->type != R_ARM_PC24) &&
1531 ((*p)->howto->type != R_ARM_PLT32)))
1532 tmp.c[i3] = (hl >> 24) & 0xff;
1533 if ((*p)->howto->type == R_ARM_ABS32)
1534 *(unsigned long *)r_mem = htonl(hl);
1536 *(unsigned long *)r_mem = tmp.l;
1538 #elif defined(TARGET_bfin)
1539 if ((*p)->howto->type == R_pcrel24
1540 || (*p)->howto->type == R_pcrel24_jump_l
1541 || (*p)->howto->type == R_pcrel24_jump_x
1542 || (*p)->howto->type == R_pcrel24_call_x)
1544 sym_addr += 2*-1*PCREL24_MAGIC_OFFSET;
1545 *((unsigned short *)(sectionp + q->address) + 1 + PCREL24_MAGIC_OFFSET)
1546 = (sym_addr >> 1) & 0xffff;
1547 *((unsigned short *)(sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1548 = (0xff00 & *((unsigned short *) (sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1549 | ((sym_addr >> 17) & 0xff));
1550 } else if ((*p)->howto->type == R_byte4_data) {
1551 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1552 } else if ((*p)->howto->type == R_pcrel12_jump
1553 || (*p)->howto->type == R_pcrel12_jump_s) {
1554 *((unsigned short *)(sectionp + q->address))
1555 = (0xf000 & *((unsigned short *)(sectionp + q->address))
1556 | ((sym_addr >> 1) & 0xfff));
1557 } else if ((*p)->howto->type == R_pcrel10) {
1558 *((unsigned short *)(sectionp + q->address))
1559 = (~0x3ff & *((unsigned short *)(sectionp + q->address))
1560 | ((sym_addr >> 1) & 0x3ff));
1561 } else if ((*p)->howto->type == R_rimm16
1562 || (*p)->howto->type == R_huimm16
1563 || (*p)->howto->type == R_luimm16) {
1564 /* for l and h we set the lower 16 bits which is only when it will be used */
1565 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1566 } else if ((*p)->howto->type == R_pcrel5m2) {
1567 *((unsigned short *)(sectionp + q->address))
1568 = (0xfff0 & *((unsigned short *)(sectionp + q->address))
1569 | ((sym_addr >> 1) & 0xf));
1570 } else if ((*p)->howto->type == R_pcrel11){
1571 *((unsigned short *)(sectionp + q->address))
1572 = (0xfc00 & *((unsigned short *)(sectionp + q->address))
1573 | ((sym_addr >> 1) & 0x3ff));
1574 } else if (0xE0 <= (*p)->howto->type && 0xF3 >= (*p)->howto->type) {
1575 //arith relocs dont generate a real relocation
1577 printf("Blackfin relocation fail for reloc type: 0x%x\n", (*p)->howto->type);
1579 #elif defined(TARGET_e1)
1580 #define OPCODE_SIZE 2 /* Add 2 bytes, counting the opcode size*/
1581 switch ((*p)->howto->type) {
1583 case R_E1_CONST31_PCREL:
1584 case R_E1_DIS29W_PCREL:
1588 case R_E1_IMM32_PCREL:
1590 DBG_E1("In addr + 2:[0x%x] <- write [0x%x]\n",
1591 (sectionp + q->address + 2), sym_addr );
1592 *((unsigned long *) (sectionp + q->address + OPCODE_SIZE)) =
1596 DBG_E1("In addr : [0x%x] <- write [0x%x]\n",
1597 (sectionp + q->address), sym_addr );
1598 *((unsigned long *) (sectionp + q->address )) = htonl(sym_addr);
1601 printf("ERROR:Unhandled Relocation. Exiting...\n");
1605 #else /* ! TARGET_arm && ! TARGET_e1 */
1607 switch (q->howto->type) {
1612 /* Do nothing -- for cases we handle,
1613 the bits produced by the linker are
1614 what we want in the final flat file
1615 (and other cases are errors). Note
1616 that unlike most relocated values,
1617 it is stored in little-endian order,
1618 but this is necessary to avoid
1619 trashing the low-bit, and the float
1620 loaders knows about it. */
1622 #endif /* TARGET_V850 */
1625 case R_NIOS2_BFD_RELOC_32:
1626 case R_NIOS2_CALL26:
1627 case R_NIOS2_HIADJ16:
1631 #endif /* TARGET_nios2 */
1633 #if defined(TARGET_m68k)
1635 if (sym_addr < -0x8000 || sym_addr > 0x7fff) {
1636 fprintf (stderr, "Relocation overflow for R_68K_PC16 relocation against %s\n", sym_name);
1639 r_mem[0] = (sym_addr >> 8) & 0xff;
1640 r_mem[1] = sym_addr & 0xff;
1646 /* The alignment of the build host
1647 might be stricter than that of the
1648 target, so be careful. We store in
1649 network byte order. */
1650 r_mem[0] = (sym_addr >> 24) & 0xff;
1651 r_mem[1] = (sym_addr >> 16) & 0xff;
1652 r_mem[2] = (sym_addr >> 8) & 0xff;
1653 r_mem[3] = sym_addr & 0xff;
1655 #endif /* !TARGET_arm */
1660 if ((*p)->howto->type == R_rimm16
1661 || (*p)->howto->type == R_huimm16
1662 || (*p)->howto->type == R_luimm16)
1664 /* for l and h we set the lower 16 bits which is only when it will be used */
1665 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1666 } else if ((*p)->howto->type == R_byte4_data) {
1667 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1672 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
1673 "section=%s size=%d "
1674 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
1675 q->address, sym_name, addstr,
1676 section_name, sym_reloc_size,
1677 sym_addr, section_vma + q->address);
1680 * Create relocation entry (PC relative doesn't need this).
1682 if (relocation_needed) {
1684 flat_relocs = realloc(flat_relocs,
1685 (flat_reloc_count + 1) * sizeof(uint32_t));
1687 flat_relocs[flat_reloc_count] = pflags |
1688 (section_vma + q->address);
1691 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
1692 section_vma + q->address);
1694 switch ((*p)->howto->type) {
1696 case R_E1_CONST31_PCREL:
1697 case R_E1_DIS29W_PCREL:
1701 case R_E1_IMM32_PCREL:
1703 flat_relocs[flat_reloc_count] = pflags |
1704 (section_vma + q->address + OPCODE_SIZE);
1706 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1707 flat_relocs[flat_reloc_count] );
1710 flat_relocs[flat_reloc_count] = pflags |
1711 (section_vma + q->address);
1713 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1714 flat_relocs[flat_reloc_count] );
1720 relocation_needed = 0;
1725 printf("%s(%d): symbol name=%s address=0x%x section=%s -> RELOC=0x%x\n",
1726 __FILE__, __LINE__, sym_name, q->address, section_name,
1727 flat_relocs[flat_reloc_count]);
1734 printf("%d bad relocs\n", bad_relocs);
1741 *n_relocs = flat_reloc_count;
1747 static char * program;
1749 static void usage(void)
1751 fprintf(stderr, "Usage: %s [vrzd] [-p <abs-pic-file>] [-s stack-size] "
1752 "[-o <output-file>] <elf-file>\n\n"
1753 " -v : verbose operation\n"
1754 " -r : force load to RAM\n"
1755 " -k : enable kernel trace on load (for debug)\n"
1756 " -z : compress code/data/relocs\n"
1757 " -d : compress data/relocs\n"
1758 " -a : use existing symbol references\n"
1759 " instead of recalculating from\n"
1760 " relocation info\n"
1761 " -R reloc-file : read relocations from a separate file\n"
1762 " -p abs-pic-file : GOT/PIC processing with files\n"
1763 " -s stacksize : set application stack size\n"
1764 " -o output-file : output file name\n\n",
1766 fprintf(stderr, "Compiled for " ARCH " architecture\n\n");
1771 /* Write NUM zeroes to STREAM. */
1772 static void write_zeroes (unsigned long num, FILE *stream)
1776 /* It'd be nice if we could just use fseek, but that doesn't seem to
1777 work for stdio output files. */
1778 memset(zeroes, 0x00, 1024);
1779 while (num > sizeof(zeroes)) {
1780 fwrite(zeroes, sizeof(zeroes), 1, stream);
1781 num -= sizeof(zeroes);
1784 fwrite(zeroes, num, 1, stream);
1789 int main(int argc, char *argv[])
1792 bfd *rel_bfd, *abs_bfd;
1794 char *ofile=NULL, *pfile=NULL, *abs_file = NULL, *rel_file = NULL;
1802 asymbol **symbol_table;
1803 long number_of_symbols;
1805 unsigned long data_len = 0;
1806 unsigned long bss_len = 0;
1807 unsigned long text_len = 0;
1808 unsigned long reloc_len;
1810 unsigned long data_vma = ~0;
1811 unsigned long bss_vma = ~0;
1812 unsigned long text_vma = ~0;
1814 unsigned long text_offs;
1820 struct flat_hdr hdr;
1830 if (sizeof(hdr) != 64) {
1832 "Potential flat header incompatibility detected\n"
1833 "header size should be 64 but is %d\n",
1840 #else /* We need plenty of stack for both of them (Aggregate and Register) */
1844 while ((opt = getopt(argc, argv, "avzdrkp:s:o:R:")) != -1) {
1871 stack = atoi(optarg);
1877 fprintf(stderr, "%s Unknown option\n", argv[0]);
1884 * if neither the -r or -p options was given, default to
1885 * a RAM load as that is the only option that makes sense.
1887 if (!load_to_ram && !pfile)
1890 filename = fname = argv[argc-1];
1901 if (!(rel_bfd = bfd_openr(rel_file, 0))) {
1902 fprintf(stderr, "Can't open %s\n", rel_file);
1906 if (bfd_check_format (rel_bfd, bfd_object) == 0) {
1907 fprintf(stderr, "File is not an object file\n");
1911 if (abs_file == rel_file)
1912 abs_bfd = rel_bfd; /* one file does all */
1914 if (!(abs_bfd = bfd_openr(abs_file, 0))) {
1915 fprintf(stderr, "Can't open %s\n", abs_file);
1919 if (bfd_check_format (abs_bfd, bfd_object) == 0) {
1920 fprintf(stderr, "File is not an object file\n");
1925 if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC)) {
1926 fprintf (stderr, "%s: Input file contains no relocation info\n", rel_file);
1930 if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P)) {
1931 /* `Absolute' file is not absolute, so neither are address
1932 contained therein. */
1934 "%s: `-a' option specified with non-fully-resolved input file\n",
1935 bfd_get_filename (abs_bfd));
1939 symbol_table = get_symbols(abs_bfd, &number_of_symbols);
1941 /* Group output sections into text, data, and bss, and calc their sizes. */
1942 for (s = abs_bfd->sections; s != NULL; s = s->next) {
1943 unsigned long *vma, *len;
1944 bfd_size_type sec_size;
1947 if (s->flags & SEC_CODE) {
1950 } else if (s->flags & SEC_DATA) {
1953 } else if (s->flags & SEC_ALLOC) {
1959 sec_size = bfd_section_size(abs_bfd, s);
1960 sec_vma = bfd_section_vma(abs_bfd, s);
1962 if (sec_vma < *vma) {
1964 *len += sec_vma - *vma;
1968 } else if (sec_vma + sec_size > *vma + *len)
1969 *len = sec_vma + sec_size - *vma;
1972 if (text_len == 0) {
1973 fprintf (stderr, "%s: no .text section", abs_file);
1977 text = malloc(text_len);
1980 printf("TEXT -> vma=0x%x len=0x%x\n", text_vma, text_len);
1982 /* Read in all text sections. */
1983 for (s = abs_bfd->sections; s != NULL; s = s->next)
1984 if (s->flags & SEC_CODE)
1985 if (!bfd_get_section_contents(abs_bfd, s,
1986 text + (s->vma - text_vma), 0,
1987 bfd_section_size(abs_bfd, s)))
1989 fprintf(stderr, "read error section %s\n", s->name);
1993 if (data_len == 0) {
1994 fprintf (stderr, "%s: no .data section", abs_file);
1997 data = malloc(data_len);
2000 printf("DATA -> vma=0x%x len=0x%x\n", data_vma, data_len);
2002 if ((text_vma + text_len) != data_vma) {
2003 if ((text_vma + text_len) > data_vma) {
2004 printf("ERROR: text=0x%x overlaps data=0x%x ?\n", text_len, data_vma);
2008 printf("WARNING: data=0x%x does not directly follow text=0x%x\n",
2009 data_vma, text_len);
2010 text_len = data_vma - text_vma;
2013 /* Read in all data sections. */
2014 for (s = abs_bfd->sections; s != NULL; s = s->next)
2015 if (s->flags & SEC_DATA)
2016 if (!bfd_get_section_contents(abs_bfd, s,
2017 data + (s->vma - data_vma), 0,
2018 bfd_section_size(abs_bfd, s)))
2020 fprintf(stderr, "read error section %s\n", s->name);
2024 /* Put common symbols in bss. */
2025 bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len);
2028 printf("BSS -> vma=0x%x len=0x%x\n", bss_vma, bss_len);
2030 if ((data_vma + data_len) != bss_vma) {
2031 if ((data_vma + data_len) > bss_vma) {
2032 printf("ERROR: text=0x%x + data=0x%x overlaps bss=0x%x ?\n", text_len,
2037 printf("WARNING: bss=0x%x does not directly follow text=0x%x + data=0x%x(0x%x)\n",
2038 bss_vma, text_len, data_len, text_len + data_len);
2039 data_len = bss_vma - data_vma;
2042 reloc = output_relocs(abs_bfd, symbol_table, number_of_symbols, &reloc_len,
2043 text, text_len, text_vma, data, data_len, data_vma,
2047 printf("No relocations in code!\n");
2049 text_offs = real_address_bits(text_vma);
2051 /* Fill in the binflt_flat header */
2052 memcpy(hdr.magic,"bFLT",4);
2053 hdr.rev = htonl(FLAT_VERSION);
2054 hdr.entry = htonl(sizeof(hdr) + bfd_get_start_address(abs_bfd));
2055 hdr.data_start = htonl(sizeof(hdr) + text_offs + text_len);
2056 hdr.data_end = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2057 hdr.bss_end = htonl(sizeof(hdr) + text_offs + text_len +data_len+bss_len);
2058 hdr.stack_size = htonl(stack); /* FIXME */
2059 hdr.reloc_start = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2060 hdr.reloc_count = htonl(reloc_len);
2062 | (load_to_ram ? FLAT_FLAG_RAM : 0)
2063 | (ktrace ? FLAT_FLAG_KTRACE : 0)
2064 | (pic_with_got ? FLAT_FLAG_GOTPIC : 0)
2065 | (compress ? (compress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
2067 hdr.build_date = htonl((unsigned long)time(NULL));
2068 memset(hdr.filler, 0x00, sizeof(hdr.filler));
2070 for (i=0; i<reloc_len; i++) reloc[i] = htonl(reloc[i]);
2073 printf("SIZE: .text=0x%04x, .data=0x%04x, .bss=0x%04x",
2074 text_len, data_len, bss_len);
2076 printf(", relocs=0x%04x", reloc_len);
2081 ofile = malloc(strlen(fname) + 5 + 1); /* 5 to add suffix */
2082 strcpy(ofile, fname);
2083 strcat(ofile, ".bflt");
2086 if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0) {
2087 fprintf (stderr, "Can't open output file %s\n", ofile);
2091 write(fd, &hdr, sizeof(hdr));
2095 * get the compression command ready
2097 sprintf(cmd, "gzip -f -9 >> %s", ofile);
2099 #define START_COMPRESSOR do { \
2105 if (!(gf = popen(cmd, "w" BINARY_FILE_OPTS))) { \
2106 fprintf(stderr, "Can't run cmd %s\n", cmd); \
2112 gf = fopen(ofile, "ab"); /* Add 'b' to support non-posix (ie windows) */
2114 fprintf(stderr, "Can't open file %s for writing\n", ofile); \
2121 /* Fill in any hole at the beginning of the text segment. */
2123 printf("ZERO before text len=0x%x\n", text_offs);
2124 write_zeroes(text_offs, gf);
2126 /* Write the text segment. */
2127 fwrite(text, text_len, 1, gf);
2132 /* Write the data segment. */
2133 fwrite(data, data_len, 1, gf);
2136 fwrite(reloc, reloc_len * 4, 1, gf);
2148 * this __MUST__ be at the VERY end of the file - do NOT move!!
2154 * vi: tabstop=8 shiftwidth=4 textwidth=79 noexpandtab