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) 2004, Nios II support, Wentao Xu <wentao@microtronix.com>
10 * (c) 2003, H8 support, ktrace <davidm@snapgear.com>
11 * (c) 2003-2004, MicroBlaze support, John Williams <jwilliams@itee.uq.edu.au>
12 * (c) 2001-2003, arm/arm-pic/arm-big-endian support <davidm@snapgear.com>
13 * (c) 2001, v850 changes, Mile Bader <miles@lsi.nec.co.jp>
14 * (c) 2003, SuperH support, Paul Mundt <lethal@linux-sh.org>
15 * (c) 2001, zflat support <davidm@snapgear.com>
16 * (c) 2001, Changes for GOT entries Paul Dale <pauli@snapgear.com> and
17 * David McCullough <davidm@snapgear.com>
19 * Now supports PIC with GOT tables. This works by taking a '.elf' file
20 * and a fully linked elf executable (at address 0) and produces a flat
21 * file that can be loaded with some fixups. It still supports the old
22 * style fully relocatable elf format files.
24 * Originally obj-res.c
26 * (c) 1998, Kenneth Albanowski <kjahds@kjahds.com>
27 * (c) 1998, D. Jeff Dionne
28 * (c) 1998, The Silver Hammer Group Ltd.
29 * (c) 1996, 1997 Dionne & Associates <jeff@ryeham.ee.ryerson.ca>
31 * This is Free Software, under the GNU Public Licence v2 or greater.
33 * Relocation added March 1997, Kresten Krab Thorup
34 * krab@california.daimi.aau.dk
37 #include <stdio.h> /* Userland pieces of the ANSI C standard I/O package */
38 #include <stdlib.h> /* Userland prototypes of the ANSI C std lib functions */
39 #include <stdarg.h> /* Allows va_list to exist in the these namespaces */
40 #include <string.h> /* Userland prototypes of the string handling funcs */
42 #include <unistd.h> /* Userland prototypes of the Unix std system calls */
43 #include <fcntl.h> /* Flag value for file handling functions */
46 #include <netinet/in.h> /* Consts and structs defined by the internet system */
47 #define BINARY_FILE_OPTS
50 #define BINARY_FILE_OPTS "b"
53 /* from $(INSTALLDIR)/include */
54 #include <bfd.h> /* Main header file for the BFD library */
56 #if defined(TARGET_h8300)
57 #include <elf/h8.h> /* TARGET_* ELF support for the BFD library */
58 #elif defined(__CYGWIN__) || defined(__MINGW32__) || defined(TARGET_nios) || defined(TARGET_nios2)
59 #include "cygwin-elf.h" /* Cygwin uses a local copy */
60 #elif defined(TARGET_microblaze)
61 #include <elf/microblaze.h> /* TARGET_* ELF support for the BFD library */
62 #elif defined(TARGET_bfin)
65 #include <elf.h> /* TARGET_* ELF support for the BFD library */
68 #if defined(__MINGW32__)
72 /* from uClinux-x.x.x/include/linux */
73 #include "flat.h" /* Binary flat header description */
83 #if defined(TARGET_m68k)
84 #define ARCH "m68k/coldfire"
85 #elif defined(TARGET_arm)
87 #elif defined(TARGET_sparc)
89 #elif defined(TARGET_v850)
91 #elif defined(TARGET_sh)
93 #elif defined(TARGET_h8300)
95 #elif defined(TARGET_microblaze)
96 #define ARCH "microblaze"
97 #elif defined(TARGET_e1)
98 #define ARCH "e1-coff"
99 #elif defined(TARGET_bfin)
101 #define FLAT_RELOC_TYPE_TEXT 0
102 #define FLAT_RELOC_TYPE_DATA 1
103 #define FLAT_RELOC_TYPE_BSS 2
104 #define FLAT_RELOC_TYPE_STACK 3
105 #define FLAT_RELOC_PART_LO 0
106 #define FLAT_RELOC_PART_HI 1
107 #define PCREL24_MAGIC_OFFSET -1
108 #elif defined(TARGET_nios)
110 #elif defined(TARGET_nios2)
113 #error "Don't know how to support your CPU architecture??"
116 #if defined(TARGET_m68k) || defined(TARGET_h8300) || defined(TARGET_bfin)
118 * Define a maximum number of bytes allowed in the offset table.
119 * We'll fail if the table is larger than this.
121 * This limit may be different for platforms other than m68k, but
122 * 8000 entries is a lot, trust me :-) (davidm)
124 #define GOT_LIMIT 32767
126 * we have to mask out the shared library id here and there, this gives
127 * us the real address bits when needed
129 #define real_address_bits(x) (pic_with_got ? ((x) & 0xffffff) : (x))
131 #define real_address_bits(x) (x)
139 int verbose = 0; /* extra output when running */
140 int pic_with_got = 0; /* do elf/got processing with PIC code */
141 int load_to_ram = 0; /* instruct loader to allocate everything into RAM */
142 int ktrace = 0; /* instruct loader output kernel trace on load */
143 int compress = 0; /* 1 = compress everything, 2 = compress data only */
144 int use_resolved = 0; /* If true, get the value of symbol references from */
145 /* the program contents, not from the relocation table. */
146 /* In this case, the input ELF file must be already */
147 /* fully resolved (using the `-q' flag with recent */
148 /* versions of GNU ld will give you a fully resolved */
149 /* output file with relocation entries). */
151 const char *progname, *filename;
157 static char where[200];
160 /* Use exactly one of these: */
161 E_NOFILE = 0, /* "progname: " */
162 E_FILE = 1, /* "filename: " */
163 E_FILELINE = 2, /* "filename:lineno: " */
164 E_FILEWHERE = 3, /* "filename:%s: " -- set %s with ewhere() */
166 /* Add in any of these with |': */
171 void ewhere (const char *format, ...);
172 void einfo (int type, const char *format, ...);
176 ewhere (const char *format, ...) {
178 va_start (args, format);
179 vsprintf (where, format, args);
185 einfo (int type, const char *format, ...) {
188 switch (type & 0x0f) {
190 fprintf (stderr, "%s: ", progname);
193 fprintf (stderr, "%s: ", filename);
196 ewhere ("%d", lineno);
199 fprintf (stderr, "%s:%s: ", filename, where);
203 if (type & E_WARNING) {
204 fprintf (stderr, "warning: ");
210 va_start (args, format);
211 vfprintf (stderr, format, args);
217 fprintf (stderr, "\n");
222 get_symbols (bfd *abfd, long *num)
225 asymbol **symbol_table;
226 long number_of_symbols;
228 storage_needed = bfd_get_symtab_upper_bound (abfd);
230 if (storage_needed < 0)
233 if (storage_needed == 0)
236 symbol_table = (asymbol **) malloc (storage_needed);
238 number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
240 if (number_of_symbols < 0)
243 *num = number_of_symbols;
250 dump_symbols(asymbol **symbol_table, long number_of_symbols)
253 printf("SYMBOL TABLE:\n");
254 for (i=0; i<number_of_symbols; i++) {
255 printf(" NAME=%s VALUE=0x%x\n", symbol_table[i]->name,
256 symbol_table[i]->value);
265 get_symbol_offset(char *name, asection *sec, asymbol **symbol_table, long number_of_symbols)
268 for (i=0; i<number_of_symbols; i++) {
269 if (symbol_table[i]->section == sec) {
270 if (!strcmp(symbol_table[i]->name, name)) {
271 return symbol_table[i]->value;
281 get_gp_value(asymbol **symbol_table, long number_of_symbols)
284 for (i=0; i<number_of_symbols; i++) {
285 if (!strcmp(symbol_table[i]->name, "_gp"))
286 return symbol_table[i]->value;
294 add_com_to_bss(asymbol **symbol_table, long number_of_symbols, long bss_len)
300 for (i=0; i<number_of_symbols; i++) {
301 if (strcmp("*COM*", symbol_table[i]->section->name) == 0) {
302 offset = bss_len + comsize;
303 comsize += symbol_table[i]->value;
304 symbol_table[i]->value = offset;
311 /* FUNCTION : weak_und_symbol
312 ABSTRACT : return true if symbol is weak and undefined.
315 weak_und_symbol(const char *reloc_section_name,
316 struct bfd_symbol *symbol)
318 if (!(strstr (reloc_section_name, "text")
319 || strstr (reloc_section_name, "data")
320 || strstr (reloc_section_name, "bss"))) {
321 if (symbol->flags & BSF_WEAK) {
323 fprintf(stderr, "found weak undefined symbol %s\n", symbol->name);
332 bfin_set_reloc (uint32_t *reloc,
333 const char *reloc_section_name,
334 const char *sym_name,
335 struct bfd_symbol *symbol,
336 int sp, int hilo, int32_t offset)
341 if (strstr (reloc_section_name, "text"))
342 type = FLAT_RELOC_TYPE_TEXT;
343 else if (strstr (reloc_section_name, "data"))
344 type = FLAT_RELOC_TYPE_DATA;
345 else if (strstr (reloc_section_name, "bss"))
346 type = FLAT_RELOC_TYPE_BSS;
347 else if (strstr (reloc_section_name, "stack"))
348 type = FLAT_RELOC_TYPE_STACK;
349 else if (symbol->flags & BSF_WEAK){
350 /* weak symbol support ... if a weak symbol is undefined at the
351 end of a final link, it should return 0 rather than error
352 We will assume text section for the moment.
354 type = FLAT_RELOC_TYPE_TEXT;
355 } else if (strstr (reloc_section_name, "*ABS*")){
356 /* (A data section initialization of something in the shared libc's text section
357 does not resolve - i.e. a global pointer to function initialized with
359 The text section here is appropriate as the section information
360 of the shared library is lost. The loader will do some calcs.
362 type = FLAT_RELOC_TYPE_TEXT;
364 printf ("Unknown Type - relocation for %s in bad section - %s\n", sym_name, reloc_section_name);
368 val = (offset & ((1 << 26) - 1)) << 6;
369 val |= (sp & (1 << 3) - 1) << 3;
370 val |= (hilo & 1) << 2;
371 val |= (type & (1 << 2) - 1);
382 int number_of_symbols,
383 unsigned long *n_relocs,
384 unsigned char *text, int text_len, unsigned long text_vma,
385 unsigned char *data, int data_len, unsigned long data_vma,
388 uint32_t *flat_relocs;
389 asection *a, *sym_section, *r;
390 arelent **relpp, **p, *q;
391 const char *sym_name, *section_name;
392 unsigned char *sectionp;
393 unsigned long pflags;
395 long sym_addr, sym_vma, section_vma;
396 int relsize, relcount;
397 int flat_reloc_count;
398 int sym_reloc_size, rc;
405 printf("%s(%d): output_relocs(abs_bfd=%d,synbols=0x%x,number_of_symbols=%d"
406 "n_relocs=0x%x,text=0x%x,text_len=%d,data=0x%x,data_len=%d)\n",
407 __FILE__, __LINE__, abs_bfd, symbols, number_of_symbols, n_relocs,
408 text, text_len, data, data_len);
412 dump_symbols(symbols, number_of_symbols);
417 flat_reloc_count = 0;
421 /* Determine how big our offset table is in bytes.
422 * This isn't too difficult as we've terminated the table with -1.
423 * Also note that both the relocatable and absolute versions have this
424 * terminator even though the relocatable one doesn't have the GOT!
427 unsigned long *lp = (unsigned long *)data;
428 /* Should call ntohl(*lp) here but is isn't going to matter */
429 while (*lp != 0xffffffff) lp++;
430 got_size = ((unsigned char *)lp) - data;
432 printf("GOT table contains %d entries (%d bytes)\n",
433 got_size/sizeof(unsigned long), got_size);
435 if (got_size > GOT_LIMIT) {
436 fprintf(stderr, "GOT too large: %d bytes (limit = %d bytes)\n",
437 got_size, GOT_LIMIT);
443 for (a = abs_bfd->sections; (a != (asection *) NULL); a = a->next) {
444 section_vma = bfd_section_vma(abs_bfd, a);
447 printf("SECTION: %s [0x%x]: flags=0x%x vma=0x%x\n", a->name, a,
448 a->flags, section_vma);
450 // if (bfd_is_abs_section(a))
452 if (bfd_is_und_section(a))
454 if (bfd_is_com_section(a))
456 // if ((a->flags & SEC_RELOC) == 0)
460 * Only relocate things in the data sections if we are PIC/GOT.
461 * otherwise do text as well
463 if (!pic_with_got && (a->flags & SEC_CODE))
464 sectionp = text + (a->vma - text_vma);
465 else if (a->flags & SEC_DATA)
466 sectionp = data + (a->vma - data_vma);
470 /* Now search for the equivalent section in the relocation binary
471 * and use that relocation information to build reloc entries
474 for (r=rel_bfd->sections; r != NULL; r=r->next)
475 if (strcmp(a->name, r->name) == 0)
480 printf(" RELOCS: %s [0x%x]: flags=0x%x vma=0x%x\n", r->name, r,
481 r->flags, bfd_section_vma(abs_bfd, r));
482 if ((r->flags & SEC_RELOC) == 0)
484 relsize = bfd_get_reloc_upper_bound(rel_bfd, r);
487 printf("%s(%d): no relocation entries section=0x%x\n",
488 __FILE__, __LINE__, r->name);
492 symb = get_symbols(rel_bfd, &nsymb);
493 relpp = (arelent **) xmalloc(relsize);
494 relcount = bfd_canonicalize_reloc(rel_bfd, r, relpp, symb);
497 printf("%s(%d): no relocation entries section=%s\n",
498 __FILE__, __LINE__, r->name);
501 for (p = relpp; (relcount && (*p != NULL)); p++, relcount--) {
502 unsigned char *r_mem;
503 int relocation_needed = 0;
505 #ifdef TARGET_microblaze
506 /* The MICROBLAZE_XX_NONE relocs can be skipped.
507 They represent PC relative branches that the
508 linker has already resolved */
510 switch ((*p)->howto->type)
512 case R_MICROBLAZE_NONE:
513 case R_MICROBLAZE_64_NONE:
516 #endif /* TARGET_microblaze */
519 /* Skip this relocation entirely if possible (we
520 do this early, before doing any other
521 processing on it). */
522 switch ((*p)->howto->type) {
523 #ifdef R_V850_9_PCREL
526 #ifdef R_V850_22_PCREL
527 case R_V850_22_PCREL:
529 #ifdef R_V850_SDA_16_16_OFFSET
530 case R_V850_SDA_16_16_OFFSET:
532 #ifdef R_V850_SDA_15_16_OFFSET
533 case R_V850_SDA_15_16_OFFSET:
535 #ifdef R_V850_ZDA_15_16_OFFSET
536 case R_V850_ZDA_15_16_OFFSET:
538 #ifdef R_V850_TDA_6_8_OFFSET
539 case R_V850_TDA_6_8_OFFSET:
541 #ifdef R_V850_TDA_7_8_OFFSET
542 case R_V850_TDA_7_8_OFFSET:
544 #ifdef R_V850_TDA_7_7_OFFSET
545 case R_V850_TDA_7_7_OFFSET:
547 #ifdef R_V850_TDA_16_16_OFFSET
548 case R_V850_TDA_16_16_OFFSET:
550 #ifdef R_V850_TDA_4_5_OFFSET
551 case R_V850_TDA_4_5_OFFSET:
553 #ifdef R_V850_TDA_4_4_OFFSET
554 case R_V850_TDA_4_4_OFFSET:
556 #ifdef R_V850_SDA_16_16_SPLIT_OFFSET
557 case R_V850_SDA_16_16_SPLIT_OFFSET:
559 #ifdef R_V850_CALLT_6_7_OFFSET
560 case R_V850_CALLT_6_7_OFFSET:
562 #ifdef R_V850_CALLT_16_16_OFFSET
563 case R_V850_CALLT_16_16_OFFSET:
565 /* These are relative relocations, which
566 have already been fixed up by the
567 linker at this point, so just ignore
571 #endif /* USE_V850_RELOCS */
574 if (q->sym_ptr_ptr && *q->sym_ptr_ptr) {
575 sym_name = (*(q->sym_ptr_ptr))->name;
576 sym_section = (*(q->sym_ptr_ptr))->section;
577 section_name=(*(q->sym_ptr_ptr))->section->name;
579 printf("ERROR: undefined relocation entry\n");
584 /* Adjust the address to account for the GOT table which wasn't
585 * present in the relative file link.
588 q->address += got_size;
591 /* A pointer to what's being relocated, used often
593 r_mem = sectionp + q->address;
596 * Fixup offset in the actual section.
600 if ((sym_addr = get_symbol_offset((char *) sym_name,
601 sym_section, symbols, number_of_symbols)) == -1) {
605 sym_addr = (*(q->sym_ptr_ptr))->value;
608 /* Use the address of the symbol already in
609 the program text. How this is handled may
610 still depend on the particular relocation
612 switch (q->howto->type) {
616 /* We specially handle adjacent
617 HI16_S/ZDA_15_16_OFFSET and
618 HI16_S/LO16 pairs that reference the
619 same address (these are usually
620 movhi/ld and movhi/movea pairs,
623 r2_type = R_V850_NONE;
625 r2_type = p[1]->howto->type;
626 if ((r2_type == R_V850_ZDA_15_16_OFFSET
627 || r2_type == R_V850_LO16)
628 && (p[0]->sym_ptr_ptr
629 == p[1]->sym_ptr_ptr)
630 && (p[0]->addend == p[1]->addend))
632 relocation_needed = 1;
635 case R_V850_ZDA_15_16_OFFSET:
643 /* We don't really need the
644 actual value -- the bits
645 produced by the linker are
646 what we want in the final
647 flat file -- but get it
651 unsigned char *r2_mem =
659 /* Sign extend LO. */
663 /* Maybe ignore the LSB
667 if (r2_type != R_V850_LO16)
675 goto bad_v850_reloc_err;
679 /* See if this is actually the
680 2nd half of a pair. */
682 && (p[-1]->howto->type
684 && (p[-1]->sym_ptr_ptr
685 == p[0]->sym_ptr_ptr)
686 && (p[-1]->addend == p[0]->addend))
687 break; /* not an error */
689 goto bad_v850_reloc_err;
693 printf("ERROR: reloc type %s unsupported in this context\n",
697 #endif /* TARGET_V850 */
700 /* The default is to assume that the
701 relocation is relative and has
702 already been fixed up by the
703 linker (perhaps we ought to make
704 give an error by default, and
705 require `safe' relocations to be
706 enumberated explicitly?). */
707 if (bfd_big_endian (abs_bfd))
719 relocation_needed = 1;
722 /* Calculate the sym address ourselves. */
723 sym_reloc_size = bfd_get_reloc_size(q->howto);
725 #if !defined(TARGET_h8300) && !defined(TARGET_e1) && !defined(TARGET_bfin) && !defined(TARGET_m68k)
726 if (sym_reloc_size != 4) {
727 printf("ERROR: bad reloc type %d size=%d for symbol=%s\n",
728 (*p)->howto->type, sym_reloc_size, sym_name);
735 switch ((*p)->howto->type) {
737 #if defined(TARGET_m68k)
739 relocation_needed = 1;
740 sym_vma = bfd_section_vma(abs_bfd, sym_section);
741 sym_addr += sym_vma + q->addend;
746 sym_addr += sym_vma + q->addend;
747 sym_addr -= q->address;
751 #if defined(TARGET_arm)
753 relocation_needed = 1;
756 "%s vma=0x%x, value=0x%x, address=0x%x "
757 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
759 sym_vma, (*(q->sym_ptr_ptr))->value,
760 q->address, sym_addr,
761 (*p)->howto->rightshift,
762 *(unsigned long *)r_mem);
763 sym_vma = bfd_section_vma(abs_bfd, sym_section);
764 sym_addr += sym_vma + q->addend;
768 /* Should be fine as is */
773 "%s vma=0x%x, value=0x%x, address=0x%x "
774 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
776 sym_vma, (*(q->sym_ptr_ptr))->value,
777 q->address, sym_addr,
778 (*p)->howto->rightshift,
779 *(unsigned long *)r_mem);
782 sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift;
788 relocation_needed = 1;
789 sym_vma = bfd_section_vma(abs_bfd, sym_section);
790 sym_addr += sym_vma + q->addend;
792 #if defined(R_V850_ZDA_16_16_OFFSET) || defined(R_V850_ZDA_16_16_SPLIT_OFFSET)
793 #ifdef R_V850_ZDA_16_16_OFFSET
794 case R_V850_ZDA_16_16_OFFSET:
796 #ifdef R_V850_ZDA_16_16_SPLIT_OFFSET
797 case R_V850_ZDA_16_16_SPLIT_OFFSET:
799 /* Can't support zero-relocations. */
800 printf ("ERROR: %s+0x%x: zero relocations not supported\n",
801 sym_name, q->addend);
803 #endif /* R_V850_ZDA_16_16_OFFSET || R_V850_ZDA_16_16_SPLIT_OFFSET */
804 #endif /* TARGET_v850 */
808 if (sym_reloc_size != 4) {
809 printf("R_H8_DIR24R8 size %d\n", sym_reloc_size);
813 relocation_needed = 1;
814 sym_addr = (*(q->sym_ptr_ptr))->value;
816 r_mem -= 1; /* tracks q->address */
817 sym_vma = bfd_section_vma(abs_bfd, sym_section);
818 sym_addr += sym_vma + q->addend;
819 sym_addr |= (*(unsigned char *)r_mem<<24);
822 if (sym_reloc_size != 4) {
823 printf("R_H8_DIR24A8 size %d\n", sym_reloc_size);
827 /* Absolute symbol done not relocation */
828 relocation_needed = !bfd_is_abs_section(sym_section);
829 sym_addr = (*(q->sym_ptr_ptr))->value;
830 sym_vma = bfd_section_vma(abs_bfd, sym_section);
831 sym_addr += sym_vma + q->addend;
834 case R_H8_DIR32A16: /* currently 32, could be made 16 */
835 if (sym_reloc_size != 4) {
836 printf("R_H8_DIR32 size %d\n", sym_reloc_size);
840 relocation_needed = 1;
841 sym_addr = (*(q->sym_ptr_ptr))->value;
842 sym_vma = bfd_section_vma(abs_bfd, sym_section);
843 sym_addr += sym_vma + q->addend;
847 sym_addr = (*(q->sym_ptr_ptr))->value;
848 sym_addr += sym_vma + q->addend;
849 sym_addr -= (q->address + 2);
850 if (bfd_big_endian(abs_bfd))
851 *(unsigned short *)r_mem =
852 bfd_big_endian(abs_bfd) ? htons(sym_addr) : sym_addr;
856 sym_addr = (*(q->sym_ptr_ptr))->value;
857 sym_addr += sym_vma + q->addend;
858 sym_addr -= (q->address + 1);
859 *(unsigned char *)r_mem = sym_addr;
863 #ifdef TARGET_microblaze
864 case R_MICROBLAZE_64:
865 /* The symbol is split over two consecutive instructions.
866 Flag this to the flat loader by setting the high bit of
867 the relocation symbol. */
869 unsigned char *p = r_mem;
870 unsigned long offset;
873 /* work out the relocation */
874 sym_vma = bfd_section_vma(abs_bfd, sym_section);
875 /* grab any offset from the text */
876 offset = (p[2]<<24) + (p[3] << 16) + (p[6] << 8) + (p[7]);
877 /* Update the address */
878 sym_addr += offset + sym_vma + q->addend;
879 /* Write relocated pointer back */
880 p[2] = (sym_addr >> 24) & 0xff;
881 p[3] = (sym_addr >> 16) & 0xff;
882 p[6] = (sym_addr >> 8) & 0xff;
883 p[7] = sym_addr & 0xff;
885 /* create a new reloc entry */
886 flat_relocs = realloc(flat_relocs,
887 (flat_reloc_count + 1) * sizeof(uint32_t));
888 flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address);
890 relocation_needed = 0;
892 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
893 bfd_section_vma(abs_bfd, sym_section));
895 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
896 "section=%s size=%d "
897 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
898 q->address, sym_name, addstr,
899 section_name, sym_reloc_size,
900 sym_addr, section_vma + q->address);
902 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
903 section_vma + q->address);
907 case R_MICROBLAZE_32:
909 unsigned char *p = r_mem;
910 unsigned long offset;
912 /* grab any offset from the text */
913 offset = (p[0]<<24) + (p[1] << 16) + (p[2] << 8) + (p[3]);
914 sym_vma = bfd_section_vma(abs_bfd, sym_section);
915 /* This is a horrible kludge. For some
916 reason, *sometimes* the offset is in
917 both addend and the code. Detect
918 it, and cancel the effect. Otherwise
919 the offset gets added twice - ouch.
920 There should be a better test
921 for this condition, based on the
922 BFD data structures */
923 if(offset==q->addend)
926 sym_addr += offset + sym_vma + q->addend;
927 relocation_needed = 1;
930 case R_MICROBLAZE_64_PCREL:
932 //sym_addr = (*(q->sym_ptr_ptr))->value;
933 sym_addr += sym_vma + q->addend;
934 sym_addr -= (q->address + 4);
935 sym_addr = htonl(sym_addr);
937 * ((unsigned short *) (r_mem+2)) |= (sym_addr) & 0xFFFF;
939 * ((unsigned short *) (r_mem+6)) |= (sym_addr >> 16) & 0xFFFF;
940 /* We've done all the work, so continue
941 to next reloc instead of break */
944 #endif /* TARGET_microblaze */
947 #define htoniosl(x) (x)
948 #define niostohl(x) (x)
949 switch ((*p)->howto->type)
951 case R_NIOS2_BFD_RELOC_32:
952 relocation_needed = 1;
953 pflags = (FLAT_NIOS2_R_32 << 28);
954 sym_vma = bfd_section_vma(abs_bfd, sym_section);
955 sym_addr += sym_vma + q->addend;
956 /* modify target, in target order */
957 *(unsigned long *)r_mem = htoniosl(sym_addr);
961 unsigned long exist_val;
962 relocation_needed = 1;
963 pflags = (FLAT_NIOS2_R_CALL26 << 28);
964 sym_vma = bfd_section_vma(abs_bfd, sym_section);
965 sym_addr += sym_vma + q->addend;
967 /* modify target, in target order */
968 // exist_val = niostohl(*(unsigned long *)r_mem);
969 exist_val = ((sym_addr >> 2) << 6);
970 *(unsigned long *)r_mem = htoniosl(exist_val);
973 case R_NIOS2_HIADJ16:
976 unsigned long exist_val;
978 /* handle the adjacent HI/LO pairs */
980 r2_type = R_NIOS2_NONE;
982 r2_type = p[1]->howto->type;
983 if ((r2_type == R_NIOS2_LO16)
984 && (p[0]->sym_ptr_ptr == p[1]->sym_ptr_ptr)
985 && (p[0]->addend == p[1]->addend))
987 unsigned char * r2_mem = sectionp + p[1]->address;
988 if (p[1]->address - q->address!=4)
989 printf("Err: HI/LO not adjacent %d\n", p[1]->address - q->address);
990 relocation_needed = 1;
991 pflags = (q->howto->type == R_NIOS2_HIADJ16)
992 ? FLAT_NIOS2_R_HIADJ_LO : FLAT_NIOS2_R_HI_LO;
995 sym_vma = bfd_section_vma(abs_bfd, sym_section);
996 sym_addr += sym_vma + q->addend;
998 /* modify high 16 bits, in target order */
999 exist_val = niostohl(*(unsigned long *)r_mem);
1000 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1001 if (q->howto->type == R_NIOS2_HIADJ16)
1002 exist_val |= ((((sym_addr >> 16) + ((sym_addr >> 15) & 1)) & 0xFFFF) << 6);
1004 exist_val |= (((sym_addr >> 16) & 0xFFFF) << 6);
1005 *(unsigned long *)r_mem = htoniosl(exist_val);
1007 /* modify low 16 bits, in target order */
1008 exist_val = niostohl(*(unsigned long *)r2_mem);
1009 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1010 exist_val |= ((sym_addr & 0xFFFF) << 6);
1011 *(unsigned long *)r2_mem = htoniosl(exist_val);
1014 goto NIOS2_RELOC_ERR;
1020 unsigned long exist_val, temp;
1021 //long gp = get_symbol_offset("_gp", sym_section, symbols, number_of_symbols);
1022 long gp = get_gp_value(symbols, number_of_symbols);
1024 printf("Err: unresolved symbol _gp when relocating %s\n", sym_name);
1025 goto NIOS2_RELOC_ERR;
1027 /* _gp holds a absolute value, otherwise the ld cannot generate correct code */
1028 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1029 //printf("sym=%x, %d, _gp=%x, %d\n", sym_addr+sym_vma, sym_addr+sym_vma, gp, gp);
1030 sym_addr += sym_vma + q->addend;
1032 //printf("sym - _gp=%x, %d\n", sym_addr, sym_addr);
1033 /* modify the target, in target order (little_endian) */
1034 exist_val = niostohl(*(unsigned long *)r_mem);
1035 temp = ((exist_val >> 6) & 0x3ff0000) | (sym_addr & 0xffff);
1037 temp |= (exist_val & 0x3f);
1038 *(unsigned long *)r_mem = htoniosl(temp);
1040 printf("omit: offset=0x%x symbol=%s%s "
1041 "section=%s size=%d "
1042 "fixup=0x%x (reloc=0x%x) GPREL\n",
1043 q->address, sym_name, addstr,
1044 section_name, sym_reloc_size,
1045 sym_addr, section_vma + q->address);
1048 case R_NIOS2_PCREL16:
1050 unsigned long exist_val;
1052 sym_addr += sym_vma + q->addend;
1053 sym_addr -= (q->address + 4);
1054 /* modify the target, in target order (little_endian) */
1055 exist_val = niostohl(*(unsigned long *)r_mem);
1056 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1057 exist_val |= ((sym_addr & 0xFFFF) << 6);
1058 *(unsigned long *)r_mem = htoniosl(exist_val);
1060 printf("omit: offset=0x%x symbol=%s%s "
1061 "section=%s size=%d "
1062 "fixup=0x%x (reloc=0x%x) PCREL\n",
1063 q->address, sym_name, addstr,
1064 section_name, sym_reloc_size,
1065 sym_addr, section_vma + q->address);
1070 /* check if this is actually the 2nd half of a pair */
1072 && ((p[-1]->howto->type == R_NIOS2_HIADJ16)
1073 || (p[-1]->howto->type == R_NIOS2_HI16))
1074 && (p[-1]->sym_ptr_ptr == p[0]->sym_ptr_ptr)
1075 && (p[-1]->addend == p[0]->addend)) {
1077 printf("omit: offset=0x%x symbol=%s%s "
1078 "section=%s size=%d LO16\n",
1079 q->address, sym_name, addstr,
1080 section_name, sym_reloc_size);
1084 /* error, fall through */
1088 case R_NIOS2_CACHE_OPX:
1092 case R_NIOS2_BFD_RELOC_16:
1093 case R_NIOS2_BFD_RELOC_8:
1094 case R_NIOS2_GNU_VTINHERIT:
1095 case R_NIOS2_GNU_VTENTRY:
1100 printf("Err: unexpected reloc type %s(%d)\n", q->howto->name, q->howto->type);
1104 #endif /* TARGET_nios2 */
1109 relocation_needed = 1;
1110 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1111 sym_addr += sym_vma + q->addend;
1115 sym_addr += sym_vma + q->addend;
1116 sym_addr -= q->address;
1118 case R_SPARC_WDISP30:
1119 sym_addr = (((*(q->sym_ptr_ptr))->value-
1120 q->address) >> 2) & 0x3fffffff;
1122 ntohl(*(unsigned long *)r_mem)
1127 relocation_needed = 1;
1128 pflags = 0x80000000;
1129 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1130 sym_addr += sym_vma + q->addend;
1132 htonl(*(unsigned long *)r_mem)
1137 relocation_needed = 1;
1138 pflags = 0x40000000;
1139 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1140 sym_addr += sym_vma + q->addend;
1141 sym_addr &= 0x000003ff;
1143 htonl(*(unsigned long *)r_mem)
1147 #endif /* TARGET_sparc */
1150 case R_pcrel12_jump:
1151 case R_pcrel12_jump_s:
1153 case R_pcrel24_jump_l:
1154 case R_pcrel24_jump_x:
1155 case R_pcrel24_call_x:
1159 sym_addr += q->addend;// get the symbol addr
1160 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1161 sym_addr -= q->address; // make it PC relative
1162 // implicitly assumes code section and symbol section are same
1169 sym_addr += q->addend;
1170 if(weak_und_symbol(sym_section->name, (*(q->sym_ptr_ptr))))
1172 if(0xFFFF0000 & sym_addr){
1173 fprintf (stderr, "Relocation overflow for rN = %s\n",sym_name);
1176 flat_relocs = (uint32_t *)
1177 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1178 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1179 sym_section->name, sym_name,
1180 (*(q->sym_ptr_ptr)),
1181 0, FLAT_RELOC_PART_LO,
1182 section_vma + q->address))
1191 unsigned int reloc_count_incr;
1194 if (q->howto->type == R_luimm16)
1195 hi_lo = FLAT_RELOC_PART_LO;
1197 hi_lo = FLAT_RELOC_PART_HI;
1199 sym_addr += q->addend;
1201 flat_relocs = (uint32_t *)
1202 (realloc (flat_relocs, (flat_reloc_count + 2) * sizeof (uint32_t)));
1203 reloc_count_incr = 1;
1204 if (weak_und_symbol (sym_section->name, (*(q->sym_ptr_ptr))))
1206 if (0xFFFF0000 & sym_addr) {
1207 /* value is > 16 bits - use an extra field */
1208 /* see if we have already output that symbol */
1209 /* reloc may be addend from symbol and */
1210 /* we can only store 16 bit offsets */
1212 if ((*(q->sym_ptr_ptr))->udata.i == 0
1213 || flat_relocs[(*(q->sym_ptr_ptr))->udata.i] != sym_addr
1214 || ((*(q->sym_ptr_ptr))->udata.i & 0xFFFF0000))
1216 reloc_count_incr = 2;
1217 flat_relocs[flat_reloc_count + 1] = sym_addr;
1218 (*(q->sym_ptr_ptr))->udata.i = flat_reloc_count + 1;
1219 sym_addr = 0; // indication to loader to read next
1221 sym_addr = (*(q->sym_ptr_ptr))->udata.i;
1227 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1228 sym_section->name, sym_name,
1229 (*(q->sym_ptr_ptr)),
1231 section_vma + q->address))
1233 flat_reloc_count += reloc_count_incr;
1237 sym_addr += q->addend;
1239 if (weak_und_symbol (sym_section->name, *q->sym_ptr_ptr))
1242 flat_relocs = (uint32_t *)
1243 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1244 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1245 sym_section->name, sym_name,
1246 (*(q->sym_ptr_ptr)),
1247 2, FLAT_RELOC_PART_LO,
1248 section_vma + q->address))
1254 #endif //TARGET_bfin
1258 relocation_needed = 1;
1259 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1260 sym_addr += sym_vma + q->addend;
1264 sym_addr += sym_vma + q->addend;
1265 sym_addr -= q->address;
1267 #endif /* TARGET_sh */
1270 #define htoe1l(x) htonl(x)
1277 #define DBG_E1 printf
1279 #define DBG_E1(x, ... )
1282 #define _32BITS_RELOC 0x00000000
1283 #define _30BITS_RELOC 0x80000000
1284 #define _28BITS_RELOC 0x40000000
1287 unsigned long sec_vma, exist_val, S;
1289 relocation_needed = 1;
1290 DBG_E1("Handling Reloc <CONST31>\n");
1291 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1292 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1293 sec_vma, sym_addr, q->address);
1294 sym_addr = sec_vma + sym_addr;
1295 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1296 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1297 exist_val = htoe1l(exist_val);
1298 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1299 sym_addr += exist_val;
1300 pflags = _30BITS_RELOC;
1302 case R_E1_CONST31_PCREL:
1303 relocation_needed = 0;
1304 DBG_E1("Handling Reloc <CONST31_PCREL>\n");
1305 DBG_E1("DONT RELOCATE AT LOADING\n");
1306 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1307 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1308 sec_vma, sym_addr, q->address);
1309 sym_addr = sec_vma + sym_addr;
1310 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1312 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1314 q->address = q->address + section_vma;
1315 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1317 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1318 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1319 DBG_E1( "sym_addr := sym_addr - q->address - "
1320 "sizeof(CONST31_PCREL): [0x%x]\n",
1322 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1323 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1324 exist_val = htoe1l(exist_val);
1325 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1326 sym_addr |= exist_val;
1327 DBG_E1("sym_addr |= exist_val) : [0x%x]\n", sym_addr );
1329 case R_E1_DIS29W_PCREL:
1330 relocation_needed = 0;
1331 DBG_E1("Handling Reloc <DIS29W_PCREL>\n");
1332 DBG_E1("DONT RELOCATE AT LOADING\n");
1333 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1334 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1335 sec_vma, sym_addr, q->address);
1336 sym_addr = sec_vma + sym_addr;
1337 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1339 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1341 q->address = q->address + section_vma;
1342 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1344 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1345 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1346 DBG_E1( "sym_addr := sym_addr - q->address - "
1347 "sizeof(CONST31_PCREL): [0x%x]\n",
1349 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1350 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1351 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1352 exist_val = htoe1l(exist_val);
1353 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1354 sym_addr += exist_val;
1357 DBG_E1("Handling Reloc <DIS29W>\n");
1358 goto DIS29_RELOCATION;
1360 DBG_E1("Handling Reloc <DIS29H>\n");
1361 goto DIS29_RELOCATION;
1363 DBG_E1("Handling Reloc <DIS29B>\n");
1365 relocation_needed = 1;
1366 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1367 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%08x]\n",
1369 sym_addr = sec_vma + sym_addr;
1370 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%08x]\n", sym_addr);
1371 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1372 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1373 exist_val = htoe1l(exist_val);
1374 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1375 sym_addr += exist_val;
1376 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1377 pflags = _28BITS_RELOC;
1379 case R_E1_IMM32_PCREL:
1380 relocation_needed = 0;
1381 DBG_E1("Handling Reloc <IMM32_PCREL>\n");
1382 DBG_E1("DONT RELOCATE AT LOADING\n");
1383 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1384 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1386 sym_addr = sec_vma + sym_addr;
1388 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1389 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1391 q->address = q->address + section_vma;
1392 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1394 if( (sym_addr = (sym_addr - q->address - 6 )) < 0 )
1395 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1396 DBG_E1( "sym_addr := sym_addr - q->address - "
1397 "sizeof(CONST31_PCREL): [0x%x]\n",
1399 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1400 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1401 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1402 exist_val = htoe1l(exist_val);
1403 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1404 sym_addr += exist_val;
1407 relocation_needed = 1;
1408 DBG_E1("Handling Reloc <IMM32>\n");
1409 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1410 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1412 sym_addr = sec_vma + sym_addr;
1413 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1414 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1415 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1416 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1417 exist_val = htoe1l(exist_val);
1418 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1419 sym_addr += exist_val;
1420 pflags = _32BITS_RELOC;
1423 relocation_needed = 1;
1424 DBG_E1("Handling Reloc <WORD>\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 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address );
1431 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1432 exist_val = htoe1l(exist_val);
1433 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1434 sym_addr += exist_val;
1435 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1436 pflags = _32BITS_RELOC;
1439 #undef _32BITS_RELOC
1440 #undef _30BITS_RELOC
1441 #undef _28BITS_RELOC
1444 /* missing support for other types of relocs */
1445 printf("ERROR: bad reloc type %d\n", (*p)->howto->type);
1451 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
1452 bfd_section_vma(abs_bfd, sym_section));
1456 * for full elf relocation we have to write back the
1457 * start_code relative value to use.
1459 if (!pic_with_got) {
1460 #if defined(TARGET_arm)
1469 * horrible nasty hack to support different endianess
1471 if (!bfd_big_endian(abs_bfd)) {
1483 tmp.l = *(unsigned long *)r_mem;
1484 hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16);
1485 if (((*p)->howto->type != R_ARM_PC24) &&
1486 ((*p)->howto->type != R_ARM_PLT32))
1487 hl |= (tmp.c[i3] << 24);
1488 else if (tmp.c[i2] & 0x80)
1489 hl |= 0xff000000; /* sign extend */
1491 tmp.c[i0] = hl & 0xff;
1492 tmp.c[i1] = (hl >> 8) & 0xff;
1493 tmp.c[i2] = (hl >> 16) & 0xff;
1494 if (((*p)->howto->type != R_ARM_PC24) &&
1495 ((*p)->howto->type != R_ARM_PLT32))
1496 tmp.c[i3] = (hl >> 24) & 0xff;
1497 if ((*p)->howto->type == R_ARM_ABS32)
1498 *(unsigned long *)r_mem = htonl(hl);
1500 *(unsigned long *)r_mem = tmp.l;
1502 #elif defined(TARGET_bfin)
1503 if ((*p)->howto->type == R_pcrel24
1504 || (*p)->howto->type == R_pcrel24_jump_l
1505 || (*p)->howto->type == R_pcrel24_jump_x
1506 || (*p)->howto->type == R_pcrel24_call_x)
1508 sym_addr += 2*-1*PCREL24_MAGIC_OFFSET;
1509 *((unsigned short *)(sectionp + q->address) + 1 + PCREL24_MAGIC_OFFSET)
1510 = (sym_addr >> 1) & 0xffff;
1511 *((unsigned short *)(sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1512 = (0xff00 & *((unsigned short *) (sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1513 | ((sym_addr >> 17) & 0xff));
1514 } else if ((*p)->howto->type == R_byte4_data) {
1515 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1516 } else if ((*p)->howto->type == R_pcrel12_jump
1517 || (*p)->howto->type == R_pcrel12_jump_s) {
1518 *((unsigned short *)(sectionp + q->address))
1519 = (0xf000 & *((unsigned short *)(sectionp + q->address))
1520 | ((sym_addr >> 1) & 0xfff));
1521 } else if ((*p)->howto->type == R_pcrel10) {
1522 *((unsigned short *)(sectionp + q->address))
1523 = (~0x3ff & *((unsigned short *)(sectionp + q->address))
1524 | ((sym_addr >> 1) & 0x3ff));
1525 } else if ((*p)->howto->type == R_rimm16
1526 || (*p)->howto->type == R_huimm16
1527 || (*p)->howto->type == R_luimm16) {
1528 /* for l and h we set the lower 16 bits which is only when it will be used */
1529 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1530 } else if ((*p)->howto->type == R_pcrel5m2) {
1531 *((unsigned short *)(sectionp + q->address))
1532 = (0xfff0 & *((unsigned short *)(sectionp + q->address))
1533 | ((sym_addr >> 1) & 0xf));
1534 } else if ((*p)->howto->type == R_pcrel11){
1535 *((unsigned short *)(sectionp + q->address))
1536 = (0xfc00 & *((unsigned short *)(sectionp + q->address))
1537 | ((sym_addr >> 1) & 0x3ff));
1538 } else if (0xE0 <= (*p)->howto->type && 0xF3 >= (*p)->howto->type) {
1539 //arith relocs dont generate a real relocation
1541 printf("Blackfin relocation fail for reloc type: 0x%x\n", (*p)->howto->type);
1543 #elif defined(TARGET_e1)
1544 #define OPCODE_SIZE 2 /* Add 2 bytes, counting the opcode size*/
1545 switch ((*p)->howto->type) {
1547 case R_E1_CONST31_PCREL:
1548 case R_E1_DIS29W_PCREL:
1552 case R_E1_IMM32_PCREL:
1554 DBG_E1("In addr + 2:[0x%x] <- write [0x%x]\n",
1555 (sectionp + q->address + 2), sym_addr );
1556 *((unsigned long *) (sectionp + q->address + OPCODE_SIZE)) =
1560 DBG_E1("In addr : [0x%x] <- write [0x%x]\n",
1561 (sectionp + q->address), sym_addr );
1562 *((unsigned long *) (sectionp + q->address )) = htonl(sym_addr);
1565 printf("ERROR:Unhandled Relocation. Exiting...\n");
1569 #else /* ! TARGET_arm && ! TARGET_e1 */
1571 switch (q->howto->type) {
1576 /* Do nothing -- for cases we handle,
1577 the bits produced by the linker are
1578 what we want in the final flat file
1579 (and other cases are errors). Note
1580 that unlike most relocated values,
1581 it is stored in little-endian order,
1582 but this is necessary to avoid
1583 trashing the low-bit, and the float
1584 loaders knows about it. */
1586 #endif /* TARGET_V850 */
1589 case R_NIOS2_BFD_RELOC_32:
1590 case R_NIOS2_CALL26:
1591 case R_NIOS2_HIADJ16:
1595 #endif /* TARGET_nios2 */
1597 #if defined(TARGET_m68k)
1599 if (sym_addr < -0x8000 || sym_addr > 0x7fff) {
1600 fprintf (stderr, "Relocation overflow for R_68K_PC16 relocation against %s\n", sym_name);
1603 r_mem[0] = (sym_addr >> 8) & 0xff;
1604 r_mem[1] = sym_addr & 0xff;
1610 /* The alignment of the build host
1611 might be stricter than that of the
1612 target, so be careful. We store in
1613 network byte order. */
1614 r_mem[0] = (sym_addr >> 24) & 0xff;
1615 r_mem[1] = (sym_addr >> 16) & 0xff;
1616 r_mem[2] = (sym_addr >> 8) & 0xff;
1617 r_mem[3] = sym_addr & 0xff;
1619 #endif /* !TARGET_arm */
1624 if ((*p)->howto->type == R_rimm16
1625 || (*p)->howto->type == R_huimm16
1626 || (*p)->howto->type == R_luimm16)
1628 /* for l and h we set the lower 16 bits which is only when it will be used */
1629 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1630 } else if ((*p)->howto->type == R_byte4_data) {
1631 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1636 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
1637 "section=%s size=%d "
1638 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
1639 q->address, sym_name, addstr,
1640 section_name, sym_reloc_size,
1641 sym_addr, section_vma + q->address);
1644 * Create relocation entry (PC relative doesn't need this).
1646 if (relocation_needed) {
1648 flat_relocs = realloc(flat_relocs,
1649 (flat_reloc_count + 1) * sizeof(uint32_t));
1651 flat_relocs[flat_reloc_count] = pflags |
1652 (section_vma + q->address);
1655 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
1656 section_vma + q->address);
1658 switch ((*p)->howto->type) {
1660 case R_E1_CONST31_PCREL:
1661 case R_E1_DIS29W_PCREL:
1665 case R_E1_IMM32_PCREL:
1667 flat_relocs[flat_reloc_count] = pflags |
1668 (section_vma + q->address + OPCODE_SIZE);
1670 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1671 flat_relocs[flat_reloc_count] );
1674 flat_relocs[flat_reloc_count] = pflags |
1675 (section_vma + q->address);
1677 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1678 flat_relocs[flat_reloc_count] );
1684 relocation_needed = 0;
1689 printf("%s(%d): symbol name=%s address=0x%x section=%s -> RELOC=0x%x\n",
1690 __FILE__, __LINE__, sym_name, q->address, section_name,
1691 flat_relocs[flat_reloc_count]);
1698 printf("%d bad relocs\n", bad_relocs);
1705 *n_relocs = flat_reloc_count;
1711 static char * program;
1713 static void usage(void)
1715 fprintf(stderr, "Usage: %s [vrzd] [-p <abs-pic-file>] [-s stack-size] "
1716 "[-o <output-file>] <elf-file>\n\n"
1717 " -v : verbose operation\n"
1718 " -r : force load to RAM\n"
1719 " -k : enable kernel trace on load (for debug)\n"
1720 " -z : compress code/data/relocs\n"
1721 " -d : compress data/relocs\n"
1722 " -a : use existing symbol references\n"
1723 " instead of recalculating from\n"
1724 " relocation info\n"
1725 " -R reloc-file : read relocations from a separate file\n"
1726 " -p abs-pic-file : GOT/PIC processing with files\n"
1727 " -s stacksize : set application stack size\n"
1728 " -o output-file : output file name\n\n",
1730 fprintf(stderr, "Compiled for " ARCH " architecture\n\n");
1735 /* Write NUM zeroes to STREAM. */
1736 static void write_zeroes (unsigned long num, FILE *stream)
1740 /* It'd be nice if we could just use fseek, but that doesn't seem to
1741 work for stdio output files. */
1742 bzero(zeroes, 1024);
1743 while (num > sizeof(zeroes)) {
1744 fwrite(zeroes, sizeof(zeroes), 1, stream);
1745 num -= sizeof(zeroes);
1748 fwrite(zeroes, num, 1, stream);
1753 int main(int argc, char *argv[])
1756 bfd *rel_bfd, *abs_bfd;
1758 char *ofile=NULL, *pfile=NULL, *abs_file = NULL, *rel_file = NULL;
1766 asymbol **symbol_table;
1767 long number_of_symbols;
1769 unsigned long data_len = 0;
1770 unsigned long bss_len = 0;
1771 unsigned long text_len = 0;
1772 unsigned long reloc_len;
1774 unsigned long data_vma = ~0;
1775 unsigned long bss_vma = ~0;
1776 unsigned long text_vma = ~0;
1778 unsigned long text_offs;
1784 struct flat_hdr hdr;
1794 if (sizeof(hdr) != 64) {
1796 "Potential flat header incompatibility detected\n"
1797 "header size should be 64 but is %d\n",
1804 #else /* We need plenty of stack for both of them (Aggregate and Register) */
1808 while ((opt = getopt(argc, argv, "avzdrkp:s:o:R:")) != -1) {
1835 stack = atoi(optarg);
1841 fprintf(stderr, "%s Unknown option\n", argv[0]);
1848 * if neither the -r or -p options was given, default to
1849 * a RAM load as that is the only option that makes sense.
1851 if (!load_to_ram && !pfile)
1854 filename = fname = argv[argc-1];
1865 if (!(rel_bfd = bfd_openr(rel_file, 0))) {
1866 fprintf(stderr, "Can't open %s\n", rel_file);
1870 if (bfd_check_format (rel_bfd, bfd_object) == 0) {
1871 fprintf(stderr, "File is not an object file\n");
1875 if (abs_file == rel_file)
1876 abs_bfd = rel_bfd; /* one file does all */
1878 if (!(abs_bfd = bfd_openr(abs_file, 0))) {
1879 fprintf(stderr, "Can't open %s\n", abs_file);
1883 if (bfd_check_format (abs_bfd, bfd_object) == 0) {
1884 fprintf(stderr, "File is not an object file\n");
1889 if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC)) {
1890 fprintf (stderr, "%s: Input file contains no relocation info\n", rel_file);
1894 if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P)) {
1895 /* `Absolute' file is not absolute, so neither are address
1896 contained therein. */
1898 "%s: `-a' option specified with non-fully-resolved input file\n",
1899 bfd_get_filename (abs_bfd));
1903 symbol_table = get_symbols(abs_bfd, &number_of_symbols);
1905 /* Group output sections into text, data, and bss, and calc their sizes. */
1906 for (s = abs_bfd->sections; s != NULL; s = s->next) {
1907 unsigned long *vma, *len;
1908 bfd_size_type sec_size;
1911 if (s->flags & SEC_CODE) {
1914 } else if (s->flags & SEC_DATA) {
1917 } else if (s->flags & SEC_ALLOC) {
1923 sec_size = bfd_section_size(abs_bfd, s);
1924 sec_vma = bfd_section_vma(abs_bfd, s);
1926 if (sec_vma < *vma) {
1928 *len += sec_vma - *vma;
1932 } else if (sec_vma + sec_size > *vma + *len)
1933 *len = sec_vma + sec_size - *vma;
1936 if (text_len == 0) {
1937 fprintf (stderr, "%s: no .text section", abs_file);
1941 text = malloc(text_len);
1944 printf("TEXT -> vma=0x%x len=0x%x\n", text_vma, text_len);
1946 /* Read in all text sections. */
1947 for (s = abs_bfd->sections; s != NULL; s = s->next)
1948 if (s->flags & SEC_CODE)
1949 if (!bfd_get_section_contents(abs_bfd, s,
1950 text + (s->vma - text_vma), 0,
1951 bfd_section_size(abs_bfd, s)))
1953 fprintf(stderr, "read error section %s\n", s->name);
1957 if (data_len == 0) {
1958 fprintf (stderr, "%s: no .data section", abs_file);
1961 data = malloc(data_len);
1964 printf("DATA -> vma=0x%x len=0x%x\n", data_vma, data_len);
1966 if ((text_vma + text_len) != data_vma) {
1967 if ((text_vma + text_len) > data_vma) {
1968 printf("ERROR: text=0x%x overlaps data=0x%x ?\n", text_len, data_vma);
1972 printf("WARNING: data=0x%x does not directly follow text=0x%x\n",
1973 data_vma, text_len);
1974 text_len = data_vma - text_vma;
1977 /* Read in all data sections. */
1978 for (s = abs_bfd->sections; s != NULL; s = s->next)
1979 if (s->flags & SEC_DATA)
1980 if (!bfd_get_section_contents(abs_bfd, s,
1981 data + (s->vma - data_vma), 0,
1982 bfd_section_size(abs_bfd, s)))
1984 fprintf(stderr, "read error section %s\n", s->name);
1988 /* Put common symbols in bss. */
1989 bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len);
1992 printf("BSS -> vma=0x%x len=0x%x\n", bss_vma, bss_len);
1994 if ((data_vma + data_len) != bss_vma) {
1995 if ((data_vma + data_len) > bss_vma) {
1996 printf("ERROR: text=0x%x + data=0x%x overlaps bss=0x%x ?\n", text_len,
2001 printf("WARNING: bss=0x%x does not directly follow text=0x%x + data=0x%x(0x%x)\n",
2002 bss_vma, text_len, data_len, text_len + data_len);
2003 data_len = bss_vma - data_vma;
2006 reloc = output_relocs(abs_bfd, symbol_table, number_of_symbols, &reloc_len,
2007 text, text_len, text_vma, data, data_len, data_vma,
2011 printf("No relocations in code!\n");
2013 text_offs = real_address_bits(text_vma);
2015 /* Fill in the binflt_flat header */
2016 memcpy(hdr.magic,"bFLT",4);
2017 hdr.rev = htonl(FLAT_VERSION);
2018 hdr.entry = htonl(sizeof(hdr) + bfd_get_start_address(abs_bfd));
2019 hdr.data_start = htonl(sizeof(hdr) + text_offs + text_len);
2020 hdr.data_end = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2021 hdr.bss_end = htonl(sizeof(hdr) + text_offs + text_len +data_len+bss_len);
2022 hdr.stack_size = htonl(stack); /* FIXME */
2023 hdr.reloc_start = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2024 hdr.reloc_count = htonl(reloc_len);
2026 | (load_to_ram ? FLAT_FLAG_RAM : 0)
2027 | (ktrace ? FLAT_FLAG_KTRACE : 0)
2028 | (pic_with_got ? FLAT_FLAG_GOTPIC : 0)
2029 | (compress ? (compress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
2031 hdr.build_date = htonl((unsigned long)time(NULL));
2032 bzero(hdr.filler, sizeof(hdr.filler));
2034 for (i=0; i<reloc_len; i++) reloc[i] = htonl(reloc[i]);
2037 printf("SIZE: .text=0x%04x, .data=0x%04x, .bss=0x%04x",
2038 text_len, data_len, bss_len);
2040 printf(", relocs=0x%04x", reloc_len);
2045 ofile = malloc(strlen(fname) + 5 + 1); /* 5 to add suffix */
2046 strcpy(ofile, fname);
2047 strcat(ofile, ".bflt");
2050 if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0) {
2051 fprintf (stderr, "Can't open output file %s\n", ofile);
2055 write(fd, &hdr, sizeof(hdr));
2059 * get the compression command ready
2061 sprintf(cmd, "gzip -f -9 >> %s", ofile);
2063 #define START_COMPRESSOR do { \
2069 if (!(gf = popen(cmd, "w" BINARY_FILE_OPTS))) { \
2070 fprintf(stderr, "Can't run cmd %s\n", cmd); \
2076 gf = fopen(ofile, "ab"); /* Add 'b' to support non-posix (ie windows) */
2078 fprintf(stderr, "Can't open file %s for writing\n", ofile); \
2085 /* Fill in any hole at the beginning of the text segment. */
2087 printf("ZERO before text len=0x%x\n", text_offs);
2088 write_zeroes(text_offs, gf);
2090 /* Write the text segment. */
2091 fwrite(text, text_len, 1, gf);
2096 /* Write the data segment. */
2097 fwrite(data, data_len, 1, gf);
2100 fwrite(reloc, reloc_len * 4, 1, gf);
2112 * this __MUST__ be at the VERY end of the file - do NOT move!!
2118 * vi: tabstop=8 shiftwidth=4 textwidth=79 noexpandtab