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 */
57 #include <libiberty.h>
59 #if defined(TARGET_h8300)
60 #include <elf/h8.h> /* TARGET_* ELF support for the BFD library */
61 #elif defined(__CYGWIN__) || defined(__MINGW32__) || defined(TARGET_nios) || defined(TARGET_nios2)
62 #include "cygwin-elf.h" /* Cygwin uses a local copy */
63 #elif defined(TARGET_microblaze)
64 #include <elf/microblaze.h> /* TARGET_* ELF support for the BFD library */
65 #elif defined(TARGET_bfin)
68 #include <elf.h> /* TARGET_* ELF support for the BFD library */
71 #if defined(__MINGW32__)
75 /* from uClinux-x.x.x/include/linux */
76 #include "flat.h" /* Binary flat header description */
87 #if defined(TARGET_m68k)
88 #define ARCH "m68k/coldfire"
89 #elif defined(TARGET_arm)
91 #elif defined(TARGET_sparc)
93 #elif defined(TARGET_v850)
95 #elif defined(TARGET_sh)
97 #elif defined(TARGET_h8300)
99 #elif defined(TARGET_microblaze)
100 #define ARCH "microblaze"
101 #elif defined(TARGET_e1)
102 #define ARCH "e1-coff"
103 #elif defined(TARGET_bfin)
105 #define FLAT_RELOC_TYPE_TEXT 0
106 #define FLAT_RELOC_TYPE_DATA 1
107 #define FLAT_RELOC_TYPE_BSS 2
108 #define FLAT_RELOC_TYPE_STACK 3
109 #define FLAT_RELOC_PART_LO 0
110 #define FLAT_RELOC_PART_HI 1
111 #define PCREL24_MAGIC_OFFSET -1
112 #elif defined(TARGET_nios)
114 #elif defined(TARGET_nios2)
117 #error "Don't know how to support your CPU architecture??"
120 #if defined(TARGET_m68k) || defined(TARGET_h8300) || defined(TARGET_bfin)
122 * Define a maximum number of bytes allowed in the offset table.
123 * We'll fail if the table is larger than this.
125 * This limit may be different for platforms other than m68k, but
126 * 8000 entries is a lot, trust me :-) (davidm)
128 #define GOT_LIMIT 32767
130 * we have to mask out the shared library id here and there, this gives
131 * us the real address bits when needed
133 #define real_address_bits(x) (pic_with_got ? ((x) & 0xffffff) : (x))
135 #define real_address_bits(x) (x)
143 int verbose = 0; /* extra output when running */
144 int pic_with_got = 0; /* do elf/got processing with PIC code */
145 int load_to_ram = 0; /* instruct loader to allocate everything into RAM */
146 int ktrace = 0; /* instruct loader output kernel trace on load */
147 int docompress = 0; /* 1 = compress everything, 2 = compress data only */
148 int use_resolved = 0; /* If true, get the value of symbol references from */
149 /* the program contents, not from the relocation table. */
150 /* In this case, the input ELF file must be already */
151 /* fully resolved (using the `-q' flag with recent */
152 /* versions of GNU ld will give you a fully resolved */
153 /* output file with relocation entries). */
155 const char *progname, *filename;
161 static char where[200];
164 /* Use exactly one of these: */
165 E_NOFILE = 0, /* "progname: " */
166 E_FILE = 1, /* "filename: " */
167 E_FILELINE = 2, /* "filename:lineno: " */
168 E_FILEWHERE = 3, /* "filename:%s: " -- set %s with ewhere() */
170 /* Add in any of these with |': */
175 void ewhere (const char *format, ...);
176 void einfo (int type, const char *format, ...);
180 ewhere (const char *format, ...) {
182 va_start (args, format);
183 vsprintf (where, format, args);
189 einfo (int type, const char *format, ...) {
192 switch (type & 0x0f) {
194 fprintf (stderr, "%s: ", progname);
197 fprintf (stderr, "%s: ", filename);
200 ewhere ("%d", lineno);
203 fprintf (stderr, "%s:%s: ", filename, where);
207 if (type & E_WARNING) {
208 fprintf (stderr, "warning: ");
214 va_start (args, format);
215 vfprintf (stderr, format, args);
221 fprintf (stderr, "\n");
226 get_symbols (bfd *abfd, long *num)
228 int32_t storage_needed;
229 asymbol **symbol_table;
230 long number_of_symbols;
232 storage_needed = bfd_get_symtab_upper_bound (abfd);
234 if (storage_needed < 0)
237 if (storage_needed == 0)
240 symbol_table = xmalloc (storage_needed);
242 number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
244 if (number_of_symbols < 0)
247 *num = number_of_symbols;
254 dump_symbols(asymbol **symbol_table, long number_of_symbols)
257 printf("SYMBOL TABLE:\n");
258 for (i=0; i<number_of_symbols; i++) {
259 printf(" NAME=%s VALUE=0x%x\n", symbol_table[i]->name,
260 symbol_table[i]->value);
269 get_symbol_offset(char *name, asection *sec, asymbol **symbol_table, long number_of_symbols)
272 for (i=0; i<number_of_symbols; i++) {
273 if (symbol_table[i]->section == sec) {
274 if (!strcmp(symbol_table[i]->name, name)) {
275 return symbol_table[i]->value;
286 get_gp_value(asymbol **symbol_table, long number_of_symbols)
289 for (i=0; i<number_of_symbols; i++) {
290 if (!strcmp(symbol_table[i]->name, "_gp"))
291 return symbol_table[i]->value;
300 add_com_to_bss(asymbol **symbol_table, int32_t number_of_symbols, int32_t bss_len)
306 for (i=0; i<number_of_symbols; i++) {
307 if (strcmp("*COM*", symbol_table[i]->section->name) == 0) {
308 offset = bss_len + comsize;
309 comsize += symbol_table[i]->value;
310 symbol_table[i]->value = offset;
317 /* FUNCTION : weak_und_symbol
318 ABSTRACT : return true if symbol is weak and undefined.
321 weak_und_symbol(const char *reloc_section_name,
322 struct bfd_symbol *symbol)
324 if (!(strstr (reloc_section_name, "text")
325 || strstr (reloc_section_name, "data")
326 || strstr (reloc_section_name, "bss"))) {
327 if (symbol->flags & BSF_WEAK) {
329 fprintf(stderr, "found weak undefined symbol %s\n", symbol->name);
338 bfin_set_reloc (uint32_t *reloc,
339 const char *reloc_section_name,
340 const char *sym_name,
341 struct bfd_symbol *symbol,
342 int sp, int hilo, int32_t offset)
347 if (strstr (reloc_section_name, "text"))
348 type = FLAT_RELOC_TYPE_TEXT;
349 else if (strstr (reloc_section_name, "data"))
350 type = FLAT_RELOC_TYPE_DATA;
351 else if (strstr (reloc_section_name, "bss"))
352 type = FLAT_RELOC_TYPE_BSS;
353 else if (strstr (reloc_section_name, "stack"))
354 type = FLAT_RELOC_TYPE_STACK;
355 else if (symbol->flags & BSF_WEAK){
356 /* weak symbol support ... if a weak symbol is undefined at the
357 end of a final link, it should return 0 rather than error
358 We will assume text section for the moment.
360 type = FLAT_RELOC_TYPE_TEXT;
361 } else if (strstr (reloc_section_name, "*ABS*")){
362 /* (A data section initialization of something in the shared libc's text section
363 does not resolve - i.e. a global pointer to function initialized with
365 The text section here is appropriate as the section information
366 of the shared library is lost. The loader will do some calcs.
368 type = FLAT_RELOC_TYPE_TEXT;
370 printf ("Unknown Type - relocation for %s in bad section - %s\n", sym_name, reloc_section_name);
374 val = (offset & ((1 << 26) - 1)) << 6;
375 val |= (sp & (1 << 3) - 1) << 3;
376 val |= (hilo & 1) << 2;
377 val |= (type & (1 << 2) - 1);
388 int number_of_symbols,
390 unsigned char *text, int text_len, uint32_t text_vma,
391 unsigned char *data, int data_len, uint32_t data_vma,
394 uint32_t *flat_relocs;
395 asection *a, *sym_section, *r;
396 arelent **relpp, **p, *q;
397 const char *sym_name, *section_name;
398 unsigned char *sectionp;
399 unsigned long pflags;
401 uint32_t sym_addr, sym_vma, section_vma;
402 int relsize, relcount;
403 int flat_reloc_count;
404 int sym_reloc_size, rc;
411 printf("%s(%d): output_relocs(abs_bfd=%d,synbols=0x%x,number_of_symbols=%d"
412 "n_relocs=0x%x,text=0x%x,text_len=%d,data=0x%x,data_len=%d)\n",
413 __FILE__, __LINE__, abs_bfd, symbols, number_of_symbols, n_relocs,
414 text, text_len, data, data_len);
418 dump_symbols(symbols, number_of_symbols);
423 flat_reloc_count = 0;
427 /* Determine how big our offset table is in bytes.
428 * This isn't too difficult as we've terminated the table with -1.
429 * Also note that both the relocatable and absolute versions have this
430 * terminator even though the relocatable one doesn't have the GOT!
432 if (pic_with_got && !use_resolved) {
433 uint32_t *lp = (uint32_t *)data;
434 /* Should call ntohl(*lp) here but is isn't going to matter */
435 while (*lp != 0xffffffff) lp++;
436 got_size = ((unsigned char *)lp) - data;
438 printf("GOT table contains %d entries (%d bytes)\n",
439 got_size/sizeof(uint32_t), got_size);
441 if (got_size > GOT_LIMIT) {
442 fprintf(stderr, "GOT too large: %d bytes (limit = %d bytes)\n",
443 got_size, GOT_LIMIT);
449 for (a = abs_bfd->sections; (a != (asection *) NULL); a = a->next) {
450 section_vma = bfd_section_vma(abs_bfd, a);
453 printf("SECTION: %s [0x%x]: flags=0x%x vma=0x%x\n", a->name, a,
454 a->flags, section_vma);
456 // if (bfd_is_abs_section(a))
458 if (bfd_is_und_section(a))
460 if (bfd_is_com_section(a))
462 // if ((a->flags & SEC_RELOC) == 0)
466 * Only relocate things in the data sections if we are PIC/GOT.
467 * otherwise do text as well
469 if (!pic_with_got && (a->flags & SEC_CODE))
470 sectionp = text + (a->vma - text_vma);
471 else if (a->flags & SEC_DATA)
472 sectionp = data + (a->vma - data_vma);
476 /* Now search for the equivalent section in the relocation binary
477 * and use that relocation information to build reloc entries
480 for (r=rel_bfd->sections; r != NULL; r=r->next)
481 if (strcmp(a->name, r->name) == 0)
486 printf(" RELOCS: %s [0x%x]: flags=0x%x vma=0x%x\n", r->name, r,
487 r->flags, bfd_section_vma(abs_bfd, r));
488 if ((r->flags & SEC_RELOC) == 0)
490 relsize = bfd_get_reloc_upper_bound(rel_bfd, r);
493 printf("%s(%d): no relocation entries section=0x%x\n",
494 __FILE__, __LINE__, r->name);
498 symb = get_symbols(rel_bfd, &nsymb);
499 relpp = xmalloc(relsize);
501 relcount = bfd_canonicalize_reloc(rel_bfd, r, relpp, symb);
504 printf("%s(%d): no relocation entries section=%s\n",
505 __FILE__, __LINE__, r->name);
508 for (p = relpp; (relcount && (*p != NULL)); p++, relcount--) {
509 unsigned char *r_mem;
510 int relocation_needed = 0;
512 #ifdef TARGET_microblaze
513 /* The MICROBLAZE_XX_NONE relocs can be skipped.
514 They represent PC relative branches that the
515 linker has already resolved */
517 switch ((*p)->howto->type)
519 case R_MICROBLAZE_NONE:
520 case R_MICROBLAZE_64_NONE:
523 #endif /* TARGET_microblaze */
526 /* Skip this relocation entirely if possible (we
527 do this early, before doing any other
528 processing on it). */
529 switch ((*p)->howto->type) {
530 #ifdef R_V850_9_PCREL
533 #ifdef R_V850_22_PCREL
534 case R_V850_22_PCREL:
536 #ifdef R_V850_SDA_16_16_OFFSET
537 case R_V850_SDA_16_16_OFFSET:
539 #ifdef R_V850_SDA_15_16_OFFSET
540 case R_V850_SDA_15_16_OFFSET:
542 #ifdef R_V850_ZDA_15_16_OFFSET
543 case R_V850_ZDA_15_16_OFFSET:
545 #ifdef R_V850_TDA_6_8_OFFSET
546 case R_V850_TDA_6_8_OFFSET:
548 #ifdef R_V850_TDA_7_8_OFFSET
549 case R_V850_TDA_7_8_OFFSET:
551 #ifdef R_V850_TDA_7_7_OFFSET
552 case R_V850_TDA_7_7_OFFSET:
554 #ifdef R_V850_TDA_16_16_OFFSET
555 case R_V850_TDA_16_16_OFFSET:
557 #ifdef R_V850_TDA_4_5_OFFSET
558 case R_V850_TDA_4_5_OFFSET:
560 #ifdef R_V850_TDA_4_4_OFFSET
561 case R_V850_TDA_4_4_OFFSET:
563 #ifdef R_V850_SDA_16_16_SPLIT_OFFSET
564 case R_V850_SDA_16_16_SPLIT_OFFSET:
566 #ifdef R_V850_CALLT_6_7_OFFSET
567 case R_V850_CALLT_6_7_OFFSET:
569 #ifdef R_V850_CALLT_16_16_OFFSET
570 case R_V850_CALLT_16_16_OFFSET:
572 /* These are relative relocations, which
573 have already been fixed up by the
574 linker at this point, so just ignore
578 #endif /* USE_V850_RELOCS */
581 if (q->sym_ptr_ptr && *q->sym_ptr_ptr) {
582 sym_name = (*(q->sym_ptr_ptr))->name;
583 sym_section = (*(q->sym_ptr_ptr))->section;
584 section_name=(*(q->sym_ptr_ptr))->section->name;
586 printf("ERROR: undefined relocation entry\n");
591 /* Adjust the address to account for the GOT table which wasn't
592 * present in the relative file link.
594 if (pic_with_got && !use_resolved)
595 q->address += got_size;
598 /* A pointer to what's being relocated, used often
600 r_mem = sectionp + q->address;
603 * Fixup offset in the actual section.
607 if ((sym_addr = get_symbol_offset((char *) sym_name,
608 sym_section, symbols, number_of_symbols)) == -1) {
612 sym_addr = (*(q->sym_ptr_ptr))->value;
615 /* Use the address of the symbol already in
616 the program text. How this is handled may
617 still depend on the particular relocation
619 switch (q->howto->type) {
623 /* We specially handle adjacent
624 HI16_S/ZDA_15_16_OFFSET and
625 HI16_S/LO16 pairs that reference the
626 same address (these are usually
627 movhi/ld and movhi/movea pairs,
630 r2_type = R_V850_NONE;
632 r2_type = p[1]->howto->type;
633 if ((r2_type == R_V850_ZDA_15_16_OFFSET
634 || r2_type == R_V850_LO16)
635 && (p[0]->sym_ptr_ptr
636 == p[1]->sym_ptr_ptr)
637 && (p[0]->addend == p[1]->addend))
639 relocation_needed = 1;
642 case R_V850_ZDA_15_16_OFFSET:
650 /* We don't really need the
651 actual value -- the bits
652 produced by the linker are
653 what we want in the final
654 flat file -- but get it
658 unsigned char *r2_mem =
666 /* Sign extend LO. */
670 /* Maybe ignore the LSB
674 if (r2_type != R_V850_LO16)
682 goto bad_resolved_reloc;
686 /* See if this is actually the
687 2nd half of a pair. */
689 && (p[-1]->howto->type
691 && (p[-1]->sym_ptr_ptr
692 == p[0]->sym_ptr_ptr)
693 && (p[-1]->addend == p[0]->addend))
694 break; /* not an error */
696 goto bad_resolved_reloc;
699 goto bad_resolved_reloc;
701 goto good_32bit_resolved_reloc;
702 #elif defined(TARGET_arm)
704 relocation_needed = 1;
709 relocation_needed = 0;
712 goto bad_resolved_reloc;
713 #elif defined(TARGET_m68k)
715 goto good_32bit_resolved_reloc;
718 /* The linker has already resolved
719 PC relocs for us. In PIC links,
720 the symbol must be in the data
725 goto bad_resolved_reloc;
728 /* The default is to assume that the
729 relocation is relative and has
730 already been fixed up by the
731 linker (perhaps we ought to make
732 give an error by default, and
733 require `safe' relocations to be
734 enumberated explicitly?). */
735 goto good_32bit_resolved_reloc;
737 good_32bit_resolved_reloc:
738 if (bfd_big_endian (abs_bfd))
750 relocation_needed = 1;
754 printf("ERROR: reloc type %s unsupported in this context\n",
760 /* Calculate the sym address ourselves. */
761 sym_reloc_size = bfd_get_reloc_size(q->howto);
763 #if !defined(TARGET_h8300) && !defined(TARGET_e1) && !defined(TARGET_bfin) && !defined(TARGET_m68k)
764 if (sym_reloc_size != 4) {
765 printf("ERROR: bad reloc type %d size=%d for symbol=%s\n",
766 (*p)->howto->type, sym_reloc_size, sym_name);
773 switch ((*p)->howto->type) {
775 #if defined(TARGET_m68k)
777 relocation_needed = 1;
778 sym_vma = bfd_section_vma(abs_bfd, sym_section);
779 sym_addr += sym_vma + q->addend;
784 sym_addr += sym_vma + q->addend;
785 sym_addr -= q->address;
789 #if defined(TARGET_arm)
791 relocation_needed = 1;
794 "%s vma=0x%x, value=0x%x, address=0x%x "
795 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
797 sym_vma, (*(q->sym_ptr_ptr))->value,
798 q->address, sym_addr,
799 (*p)->howto->rightshift,
801 sym_vma = bfd_section_vma(abs_bfd, sym_section);
802 sym_addr += sym_vma + q->addend;
806 /* Should be fine as is */
811 "%s vma=0x%x, value=0x%x, address=0x%x "
812 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
814 sym_vma, (*(q->sym_ptr_ptr))->value,
815 q->address, sym_addr,
816 (*p)->howto->rightshift,
820 sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift;
826 relocation_needed = 1;
827 sym_vma = bfd_section_vma(abs_bfd, sym_section);
828 sym_addr += sym_vma + q->addend;
830 #if defined(R_V850_ZDA_16_16_OFFSET) || defined(R_V850_ZDA_16_16_SPLIT_OFFSET)
831 #ifdef R_V850_ZDA_16_16_OFFSET
832 case R_V850_ZDA_16_16_OFFSET:
834 #ifdef R_V850_ZDA_16_16_SPLIT_OFFSET
835 case R_V850_ZDA_16_16_SPLIT_OFFSET:
837 /* Can't support zero-relocations. */
838 printf ("ERROR: %s+0x%x: zero relocations not supported\n",
839 sym_name, q->addend);
841 #endif /* R_V850_ZDA_16_16_OFFSET || R_V850_ZDA_16_16_SPLIT_OFFSET */
842 #endif /* TARGET_v850 */
846 if (sym_reloc_size != 4) {
847 printf("R_H8_DIR24R8 size %d\n", sym_reloc_size);
851 relocation_needed = 1;
852 sym_addr = (*(q->sym_ptr_ptr))->value;
854 r_mem -= 1; /* tracks q->address */
855 sym_vma = bfd_section_vma(abs_bfd, sym_section);
856 sym_addr += sym_vma + q->addend;
857 sym_addr |= (*(unsigned char *)r_mem<<24);
860 if (sym_reloc_size != 4) {
861 printf("R_H8_DIR24A8 size %d\n", sym_reloc_size);
865 /* Absolute symbol done not relocation */
866 relocation_needed = !bfd_is_abs_section(sym_section);
867 sym_addr = (*(q->sym_ptr_ptr))->value;
868 sym_vma = bfd_section_vma(abs_bfd, sym_section);
869 sym_addr += sym_vma + q->addend;
872 case R_H8_DIR32A16: /* currently 32, could be made 16 */
873 if (sym_reloc_size != 4) {
874 printf("R_H8_DIR32 size %d\n", sym_reloc_size);
878 relocation_needed = 1;
879 sym_addr = (*(q->sym_ptr_ptr))->value;
880 sym_vma = bfd_section_vma(abs_bfd, sym_section);
881 sym_addr += sym_vma + q->addend;
885 sym_addr = (*(q->sym_ptr_ptr))->value;
886 sym_addr += sym_vma + q->addend;
887 sym_addr -= (q->address + 2);
888 if (bfd_big_endian(abs_bfd))
889 *(unsigned short *)r_mem =
890 bfd_big_endian(abs_bfd) ? htons(sym_addr) : sym_addr;
894 sym_addr = (*(q->sym_ptr_ptr))->value;
895 sym_addr += sym_vma + q->addend;
896 sym_addr -= (q->address + 1);
897 *(unsigned char *)r_mem = sym_addr;
901 #ifdef TARGET_microblaze
902 case R_MICROBLAZE_64:
903 /* The symbol is split over two consecutive instructions.
904 Flag this to the flat loader by setting the high bit of
905 the relocation symbol. */
907 unsigned char *p = r_mem;
911 /* work out the relocation */
912 sym_vma = bfd_section_vma(abs_bfd, sym_section);
913 /* grab any offset from the text */
914 offset = (p[2]<<24) + (p[3] << 16) + (p[6] << 8) + (p[7]);
915 /* Update the address */
916 sym_addr += offset + sym_vma + q->addend;
917 /* Write relocated pointer back */
918 p[2] = (sym_addr >> 24) & 0xff;
919 p[3] = (sym_addr >> 16) & 0xff;
920 p[6] = (sym_addr >> 8) & 0xff;
921 p[7] = sym_addr & 0xff;
923 /* create a new reloc entry */
924 flat_relocs = realloc(flat_relocs,
925 (flat_reloc_count + 1) * sizeof(uint32_t));
926 flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address);
928 relocation_needed = 0;
930 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
931 bfd_section_vma(abs_bfd, sym_section));
933 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
934 "section=%s size=%d "
935 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
936 q->address, sym_name, addstr,
937 section_name, sym_reloc_size,
938 sym_addr, section_vma + q->address);
940 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
941 section_vma + q->address);
945 case R_MICROBLAZE_32:
947 unsigned char *p = r_mem;
948 unsigned long offset;
950 /* grab any offset from the text */
951 offset = (p[0]<<24) + (p[1] << 16) + (p[2] << 8) + (p[3]);
952 sym_vma = bfd_section_vma(abs_bfd, sym_section);
953 /* This is a horrible kludge. For some
954 reason, *sometimes* the offset is in
955 both addend and the code. Detect
956 it, and cancel the effect. Otherwise
957 the offset gets added twice - ouch.
958 There should be a better test
959 for this condition, based on the
960 BFD data structures */
961 if(offset==q->addend)
964 sym_addr += offset + sym_vma + q->addend;
965 relocation_needed = 1;
968 case R_MICROBLAZE_64_PCREL:
970 //sym_addr = (*(q->sym_ptr_ptr))->value;
971 sym_addr += sym_vma + q->addend;
972 sym_addr -= (q->address + 4);
973 sym_addr = htonl(sym_addr);
975 * ((unsigned short *) (r_mem+2)) |= (sym_addr) & 0xFFFF;
977 * ((unsigned short *) (r_mem+6)) |= (sym_addr >> 16) & 0xFFFF;
978 /* We've done all the work, so continue
979 to next reloc instead of break */
982 #endif /* TARGET_microblaze */
985 #define htoniosl(x) (x)
986 #define niostohl(x) (x)
987 case R_NIOS2_BFD_RELOC_32:
988 relocation_needed = 1;
989 pflags = (FLAT_NIOS2_R_32 << 28);
990 sym_vma = bfd_section_vma(abs_bfd, sym_section);
991 sym_addr += sym_vma + q->addend;
992 /* modify target, in target order */
993 *(unsigned long *)r_mem = htoniosl(sym_addr);
997 unsigned long exist_val;
998 relocation_needed = 1;
999 pflags = (FLAT_NIOS2_R_CALL26 << 28);
1000 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1001 sym_addr += sym_vma + q->addend;
1003 /* modify target, in target order */
1004 // exist_val = niostohl(*(unsigned long *)r_mem);
1005 exist_val = ((sym_addr >> 2) << 6);
1006 *(unsigned long *)r_mem = htoniosl(exist_val);
1009 case R_NIOS2_HIADJ16:
1012 unsigned long exist_val;
1014 /* handle the adjacent HI/LO pairs */
1016 r2_type = R_NIOS2_NONE;
1018 r2_type = p[1]->howto->type;
1019 if ((r2_type == R_NIOS2_LO16)
1020 && (p[0]->sym_ptr_ptr == p[1]->sym_ptr_ptr)
1021 && (p[0]->addend == p[1]->addend))
1023 unsigned char * r2_mem = sectionp + p[1]->address;
1024 if (p[1]->address - q->address!=4)
1025 printf("Err: HI/LO not adjacent %d\n", p[1]->address - q->address);
1026 relocation_needed = 1;
1027 pflags = (q->howto->type == R_NIOS2_HIADJ16)
1028 ? FLAT_NIOS2_R_HIADJ_LO : FLAT_NIOS2_R_HI_LO;
1031 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1032 sym_addr += sym_vma + q->addend;
1034 /* modify high 16 bits, in target order */
1035 exist_val = niostohl(*(unsigned long *)r_mem);
1036 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1037 if (q->howto->type == R_NIOS2_HIADJ16)
1038 exist_val |= ((((sym_addr >> 16) + ((sym_addr >> 15) & 1)) & 0xFFFF) << 6);
1040 exist_val |= (((sym_addr >> 16) & 0xFFFF) << 6);
1041 *(unsigned long *)r_mem = htoniosl(exist_val);
1043 /* modify low 16 bits, in target order */
1044 exist_val = niostohl(*(unsigned long *)r2_mem);
1045 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1046 exist_val |= ((sym_addr & 0xFFFF) << 6);
1047 *(unsigned long *)r2_mem = htoniosl(exist_val);
1050 goto NIOS2_RELOC_ERR;
1056 unsigned long exist_val, temp;
1057 //long gp = get_symbol_offset("_gp", sym_section, symbols, number_of_symbols);
1058 long gp = get_gp_value(symbols, number_of_symbols);
1060 printf("Err: unresolved symbol _gp when relocating %s\n", sym_name);
1061 goto NIOS2_RELOC_ERR;
1063 /* _gp holds a absolute value, otherwise the ld cannot generate correct code */
1064 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1065 //printf("sym=%x, %d, _gp=%x, %d\n", sym_addr+sym_vma, sym_addr+sym_vma, gp, gp);
1066 sym_addr += sym_vma + q->addend;
1068 //printf("sym - _gp=%x, %d\n", sym_addr, sym_addr);
1069 /* modify the target, in target order (little_endian) */
1070 exist_val = niostohl(*(unsigned long *)r_mem);
1071 temp = ((exist_val >> 6) & 0x3ff0000) | (sym_addr & 0xffff);
1073 temp |= (exist_val & 0x3f);
1074 *(unsigned long *)r_mem = htoniosl(temp);
1076 printf("omit: offset=0x%x symbol=%s%s "
1077 "section=%s size=%d "
1078 "fixup=0x%x (reloc=0x%x) GPREL\n",
1079 q->address, sym_name, addstr,
1080 section_name, sym_reloc_size,
1081 sym_addr, section_vma + q->address);
1084 case R_NIOS2_PCREL16:
1086 unsigned long exist_val;
1088 sym_addr += sym_vma + q->addend;
1089 sym_addr -= (q->address + 4);
1090 /* modify the target, in target order (little_endian) */
1091 exist_val = niostohl(*(unsigned long *)r_mem);
1092 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1093 exist_val |= ((sym_addr & 0xFFFF) << 6);
1094 *(unsigned long *)r_mem = htoniosl(exist_val);
1096 printf("omit: offset=0x%x symbol=%s%s "
1097 "section=%s size=%d "
1098 "fixup=0x%x (reloc=0x%x) PCREL\n",
1099 q->address, sym_name, addstr,
1100 section_name, sym_reloc_size,
1101 sym_addr, section_vma + q->address);
1106 /* check if this is actually the 2nd half of a pair */
1108 && ((p[-1]->howto->type == R_NIOS2_HIADJ16)
1109 || (p[-1]->howto->type == R_NIOS2_HI16))
1110 && (p[-1]->sym_ptr_ptr == p[0]->sym_ptr_ptr)
1111 && (p[-1]->addend == p[0]->addend)) {
1113 printf("omit: offset=0x%x symbol=%s%s "
1114 "section=%s size=%d LO16\n",
1115 q->address, sym_name, addstr,
1116 section_name, sym_reloc_size);
1120 /* error, fall through */
1124 case R_NIOS2_CACHE_OPX:
1128 case R_NIOS2_BFD_RELOC_16:
1129 case R_NIOS2_BFD_RELOC_8:
1130 case R_NIOS2_GNU_VTINHERIT:
1131 case R_NIOS2_GNU_VTENTRY:
1136 printf("Err: unexpected reloc type %s(%d)\n", q->howto->name, q->howto->type);
1139 #endif /* TARGET_nios2 */
1144 relocation_needed = 1;
1145 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1146 sym_addr += sym_vma + q->addend;
1150 sym_addr += sym_vma + q->addend;
1151 sym_addr -= q->address;
1153 case R_SPARC_WDISP30:
1154 sym_addr = (((*(q->sym_ptr_ptr))->value-
1155 q->address) >> 2) & 0x3fffffff;
1157 ntohl(*(uint32_t *)r_mem)
1162 relocation_needed = 1;
1163 pflags = 0x80000000;
1164 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1165 sym_addr += sym_vma + q->addend;
1167 htonl(*(uint32_t *)r_mem)
1172 relocation_needed = 1;
1173 pflags = 0x40000000;
1174 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1175 sym_addr += sym_vma + q->addend;
1176 sym_addr &= 0x000003ff;
1178 htonl(*(uint32_t *)r_mem)
1182 #endif /* TARGET_sparc */
1185 case R_pcrel12_jump:
1186 case R_pcrel12_jump_s:
1188 case R_pcrel24_jump_l:
1189 case R_pcrel24_jump_x:
1190 case R_pcrel24_call_x:
1194 sym_addr += q->addend;// get the symbol addr
1195 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1196 sym_addr -= q->address; // make it PC relative
1197 // implicitly assumes code section and symbol section are same
1204 sym_addr += q->addend;
1205 if(weak_und_symbol(sym_section->name, (*(q->sym_ptr_ptr))))
1207 if(0xFFFF0000 & sym_addr){
1208 fprintf (stderr, "Relocation overflow for rN = %s\n",sym_name);
1211 flat_relocs = (uint32_t *)
1212 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1213 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1214 sym_section->name, sym_name,
1215 (*(q->sym_ptr_ptr)),
1216 0, FLAT_RELOC_PART_LO,
1217 section_vma + q->address))
1226 unsigned int reloc_count_incr;
1229 if (q->howto->type == R_luimm16)
1230 hi_lo = FLAT_RELOC_PART_LO;
1232 hi_lo = FLAT_RELOC_PART_HI;
1234 sym_addr += q->addend;
1236 flat_relocs = (uint32_t *)
1237 (realloc (flat_relocs, (flat_reloc_count + 2) * sizeof (uint32_t)));
1238 reloc_count_incr = 1;
1239 if (weak_und_symbol (sym_section->name, (*(q->sym_ptr_ptr))))
1241 if (0xFFFF0000 & sym_addr) {
1242 /* value is > 16 bits - use an extra field */
1243 /* see if we have already output that symbol */
1244 /* reloc may be addend from symbol and */
1245 /* we can only store 16 bit offsets */
1247 if ((*(q->sym_ptr_ptr))->udata.i == 0
1248 || flat_relocs[(*(q->sym_ptr_ptr))->udata.i] != sym_addr
1249 || ((*(q->sym_ptr_ptr))->udata.i & 0xFFFF0000))
1251 reloc_count_incr = 2;
1252 flat_relocs[flat_reloc_count + 1] = sym_addr;
1253 (*(q->sym_ptr_ptr))->udata.i = flat_reloc_count + 1;
1254 sym_addr = 0; // indication to loader to read next
1256 sym_addr = (*(q->sym_ptr_ptr))->udata.i;
1262 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1263 sym_section->name, sym_name,
1264 (*(q->sym_ptr_ptr)),
1266 section_vma + q->address))
1268 flat_reloc_count += reloc_count_incr;
1272 sym_addr += q->addend;
1274 if (weak_und_symbol (sym_section->name, *q->sym_ptr_ptr))
1277 flat_relocs = (uint32_t *)
1278 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1279 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1280 sym_section->name, sym_name,
1281 (*(q->sym_ptr_ptr)),
1282 2, FLAT_RELOC_PART_LO,
1283 section_vma + q->address))
1289 #endif //TARGET_bfin
1293 relocation_needed = 1;
1294 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1295 sym_addr += sym_vma + q->addend;
1299 sym_addr += sym_vma + q->addend;
1300 sym_addr -= q->address;
1302 #endif /* TARGET_sh */
1305 #define htoe1l(x) htonl(x)
1312 #define DBG_E1 printf
1314 #define DBG_E1(x, ... )
1317 #define _32BITS_RELOC 0x00000000
1318 #define _30BITS_RELOC 0x80000000
1319 #define _28BITS_RELOC 0x40000000
1322 unsigned long sec_vma, exist_val, S;
1324 relocation_needed = 1;
1325 DBG_E1("Handling Reloc <CONST31>\n");
1326 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1327 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1328 sec_vma, sym_addr, q->address);
1329 sym_addr = sec_vma + sym_addr;
1330 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1331 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1332 exist_val = htoe1l(exist_val);
1333 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1334 sym_addr += exist_val;
1335 pflags = _30BITS_RELOC;
1337 case R_E1_CONST31_PCREL:
1338 relocation_needed = 0;
1339 DBG_E1("Handling Reloc <CONST31_PCREL>\n");
1340 DBG_E1("DONT RELOCATE AT LOADING\n");
1341 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1342 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1343 sec_vma, sym_addr, q->address);
1344 sym_addr = sec_vma + sym_addr;
1345 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1347 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1349 q->address = q->address + section_vma;
1350 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1352 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1353 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1354 DBG_E1( "sym_addr := sym_addr - q->address - "
1355 "sizeof(CONST31_PCREL): [0x%x]\n",
1357 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1358 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1359 exist_val = htoe1l(exist_val);
1360 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1361 sym_addr |= exist_val;
1362 DBG_E1("sym_addr |= exist_val) : [0x%x]\n", sym_addr );
1364 case R_E1_DIS29W_PCREL:
1365 relocation_needed = 0;
1366 DBG_E1("Handling Reloc <DIS29W_PCREL>\n");
1367 DBG_E1("DONT RELOCATE AT LOADING\n");
1368 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1369 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1370 sec_vma, sym_addr, q->address);
1371 sym_addr = sec_vma + sym_addr;
1372 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1374 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1376 q->address = q->address + section_vma;
1377 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1379 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1380 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1381 DBG_E1( "sym_addr := sym_addr - q->address - "
1382 "sizeof(CONST31_PCREL): [0x%x]\n",
1384 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1385 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1386 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1387 exist_val = htoe1l(exist_val);
1388 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1389 sym_addr += exist_val;
1392 DBG_E1("Handling Reloc <DIS29W>\n");
1393 goto DIS29_RELOCATION;
1395 DBG_E1("Handling Reloc <DIS29H>\n");
1396 goto DIS29_RELOCATION;
1398 DBG_E1("Handling Reloc <DIS29B>\n");
1400 relocation_needed = 1;
1401 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1402 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%08x]\n",
1404 sym_addr = sec_vma + sym_addr;
1405 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%08x]\n", sym_addr);
1406 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1407 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1408 exist_val = htoe1l(exist_val);
1409 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1410 sym_addr += exist_val;
1411 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1412 pflags = _28BITS_RELOC;
1414 case R_E1_IMM32_PCREL:
1415 relocation_needed = 0;
1416 DBG_E1("Handling Reloc <IMM32_PCREL>\n");
1417 DBG_E1("DONT RELOCATE AT LOADING\n");
1418 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1419 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1421 sym_addr = sec_vma + sym_addr;
1423 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1424 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1426 q->address = q->address + section_vma;
1427 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1429 if( (sym_addr = (sym_addr - q->address - 6 )) < 0 )
1430 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1431 DBG_E1( "sym_addr := sym_addr - q->address - "
1432 "sizeof(CONST31_PCREL): [0x%x]\n",
1434 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1435 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1436 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1437 exist_val = htoe1l(exist_val);
1438 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1439 sym_addr += exist_val;
1442 relocation_needed = 1;
1443 DBG_E1("Handling Reloc <IMM32>\n");
1444 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1445 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1447 sym_addr = sec_vma + sym_addr;
1448 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1449 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1450 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1451 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1452 exist_val = htoe1l(exist_val);
1453 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1454 sym_addr += exist_val;
1455 pflags = _32BITS_RELOC;
1458 relocation_needed = 1;
1459 DBG_E1("Handling Reloc <WORD>\n");
1460 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1461 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1463 sym_addr = sec_vma + sym_addr;
1464 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1465 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address );
1466 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1467 exist_val = htoe1l(exist_val);
1468 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1469 sym_addr += exist_val;
1470 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1471 pflags = _32BITS_RELOC;
1474 #undef _32BITS_RELOC
1475 #undef _30BITS_RELOC
1476 #undef _28BITS_RELOC
1479 /* missing support for other types of relocs */
1480 printf("ERROR: bad reloc type %d\n", (*p)->howto->type);
1486 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
1487 bfd_section_vma(abs_bfd, sym_section));
1491 * for full elf relocation we have to write back the
1492 * start_code relative value to use.
1494 if (!pic_with_got) {
1495 #if defined(TARGET_arm)
1504 * horrible nasty hack to support different endianess
1506 if (!bfd_big_endian(abs_bfd)) {
1518 tmp.l = *(uint32_t *)r_mem;
1519 hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16);
1521 (((*p)->howto->type != R_ARM_PC24) &&
1522 ((*p)->howto->type != R_ARM_PLT32)))
1523 hl |= (tmp.c[i3] << 24);
1524 else if (tmp.c[i2] & 0x80)
1525 hl |= 0xff000000; /* sign extend */
1528 tmp.c[i0] = hl & 0xff;
1529 tmp.c[i1] = (hl >> 8) & 0xff;
1530 tmp.c[i2] = (hl >> 16) & 0xff;
1532 (((*p)->howto->type != R_ARM_PC24) &&
1533 ((*p)->howto->type != R_ARM_PLT32)))
1534 tmp.c[i3] = (hl >> 24) & 0xff;
1535 if ((*p)->howto->type == R_ARM_ABS32)
1536 *(uint32_t *)r_mem = htonl(hl);
1538 *(uint32_t *)r_mem = tmp.l;
1540 #elif defined(TARGET_bfin)
1541 if ((*p)->howto->type == R_pcrel24
1542 || (*p)->howto->type == R_pcrel24_jump_l
1543 || (*p)->howto->type == R_pcrel24_jump_x
1544 || (*p)->howto->type == R_pcrel24_call_x)
1546 sym_addr += 2*-1*PCREL24_MAGIC_OFFSET;
1547 *((unsigned short *)(sectionp + q->address) + 1 + PCREL24_MAGIC_OFFSET)
1548 = (sym_addr >> 1) & 0xffff;
1549 *((unsigned short *)(sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1550 = (0xff00 & *((unsigned short *) (sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1551 | ((sym_addr >> 17) & 0xff));
1552 } else if ((*p)->howto->type == R_byte4_data) {
1553 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1554 } else if ((*p)->howto->type == R_pcrel12_jump
1555 || (*p)->howto->type == R_pcrel12_jump_s) {
1556 *((unsigned short *)(sectionp + q->address))
1557 = (0xf000 & *((unsigned short *)(sectionp + q->address))
1558 | ((sym_addr >> 1) & 0xfff));
1559 } else if ((*p)->howto->type == R_pcrel10) {
1560 *((unsigned short *)(sectionp + q->address))
1561 = (~0x3ff & *((unsigned short *)(sectionp + q->address))
1562 | ((sym_addr >> 1) & 0x3ff));
1563 } else if ((*p)->howto->type == R_rimm16
1564 || (*p)->howto->type == R_huimm16
1565 || (*p)->howto->type == R_luimm16) {
1566 /* for l and h we set the lower 16 bits which is only when it will be used */
1567 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1568 } else if ((*p)->howto->type == R_pcrel5m2) {
1569 *((unsigned short *)(sectionp + q->address))
1570 = (0xfff0 & *((unsigned short *)(sectionp + q->address))
1571 | ((sym_addr >> 1) & 0xf));
1572 } else if ((*p)->howto->type == R_pcrel11){
1573 *((unsigned short *)(sectionp + q->address))
1574 = (0xfc00 & *((unsigned short *)(sectionp + q->address))
1575 | ((sym_addr >> 1) & 0x3ff));
1576 } else if (0xE0 <= (*p)->howto->type && 0xF3 >= (*p)->howto->type) {
1577 //arith relocs dont generate a real relocation
1579 printf("Blackfin relocation fail for reloc type: 0x%x\n", (*p)->howto->type);
1581 #elif defined(TARGET_e1)
1582 #define OPCODE_SIZE 2 /* Add 2 bytes, counting the opcode size*/
1583 switch ((*p)->howto->type) {
1585 case R_E1_CONST31_PCREL:
1586 case R_E1_DIS29W_PCREL:
1590 case R_E1_IMM32_PCREL:
1592 DBG_E1("In addr + 2:[0x%x] <- write [0x%x]\n",
1593 (sectionp + q->address + 2), sym_addr );
1594 *((unsigned long *) (sectionp + q->address + OPCODE_SIZE)) =
1598 DBG_E1("In addr : [0x%x] <- write [0x%x]\n",
1599 (sectionp + q->address), sym_addr );
1600 *((unsigned long *) (sectionp + q->address )) = htonl(sym_addr);
1603 printf("ERROR:Unhandled Relocation. Exiting...\n");
1607 #else /* ! TARGET_arm && ! TARGET_e1 */
1609 switch (q->howto->type) {
1614 /* Do nothing -- for cases we handle,
1615 the bits produced by the linker are
1616 what we want in the final flat file
1617 (and other cases are errors). Note
1618 that unlike most relocated values,
1619 it is stored in little-endian order,
1620 but this is necessary to avoid
1621 trashing the low-bit, and the float
1622 loaders knows about it. */
1624 #endif /* TARGET_V850 */
1627 case R_NIOS2_BFD_RELOC_32:
1628 case R_NIOS2_CALL26:
1629 case R_NIOS2_HIADJ16:
1633 #endif /* TARGET_nios2 */
1635 #if defined(TARGET_m68k)
1637 if (sym_addr < -0x8000 || sym_addr > 0x7fff) {
1638 fprintf (stderr, "Relocation overflow for R_68K_PC16 relocation against %s\n", sym_name);
1641 r_mem[0] = (sym_addr >> 8) & 0xff;
1642 r_mem[1] = sym_addr & 0xff;
1648 /* The alignment of the build host
1649 might be stricter than that of the
1650 target, so be careful. We store in
1651 network byte order. */
1652 r_mem[0] = (sym_addr >> 24) & 0xff;
1653 r_mem[1] = (sym_addr >> 16) & 0xff;
1654 r_mem[2] = (sym_addr >> 8) & 0xff;
1655 r_mem[3] = sym_addr & 0xff;
1657 #endif /* !TARGET_arm */
1662 if ((*p)->howto->type == R_rimm16
1663 || (*p)->howto->type == R_huimm16
1664 || (*p)->howto->type == R_luimm16)
1666 /* for l and h we set the lower 16 bits which is only when it will be used */
1667 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1668 } else if ((*p)->howto->type == R_byte4_data) {
1669 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1674 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
1675 "section=%s size=%d "
1676 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
1677 q->address, sym_name, addstr,
1678 section_name, sym_reloc_size,
1679 sym_addr, section_vma + q->address);
1682 * Create relocation entry (PC relative doesn't need this).
1684 if (relocation_needed) {
1686 flat_relocs = realloc(flat_relocs,
1687 (flat_reloc_count + 1) * sizeof(uint32_t));
1689 flat_relocs[flat_reloc_count] = pflags |
1690 (section_vma + q->address);
1693 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
1694 section_vma + q->address);
1696 switch ((*p)->howto->type) {
1698 case R_E1_CONST31_PCREL:
1699 case R_E1_DIS29W_PCREL:
1703 case R_E1_IMM32_PCREL:
1705 flat_relocs[flat_reloc_count] = pflags |
1706 (section_vma + q->address + OPCODE_SIZE);
1708 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1709 flat_relocs[flat_reloc_count] );
1712 flat_relocs[flat_reloc_count] = pflags |
1713 (section_vma + q->address);
1715 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1716 flat_relocs[flat_reloc_count] );
1722 relocation_needed = 0;
1727 printf("%s(%d): symbol name=%s address=0x%x section=%s -> RELOC=0x%x\n",
1728 __FILE__, __LINE__, sym_name, q->address, section_name,
1729 flat_relocs[flat_reloc_count]);
1736 printf("%d bad relocs\n", bad_relocs);
1743 *n_relocs = flat_reloc_count;
1749 static char * program;
1751 static void usage(void)
1753 fprintf(stderr, "Usage: %s [vrzd] [-p <abs-pic-file>] [-s stack-size] "
1754 "[-o <output-file>] <elf-file>\n\n"
1755 " -v : verbose operation\n"
1756 " -r : force load to RAM\n"
1757 " -k : enable kernel trace on load (for debug)\n"
1758 " -z : compress code/data/relocs\n"
1759 " -d : compress data/relocs\n"
1760 " -a : use existing symbol references\n"
1761 " instead of recalculating from\n"
1762 " relocation info\n"
1763 " -R reloc-file : read relocations from a separate file\n"
1764 " -p abs-pic-file : GOT/PIC processing with files\n"
1765 " -s stacksize : set application stack size\n"
1766 " -o output-file : output file name\n\n",
1768 fprintf(stderr, "Compiled for " ARCH " architecture\n\n");
1773 /* Write NUM zeroes to STREAM. */
1774 static void write_zeroes (unsigned long num, stream *stream)
1778 /* It'd be nice if we could just use fseek, but that doesn't seem to
1779 work for stdio output files. */
1780 memset(zeroes, 0x00, 1024);
1781 while (num > sizeof(zeroes)) {
1782 fwrite_stream(zeroes, sizeof(zeroes), 1, stream);
1783 num -= sizeof(zeroes);
1786 fwrite_stream(zeroes, num, 1, stream);
1791 int main(int argc, char *argv[])
1794 bfd *rel_bfd, *abs_bfd;
1796 char *ofile=NULL, *pfile=NULL, *abs_file = NULL, *rel_file = NULL;
1803 asymbol **symbol_table;
1804 long number_of_symbols;
1806 uint32_t data_len = 0;
1807 uint32_t bss_len = 0;
1808 uint32_t text_len = 0;
1811 uint32_t data_vma = ~0;
1812 uint32_t bss_vma = ~0;
1813 uint32_t text_vma = ~0;
1821 struct flat_hdr hdr;
1825 xmalloc_set_program_name(program);
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 if (sscanf(optarg, "%i", &stack) != 1) {
1872 fprintf(stderr, "%s invalid stack size %s\n", argv[0], optarg);
1880 fprintf(stderr, "%s Unknown option\n", argv[0]);
1887 * if neither the -r or -p options was given, default to
1888 * a RAM load as that is the only option that makes sense.
1890 if (!load_to_ram && !pfile)
1893 filename = fname = argv[argc-1];
1904 if (!(rel_bfd = bfd_openr(rel_file, 0))) {
1905 fprintf(stderr, "Can't open %s\n", rel_file);
1909 if (bfd_check_format (rel_bfd, bfd_object) == 0) {
1910 fprintf(stderr, "File is not an object file\n");
1914 if (abs_file == rel_file)
1915 abs_bfd = rel_bfd; /* one file does all */
1917 if (!(abs_bfd = bfd_openr(abs_file, 0))) {
1918 fprintf(stderr, "Can't open %s\n", abs_file);
1922 if (bfd_check_format (abs_bfd, bfd_object) == 0) {
1923 fprintf(stderr, "File is not an object file\n");
1928 if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC)) {
1929 fprintf (stderr, "%s: Input file contains no relocation info\n", rel_file);
1933 if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P)) {
1934 /* `Absolute' file is not absolute, so neither are address
1935 contained therein. */
1937 "%s: `-a' option specified with non-fully-resolved input file\n",
1938 bfd_get_filename (abs_bfd));
1942 symbol_table = get_symbols(abs_bfd, &number_of_symbols);
1944 /* Group output sections into text, data, and bss, and calc their sizes. */
1945 for (s = abs_bfd->sections; s != NULL; s = s->next) {
1946 uint32_t *vma, *len;
1947 bfd_size_type sec_size;
1950 if (s->flags & SEC_CODE) {
1953 } else if (s->flags & SEC_DATA) {
1956 } else if (s->flags & SEC_ALLOC) {
1962 sec_size = bfd_section_size(abs_bfd, s);
1963 sec_vma = bfd_section_vma(abs_bfd, s);
1965 if (sec_vma < *vma) {
1967 *len += sec_vma - *vma;
1971 } else if (sec_vma + sec_size > *vma + *len)
1972 *len = sec_vma + sec_size - *vma;
1975 if (text_len == 0) {
1976 fprintf (stderr, "%s: no .text section", abs_file);
1980 text = xmalloc(text_len);
1983 printf("TEXT -> vma=0x%x len=0x%x\n", text_vma, text_len);
1985 /* Read in all text sections. */
1986 for (s = abs_bfd->sections; s != NULL; s = s->next)
1987 if (s->flags & SEC_CODE)
1988 if (!bfd_get_section_contents(abs_bfd, s,
1989 text + (s->vma - text_vma), 0,
1990 bfd_section_size(abs_bfd, s)))
1992 fprintf(stderr, "read error section %s\n", s->name);
1996 if (data_len == 0) {
1997 fprintf (stderr, "%s: no .data section", abs_file);
2000 data = xmalloc(data_len);
2003 printf("DATA -> vma=0x%x len=0x%x\n", data_vma, data_len);
2005 if ((text_vma + text_len) != data_vma) {
2006 if ((text_vma + text_len) > data_vma) {
2007 printf("ERROR: text=0x%x overlaps data=0x%x ?\n", text_len, data_vma);
2011 printf("WARNING: data=0x%x does not directly follow text=0x%x\n",
2012 data_vma, text_len);
2013 text_len = data_vma - text_vma;
2016 /* Read in all data sections. */
2017 for (s = abs_bfd->sections; s != NULL; s = s->next)
2018 if (s->flags & SEC_DATA)
2019 if (!bfd_get_section_contents(abs_bfd, s,
2020 data + (s->vma - data_vma), 0,
2021 bfd_section_size(abs_bfd, s)))
2023 fprintf(stderr, "read error section %s\n", s->name);
2028 bss_vma = data_vma + data_len;
2030 /* Put common symbols in bss. */
2031 bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len);
2034 printf("BSS -> vma=0x%x len=0x%x\n", bss_vma, bss_len);
2036 if ((data_vma + data_len) != bss_vma) {
2037 if ((data_vma + data_len) > bss_vma) {
2038 printf("ERROR: text=0x%x + data=0x%x overlaps bss=0x%x ?\n", text_len,
2043 printf("WARNING: bss=0x%x does not directly follow text=0x%x + data=0x%x(0x%x)\n",
2044 bss_vma, text_len, data_len, text_len + data_len);
2045 data_len = bss_vma - data_vma;
2048 reloc = (uint32_t *)
2049 output_relocs(abs_bfd, symbol_table, number_of_symbols, &reloc_len,
2050 text, text_len, text_vma, data, data_len, data_vma, rel_bfd);
2053 printf("No relocations in code!\n");
2055 text_offs = real_address_bits(text_vma);
2057 /* Fill in the binflt_flat header */
2058 memcpy(hdr.magic,"bFLT",4);
2059 hdr.rev = htonl(FLAT_VERSION);
2060 hdr.entry = htonl(sizeof(hdr) + bfd_get_start_address(abs_bfd));
2061 hdr.data_start = htonl(sizeof(hdr) + text_offs + text_len);
2062 hdr.data_end = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2063 hdr.bss_end = htonl(sizeof(hdr) + text_offs + text_len +data_len+bss_len);
2064 hdr.stack_size = htonl(stack); /* FIXME */
2065 hdr.reloc_start = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2066 hdr.reloc_count = htonl(reloc_len);
2068 | (load_to_ram ? FLAT_FLAG_RAM : 0)
2069 | (ktrace ? FLAT_FLAG_KTRACE : 0)
2070 | (pic_with_got ? FLAT_FLAG_GOTPIC : 0)
2071 | (docompress ? (docompress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
2073 hdr.build_date = htonl((uint32_t)time(NULL));
2074 memset(hdr.filler, 0x00, sizeof(hdr.filler));
2076 for (i=0; i<reloc_len; i++) reloc[i] = htonl(reloc[i]);
2079 printf("SIZE: .text=0x%04x, .data=0x%04x, .bss=0x%04x",
2080 text_len, data_len, bss_len);
2082 printf(", relocs=0x%04x", reloc_len);
2087 ofile = xmalloc(strlen(fname) + 5 + 1); /* 5 to add suffix */
2088 strcpy(ofile, fname);
2089 strcat(ofile, ".bflt");
2092 if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0) {
2093 fprintf (stderr, "Can't open output file %s\n", ofile);
2097 write(fd, &hdr, sizeof(hdr));
2100 if (fopen_stream_u(&gf, ofile, "a" BINARY_FILE_OPTS)) {
2101 fprintf(stderr, "Can't open file %s for writing\n", ofile);
2105 if (docompress == 1)
2106 reopen_stream_compressed(&gf);
2108 /* Fill in any hole at the beginning of the text segment. */
2110 printf("ZERO before text len=0x%x\n", text_offs);
2111 write_zeroes(text_offs, &gf);
2113 /* Write the text segment. */
2114 fwrite_stream(text, text_len, 1, &gf);
2116 if (docompress == 2)
2117 reopen_stream_compressed(&gf);
2119 /* Write the data segment. */
2120 fwrite_stream(data, data_len, 1, &gf);
2123 fwrite_stream(reloc, reloc_len * 4, 1, &gf);
2132 * this __MUST__ be at the VERY end of the file - do NOT move!!
2138 * vi: tabstop=8 shiftwidth=4 textwidth=79 noexpandtab