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 */
51 /* from $(INSTALLDIR)/include */
52 #include <bfd.h> /* Main header file for the BFD library */
54 #if defined(TARGET_h8300)
55 #include <elf/h8.h> /* TARGET_* ELF support for the BFD library */
56 #elif defined(__CYGWIN__) || defined(__MINGW32__) || defined(TARGET_nios) || defined(TARGET_nios2)
57 #include "cygwin-elf.h" /* Cygwin uses a local copy */
58 #elif defined(TARGET_microblaze)
59 #include <elf/microblaze.h> /* TARGET_* ELF support for the BFD library */
60 #elif defined(TARGET_bfin)
63 #include <elf.h> /* TARGET_* ELF support for the BFD library */
66 #if defined(__MINGW32__)
70 /* from uClinux-x.x.x/include/linux */
71 #include "flat.h" /* Binary flat header description */
81 #if defined(TARGET_m68k)
82 #define ARCH "m68k/coldfire"
83 #elif defined(TARGET_arm)
85 #elif defined(TARGET_sparc)
87 #elif defined(TARGET_v850)
89 #elif defined(TARGET_sh)
91 #elif defined(TARGET_h8300)
93 #elif defined(TARGET_microblaze)
94 #define ARCH "microblaze"
95 #elif defined(TARGET_e1)
96 #define ARCH "e1-coff"
97 #elif defined(TARGET_bfin)
99 #define FLAT_RELOC_TYPE_TEXT 0
100 #define FLAT_RELOC_TYPE_DATA 1
101 #define FLAT_RELOC_TYPE_BSS 2
102 #define FLAT_RELOC_TYPE_STACK 3
103 #define FLAT_RELOC_PART_LO 0
104 #define FLAT_RELOC_PART_HI 1
105 #define PCREL24_MAGIC_OFFSET -1
106 #elif defined(TARGET_nios)
108 #elif defined(TARGET_nios2)
111 #error "Don't know how to support your CPU architecture??"
114 #if defined(TARGET_m68k) || defined(TARGET_h8300) || defined(TARGET_bfin)
116 * Define a maximum number of bytes allowed in the offset table.
117 * We'll fail if the table is larger than this.
119 * This limit may be different for platforms other than m68k, but
120 * 8000 entries is a lot, trust me :-) (davidm)
122 #define GOT_LIMIT 32767
124 * we have to mask out the shared library id here and there, this gives
125 * us the real address bits when needed
127 #define real_address_bits(x) (pic_with_got ? ((x) & 0xffffff) : (x))
129 #define real_address_bits(x) (x)
137 int verbose = 0; /* extra output when running */
138 int pic_with_got = 0; /* do elf/got processing with PIC code */
139 int load_to_ram = 0; /* instruct loader to allocate everything into RAM */
140 int ktrace = 0; /* instruct loader output kernel trace on load */
141 int compress = 0; /* 1 = compress everything, 2 = compress data only */
142 int use_resolved = 0; /* If true, get the value of symbol references from */
143 /* the program contents, not from the relocation table. */
144 /* In this case, the input ELF file must be already */
145 /* fully resolved (using the `-q' flag with recent */
146 /* versions of GNU ld will give you a fully resolved */
147 /* output file with relocation entries). */
149 const char *progname, *filename;
155 static char where[200];
158 /* Use exactly one of these: */
159 E_NOFILE = 0, /* "progname: " */
160 E_FILE = 1, /* "filename: " */
161 E_FILELINE = 2, /* "filename:lineno: " */
162 E_FILEWHERE = 3, /* "filename:%s: " -- set %s with ewhere() */
164 /* Add in any of these with |': */
169 void ewhere (const char *format, ...);
170 void einfo (int type, const char *format, ...);
174 ewhere (const char *format, ...) {
176 va_start (args, format);
177 vsprintf (where, format, args);
183 einfo (int type, const char *format, ...) {
186 switch (type & 0x0f) {
188 fprintf (stderr, "%s: ", progname);
191 fprintf (stderr, "%s: ", filename);
194 ewhere ("%d", lineno);
197 fprintf (stderr, "%s:%s: ", filename, where);
201 if (type & E_WARNING) {
202 fprintf (stderr, "warning: ");
208 va_start (args, format);
209 vfprintf (stderr, format, args);
215 fprintf (stderr, "\n");
220 get_symbols (bfd *abfd, long *num)
223 asymbol **symbol_table;
224 long number_of_symbols;
226 storage_needed = bfd_get_symtab_upper_bound (abfd);
228 if (storage_needed < 0)
231 if (storage_needed == 0)
234 symbol_table = (asymbol **) malloc (storage_needed);
236 number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
238 if (number_of_symbols < 0)
241 *num = number_of_symbols;
248 dump_symbols(asymbol **symbol_table, long number_of_symbols)
251 printf("SYMBOL TABLE:\n");
252 for (i=0; i<number_of_symbols; i++) {
253 printf(" NAME=%s VALUE=0x%x\n", symbol_table[i]->name,
254 symbol_table[i]->value);
263 get_symbol_offset(char *name, asection *sec, asymbol **symbol_table, long number_of_symbols)
266 for (i=0; i<number_of_symbols; i++) {
267 if (symbol_table[i]->section == sec) {
268 if (!strcmp(symbol_table[i]->name, name)) {
269 return symbol_table[i]->value;
279 get_gp_value(asymbol **symbol_table, long number_of_symbols)
282 for (i=0; i<number_of_symbols; i++) {
283 if (!strcmp(symbol_table[i]->name, "_gp"))
284 return symbol_table[i]->value;
292 add_com_to_bss(asymbol **symbol_table, long number_of_symbols, long bss_len)
298 for (i=0; i<number_of_symbols; i++) {
299 if (strcmp("*COM*", symbol_table[i]->section->name) == 0) {
300 offset = bss_len + comsize;
301 comsize += symbol_table[i]->value;
302 symbol_table[i]->value = offset;
309 /* stack to handle "arithmetic" relocations */
310 #define RELOC_STACK_SIZE 100
311 static bfd_vma reloc_stack[RELOC_STACK_SIZE];
312 static unsigned int reloc_stack_tos = 0;
313 static char sym_section_name[80];
314 static asection *stack_sym_section = 0;
317 reloc_stack_set_section(asection *section, const char *sym_section_name_in)
319 /* TODO : we can add checks to make sure we do not
320 add different section names to the same arithmetic
322 strcpy(sym_section_name, sym_section_name_in);
323 stack_sym_section = section;
327 reloc_stack_get_section_name()
329 return sym_section_name;
331 static asection *reloc_stack_get_section()
333 return stack_sym_section;
336 #define is_reloc_stack_empty() ((reloc_stack_tos > 0)?0:1)
339 reloc_stack_push(bfd_vma value)
341 reloc_stack[reloc_stack_tos++] = value;
347 return reloc_stack[--reloc_stack_tos];
351 reloc_stack_operate(unsigned int oper)
356 value = reloc_stack[reloc_stack_tos - 2] + reloc_stack[reloc_stack_tos - 1];
357 reloc_stack_tos -= 2;
360 value = reloc_stack[reloc_stack_tos - 2] - reloc_stack[reloc_stack_tos - 1];
361 reloc_stack_tos -= 2;
364 value = reloc_stack[reloc_stack_tos - 2] * reloc_stack[reloc_stack_tos - 1];
365 reloc_stack_tos -= 2;
368 value = reloc_stack[reloc_stack_tos - 2] / reloc_stack[reloc_stack_tos - 1];
369 reloc_stack_tos -= 2;
372 value = reloc_stack[reloc_stack_tos - 2] % reloc_stack[reloc_stack_tos - 1];
373 reloc_stack_tos -= 2;
376 value = reloc_stack[reloc_stack_tos - 2] << reloc_stack[reloc_stack_tos - 1];
377 reloc_stack_tos -= 2;
380 value = reloc_stack[reloc_stack_tos - 2] >> reloc_stack[reloc_stack_tos - 1];
381 reloc_stack_tos -= 2;
384 value = reloc_stack[reloc_stack_tos - 2] & reloc_stack[reloc_stack_tos - 1];
385 reloc_stack_tos -= 2;
388 value = reloc_stack[reloc_stack_tos - 2] | reloc_stack[reloc_stack_tos - 1];
389 reloc_stack_tos -= 2;
392 value = reloc_stack[reloc_stack_tos - 2] ^ reloc_stack[reloc_stack_tos - 1];
393 reloc_stack_tos -= 2;
396 value = reloc_stack[reloc_stack_tos - 2] && reloc_stack[reloc_stack_tos - 1];
397 reloc_stack_tos -= 2;
400 value = reloc_stack[reloc_stack_tos - 2] || reloc_stack[reloc_stack_tos - 1];
401 reloc_stack_tos -= 2;
404 value = -reloc_stack[reloc_stack_tos - 1];
408 value = ~reloc_stack[reloc_stack_tos - 1];
409 reloc_stack_tos -= 1;
412 fprintf(stderr, "bfin relocation : Internal bug\n");
416 // now push the new value back on stack
417 reloc_stack_push(value);
422 /* FUNCTION : weak_und_symbol
423 ABSTRACT : return true if symbol is weak and undefined.
426 weak_und_symbol(const char *reloc_section_name,
427 struct bfd_symbol *symbol)
429 if (!(strstr (reloc_section_name, "text")
430 || strstr (reloc_section_name, "data")
431 || strstr (reloc_section_name, "bss"))) {
432 if (symbol->flags & BSF_WEAK) {
434 fprintf(stderr, "found weak undefined symbol %s\n", symbol->name);
443 bfin_set_reloc (uint32_t *reloc,
444 const char *reloc_section_name,
445 const char *sym_name,
446 struct bfd_symbol *symbol,
447 int sp, int hilo, int32_t offset)
452 if (strstr (reloc_section_name, "text"))
453 type = FLAT_RELOC_TYPE_TEXT;
454 else if (strstr (reloc_section_name, "data"))
455 type = FLAT_RELOC_TYPE_DATA;
456 else if (strstr (reloc_section_name, "bss"))
457 type = FLAT_RELOC_TYPE_BSS;
458 else if (strstr (reloc_section_name, "stack"))
459 type = FLAT_RELOC_TYPE_STACK;
460 else if (symbol->flags & BSF_WEAK){
461 /* weak symbol support ... if a weak symbol is undefined at the
462 end of a final link, it should return 0 rather than error
463 We will assume text section for the moment.
465 type = FLAT_RELOC_TYPE_TEXT;
466 } else if (strstr (reloc_section_name, "*ABS*")){
467 /* (A data section initialization of something in the shared libc's text section
468 does not resolve - i.e. a global pointer to function initialized with
470 The text section here is appropriate as the section information
471 of the shared library is lost. The loader will do some calcs.
473 type = FLAT_RELOC_TYPE_TEXT;
475 printf ("Unknown Type - relocation for %s in bad section - %s\n", sym_name, reloc_section_name);
479 val = (offset & ((1 << 26) - 1)) << 6;
480 val |= (sp & (1 << 3) - 1) << 3;
481 val |= (hilo & 1) << 2;
482 val |= (type & (1 << 2) - 1);
493 int number_of_symbols,
494 unsigned long *n_relocs,
495 unsigned char *text, int text_len, unsigned long text_vma,
496 unsigned char *data, int data_len, unsigned long data_vma,
499 uint32_t *flat_relocs;
500 asection *a, *sym_section, *r;
501 arelent **relpp, **p, *q;
502 const char *sym_name, *section_name;
503 unsigned char *sectionp;
504 unsigned long pflags;
506 long sym_addr, sym_vma, section_vma;
507 int relsize, relcount;
508 int flat_reloc_count;
509 int sym_reloc_size, rc;
516 printf("%s(%d): output_relocs(abs_bfd=%d,synbols=0x%x,number_of_symbols=%d"
517 "n_relocs=0x%x,text=0x%x,text_len=%d,data=0x%x,data_len=%d)\n",
518 __FILE__, __LINE__, abs_bfd, symbols, number_of_symbols, n_relocs,
519 text, text_len, data, data_len);
523 dump_symbols(symbols, number_of_symbols);
528 flat_reloc_count = 0;
532 /* Determine how big our offset table is in bytes.
533 * This isn't too difficult as we've terminated the table with -1.
534 * Also note that both the relocatable and absolute versions have this
535 * terminator even though the relocatable one doesn't have the GOT!
538 unsigned long *lp = (unsigned long *)data;
539 /* Should call ntohl(*lp) here but is isn't going to matter */
540 while (*lp != 0xffffffff) lp++;
541 got_size = ((unsigned char *)lp) - data;
543 printf("GOT table contains %d entries (%d bytes)\n",
544 got_size/sizeof(unsigned long), got_size);
546 if (got_size > GOT_LIMIT) {
547 fprintf(stderr, "GOT too large: %d bytes (limit = %d bytes)\n",
548 got_size, GOT_LIMIT);
554 for (a = abs_bfd->sections; (a != (asection *) NULL); a = a->next) {
555 section_vma = bfd_section_vma(abs_bfd, a);
558 printf("SECTION: %s [0x%x]: flags=0x%x vma=0x%x\n", a->name, a,
559 a->flags, section_vma);
561 // if (bfd_is_abs_section(a))
563 if (bfd_is_und_section(a))
565 if (bfd_is_com_section(a))
567 // if ((a->flags & SEC_RELOC) == 0)
571 * Only relocate things in the data sections if we are PIC/GOT.
572 * otherwise do text as well
574 if (!pic_with_got && (a->flags & SEC_CODE))
575 sectionp = text + (a->vma - text_vma);
576 else if (a->flags & SEC_DATA)
577 sectionp = data + (a->vma - data_vma);
581 /* Now search for the equivalent section in the relocation binary
582 * and use that relocation information to build reloc entries
585 for (r=rel_bfd->sections; r != NULL; r=r->next)
586 if (strcmp(a->name, r->name) == 0)
591 printf(" RELOCS: %s [0x%x]: flags=0x%x vma=0x%x\n", r->name, r,
592 r->flags, bfd_section_vma(abs_bfd, r));
593 if ((r->flags & SEC_RELOC) == 0)
595 relsize = bfd_get_reloc_upper_bound(rel_bfd, r);
598 printf("%s(%d): no relocation entries section=0x%x\n",
599 __FILE__, __LINE__, r->name);
603 symb = get_symbols(rel_bfd, &nsymb);
604 relpp = (arelent **) xmalloc(relsize);
605 relcount = bfd_canonicalize_reloc(rel_bfd, r, relpp, symb);
608 printf("%s(%d): no relocation entries section=%s\n",
609 __FILE__, __LINE__, r->name);
612 for (p = relpp; (relcount && (*p != NULL)); p++, relcount--) {
613 unsigned char *r_mem;
614 int relocation_needed = 0;
616 #ifdef TARGET_microblaze
617 /* The MICROBLAZE_XX_NONE relocs can be skipped.
618 They represent PC relative branches that the
619 linker has already resolved */
621 switch ((*p)->howto->type)
623 case R_MICROBLAZE_NONE:
624 case R_MICROBLAZE_64_NONE:
627 #endif /* TARGET_microblaze */
630 /* Skip this relocation entirely if possible (we
631 do this early, before doing any other
632 processing on it). */
633 switch ((*p)->howto->type) {
634 #ifdef R_V850_9_PCREL
637 #ifdef R_V850_22_PCREL
638 case R_V850_22_PCREL:
640 #ifdef R_V850_SDA_16_16_OFFSET
641 case R_V850_SDA_16_16_OFFSET:
643 #ifdef R_V850_SDA_15_16_OFFSET
644 case R_V850_SDA_15_16_OFFSET:
646 #ifdef R_V850_ZDA_15_16_OFFSET
647 case R_V850_ZDA_15_16_OFFSET:
649 #ifdef R_V850_TDA_6_8_OFFSET
650 case R_V850_TDA_6_8_OFFSET:
652 #ifdef R_V850_TDA_7_8_OFFSET
653 case R_V850_TDA_7_8_OFFSET:
655 #ifdef R_V850_TDA_7_7_OFFSET
656 case R_V850_TDA_7_7_OFFSET:
658 #ifdef R_V850_TDA_16_16_OFFSET
659 case R_V850_TDA_16_16_OFFSET:
661 #ifdef R_V850_TDA_4_5_OFFSET
662 case R_V850_TDA_4_5_OFFSET:
664 #ifdef R_V850_TDA_4_4_OFFSET
665 case R_V850_TDA_4_4_OFFSET:
667 #ifdef R_V850_SDA_16_16_SPLIT_OFFSET
668 case R_V850_SDA_16_16_SPLIT_OFFSET:
670 #ifdef R_V850_CALLT_6_7_OFFSET
671 case R_V850_CALLT_6_7_OFFSET:
673 #ifdef R_V850_CALLT_16_16_OFFSET
674 case R_V850_CALLT_16_16_OFFSET:
676 /* These are relative relocations, which
677 have already been fixed up by the
678 linker at this point, so just ignore
682 #endif /* USE_V850_RELOCS */
686 if ((q->sym_ptr_ptr && *q->sym_ptr_ptr) &&
687 (!is_reloc_stack_empty() && strstr((*(q->sym_ptr_ptr))->name, "operator"))){
688 /* must be an arith reloc ... get the value from the stack */
689 sym_name = (*(q->sym_ptr_ptr))->name;
690 sym_section = reloc_stack_get_section();
691 section_name = reloc_stack_get_section_name();
695 if (q->sym_ptr_ptr && *q->sym_ptr_ptr) {
696 sym_name = (*(q->sym_ptr_ptr))->name;
697 sym_section = (*(q->sym_ptr_ptr))->section;
698 section_name=(*(q->sym_ptr_ptr))->section->name;
700 printf("ERROR: undefined relocation entry\n");
705 /* Adjust the address to account for the GOT table which wasn't
706 * present in the relative file link.
709 q->address += got_size;
712 /* A pointer to what's being relocated, used often
714 r_mem = sectionp + q->address;
717 * Fixup offset in the actual section.
721 if ((sym_addr = get_symbol_offset((char *) sym_name,
722 sym_section, symbols, number_of_symbols)) == -1) {
726 sym_addr = (*(q->sym_ptr_ptr))->value;
729 /* Use the address of the symbol already in
730 the program text. How this is handled may
731 still depend on the particular relocation
733 switch (q->howto->type) {
737 /* We specially handle adjacent
738 HI16_S/ZDA_15_16_OFFSET and
739 HI16_S/LO16 pairs that reference the
740 same address (these are usually
741 movhi/ld and movhi/movea pairs,
744 r2_type = R_V850_NONE;
746 r2_type = p[1]->howto->type;
747 if ((r2_type == R_V850_ZDA_15_16_OFFSET
748 || r2_type == R_V850_LO16)
749 && (p[0]->sym_ptr_ptr
750 == p[1]->sym_ptr_ptr)
751 && (p[0]->addend == p[1]->addend))
753 relocation_needed = 1;
756 case R_V850_ZDA_15_16_OFFSET:
764 /* We don't really need the
765 actual value -- the bits
766 produced by the linker are
767 what we want in the final
768 flat file -- but get it
772 unsigned char *r2_mem =
780 /* Sign extend LO. */
784 /* Maybe ignore the LSB
788 if (r2_type != R_V850_LO16)
796 goto bad_v850_reloc_err;
800 /* See if this is actually the
801 2nd half of a pair. */
803 && (p[-1]->howto->type
805 && (p[-1]->sym_ptr_ptr
806 == p[0]->sym_ptr_ptr)
807 && (p[-1]->addend == p[0]->addend))
808 break; /* not an error */
810 goto bad_v850_reloc_err;
814 printf("ERROR: reloc type %s unsupported in this context\n",
818 #endif /* TARGET_V850 */
821 /* The default is to assume that the
822 relocation is relative and has
823 already been fixed up by the
824 linker (perhaps we ought to make
825 give an error by default, and
826 require `safe' relocations to be
827 enumberated explicitly?). */
828 if (bfd_big_endian (abs_bfd))
840 relocation_needed = 1;
843 /* Calculate the sym address ourselves. */
844 sym_reloc_size = bfd_get_reloc_size(q->howto);
846 #if !defined(TARGET_h8300) && !defined(TARGET_e1) && !defined(TARGET_bfin)
847 if (sym_reloc_size != 4) {
848 printf("ERROR: bad reloc type %d size=%d for symbol=%s\n",
849 (*p)->howto->type, sym_reloc_size, sym_name);
856 switch ((*p)->howto->type) {
858 #if defined(TARGET_m68k)
860 relocation_needed = 1;
861 sym_vma = bfd_section_vma(abs_bfd, sym_section);
862 sym_addr += sym_vma + q->addend;
866 sym_addr += sym_vma + q->addend;
867 sym_addr -= q->address;
871 #if defined(TARGET_arm)
873 relocation_needed = 1;
876 "%s vma=0x%x, value=0x%x, address=0x%x "
877 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
879 sym_vma, (*(q->sym_ptr_ptr))->value,
880 q->address, sym_addr,
881 (*p)->howto->rightshift,
882 *(unsigned long *)r_mem);
883 sym_vma = bfd_section_vma(abs_bfd, sym_section);
884 sym_addr += sym_vma + q->addend;
888 /* Should be fine as is */
893 "%s vma=0x%x, value=0x%x, address=0x%x "
894 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
896 sym_vma, (*(q->sym_ptr_ptr))->value,
897 q->address, sym_addr,
898 (*p)->howto->rightshift,
899 *(unsigned long *)r_mem);
902 sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift;
908 relocation_needed = 1;
909 sym_vma = bfd_section_vma(abs_bfd, sym_section);
910 sym_addr += sym_vma + q->addend;
912 #if defined(R_V850_ZDA_16_16_OFFSET) || defined(R_V850_ZDA_16_16_SPLIT_OFFSET)
913 #ifdef R_V850_ZDA_16_16_OFFSET
914 case R_V850_ZDA_16_16_OFFSET:
916 #ifdef R_V850_ZDA_16_16_SPLIT_OFFSET
917 case R_V850_ZDA_16_16_SPLIT_OFFSET:
919 /* Can't support zero-relocations. */
920 printf ("ERROR: %s+0x%x: zero relocations not supported\n",
921 sym_name, q->addend);
923 #endif /* R_V850_ZDA_16_16_OFFSET || R_V850_ZDA_16_16_SPLIT_OFFSET */
924 #endif /* TARGET_v850 */
928 if (sym_reloc_size != 4) {
929 printf("R_H8_DIR24R8 size %d\n", sym_reloc_size);
933 relocation_needed = 1;
934 sym_addr = (*(q->sym_ptr_ptr))->value;
936 r_mem -= 1; /* tracks q->address */
937 sym_vma = bfd_section_vma(abs_bfd, sym_section);
938 sym_addr += sym_vma + q->addend;
939 sym_addr |= (*(unsigned char *)r_mem<<24);
942 if (sym_reloc_size != 4) {
943 printf("R_H8_DIR24A8 size %d\n", sym_reloc_size);
947 /* Absolute symbol done not relocation */
948 relocation_needed = !bfd_is_abs_section(sym_section);
949 sym_addr = (*(q->sym_ptr_ptr))->value;
950 sym_vma = bfd_section_vma(abs_bfd, sym_section);
951 sym_addr += sym_vma + q->addend;
954 case R_H8_DIR32A16: /* currently 32, could be made 16 */
955 if (sym_reloc_size != 4) {
956 printf("R_H8_DIR32 size %d\n", sym_reloc_size);
960 relocation_needed = 1;
961 sym_addr = (*(q->sym_ptr_ptr))->value;
962 sym_vma = bfd_section_vma(abs_bfd, sym_section);
963 sym_addr += sym_vma + q->addend;
967 sym_addr = (*(q->sym_ptr_ptr))->value;
968 sym_addr += sym_vma + q->addend;
969 sym_addr -= (q->address + 2);
970 if (bfd_big_endian(abs_bfd))
971 *(unsigned short *)r_mem =
972 bfd_big_endian(abs_bfd) ? htons(sym_addr) : sym_addr;
976 sym_addr = (*(q->sym_ptr_ptr))->value;
977 sym_addr += sym_vma + q->addend;
978 sym_addr -= (q->address + 1);
979 *(unsigned char *)r_mem = sym_addr;
983 #ifdef TARGET_microblaze
984 case R_MICROBLAZE_64:
985 /* The symbol is split over two consecutive instructions.
986 Flag this to the flat loader by setting the high bit of
987 the relocation symbol. */
989 unsigned char *p = r_mem;
990 unsigned long offset;
993 /* work out the relocation */
994 sym_vma = bfd_section_vma(abs_bfd, sym_section);
995 /* grab any offset from the text */
996 offset = (p[2]<<24) + (p[3] << 16) + (p[6] << 8) + (p[7]);
997 /* Update the address */
998 sym_addr += offset + sym_vma + q->addend;
999 /* Write relocated pointer back */
1000 p[2] = (sym_addr >> 24) & 0xff;
1001 p[3] = (sym_addr >> 16) & 0xff;
1002 p[6] = (sym_addr >> 8) & 0xff;
1003 p[7] = sym_addr & 0xff;
1005 /* create a new reloc entry */
1006 flat_relocs = realloc(flat_relocs,
1007 (flat_reloc_count + 1) * sizeof(uint32_t));
1008 flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address);
1010 relocation_needed = 0;
1012 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
1013 bfd_section_vma(abs_bfd, sym_section));
1015 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
1016 "section=%s size=%d "
1017 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
1018 q->address, sym_name, addstr,
1019 section_name, sym_reloc_size,
1020 sym_addr, section_vma + q->address);
1022 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
1023 section_vma + q->address);
1027 case R_MICROBLAZE_32:
1029 unsigned char *p = r_mem;
1030 unsigned long offset;
1032 /* grab any offset from the text */
1033 offset = (p[0]<<24) + (p[1] << 16) + (p[2] << 8) + (p[3]);
1034 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1035 /* This is a horrible kludge. For some
1036 reason, *sometimes* the offset is in
1037 both addend and the code. Detect
1038 it, and cancel the effect. Otherwise
1039 the offset gets added twice - ouch.
1040 There should be a better test
1041 for this condition, based on the
1042 BFD data structures */
1043 if(offset==q->addend)
1046 sym_addr += offset + sym_vma + q->addend;
1047 relocation_needed = 1;
1050 case R_MICROBLAZE_64_PCREL:
1052 //sym_addr = (*(q->sym_ptr_ptr))->value;
1053 sym_addr += sym_vma + q->addend;
1054 sym_addr -= (q->address + 4);
1055 sym_addr = htonl(sym_addr);
1057 * ((unsigned short *) (r_mem+2)) |= (sym_addr) & 0xFFFF;
1059 * ((unsigned short *) (r_mem+6)) |= (sym_addr >> 16) & 0xFFFF;
1060 /* We've done all the work, so continue
1061 to next reloc instead of break */
1064 #endif /* TARGET_microblaze */
1067 #define htoniosl(x) (x)
1068 #define niostohl(x) (x)
1069 switch ((*p)->howto->type)
1071 case R_NIOS2_BFD_RELOC_32:
1072 relocation_needed = 1;
1073 pflags = (FLAT_NIOS2_R_32 << 28);
1074 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1075 sym_addr += sym_vma + q->addend;
1076 /* modify target, in target order */
1077 *(unsigned long *)r_mem = htoniosl(sym_addr);
1079 case R_NIOS2_CALL26:
1081 unsigned long exist_val;
1082 relocation_needed = 1;
1083 pflags = (FLAT_NIOS2_R_CALL26 << 28);
1084 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1085 sym_addr += sym_vma + q->addend;
1087 /* modify target, in target order */
1088 // exist_val = niostohl(*(unsigned long *)r_mem);
1089 exist_val = ((sym_addr >> 2) << 6);
1090 *(unsigned long *)r_mem = htoniosl(exist_val);
1093 case R_NIOS2_HIADJ16:
1096 unsigned long exist_val;
1098 /* handle the adjacent HI/LO pairs */
1100 r2_type = R_NIOS2_NONE;
1102 r2_type = p[1]->howto->type;
1103 if ((r2_type == R_NIOS2_LO16)
1104 && (p[0]->sym_ptr_ptr == p[1]->sym_ptr_ptr)
1105 && (p[0]->addend == p[1]->addend))
1107 unsigned char * r2_mem = sectionp + p[1]->address;
1108 if (p[1]->address - q->address!=4)
1109 printf("Err: HI/LO not adjacent %d\n", p[1]->address - q->address);
1110 relocation_needed = 1;
1111 pflags = (q->howto->type == R_NIOS2_HIADJ16)
1112 ? FLAT_NIOS2_R_HIADJ_LO : FLAT_NIOS2_R_HI_LO;
1115 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1116 sym_addr += sym_vma + q->addend;
1118 /* modify high 16 bits, in target order */
1119 exist_val = niostohl(*(unsigned long *)r_mem);
1120 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1121 if (q->howto->type == R_NIOS2_HIADJ16)
1122 exist_val |= ((((sym_addr >> 16) + ((sym_addr >> 15) & 1)) & 0xFFFF) << 6);
1124 exist_val |= (((sym_addr >> 16) & 0xFFFF) << 6);
1125 *(unsigned long *)r_mem = htoniosl(exist_val);
1127 /* modify low 16 bits, in target order */
1128 exist_val = niostohl(*(unsigned long *)r2_mem);
1129 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1130 exist_val |= ((sym_addr & 0xFFFF) << 6);
1131 *(unsigned long *)r2_mem = htoniosl(exist_val);
1134 goto NIOS2_RELOC_ERR;
1140 unsigned long exist_val, temp;
1141 //long gp = get_symbol_offset("_gp", sym_section, symbols, number_of_symbols);
1142 long gp = get_gp_value(symbols, number_of_symbols);
1144 printf("Err: unresolved symbol _gp when relocating %s\n", sym_name);
1145 goto NIOS2_RELOC_ERR;
1147 /* _gp holds a absolute value, otherwise the ld cannot generate correct code */
1148 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1149 //printf("sym=%x, %d, _gp=%x, %d\n", sym_addr+sym_vma, sym_addr+sym_vma, gp, gp);
1150 sym_addr += sym_vma + q->addend;
1152 //printf("sym - _gp=%x, %d\n", sym_addr, sym_addr);
1153 /* modify the target, in target order (little_endian) */
1154 exist_val = niostohl(*(unsigned long *)r_mem);
1155 temp = ((exist_val >> 6) & 0x3ff0000) | (sym_addr & 0xffff);
1157 temp |= (exist_val & 0x3f);
1158 *(unsigned long *)r_mem = htoniosl(temp);
1160 printf("omit: offset=0x%x symbol=%s%s "
1161 "section=%s size=%d "
1162 "fixup=0x%x (reloc=0x%x) GPREL\n",
1163 q->address, sym_name, addstr,
1164 section_name, sym_reloc_size,
1165 sym_addr, section_vma + q->address);
1168 case R_NIOS2_PCREL16:
1170 unsigned long exist_val;
1172 sym_addr += sym_vma + q->addend;
1173 sym_addr -= (q->address + 4);
1174 /* modify the target, in target order (little_endian) */
1175 exist_val = niostohl(*(unsigned long *)r_mem);
1176 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1177 exist_val |= ((sym_addr & 0xFFFF) << 6);
1178 *(unsigned long *)r_mem = htoniosl(exist_val);
1180 printf("omit: offset=0x%x symbol=%s%s "
1181 "section=%s size=%d "
1182 "fixup=0x%x (reloc=0x%x) PCREL\n",
1183 q->address, sym_name, addstr,
1184 section_name, sym_reloc_size,
1185 sym_addr, section_vma + q->address);
1190 /* check if this is actually the 2nd half of a pair */
1192 && ((p[-1]->howto->type == R_NIOS2_HIADJ16)
1193 || (p[-1]->howto->type == R_NIOS2_HI16))
1194 && (p[-1]->sym_ptr_ptr == p[0]->sym_ptr_ptr)
1195 && (p[-1]->addend == p[0]->addend)) {
1197 printf("omit: offset=0x%x symbol=%s%s "
1198 "section=%s size=%d LO16\n",
1199 q->address, sym_name, addstr,
1200 section_name, sym_reloc_size);
1204 /* error, fall through */
1208 case R_NIOS2_CACHE_OPX:
1212 case R_NIOS2_BFD_RELOC_16:
1213 case R_NIOS2_BFD_RELOC_8:
1214 case R_NIOS2_GNU_VTINHERIT:
1215 case R_NIOS2_GNU_VTENTRY:
1220 printf("Err: unexpected reloc type %s(%d)\n", q->howto->name, q->howto->type);
1224 #endif /* TARGET_nios2 */
1229 relocation_needed = 1;
1230 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1231 sym_addr += sym_vma + q->addend;
1235 sym_addr += sym_vma + q->addend;
1236 sym_addr -= q->address;
1238 case R_SPARC_WDISP30:
1239 sym_addr = (((*(q->sym_ptr_ptr))->value-
1240 q->address) >> 2) & 0x3fffffff;
1242 ntohl(*(unsigned long *)r_mem)
1247 relocation_needed = 1;
1248 pflags = 0x80000000;
1249 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1250 sym_addr += sym_vma + q->addend;
1252 htonl(*(unsigned long *)r_mem)
1257 relocation_needed = 1;
1258 pflags = 0x40000000;
1259 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1260 sym_addr += sym_vma + q->addend;
1261 sym_addr &= 0x000003ff;
1263 htonl(*(unsigned long *)r_mem)
1267 #endif /* TARGET_sparc */
1270 case R_pcrel12_jump:
1271 case R_pcrel12_jump_s:
1273 case R_pcrel24_jump_l:
1274 case R_pcrel24_jump_x:
1275 case R_pcrel24_call_x:
1279 sym_addr += q->addend;// get the symbol addr
1280 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1281 sym_addr -= q->address; // make it PC relative
1282 // implicitly assumes code section and symbol section are same
1286 if (is_reloc_stack_empty ())
1288 sym_addr += q->addend;
1290 sym_addr = reloc_stack_pop ();
1292 if(weak_und_symbol(sym_section->name, (*(q->sym_ptr_ptr))))
1294 if(0xFFFF0000 & sym_addr){
1295 fprintf (stderr, "Relocation overflow for rN = %s\n",sym_name);
1298 flat_relocs = (uint32_t *)
1299 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1300 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1301 sym_section->name, sym_name,
1302 (*(q->sym_ptr_ptr)),
1303 0, FLAT_RELOC_PART_LO,
1304 section_vma + q->address))
1313 unsigned int reloc_count_incr;
1316 if (q->howto->type == R_luimm16)
1317 hi_lo = FLAT_RELOC_PART_LO;
1319 hi_lo = FLAT_RELOC_PART_HI;
1321 if (is_reloc_stack_empty ())
1322 sym_addr += q->addend;
1324 sym_addr = reloc_stack_pop ();
1326 flat_relocs = (uint32_t *)
1327 (realloc (flat_relocs, (flat_reloc_count + 2) * sizeof (uint32_t)));
1328 reloc_count_incr = 1;
1329 if (weak_und_symbol (sym_section->name, (*(q->sym_ptr_ptr))))
1331 if (0xFFFF0000 & sym_addr) {
1332 /* value is > 16 bits - use an extra field */
1333 /* see if we have already output that symbol */
1334 /* reloc may be addend from symbol and */
1335 /* we can only store 16 bit offsets */
1337 if ((*(q->sym_ptr_ptr))->udata.i == 0
1338 || flat_relocs[(*(q->sym_ptr_ptr))->udata.i] != sym_addr
1339 || ((*(q->sym_ptr_ptr))->udata.i & 0xFFFF0000))
1341 reloc_count_incr = 2;
1342 flat_relocs[flat_reloc_count + 1] = sym_addr;
1343 (*(q->sym_ptr_ptr))->udata.i = flat_reloc_count + 1;
1344 sym_addr = 0; // indication to loader to read next
1346 sym_addr = (*(q->sym_ptr_ptr))->udata.i;
1352 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1353 sym_section->name, sym_name,
1354 (*(q->sym_ptr_ptr)),
1356 section_vma + q->address))
1358 flat_reloc_count += reloc_count_incr;
1362 if (is_reloc_stack_empty ())
1363 sym_addr += q->addend;
1365 sym_addr = reloc_stack_pop ();
1366 if (weak_und_symbol (sym_section->name, *q->sym_ptr_ptr))
1369 flat_relocs = (uint32_t *)
1370 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1371 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1372 sym_section->name, sym_name,
1373 (*(q->sym_ptr_ptr)),
1374 2, FLAT_RELOC_PART_LO,
1375 section_vma + q->address))
1383 sym_addr += q->addend;
1384 reloc_stack_push(sym_addr);
1385 reloc_stack_set_section(sym_section, section_name);
1390 reloc_stack_push(q->addend);
1394 reloc_stack_operate((*p)->howto->type);
1397 #endif //TARGET_bfin
1401 relocation_needed = 1;
1402 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1403 sym_addr += sym_vma + q->addend;
1407 sym_addr += sym_vma + q->addend;
1408 sym_addr -= q->address;
1410 #endif /* TARGET_sh */
1413 #define htoe1l(x) htonl(x)
1420 #define DBG_E1 printf
1422 #define DBG_E1(x, ... )
1425 #define _32BITS_RELOC 0x00000000
1426 #define _30BITS_RELOC 0x80000000
1427 #define _28BITS_RELOC 0x40000000
1430 unsigned long sec_vma, exist_val, S;
1432 relocation_needed = 1;
1433 DBG_E1("Handling Reloc <CONST31>\n");
1434 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1435 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1436 sec_vma, sym_addr, q->address);
1437 sym_addr = sec_vma + sym_addr;
1438 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1439 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1440 exist_val = htoe1l(exist_val);
1441 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1442 sym_addr += exist_val;
1443 pflags = _30BITS_RELOC;
1445 case R_E1_CONST31_PCREL:
1446 relocation_needed = 0;
1447 DBG_E1("Handling Reloc <CONST31_PCREL>\n");
1448 DBG_E1("DONT RELOCATE AT LOADING\n");
1449 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1450 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1451 sec_vma, sym_addr, q->address);
1452 sym_addr = sec_vma + sym_addr;
1453 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1455 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1457 q->address = q->address + section_vma;
1458 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1460 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1461 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1462 DBG_E1( "sym_addr := sym_addr - q->address - "
1463 "sizeof(CONST31_PCREL): [0x%x]\n",
1465 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
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%x]\n", sym_addr );
1472 case R_E1_DIS29W_PCREL:
1473 relocation_needed = 0;
1474 DBG_E1("Handling Reloc <DIS29W_PCREL>\n");
1475 DBG_E1("DONT RELOCATE AT LOADING\n");
1476 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1477 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1478 sec_vma, sym_addr, q->address);
1479 sym_addr = sec_vma + sym_addr;
1480 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1482 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1484 q->address = q->address + section_vma;
1485 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1487 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1488 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1489 DBG_E1( "sym_addr := sym_addr - q->address - "
1490 "sizeof(CONST31_PCREL): [0x%x]\n",
1492 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1493 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1494 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1495 exist_val = htoe1l(exist_val);
1496 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1497 sym_addr += exist_val;
1500 DBG_E1("Handling Reloc <DIS29W>\n");
1501 goto DIS29_RELOCATION;
1503 DBG_E1("Handling Reloc <DIS29H>\n");
1504 goto DIS29_RELOCATION;
1506 DBG_E1("Handling Reloc <DIS29B>\n");
1508 relocation_needed = 1;
1509 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1510 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%08x]\n",
1512 sym_addr = sec_vma + sym_addr;
1513 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%08x]\n", sym_addr);
1514 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1515 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1516 exist_val = htoe1l(exist_val);
1517 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1518 sym_addr += exist_val;
1519 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1520 pflags = _28BITS_RELOC;
1522 case R_E1_IMM32_PCREL:
1523 relocation_needed = 0;
1524 DBG_E1("Handling Reloc <IMM32_PCREL>\n");
1525 DBG_E1("DONT RELOCATE AT LOADING\n");
1526 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1527 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1529 sym_addr = sec_vma + sym_addr;
1531 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1532 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1534 q->address = q->address + section_vma;
1535 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1537 if( (sym_addr = (sym_addr - q->address - 6 )) < 0 )
1538 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1539 DBG_E1( "sym_addr := sym_addr - q->address - "
1540 "sizeof(CONST31_PCREL): [0x%x]\n",
1542 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1543 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1544 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1545 exist_val = htoe1l(exist_val);
1546 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1547 sym_addr += exist_val;
1550 relocation_needed = 1;
1551 DBG_E1("Handling Reloc <IMM32>\n");
1552 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1553 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1555 sym_addr = sec_vma + sym_addr;
1556 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1557 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1558 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1559 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1560 exist_val = htoe1l(exist_val);
1561 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1562 sym_addr += exist_val;
1563 pflags = _32BITS_RELOC;
1566 relocation_needed = 1;
1567 DBG_E1("Handling Reloc <WORD>\n");
1568 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1569 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1571 sym_addr = sec_vma + sym_addr;
1572 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1573 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address );
1574 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1575 exist_val = htoe1l(exist_val);
1576 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1577 sym_addr += exist_val;
1578 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1579 pflags = _32BITS_RELOC;
1582 #undef _32BITS_RELOC
1583 #undef _30BITS_RELOC
1584 #undef _28BITS_RELOC
1587 /* missing support for other types of relocs */
1588 printf("ERROR: bad reloc type %d\n", (*p)->howto->type);
1594 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
1595 bfd_section_vma(abs_bfd, sym_section));
1599 * for full elf relocation we have to write back the
1600 * start_code relative value to use.
1602 if (!pic_with_got) {
1603 #if defined(TARGET_arm)
1612 * horrible nasty hack to support different endianess
1614 if (!bfd_big_endian(abs_bfd)) {
1626 tmp.l = *(unsigned long *)r_mem;
1627 hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16);
1628 if (((*p)->howto->type != R_ARM_PC24) &&
1629 ((*p)->howto->type != R_ARM_PLT32))
1630 hl |= (tmp.c[i3] << 24);
1631 else if (tmp.c[i2] & 0x80)
1632 hl |= 0xff000000; /* sign extend */
1634 tmp.c[i0] = hl & 0xff;
1635 tmp.c[i1] = (hl >> 8) & 0xff;
1636 tmp.c[i2] = (hl >> 16) & 0xff;
1637 if (((*p)->howto->type != R_ARM_PC24) &&
1638 ((*p)->howto->type != R_ARM_PLT32))
1639 tmp.c[i3] = (hl >> 24) & 0xff;
1640 if ((*p)->howto->type == R_ARM_ABS32)
1641 *(unsigned long *)r_mem = htonl(hl);
1643 *(unsigned long *)r_mem = tmp.l;
1645 #elif defined(TARGET_bfin)
1646 if ((*p)->howto->type == R_pcrel24
1647 || (*p)->howto->type == R_pcrel24_jump_l
1648 || (*p)->howto->type == R_pcrel24_jump_x
1649 || (*p)->howto->type == R_pcrel24_call_x)
1651 sym_addr += 2*-1*PCREL24_MAGIC_OFFSET;
1652 *((unsigned short *)(sectionp + q->address) + 1 + PCREL24_MAGIC_OFFSET)
1653 = (sym_addr >> 1) & 0xffff;
1654 *((unsigned short *)(sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1655 = (0xff00 & *((unsigned short *) (sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1656 | ((sym_addr >> 17) & 0xff));
1657 } else if ((*p)->howto->type == R_byte4_data) {
1658 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1659 } else if ((*p)->howto->type == R_pcrel12_jump
1660 || (*p)->howto->type == R_pcrel12_jump_s) {
1661 *((unsigned short *)(sectionp + q->address))
1662 = (0xf000 & *((unsigned short *)(sectionp + q->address))
1663 | ((sym_addr >> 1) & 0xfff));
1664 } else if ((*p)->howto->type == R_pcrel10) {
1665 *((unsigned short *)(sectionp + q->address))
1666 = (~0x3ff & *((unsigned short *)(sectionp + q->address))
1667 | ((sym_addr >> 1) & 0x3ff));
1668 } else if ((*p)->howto->type == R_rimm16
1669 || (*p)->howto->type == R_huimm16
1670 || (*p)->howto->type == R_luimm16) {
1671 /* for l and h we set the lower 16 bits which is only when it will be used */
1672 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1673 } else if ((*p)->howto->type == R_pcrel5m2) {
1674 *((unsigned short *)(sectionp + q->address))
1675 = (0xfff0 & *((unsigned short *)(sectionp + q->address))
1676 | ((sym_addr >> 1) & 0xf));
1677 } else if ((*p)->howto->type == R_pcrel11){
1678 *((unsigned short *)(sectionp + q->address))
1679 = (0xfc00 & *((unsigned short *)(sectionp + q->address))
1680 | ((sym_addr >> 1) & 0x3ff));
1681 } else if (0xE0 <= (*p)->howto->type && 0xF3 >= (*p)->howto->type) {
1682 //arith relocs dont generate a real relocation
1684 printf("Blackfin relocation fail for reloc type: 0x%x\n", (*p)->howto->type);
1686 #elif defined(TARGET_e1)
1687 #define OPCODE_SIZE 2 /* Add 2 bytes, counting the opcode size*/
1688 switch ((*p)->howto->type) {
1690 case R_E1_CONST31_PCREL:
1691 case R_E1_DIS29W_PCREL:
1695 case R_E1_IMM32_PCREL:
1697 DBG_E1("In addr + 2:[0x%x] <- write [0x%x]\n",
1698 (sectionp + q->address + 2), sym_addr );
1699 *((unsigned long *) (sectionp + q->address + OPCODE_SIZE)) =
1703 DBG_E1("In addr : [0x%x] <- write [0x%x]\n",
1704 (sectionp + q->address), sym_addr );
1705 *((unsigned long *) (sectionp + q->address )) = htonl(sym_addr);
1708 printf("ERROR:Unhandled Relocation. Exiting...\n");
1712 #else /* ! TARGET_arm && ! TARGET_e1 */
1714 switch (q->howto->type) {
1719 /* Do nothing -- for cases we handle,
1720 the bits produced by the linker are
1721 what we want in the final flat file
1722 (and other cases are errors). Note
1723 that unlike most relocated values,
1724 it is stored in little-endian order,
1725 but this is necessary to avoid
1726 trashing the low-bit, and the float
1727 loaders knows about it. */
1729 #endif /* TARGET_V850 */
1732 case R_NIOS2_BFD_RELOC_32:
1733 case R_NIOS2_CALL26:
1734 case R_NIOS2_HIADJ16:
1738 #endif /* TARGET_nios2 */
1741 /* The alignment of the build host
1742 might be stricter than that of the
1743 target, so be careful. We store in
1744 network byte order. */
1745 r_mem[0] = (sym_addr >> 24) & 0xff;
1746 r_mem[1] = (sym_addr >> 16) & 0xff;
1747 r_mem[2] = (sym_addr >> 8) & 0xff;
1748 r_mem[3] = sym_addr & 0xff;
1750 #endif /* !TARGET_arm */
1755 if ((*p)->howto->type == R_rimm16
1756 || (*p)->howto->type == R_huimm16
1757 || (*p)->howto->type == R_luimm16)
1759 /* for l and h we set the lower 16 bits which is only when it will be used */
1760 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1761 } else if ((*p)->howto->type == R_byte4_data) {
1762 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1767 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
1768 "section=%s size=%d "
1769 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
1770 q->address, sym_name, addstr,
1771 section_name, sym_reloc_size,
1772 sym_addr, section_vma + q->address);
1775 * Create relocation entry (PC relative doesn't need this).
1777 if (relocation_needed) {
1779 flat_relocs = realloc(flat_relocs,
1780 (flat_reloc_count + 1) * sizeof(uint32_t));
1782 flat_relocs[flat_reloc_count] = pflags |
1783 (section_vma + q->address);
1786 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
1787 section_vma + q->address);
1789 switch ((*p)->howto->type) {
1791 case R_E1_CONST31_PCREL:
1792 case R_E1_DIS29W_PCREL:
1796 case R_E1_IMM32_PCREL:
1798 flat_relocs[flat_reloc_count] = pflags |
1799 (section_vma + q->address + OPCODE_SIZE);
1801 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1802 flat_relocs[flat_reloc_count] );
1805 flat_relocs[flat_reloc_count] = pflags |
1806 (section_vma + q->address);
1808 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1809 flat_relocs[flat_reloc_count] );
1815 relocation_needed = 0;
1820 printf("%s(%d): symbol name=%s address=0x%x section=%s -> RELOC=0x%x\n",
1821 __FILE__, __LINE__, sym_name, q->address, section_name,
1822 flat_relocs[flat_reloc_count]);
1829 printf("%d bad relocs\n", bad_relocs);
1836 *n_relocs = flat_reloc_count;
1842 static char * program;
1844 static void usage(void)
1846 fprintf(stderr, "Usage: %s [vrzd] [-p <abs-pic-file>] [-s stack-size] "
1847 "[-o <output-file>] <elf-file>\n\n"
1848 " -v : verbose operation\n"
1849 " -r : force load to RAM\n"
1850 " -k : enable kernel trace on load (for debug)\n"
1851 " -z : compress code/data/relocs\n"
1852 " -d : compress data/relocs\n"
1853 " -a : use existing symbol references\n"
1854 " instead of recalculating from\n"
1855 " relocation info\n"
1856 " -R reloc-file : read relocations from a separate file\n"
1857 " -p abs-pic-file : GOT/PIC processing with files\n"
1858 " -s stacksize : set application stack size\n"
1859 " -o output-file : output file name\n\n",
1861 fprintf(stderr, "Compiled for " ARCH " architecture\n\n");
1866 /* Write NUM zeroes to STREAM. */
1867 static void write_zeroes (unsigned long num, FILE *stream)
1871 /* It'd be nice if we could just use fseek, but that doesn't seem to
1872 work for stdio output files. */
1873 bzero(zeroes, 1024);
1874 while (num > sizeof(zeroes)) {
1875 fwrite(zeroes, sizeof(zeroes), 1, stream);
1876 num -= sizeof(zeroes);
1879 fwrite(zeroes, num, 1, stream);
1884 int main(int argc, char *argv[])
1887 bfd *rel_bfd, *abs_bfd;
1889 char *ofile=NULL, *pfile=NULL, *abs_file = NULL, *rel_file = NULL;
1897 asymbol **symbol_table;
1898 long number_of_symbols;
1900 unsigned long data_len = 0;
1901 unsigned long bss_len = 0;
1902 unsigned long text_len = 0;
1903 unsigned long reloc_len;
1905 unsigned long data_vma = ~0;
1906 unsigned long bss_vma = ~0;
1907 unsigned long text_vma = ~0;
1909 unsigned long text_offs;
1915 struct flat_hdr hdr;
1925 if (sizeof(hdr) != 64) {
1927 "Potential flat header incompatibility detected\n"
1928 "header size should be 64 but is %d\n",
1935 #else /* We need plenty of stack for both of them (Aggregate and Register) */
1939 while ((opt = getopt(argc, argv, "avzdrkp:s:o:R:")) != -1) {
1966 stack = atoi(optarg);
1972 fprintf(stderr, "%s Unknown option\n", argv[0]);
1979 * if neither the -r or -p options was given, default to
1980 * a RAM load as that is the only option that makes sense.
1982 if (!load_to_ram && !pfile)
1985 filename = fname = argv[argc-1];
1996 if (!(rel_bfd = bfd_openr(rel_file, 0))) {
1997 fprintf(stderr, "Can't open %s\n", rel_file);
2001 if (bfd_check_format (rel_bfd, bfd_object) == 0) {
2002 fprintf(stderr, "File is not an object file\n");
2006 if (abs_file == rel_file)
2007 abs_bfd = rel_bfd; /* one file does all */
2009 if (!(abs_bfd = bfd_openr(abs_file, 0))) {
2010 fprintf(stderr, "Can't open %s\n", abs_file);
2014 if (bfd_check_format (abs_bfd, bfd_object) == 0) {
2015 fprintf(stderr, "File is not an object file\n");
2020 if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC)) {
2021 fprintf (stderr, "%s: Input file contains no relocation info\n", rel_file);
2025 if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P)) {
2026 /* `Absolute' file is not absolute, so neither are address
2027 contained therein. */
2029 "%s: `-a' option specified with non-fully-resolved input file\n",
2030 bfd_get_filename (abs_bfd));
2034 symbol_table = get_symbols(abs_bfd, &number_of_symbols);
2036 /* Group output sections into text, data, and bss, and calc their sizes. */
2037 for (s = abs_bfd->sections; s != NULL; s = s->next) {
2038 unsigned long *vma, *len;
2039 bfd_size_type sec_size;
2042 if (s->flags & SEC_CODE) {
2045 } else if (s->flags & SEC_DATA) {
2048 } else if (s->flags & SEC_ALLOC) {
2054 sec_size = bfd_section_size(abs_bfd, s);
2055 sec_vma = bfd_section_vma(abs_bfd, s);
2057 if (sec_vma < *vma) {
2059 *len += sec_vma - *vma;
2063 } else if (sec_vma + sec_size > *vma + *len)
2064 *len = sec_vma + sec_size - *vma;
2067 if (text_len == 0) {
2068 fprintf (stderr, "%s: no .text section", abs_file);
2072 text = malloc(text_len);
2075 printf("TEXT -> vma=0x%x len=0x%x\n", text_vma, text_len);
2077 /* Read in all text sections. */
2078 for (s = abs_bfd->sections; s != NULL; s = s->next)
2079 if (s->flags & SEC_CODE)
2080 if (!bfd_get_section_contents(abs_bfd, s,
2081 text + (s->vma - text_vma), 0,
2082 bfd_section_size(abs_bfd, s)))
2084 fprintf(stderr, "read error section %s\n", s->name);
2088 if (data_len == 0) {
2089 fprintf (stderr, "%s: no .data section", abs_file);
2092 data = malloc(data_len);
2095 printf("DATA -> vma=0x%x len=0x%x\n", data_vma, data_len);
2097 if ((text_vma + text_len) != data_vma) {
2098 if ((text_vma + text_len) > data_vma) {
2099 printf("ERROR: text=0x%x overlaps data=0x%x ?\n", text_len, data_vma);
2103 printf("WARNING: data=0x%x does not directly follow text=0x%x\n",
2104 data_vma, text_len);
2105 text_len = data_vma - text_vma;
2108 /* Read in all data sections. */
2109 for (s = abs_bfd->sections; s != NULL; s = s->next)
2110 if (s->flags & SEC_DATA)
2111 if (!bfd_get_section_contents(abs_bfd, s,
2112 data + (s->vma - data_vma), 0,
2113 bfd_section_size(abs_bfd, s)))
2115 fprintf(stderr, "read error section %s\n", s->name);
2119 /* Put common symbols in bss. */
2120 bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len);
2123 printf("BSS -> vma=0x%x len=0x%x\n", bss_vma, bss_len);
2125 if ((data_vma + data_len) != bss_vma) {
2126 if ((data_vma + data_len) > bss_vma) {
2127 printf("ERROR: text=0x%x + data=0x%x overlaps bss=0x%x ?\n", text_len,
2132 printf("WARNING: bss=0x%x does not directly follow text=0x%x + data=0x%x(0x%x)\n",
2133 bss_vma, text_len, data_len, text_len + data_len);
2134 data_len = bss_vma - data_vma;
2137 reloc = output_relocs(abs_bfd, symbol_table, number_of_symbols, &reloc_len,
2138 text, text_len, text_vma, data, data_len, data_vma,
2142 printf("No relocations in code!\n");
2144 text_offs = real_address_bits(text_vma);
2146 /* Fill in the binflt_flat header */
2147 memcpy(hdr.magic,"bFLT",4);
2148 hdr.rev = htonl(FLAT_VERSION);
2149 hdr.entry = htonl(sizeof(hdr) + bfd_get_start_address(abs_bfd));
2150 hdr.data_start = htonl(sizeof(hdr) + text_offs + text_len);
2151 hdr.data_end = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2152 hdr.bss_end = htonl(sizeof(hdr) + text_offs + text_len +data_len+bss_len);
2153 hdr.stack_size = htonl(stack); /* FIXME */
2154 hdr.reloc_start = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2155 hdr.reloc_count = htonl(reloc_len);
2157 | (load_to_ram ? FLAT_FLAG_RAM : 0)
2158 | (ktrace ? FLAT_FLAG_KTRACE : 0)
2159 | (pic_with_got ? FLAT_FLAG_GOTPIC : 0)
2160 | (compress ? (compress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
2162 hdr.build_date = htonl((unsigned long)time(NULL));
2163 bzero(hdr.filler, sizeof(hdr.filler));
2165 for (i=0; i<reloc_len; i++) reloc[i] = htonl(reloc[i]);
2168 printf("SIZE: .text=0x%04x, .data=0x%04x, .bss=0x%04x",
2169 text_len, data_len, bss_len);
2171 printf(", relocs=0x%04x", reloc_len);
2176 ofile = malloc(strlen(fname) + 5 + 1); /* 5 to add suffix */
2177 strcpy(ofile, fname);
2178 strcat(ofile, ".bflt");
2181 if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0) {
2182 fprintf (stderr, "Can't open output file %s\n", ofile);
2186 write(fd, &hdr, sizeof(hdr));
2190 * get the compression command ready
2192 sprintf(cmd, "gzip -f -9 >> %s", ofile);
2194 #define START_COMPRESSOR do { \
2200 if (!(gf = popen(cmd, "wb"))) { \
2201 fprintf(stderr, "Can't run cmd %s\n", cmd); \
2207 gf = fopen(ofile, "ab"); /* Add 'b' to support non-posix (ie windows) */
2209 fprintf(stderr, "Can't open file %s for writing\n", ofile); \
2216 /* Fill in any hole at the beginning of the text segment. */
2218 printf("ZERO before text len=0x%x\n", text_offs);
2219 write_zeroes(text_offs, gf);
2221 /* Write the text segment. */
2222 fwrite(text, text_len, 1, gf);
2227 /* Write the data segment. */
2228 fwrite(data, data_len, 1, gf);
2231 fwrite(reloc, reloc_len * 4, 1, gf);
2243 * this __MUST__ be at the VERY end of the file - do NOT move!!
2249 * vi: tabstop=8 shiftwidth=4 textwidth=79 noexpandtab