2 * elf2flt.c: Convert ELF (or any BFD format) to FLAT binary format
4 * (c) 1999-2002, Greg Ungerer <gerg@snapgear.com>
5 * Created elf2flt from coff2flt (see copyrights below). Added all the
6 * ELF format file handling. Extended relocation support for all of
9 * (c) 2004, Nios II support, Wentao Xu <wentao@microtronix.com>
10 * (c) 2003, H8 support, ktrace <davidm@snapgear.com>
11 * (c) 2003-2004, MicroBlaze support, John Williams <jwilliams@itee.uq.edu.au>
12 * (c) 2001-2003, arm/arm-pic/arm-big-endian support <davidm@snapgear.com>
13 * (c) 2001, v850 changes, Mile Bader <miles@lsi.nec.co.jp>
14 * (c) 2003, SuperH support, Paul Mundt <lethal@linux-sh.org>
15 * (c) 2001, zflat support <davidm@snapgear.com>
16 * (c) 2001, Changes for GOT entries Paul Dale <pauli@snapgear.com> and
17 * David McCullough <davidm@snapgear.com>
19 * Now supports PIC with GOT tables. This works by taking a '.elf' file
20 * and a fully linked elf executable (at address 0) and produces a flat
21 * file that can be loaded with some fixups. It still supports the old
22 * style fully relocatable elf format files.
24 * Originally obj-res.c
26 * (c) 1998, Kenneth Albanowski <kjahds@kjahds.com>
27 * (c) 1998, D. Jeff Dionne
28 * (c) 1998, The Silver Hammer Group Ltd.
29 * (c) 1996, 1997 Dionne & Associates <jeff@ryeham.ee.ryerson.ca>
31 * This is Free Software, under the GNU Public Licence v2 or greater.
33 * Relocation added March 1997, Kresten Krab Thorup
34 * krab@california.daimi.aau.dk
37 #include <stdio.h> /* Userland pieces of the ANSI C standard I/O package */
38 #include <stdlib.h> /* Userland prototypes of the ANSI C std lib functions */
39 #include <stdarg.h> /* Allows va_list to exist in the these namespaces */
40 #include <string.h> /* Userland prototypes of the string handling funcs */
42 #include <unistd.h> /* Userland prototypes of the Unix std system calls */
43 #include <fcntl.h> /* Flag value for file handling functions */
46 #include <netinet/in.h> /* Consts and structs defined by the internet system */
47 #define BINARY_FILE_OPTS
50 #define BINARY_FILE_OPTS "b"
53 /* from $(INSTALLDIR)/include */
54 #include <bfd.h> /* Main header file for the BFD library */
56 #if defined(TARGET_h8300)
57 #include <elf/h8.h> /* TARGET_* ELF support for the BFD library */
58 #elif defined(__CYGWIN__) || defined(__MINGW32__) || defined(TARGET_nios) || defined(TARGET_nios2)
59 #include "cygwin-elf.h" /* Cygwin uses a local copy */
60 #elif defined(TARGET_microblaze)
61 #include <elf/microblaze.h> /* TARGET_* ELF support for the BFD library */
62 #elif defined(TARGET_bfin)
65 #include <elf.h> /* TARGET_* ELF support for the BFD library */
68 #if defined(__MINGW32__)
72 /* from uClinux-x.x.x/include/linux */
73 #include "flat.h" /* Binary flat header description */
83 #if defined(TARGET_m68k)
84 #define ARCH "m68k/coldfire"
85 #elif defined(TARGET_arm)
87 #elif defined(TARGET_sparc)
89 #elif defined(TARGET_v850)
91 #elif defined(TARGET_sh)
93 #elif defined(TARGET_h8300)
95 #elif defined(TARGET_microblaze)
96 #define ARCH "microblaze"
97 #elif defined(TARGET_e1)
98 #define ARCH "e1-coff"
99 #elif defined(TARGET_bfin)
101 #define FLAT_RELOC_TYPE_TEXT 0
102 #define FLAT_RELOC_TYPE_DATA 1
103 #define FLAT_RELOC_TYPE_BSS 2
104 #define FLAT_RELOC_TYPE_STACK 3
105 #define FLAT_RELOC_PART_LO 0
106 #define FLAT_RELOC_PART_HI 1
107 #define PCREL24_MAGIC_OFFSET -1
108 #elif defined(TARGET_nios)
110 #elif defined(TARGET_nios2)
113 #error "Don't know how to support your CPU architecture??"
116 #if defined(TARGET_m68k) || defined(TARGET_h8300) || defined(TARGET_bfin)
118 * Define a maximum number of bytes allowed in the offset table.
119 * We'll fail if the table is larger than this.
121 * This limit may be different for platforms other than m68k, but
122 * 8000 entries is a lot, trust me :-) (davidm)
124 #define GOT_LIMIT 32767
126 * we have to mask out the shared library id here and there, this gives
127 * us the real address bits when needed
129 #define real_address_bits(x) (pic_with_got ? ((x) & 0xffffff) : (x))
131 #define real_address_bits(x) (x)
139 int verbose = 0; /* extra output when running */
140 int pic_with_got = 0; /* do elf/got processing with PIC code */
141 int load_to_ram = 0; /* instruct loader to allocate everything into RAM */
142 int ktrace = 0; /* instruct loader output kernel trace on load */
143 int compress = 0; /* 1 = compress everything, 2 = compress data only */
144 int use_resolved = 0; /* If true, get the value of symbol references from */
145 /* the program contents, not from the relocation table. */
146 /* In this case, the input ELF file must be already */
147 /* fully resolved (using the `-q' flag with recent */
148 /* versions of GNU ld will give you a fully resolved */
149 /* output file with relocation entries). */
151 const char *progname, *filename;
157 static char where[200];
160 /* Use exactly one of these: */
161 E_NOFILE = 0, /* "progname: " */
162 E_FILE = 1, /* "filename: " */
163 E_FILELINE = 2, /* "filename:lineno: " */
164 E_FILEWHERE = 3, /* "filename:%s: " -- set %s with ewhere() */
166 /* Add in any of these with |': */
171 void ewhere (const char *format, ...);
172 void einfo (int type, const char *format, ...);
176 ewhere (const char *format, ...) {
178 va_start (args, format);
179 vsprintf (where, format, args);
185 einfo (int type, const char *format, ...) {
188 switch (type & 0x0f) {
190 fprintf (stderr, "%s: ", progname);
193 fprintf (stderr, "%s: ", filename);
196 ewhere ("%d", lineno);
199 fprintf (stderr, "%s:%s: ", filename, where);
203 if (type & E_WARNING) {
204 fprintf (stderr, "warning: ");
210 va_start (args, format);
211 vfprintf (stderr, format, args);
217 fprintf (stderr, "\n");
222 get_symbols (bfd *abfd, long *num)
225 asymbol **symbol_table;
226 long number_of_symbols;
228 storage_needed = bfd_get_symtab_upper_bound (abfd);
230 if (storage_needed < 0)
233 if (storage_needed == 0)
236 symbol_table = (asymbol **) malloc (storage_needed);
238 number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
240 if (number_of_symbols < 0)
243 *num = number_of_symbols;
250 dump_symbols(asymbol **symbol_table, long number_of_symbols)
253 printf("SYMBOL TABLE:\n");
254 for (i=0; i<number_of_symbols; i++) {
255 printf(" NAME=%s VALUE=0x%x\n", symbol_table[i]->name,
256 symbol_table[i]->value);
265 get_symbol_offset(char *name, asection *sec, asymbol **symbol_table, long number_of_symbols)
268 for (i=0; i<number_of_symbols; i++) {
269 if (symbol_table[i]->section == sec) {
270 if (!strcmp(symbol_table[i]->name, name)) {
271 return symbol_table[i]->value;
281 get_gp_value(asymbol **symbol_table, long number_of_symbols)
284 for (i=0; i<number_of_symbols; i++) {
285 if (!strcmp(symbol_table[i]->name, "_gp"))
286 return symbol_table[i]->value;
294 add_com_to_bss(asymbol **symbol_table, long number_of_symbols, long bss_len)
300 for (i=0; i<number_of_symbols; i++) {
301 if (strcmp("*COM*", symbol_table[i]->section->name) == 0) {
302 offset = bss_len + comsize;
303 comsize += symbol_table[i]->value;
304 symbol_table[i]->value = offset;
311 /* stack to handle "arithmetic" relocations */
312 #define RELOC_STACK_SIZE 100
313 static bfd_vma reloc_stack[RELOC_STACK_SIZE];
314 static unsigned int reloc_stack_tos = 0;
315 static char sym_section_name[80];
316 static asection *stack_sym_section = 0;
319 reloc_stack_set_section(asection *section, const char *sym_section_name_in)
321 /* TODO : we can add checks to make sure we do not
322 add different section names to the same arithmetic
324 strcpy(sym_section_name, sym_section_name_in);
325 stack_sym_section = section;
329 reloc_stack_get_section_name()
331 return sym_section_name;
333 static asection *reloc_stack_get_section()
335 return stack_sym_section;
338 #define is_reloc_stack_empty() ((reloc_stack_tos > 0)?0:1)
341 reloc_stack_push(bfd_vma value)
343 reloc_stack[reloc_stack_tos++] = value;
349 return reloc_stack[--reloc_stack_tos];
353 reloc_stack_operate(unsigned int oper)
358 value = reloc_stack[reloc_stack_tos - 2] + reloc_stack[reloc_stack_tos - 1];
359 reloc_stack_tos -= 2;
362 value = reloc_stack[reloc_stack_tos - 2] - reloc_stack[reloc_stack_tos - 1];
363 reloc_stack_tos -= 2;
366 value = reloc_stack[reloc_stack_tos - 2] * reloc_stack[reloc_stack_tos - 1];
367 reloc_stack_tos -= 2;
370 value = reloc_stack[reloc_stack_tos - 2] / reloc_stack[reloc_stack_tos - 1];
371 reloc_stack_tos -= 2;
374 value = reloc_stack[reloc_stack_tos - 2] % reloc_stack[reloc_stack_tos - 1];
375 reloc_stack_tos -= 2;
378 value = reloc_stack[reloc_stack_tos - 2] << reloc_stack[reloc_stack_tos - 1];
379 reloc_stack_tos -= 2;
382 value = reloc_stack[reloc_stack_tos - 2] >> reloc_stack[reloc_stack_tos - 1];
383 reloc_stack_tos -= 2;
386 value = reloc_stack[reloc_stack_tos - 2] & reloc_stack[reloc_stack_tos - 1];
387 reloc_stack_tos -= 2;
390 value = reloc_stack[reloc_stack_tos - 2] | reloc_stack[reloc_stack_tos - 1];
391 reloc_stack_tos -= 2;
394 value = reloc_stack[reloc_stack_tos - 2] ^ reloc_stack[reloc_stack_tos - 1];
395 reloc_stack_tos -= 2;
398 value = reloc_stack[reloc_stack_tos - 2] && reloc_stack[reloc_stack_tos - 1];
399 reloc_stack_tos -= 2;
402 value = reloc_stack[reloc_stack_tos - 2] || reloc_stack[reloc_stack_tos - 1];
403 reloc_stack_tos -= 2;
406 value = -reloc_stack[reloc_stack_tos - 1];
410 value = ~reloc_stack[reloc_stack_tos - 1];
411 reloc_stack_tos -= 1;
414 fprintf(stderr, "bfin relocation : Internal bug\n");
418 // now push the new value back on stack
419 reloc_stack_push(value);
424 /* FUNCTION : weak_und_symbol
425 ABSTRACT : return true if symbol is weak and undefined.
428 weak_und_symbol(const char *reloc_section_name,
429 struct bfd_symbol *symbol)
431 if (!(strstr (reloc_section_name, "text")
432 || strstr (reloc_section_name, "data")
433 || strstr (reloc_section_name, "bss"))) {
434 if (symbol->flags & BSF_WEAK) {
436 fprintf(stderr, "found weak undefined symbol %s\n", symbol->name);
445 bfin_set_reloc (uint32_t *reloc,
446 const char *reloc_section_name,
447 const char *sym_name,
448 struct bfd_symbol *symbol,
449 int sp, int hilo, int32_t offset)
454 if (strstr (reloc_section_name, "text"))
455 type = FLAT_RELOC_TYPE_TEXT;
456 else if (strstr (reloc_section_name, "data"))
457 type = FLAT_RELOC_TYPE_DATA;
458 else if (strstr (reloc_section_name, "bss"))
459 type = FLAT_RELOC_TYPE_BSS;
460 else if (strstr (reloc_section_name, "stack"))
461 type = FLAT_RELOC_TYPE_STACK;
462 else if (symbol->flags & BSF_WEAK){
463 /* weak symbol support ... if a weak symbol is undefined at the
464 end of a final link, it should return 0 rather than error
465 We will assume text section for the moment.
467 type = FLAT_RELOC_TYPE_TEXT;
468 } else if (strstr (reloc_section_name, "*ABS*")){
469 /* (A data section initialization of something in the shared libc's text section
470 does not resolve - i.e. a global pointer to function initialized with
472 The text section here is appropriate as the section information
473 of the shared library is lost. The loader will do some calcs.
475 type = FLAT_RELOC_TYPE_TEXT;
477 printf ("Unknown Type - relocation for %s in bad section - %s\n", sym_name, reloc_section_name);
481 val = (offset & ((1 << 26) - 1)) << 6;
482 val |= (sp & (1 << 3) - 1) << 3;
483 val |= (hilo & 1) << 2;
484 val |= (type & (1 << 2) - 1);
495 int number_of_symbols,
496 unsigned long *n_relocs,
497 unsigned char *text, int text_len, unsigned long text_vma,
498 unsigned char *data, int data_len, unsigned long data_vma,
501 uint32_t *flat_relocs;
502 asection *a, *sym_section, *r;
503 arelent **relpp, **p, *q;
504 const char *sym_name, *section_name;
505 unsigned char *sectionp;
506 unsigned long pflags;
508 long sym_addr, sym_vma, section_vma;
509 int relsize, relcount;
510 int flat_reloc_count;
511 int sym_reloc_size, rc;
518 printf("%s(%d): output_relocs(abs_bfd=%d,synbols=0x%x,number_of_symbols=%d"
519 "n_relocs=0x%x,text=0x%x,text_len=%d,data=0x%x,data_len=%d)\n",
520 __FILE__, __LINE__, abs_bfd, symbols, number_of_symbols, n_relocs,
521 text, text_len, data, data_len);
525 dump_symbols(symbols, number_of_symbols);
530 flat_reloc_count = 0;
534 /* Determine how big our offset table is in bytes.
535 * This isn't too difficult as we've terminated the table with -1.
536 * Also note that both the relocatable and absolute versions have this
537 * terminator even though the relocatable one doesn't have the GOT!
540 unsigned long *lp = (unsigned long *)data;
541 /* Should call ntohl(*lp) here but is isn't going to matter */
542 while (*lp != 0xffffffff) lp++;
543 got_size = ((unsigned char *)lp) - data;
545 printf("GOT table contains %d entries (%d bytes)\n",
546 got_size/sizeof(unsigned long), got_size);
548 if (got_size > GOT_LIMIT) {
549 fprintf(stderr, "GOT too large: %d bytes (limit = %d bytes)\n",
550 got_size, GOT_LIMIT);
556 for (a = abs_bfd->sections; (a != (asection *) NULL); a = a->next) {
557 section_vma = bfd_section_vma(abs_bfd, a);
560 printf("SECTION: %s [0x%x]: flags=0x%x vma=0x%x\n", a->name, a,
561 a->flags, section_vma);
563 // if (bfd_is_abs_section(a))
565 if (bfd_is_und_section(a))
567 if (bfd_is_com_section(a))
569 // if ((a->flags & SEC_RELOC) == 0)
573 * Only relocate things in the data sections if we are PIC/GOT.
574 * otherwise do text as well
576 if (!pic_with_got && (a->flags & SEC_CODE))
577 sectionp = text + (a->vma - text_vma);
578 else if (a->flags & SEC_DATA)
579 sectionp = data + (a->vma - data_vma);
583 /* Now search for the equivalent section in the relocation binary
584 * and use that relocation information to build reloc entries
587 for (r=rel_bfd->sections; r != NULL; r=r->next)
588 if (strcmp(a->name, r->name) == 0)
593 printf(" RELOCS: %s [0x%x]: flags=0x%x vma=0x%x\n", r->name, r,
594 r->flags, bfd_section_vma(abs_bfd, r));
595 if ((r->flags & SEC_RELOC) == 0)
597 relsize = bfd_get_reloc_upper_bound(rel_bfd, r);
600 printf("%s(%d): no relocation entries section=0x%x\n",
601 __FILE__, __LINE__, r->name);
605 symb = get_symbols(rel_bfd, &nsymb);
606 relpp = (arelent **) xmalloc(relsize);
607 relcount = bfd_canonicalize_reloc(rel_bfd, r, relpp, symb);
610 printf("%s(%d): no relocation entries section=%s\n",
611 __FILE__, __LINE__, r->name);
614 for (p = relpp; (relcount && (*p != NULL)); p++, relcount--) {
615 unsigned char *r_mem;
616 int relocation_needed = 0;
618 #ifdef TARGET_microblaze
619 /* The MICROBLAZE_XX_NONE relocs can be skipped.
620 They represent PC relative branches that the
621 linker has already resolved */
623 switch ((*p)->howto->type)
625 case R_MICROBLAZE_NONE:
626 case R_MICROBLAZE_64_NONE:
629 #endif /* TARGET_microblaze */
632 /* Skip this relocation entirely if possible (we
633 do this early, before doing any other
634 processing on it). */
635 switch ((*p)->howto->type) {
636 #ifdef R_V850_9_PCREL
639 #ifdef R_V850_22_PCREL
640 case R_V850_22_PCREL:
642 #ifdef R_V850_SDA_16_16_OFFSET
643 case R_V850_SDA_16_16_OFFSET:
645 #ifdef R_V850_SDA_15_16_OFFSET
646 case R_V850_SDA_15_16_OFFSET:
648 #ifdef R_V850_ZDA_15_16_OFFSET
649 case R_V850_ZDA_15_16_OFFSET:
651 #ifdef R_V850_TDA_6_8_OFFSET
652 case R_V850_TDA_6_8_OFFSET:
654 #ifdef R_V850_TDA_7_8_OFFSET
655 case R_V850_TDA_7_8_OFFSET:
657 #ifdef R_V850_TDA_7_7_OFFSET
658 case R_V850_TDA_7_7_OFFSET:
660 #ifdef R_V850_TDA_16_16_OFFSET
661 case R_V850_TDA_16_16_OFFSET:
663 #ifdef R_V850_TDA_4_5_OFFSET
664 case R_V850_TDA_4_5_OFFSET:
666 #ifdef R_V850_TDA_4_4_OFFSET
667 case R_V850_TDA_4_4_OFFSET:
669 #ifdef R_V850_SDA_16_16_SPLIT_OFFSET
670 case R_V850_SDA_16_16_SPLIT_OFFSET:
672 #ifdef R_V850_CALLT_6_7_OFFSET
673 case R_V850_CALLT_6_7_OFFSET:
675 #ifdef R_V850_CALLT_16_16_OFFSET
676 case R_V850_CALLT_16_16_OFFSET:
678 /* These are relative relocations, which
679 have already been fixed up by the
680 linker at this point, so just ignore
684 #endif /* USE_V850_RELOCS */
688 if ((q->sym_ptr_ptr && *q->sym_ptr_ptr) &&
689 (!is_reloc_stack_empty() && strstr((*(q->sym_ptr_ptr))->name, "operator"))){
690 /* must be an arith reloc ... get the value from the stack */
691 sym_name = (*(q->sym_ptr_ptr))->name;
692 sym_section = reloc_stack_get_section();
693 section_name = reloc_stack_get_section_name();
697 if (q->sym_ptr_ptr && *q->sym_ptr_ptr) {
698 sym_name = (*(q->sym_ptr_ptr))->name;
699 sym_section = (*(q->sym_ptr_ptr))->section;
700 section_name=(*(q->sym_ptr_ptr))->section->name;
702 printf("ERROR: undefined relocation entry\n");
707 /* Adjust the address to account for the GOT table which wasn't
708 * present in the relative file link.
711 q->address += got_size;
714 /* A pointer to what's being relocated, used often
716 r_mem = sectionp + q->address;
719 * Fixup offset in the actual section.
723 if ((sym_addr = get_symbol_offset((char *) sym_name,
724 sym_section, symbols, number_of_symbols)) == -1) {
728 sym_addr = (*(q->sym_ptr_ptr))->value;
731 /* Use the address of the symbol already in
732 the program text. How this is handled may
733 still depend on the particular relocation
735 switch (q->howto->type) {
739 /* We specially handle adjacent
740 HI16_S/ZDA_15_16_OFFSET and
741 HI16_S/LO16 pairs that reference the
742 same address (these are usually
743 movhi/ld and movhi/movea pairs,
746 r2_type = R_V850_NONE;
748 r2_type = p[1]->howto->type;
749 if ((r2_type == R_V850_ZDA_15_16_OFFSET
750 || r2_type == R_V850_LO16)
751 && (p[0]->sym_ptr_ptr
752 == p[1]->sym_ptr_ptr)
753 && (p[0]->addend == p[1]->addend))
755 relocation_needed = 1;
758 case R_V850_ZDA_15_16_OFFSET:
766 /* We don't really need the
767 actual value -- the bits
768 produced by the linker are
769 what we want in the final
770 flat file -- but get it
774 unsigned char *r2_mem =
782 /* Sign extend LO. */
786 /* Maybe ignore the LSB
790 if (r2_type != R_V850_LO16)
798 goto bad_v850_reloc_err;
802 /* See if this is actually the
803 2nd half of a pair. */
805 && (p[-1]->howto->type
807 && (p[-1]->sym_ptr_ptr
808 == p[0]->sym_ptr_ptr)
809 && (p[-1]->addend == p[0]->addend))
810 break; /* not an error */
812 goto bad_v850_reloc_err;
816 printf("ERROR: reloc type %s unsupported in this context\n",
820 #endif /* TARGET_V850 */
823 /* The default is to assume that the
824 relocation is relative and has
825 already been fixed up by the
826 linker (perhaps we ought to make
827 give an error by default, and
828 require `safe' relocations to be
829 enumberated explicitly?). */
830 if (bfd_big_endian (abs_bfd))
842 relocation_needed = 1;
845 /* Calculate the sym address ourselves. */
846 sym_reloc_size = bfd_get_reloc_size(q->howto);
848 #if !defined(TARGET_h8300) && !defined(TARGET_e1) && !defined(TARGET_bfin)
849 if (sym_reloc_size != 4) {
850 printf("ERROR: bad reloc type %d size=%d for symbol=%s\n",
851 (*p)->howto->type, sym_reloc_size, sym_name);
858 switch ((*p)->howto->type) {
860 #if defined(TARGET_m68k)
862 relocation_needed = 1;
863 sym_vma = bfd_section_vma(abs_bfd, sym_section);
864 sym_addr += sym_vma + q->addend;
868 sym_addr += sym_vma + q->addend;
869 sym_addr -= q->address;
873 #if defined(TARGET_arm)
875 relocation_needed = 1;
878 "%s vma=0x%x, value=0x%x, address=0x%x "
879 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
881 sym_vma, (*(q->sym_ptr_ptr))->value,
882 q->address, sym_addr,
883 (*p)->howto->rightshift,
884 *(unsigned long *)r_mem);
885 sym_vma = bfd_section_vma(abs_bfd, sym_section);
886 sym_addr += sym_vma + q->addend;
890 /* Should be fine as is */
895 "%s vma=0x%x, value=0x%x, address=0x%x "
896 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
898 sym_vma, (*(q->sym_ptr_ptr))->value,
899 q->address, sym_addr,
900 (*p)->howto->rightshift,
901 *(unsigned long *)r_mem);
904 sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift;
910 relocation_needed = 1;
911 sym_vma = bfd_section_vma(abs_bfd, sym_section);
912 sym_addr += sym_vma + q->addend;
914 #if defined(R_V850_ZDA_16_16_OFFSET) || defined(R_V850_ZDA_16_16_SPLIT_OFFSET)
915 #ifdef R_V850_ZDA_16_16_OFFSET
916 case R_V850_ZDA_16_16_OFFSET:
918 #ifdef R_V850_ZDA_16_16_SPLIT_OFFSET
919 case R_V850_ZDA_16_16_SPLIT_OFFSET:
921 /* Can't support zero-relocations. */
922 printf ("ERROR: %s+0x%x: zero relocations not supported\n",
923 sym_name, q->addend);
925 #endif /* R_V850_ZDA_16_16_OFFSET || R_V850_ZDA_16_16_SPLIT_OFFSET */
926 #endif /* TARGET_v850 */
930 if (sym_reloc_size != 4) {
931 printf("R_H8_DIR24R8 size %d\n", sym_reloc_size);
935 relocation_needed = 1;
936 sym_addr = (*(q->sym_ptr_ptr))->value;
938 r_mem -= 1; /* tracks q->address */
939 sym_vma = bfd_section_vma(abs_bfd, sym_section);
940 sym_addr += sym_vma + q->addend;
941 sym_addr |= (*(unsigned char *)r_mem<<24);
944 if (sym_reloc_size != 4) {
945 printf("R_H8_DIR24A8 size %d\n", sym_reloc_size);
949 /* Absolute symbol done not relocation */
950 relocation_needed = !bfd_is_abs_section(sym_section);
951 sym_addr = (*(q->sym_ptr_ptr))->value;
952 sym_vma = bfd_section_vma(abs_bfd, sym_section);
953 sym_addr += sym_vma + q->addend;
956 case R_H8_DIR32A16: /* currently 32, could be made 16 */
957 if (sym_reloc_size != 4) {
958 printf("R_H8_DIR32 size %d\n", sym_reloc_size);
962 relocation_needed = 1;
963 sym_addr = (*(q->sym_ptr_ptr))->value;
964 sym_vma = bfd_section_vma(abs_bfd, sym_section);
965 sym_addr += sym_vma + q->addend;
969 sym_addr = (*(q->sym_ptr_ptr))->value;
970 sym_addr += sym_vma + q->addend;
971 sym_addr -= (q->address + 2);
972 if (bfd_big_endian(abs_bfd))
973 *(unsigned short *)r_mem =
974 bfd_big_endian(abs_bfd) ? htons(sym_addr) : sym_addr;
978 sym_addr = (*(q->sym_ptr_ptr))->value;
979 sym_addr += sym_vma + q->addend;
980 sym_addr -= (q->address + 1);
981 *(unsigned char *)r_mem = sym_addr;
985 #ifdef TARGET_microblaze
986 case R_MICROBLAZE_64:
987 /* The symbol is split over two consecutive instructions.
988 Flag this to the flat loader by setting the high bit of
989 the relocation symbol. */
991 unsigned char *p = r_mem;
992 unsigned long offset;
995 /* work out the relocation */
996 sym_vma = bfd_section_vma(abs_bfd, sym_section);
997 /* grab any offset from the text */
998 offset = (p[2]<<24) + (p[3] << 16) + (p[6] << 8) + (p[7]);
999 /* Update the address */
1000 sym_addr += offset + sym_vma + q->addend;
1001 /* Write relocated pointer back */
1002 p[2] = (sym_addr >> 24) & 0xff;
1003 p[3] = (sym_addr >> 16) & 0xff;
1004 p[6] = (sym_addr >> 8) & 0xff;
1005 p[7] = sym_addr & 0xff;
1007 /* create a new reloc entry */
1008 flat_relocs = realloc(flat_relocs,
1009 (flat_reloc_count + 1) * sizeof(uint32_t));
1010 flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address);
1012 relocation_needed = 0;
1014 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
1015 bfd_section_vma(abs_bfd, sym_section));
1017 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
1018 "section=%s size=%d "
1019 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
1020 q->address, sym_name, addstr,
1021 section_name, sym_reloc_size,
1022 sym_addr, section_vma + q->address);
1024 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
1025 section_vma + q->address);
1029 case R_MICROBLAZE_32:
1031 unsigned char *p = r_mem;
1032 unsigned long offset;
1034 /* grab any offset from the text */
1035 offset = (p[0]<<24) + (p[1] << 16) + (p[2] << 8) + (p[3]);
1036 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1037 /* This is a horrible kludge. For some
1038 reason, *sometimes* the offset is in
1039 both addend and the code. Detect
1040 it, and cancel the effect. Otherwise
1041 the offset gets added twice - ouch.
1042 There should be a better test
1043 for this condition, based on the
1044 BFD data structures */
1045 if(offset==q->addend)
1048 sym_addr += offset + sym_vma + q->addend;
1049 relocation_needed = 1;
1052 case R_MICROBLAZE_64_PCREL:
1054 //sym_addr = (*(q->sym_ptr_ptr))->value;
1055 sym_addr += sym_vma + q->addend;
1056 sym_addr -= (q->address + 4);
1057 sym_addr = htonl(sym_addr);
1059 * ((unsigned short *) (r_mem+2)) |= (sym_addr) & 0xFFFF;
1061 * ((unsigned short *) (r_mem+6)) |= (sym_addr >> 16) & 0xFFFF;
1062 /* We've done all the work, so continue
1063 to next reloc instead of break */
1066 #endif /* TARGET_microblaze */
1069 #define htoniosl(x) (x)
1070 #define niostohl(x) (x)
1071 switch ((*p)->howto->type)
1073 case R_NIOS2_BFD_RELOC_32:
1074 relocation_needed = 1;
1075 pflags = (FLAT_NIOS2_R_32 << 28);
1076 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1077 sym_addr += sym_vma + q->addend;
1078 /* modify target, in target order */
1079 *(unsigned long *)r_mem = htoniosl(sym_addr);
1081 case R_NIOS2_CALL26:
1083 unsigned long exist_val;
1084 relocation_needed = 1;
1085 pflags = (FLAT_NIOS2_R_CALL26 << 28);
1086 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1087 sym_addr += sym_vma + q->addend;
1089 /* modify target, in target order */
1090 // exist_val = niostohl(*(unsigned long *)r_mem);
1091 exist_val = ((sym_addr >> 2) << 6);
1092 *(unsigned long *)r_mem = htoniosl(exist_val);
1095 case R_NIOS2_HIADJ16:
1098 unsigned long exist_val;
1100 /* handle the adjacent HI/LO pairs */
1102 r2_type = R_NIOS2_NONE;
1104 r2_type = p[1]->howto->type;
1105 if ((r2_type == R_NIOS2_LO16)
1106 && (p[0]->sym_ptr_ptr == p[1]->sym_ptr_ptr)
1107 && (p[0]->addend == p[1]->addend))
1109 unsigned char * r2_mem = sectionp + p[1]->address;
1110 if (p[1]->address - q->address!=4)
1111 printf("Err: HI/LO not adjacent %d\n", p[1]->address - q->address);
1112 relocation_needed = 1;
1113 pflags = (q->howto->type == R_NIOS2_HIADJ16)
1114 ? FLAT_NIOS2_R_HIADJ_LO : FLAT_NIOS2_R_HI_LO;
1117 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1118 sym_addr += sym_vma + q->addend;
1120 /* modify high 16 bits, in target order */
1121 exist_val = niostohl(*(unsigned long *)r_mem);
1122 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1123 if (q->howto->type == R_NIOS2_HIADJ16)
1124 exist_val |= ((((sym_addr >> 16) + ((sym_addr >> 15) & 1)) & 0xFFFF) << 6);
1126 exist_val |= (((sym_addr >> 16) & 0xFFFF) << 6);
1127 *(unsigned long *)r_mem = htoniosl(exist_val);
1129 /* modify low 16 bits, in target order */
1130 exist_val = niostohl(*(unsigned long *)r2_mem);
1131 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1132 exist_val |= ((sym_addr & 0xFFFF) << 6);
1133 *(unsigned long *)r2_mem = htoniosl(exist_val);
1136 goto NIOS2_RELOC_ERR;
1142 unsigned long exist_val, temp;
1143 //long gp = get_symbol_offset("_gp", sym_section, symbols, number_of_symbols);
1144 long gp = get_gp_value(symbols, number_of_symbols);
1146 printf("Err: unresolved symbol _gp when relocating %s\n", sym_name);
1147 goto NIOS2_RELOC_ERR;
1149 /* _gp holds a absolute value, otherwise the ld cannot generate correct code */
1150 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1151 //printf("sym=%x, %d, _gp=%x, %d\n", sym_addr+sym_vma, sym_addr+sym_vma, gp, gp);
1152 sym_addr += sym_vma + q->addend;
1154 //printf("sym - _gp=%x, %d\n", sym_addr, sym_addr);
1155 /* modify the target, in target order (little_endian) */
1156 exist_val = niostohl(*(unsigned long *)r_mem);
1157 temp = ((exist_val >> 6) & 0x3ff0000) | (sym_addr & 0xffff);
1159 temp |= (exist_val & 0x3f);
1160 *(unsigned long *)r_mem = htoniosl(temp);
1162 printf("omit: offset=0x%x symbol=%s%s "
1163 "section=%s size=%d "
1164 "fixup=0x%x (reloc=0x%x) GPREL\n",
1165 q->address, sym_name, addstr,
1166 section_name, sym_reloc_size,
1167 sym_addr, section_vma + q->address);
1170 case R_NIOS2_PCREL16:
1172 unsigned long exist_val;
1174 sym_addr += sym_vma + q->addend;
1175 sym_addr -= (q->address + 4);
1176 /* modify the target, in target order (little_endian) */
1177 exist_val = niostohl(*(unsigned long *)r_mem);
1178 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1179 exist_val |= ((sym_addr & 0xFFFF) << 6);
1180 *(unsigned long *)r_mem = htoniosl(exist_val);
1182 printf("omit: offset=0x%x symbol=%s%s "
1183 "section=%s size=%d "
1184 "fixup=0x%x (reloc=0x%x) PCREL\n",
1185 q->address, sym_name, addstr,
1186 section_name, sym_reloc_size,
1187 sym_addr, section_vma + q->address);
1192 /* check if this is actually the 2nd half of a pair */
1194 && ((p[-1]->howto->type == R_NIOS2_HIADJ16)
1195 || (p[-1]->howto->type == R_NIOS2_HI16))
1196 && (p[-1]->sym_ptr_ptr == p[0]->sym_ptr_ptr)
1197 && (p[-1]->addend == p[0]->addend)) {
1199 printf("omit: offset=0x%x symbol=%s%s "
1200 "section=%s size=%d LO16\n",
1201 q->address, sym_name, addstr,
1202 section_name, sym_reloc_size);
1206 /* error, fall through */
1210 case R_NIOS2_CACHE_OPX:
1214 case R_NIOS2_BFD_RELOC_16:
1215 case R_NIOS2_BFD_RELOC_8:
1216 case R_NIOS2_GNU_VTINHERIT:
1217 case R_NIOS2_GNU_VTENTRY:
1222 printf("Err: unexpected reloc type %s(%d)\n", q->howto->name, q->howto->type);
1226 #endif /* TARGET_nios2 */
1231 relocation_needed = 1;
1232 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1233 sym_addr += sym_vma + q->addend;
1237 sym_addr += sym_vma + q->addend;
1238 sym_addr -= q->address;
1240 case R_SPARC_WDISP30:
1241 sym_addr = (((*(q->sym_ptr_ptr))->value-
1242 q->address) >> 2) & 0x3fffffff;
1244 ntohl(*(unsigned long *)r_mem)
1249 relocation_needed = 1;
1250 pflags = 0x80000000;
1251 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1252 sym_addr += sym_vma + q->addend;
1254 htonl(*(unsigned long *)r_mem)
1259 relocation_needed = 1;
1260 pflags = 0x40000000;
1261 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1262 sym_addr += sym_vma + q->addend;
1263 sym_addr &= 0x000003ff;
1265 htonl(*(unsigned long *)r_mem)
1269 #endif /* TARGET_sparc */
1272 case R_pcrel12_jump:
1273 case R_pcrel12_jump_s:
1275 case R_pcrel24_jump_l:
1276 case R_pcrel24_jump_x:
1277 case R_pcrel24_call_x:
1281 sym_addr += q->addend;// get the symbol addr
1282 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1283 sym_addr -= q->address; // make it PC relative
1284 // implicitly assumes code section and symbol section are same
1288 if (is_reloc_stack_empty ())
1290 sym_addr += q->addend;
1292 sym_addr = reloc_stack_pop ();
1294 if(weak_und_symbol(sym_section->name, (*(q->sym_ptr_ptr))))
1296 if(0xFFFF0000 & sym_addr){
1297 fprintf (stderr, "Relocation overflow for rN = %s\n",sym_name);
1300 flat_relocs = (uint32_t *)
1301 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1302 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1303 sym_section->name, sym_name,
1304 (*(q->sym_ptr_ptr)),
1305 0, FLAT_RELOC_PART_LO,
1306 section_vma + q->address))
1315 unsigned int reloc_count_incr;
1318 if (q->howto->type == R_luimm16)
1319 hi_lo = FLAT_RELOC_PART_LO;
1321 hi_lo = FLAT_RELOC_PART_HI;
1323 if (is_reloc_stack_empty ())
1324 sym_addr += q->addend;
1326 sym_addr = reloc_stack_pop ();
1328 flat_relocs = (uint32_t *)
1329 (realloc (flat_relocs, (flat_reloc_count + 2) * sizeof (uint32_t)));
1330 reloc_count_incr = 1;
1331 if (weak_und_symbol (sym_section->name, (*(q->sym_ptr_ptr))))
1333 if (0xFFFF0000 & sym_addr) {
1334 /* value is > 16 bits - use an extra field */
1335 /* see if we have already output that symbol */
1336 /* reloc may be addend from symbol and */
1337 /* we can only store 16 bit offsets */
1339 if ((*(q->sym_ptr_ptr))->udata.i == 0
1340 || flat_relocs[(*(q->sym_ptr_ptr))->udata.i] != sym_addr
1341 || ((*(q->sym_ptr_ptr))->udata.i & 0xFFFF0000))
1343 reloc_count_incr = 2;
1344 flat_relocs[flat_reloc_count + 1] = sym_addr;
1345 (*(q->sym_ptr_ptr))->udata.i = flat_reloc_count + 1;
1346 sym_addr = 0; // indication to loader to read next
1348 sym_addr = (*(q->sym_ptr_ptr))->udata.i;
1354 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1355 sym_section->name, sym_name,
1356 (*(q->sym_ptr_ptr)),
1358 section_vma + q->address))
1360 flat_reloc_count += reloc_count_incr;
1364 if (is_reloc_stack_empty ())
1365 sym_addr += q->addend;
1367 sym_addr = reloc_stack_pop ();
1368 if (weak_und_symbol (sym_section->name, *q->sym_ptr_ptr))
1371 flat_relocs = (uint32_t *)
1372 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1373 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1374 sym_section->name, sym_name,
1375 (*(q->sym_ptr_ptr)),
1376 2, FLAT_RELOC_PART_LO,
1377 section_vma + q->address))
1385 sym_addr += q->addend;
1386 reloc_stack_push(sym_addr);
1387 reloc_stack_set_section(sym_section, section_name);
1392 reloc_stack_push(q->addend);
1396 reloc_stack_operate((*p)->howto->type);
1399 #endif //TARGET_bfin
1403 relocation_needed = 1;
1404 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1405 sym_addr += sym_vma + q->addend;
1409 sym_addr += sym_vma + q->addend;
1410 sym_addr -= q->address;
1412 #endif /* TARGET_sh */
1415 #define htoe1l(x) htonl(x)
1422 #define DBG_E1 printf
1424 #define DBG_E1(x, ... )
1427 #define _32BITS_RELOC 0x00000000
1428 #define _30BITS_RELOC 0x80000000
1429 #define _28BITS_RELOC 0x40000000
1432 unsigned long sec_vma, exist_val, S;
1434 relocation_needed = 1;
1435 DBG_E1("Handling Reloc <CONST31>\n");
1436 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1437 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1438 sec_vma, sym_addr, q->address);
1439 sym_addr = sec_vma + sym_addr;
1440 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1441 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1442 exist_val = htoe1l(exist_val);
1443 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1444 sym_addr += exist_val;
1445 pflags = _30BITS_RELOC;
1447 case R_E1_CONST31_PCREL:
1448 relocation_needed = 0;
1449 DBG_E1("Handling Reloc <CONST31_PCREL>\n");
1450 DBG_E1("DONT RELOCATE AT LOADING\n");
1451 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1452 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1453 sec_vma, sym_addr, q->address);
1454 sym_addr = sec_vma + sym_addr;
1455 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1457 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1459 q->address = q->address + section_vma;
1460 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1462 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1463 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1464 DBG_E1( "sym_addr := sym_addr - q->address - "
1465 "sizeof(CONST31_PCREL): [0x%x]\n",
1467 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1468 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1469 exist_val = htoe1l(exist_val);
1470 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1471 sym_addr |= exist_val;
1472 DBG_E1("sym_addr |= exist_val) : [0x%x]\n", sym_addr );
1474 case R_E1_DIS29W_PCREL:
1475 relocation_needed = 0;
1476 DBG_E1("Handling Reloc <DIS29W_PCREL>\n");
1477 DBG_E1("DONT RELOCATE AT LOADING\n");
1478 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1479 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1480 sec_vma, sym_addr, q->address);
1481 sym_addr = sec_vma + sym_addr;
1482 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1484 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1486 q->address = q->address + section_vma;
1487 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1489 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1490 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1491 DBG_E1( "sym_addr := sym_addr - q->address - "
1492 "sizeof(CONST31_PCREL): [0x%x]\n",
1494 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1495 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1496 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1497 exist_val = htoe1l(exist_val);
1498 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1499 sym_addr += exist_val;
1502 DBG_E1("Handling Reloc <DIS29W>\n");
1503 goto DIS29_RELOCATION;
1505 DBG_E1("Handling Reloc <DIS29H>\n");
1506 goto DIS29_RELOCATION;
1508 DBG_E1("Handling Reloc <DIS29B>\n");
1510 relocation_needed = 1;
1511 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1512 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%08x]\n",
1514 sym_addr = sec_vma + sym_addr;
1515 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%08x]\n", sym_addr);
1516 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1517 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1518 exist_val = htoe1l(exist_val);
1519 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1520 sym_addr += exist_val;
1521 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1522 pflags = _28BITS_RELOC;
1524 case R_E1_IMM32_PCREL:
1525 relocation_needed = 0;
1526 DBG_E1("Handling Reloc <IMM32_PCREL>\n");
1527 DBG_E1("DONT RELOCATE AT LOADING\n");
1528 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1529 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1531 sym_addr = sec_vma + sym_addr;
1533 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1534 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1536 q->address = q->address + section_vma;
1537 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1539 if( (sym_addr = (sym_addr - q->address - 6 )) < 0 )
1540 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1541 DBG_E1( "sym_addr := sym_addr - q->address - "
1542 "sizeof(CONST31_PCREL): [0x%x]\n",
1544 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1545 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1546 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1547 exist_val = htoe1l(exist_val);
1548 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1549 sym_addr += exist_val;
1552 relocation_needed = 1;
1553 DBG_E1("Handling Reloc <IMM32>\n");
1554 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1555 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1557 sym_addr = sec_vma + sym_addr;
1558 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1559 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1560 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1561 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1562 exist_val = htoe1l(exist_val);
1563 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1564 sym_addr += exist_val;
1565 pflags = _32BITS_RELOC;
1568 relocation_needed = 1;
1569 DBG_E1("Handling Reloc <WORD>\n");
1570 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1571 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1573 sym_addr = sec_vma + sym_addr;
1574 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1575 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address );
1576 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1577 exist_val = htoe1l(exist_val);
1578 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1579 sym_addr += exist_val;
1580 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1581 pflags = _32BITS_RELOC;
1584 #undef _32BITS_RELOC
1585 #undef _30BITS_RELOC
1586 #undef _28BITS_RELOC
1589 /* missing support for other types of relocs */
1590 printf("ERROR: bad reloc type %d\n", (*p)->howto->type);
1596 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
1597 bfd_section_vma(abs_bfd, sym_section));
1601 * for full elf relocation we have to write back the
1602 * start_code relative value to use.
1604 if (!pic_with_got) {
1605 #if defined(TARGET_arm)
1614 * horrible nasty hack to support different endianess
1616 if (!bfd_big_endian(abs_bfd)) {
1628 tmp.l = *(unsigned long *)r_mem;
1629 hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16);
1630 if (((*p)->howto->type != R_ARM_PC24) &&
1631 ((*p)->howto->type != R_ARM_PLT32))
1632 hl |= (tmp.c[i3] << 24);
1633 else if (tmp.c[i2] & 0x80)
1634 hl |= 0xff000000; /* sign extend */
1636 tmp.c[i0] = hl & 0xff;
1637 tmp.c[i1] = (hl >> 8) & 0xff;
1638 tmp.c[i2] = (hl >> 16) & 0xff;
1639 if (((*p)->howto->type != R_ARM_PC24) &&
1640 ((*p)->howto->type != R_ARM_PLT32))
1641 tmp.c[i3] = (hl >> 24) & 0xff;
1642 if ((*p)->howto->type == R_ARM_ABS32)
1643 *(unsigned long *)r_mem = htonl(hl);
1645 *(unsigned long *)r_mem = tmp.l;
1647 #elif defined(TARGET_bfin)
1648 if ((*p)->howto->type == R_pcrel24
1649 || (*p)->howto->type == R_pcrel24_jump_l
1650 || (*p)->howto->type == R_pcrel24_jump_x
1651 || (*p)->howto->type == R_pcrel24_call_x)
1653 sym_addr += 2*-1*PCREL24_MAGIC_OFFSET;
1654 *((unsigned short *)(sectionp + q->address) + 1 + PCREL24_MAGIC_OFFSET)
1655 = (sym_addr >> 1) & 0xffff;
1656 *((unsigned short *)(sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1657 = (0xff00 & *((unsigned short *) (sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1658 | ((sym_addr >> 17) & 0xff));
1659 } else if ((*p)->howto->type == R_byte4_data) {
1660 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1661 } else if ((*p)->howto->type == R_pcrel12_jump
1662 || (*p)->howto->type == R_pcrel12_jump_s) {
1663 *((unsigned short *)(sectionp + q->address))
1664 = (0xf000 & *((unsigned short *)(sectionp + q->address))
1665 | ((sym_addr >> 1) & 0xfff));
1666 } else if ((*p)->howto->type == R_pcrel10) {
1667 *((unsigned short *)(sectionp + q->address))
1668 = (~0x3ff & *((unsigned short *)(sectionp + q->address))
1669 | ((sym_addr >> 1) & 0x3ff));
1670 } else if ((*p)->howto->type == R_rimm16
1671 || (*p)->howto->type == R_huimm16
1672 || (*p)->howto->type == R_luimm16) {
1673 /* for l and h we set the lower 16 bits which is only when it will be used */
1674 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1675 } else if ((*p)->howto->type == R_pcrel5m2) {
1676 *((unsigned short *)(sectionp + q->address))
1677 = (0xfff0 & *((unsigned short *)(sectionp + q->address))
1678 | ((sym_addr >> 1) & 0xf));
1679 } else if ((*p)->howto->type == R_pcrel11){
1680 *((unsigned short *)(sectionp + q->address))
1681 = (0xfc00 & *((unsigned short *)(sectionp + q->address))
1682 | ((sym_addr >> 1) & 0x3ff));
1683 } else if (0xE0 <= (*p)->howto->type && 0xF3 >= (*p)->howto->type) {
1684 //arith relocs dont generate a real relocation
1686 printf("Blackfin relocation fail for reloc type: 0x%x\n", (*p)->howto->type);
1688 #elif defined(TARGET_e1)
1689 #define OPCODE_SIZE 2 /* Add 2 bytes, counting the opcode size*/
1690 switch ((*p)->howto->type) {
1692 case R_E1_CONST31_PCREL:
1693 case R_E1_DIS29W_PCREL:
1697 case R_E1_IMM32_PCREL:
1699 DBG_E1("In addr + 2:[0x%x] <- write [0x%x]\n",
1700 (sectionp + q->address + 2), sym_addr );
1701 *((unsigned long *) (sectionp + q->address + OPCODE_SIZE)) =
1705 DBG_E1("In addr : [0x%x] <- write [0x%x]\n",
1706 (sectionp + q->address), sym_addr );
1707 *((unsigned long *) (sectionp + q->address )) = htonl(sym_addr);
1710 printf("ERROR:Unhandled Relocation. Exiting...\n");
1714 #else /* ! TARGET_arm && ! TARGET_e1 */
1716 switch (q->howto->type) {
1721 /* Do nothing -- for cases we handle,
1722 the bits produced by the linker are
1723 what we want in the final flat file
1724 (and other cases are errors). Note
1725 that unlike most relocated values,
1726 it is stored in little-endian order,
1727 but this is necessary to avoid
1728 trashing the low-bit, and the float
1729 loaders knows about it. */
1731 #endif /* TARGET_V850 */
1734 case R_NIOS2_BFD_RELOC_32:
1735 case R_NIOS2_CALL26:
1736 case R_NIOS2_HIADJ16:
1740 #endif /* TARGET_nios2 */
1743 /* The alignment of the build host
1744 might be stricter than that of the
1745 target, so be careful. We store in
1746 network byte order. */
1747 r_mem[0] = (sym_addr >> 24) & 0xff;
1748 r_mem[1] = (sym_addr >> 16) & 0xff;
1749 r_mem[2] = (sym_addr >> 8) & 0xff;
1750 r_mem[3] = sym_addr & 0xff;
1752 #endif /* !TARGET_arm */
1757 if ((*p)->howto->type == R_rimm16
1758 || (*p)->howto->type == R_huimm16
1759 || (*p)->howto->type == R_luimm16)
1761 /* for l and h we set the lower 16 bits which is only when it will be used */
1762 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1763 } else if ((*p)->howto->type == R_byte4_data) {
1764 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1769 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
1770 "section=%s size=%d "
1771 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
1772 q->address, sym_name, addstr,
1773 section_name, sym_reloc_size,
1774 sym_addr, section_vma + q->address);
1777 * Create relocation entry (PC relative doesn't need this).
1779 if (relocation_needed) {
1781 flat_relocs = realloc(flat_relocs,
1782 (flat_reloc_count + 1) * sizeof(uint32_t));
1784 flat_relocs[flat_reloc_count] = pflags |
1785 (section_vma + q->address);
1788 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
1789 section_vma + q->address);
1791 switch ((*p)->howto->type) {
1793 case R_E1_CONST31_PCREL:
1794 case R_E1_DIS29W_PCREL:
1798 case R_E1_IMM32_PCREL:
1800 flat_relocs[flat_reloc_count] = pflags |
1801 (section_vma + q->address + OPCODE_SIZE);
1803 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1804 flat_relocs[flat_reloc_count] );
1807 flat_relocs[flat_reloc_count] = pflags |
1808 (section_vma + q->address);
1810 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1811 flat_relocs[flat_reloc_count] );
1817 relocation_needed = 0;
1822 printf("%s(%d): symbol name=%s address=0x%x section=%s -> RELOC=0x%x\n",
1823 __FILE__, __LINE__, sym_name, q->address, section_name,
1824 flat_relocs[flat_reloc_count]);
1831 printf("%d bad relocs\n", bad_relocs);
1838 *n_relocs = flat_reloc_count;
1844 static char * program;
1846 static void usage(void)
1848 fprintf(stderr, "Usage: %s [vrzd] [-p <abs-pic-file>] [-s stack-size] "
1849 "[-o <output-file>] <elf-file>\n\n"
1850 " -v : verbose operation\n"
1851 " -r : force load to RAM\n"
1852 " -k : enable kernel trace on load (for debug)\n"
1853 " -z : compress code/data/relocs\n"
1854 " -d : compress data/relocs\n"
1855 " -a : use existing symbol references\n"
1856 " instead of recalculating from\n"
1857 " relocation info\n"
1858 " -R reloc-file : read relocations from a separate file\n"
1859 " -p abs-pic-file : GOT/PIC processing with files\n"
1860 " -s stacksize : set application stack size\n"
1861 " -o output-file : output file name\n\n",
1863 fprintf(stderr, "Compiled for " ARCH " architecture\n\n");
1868 /* Write NUM zeroes to STREAM. */
1869 static void write_zeroes (unsigned long num, FILE *stream)
1873 /* It'd be nice if we could just use fseek, but that doesn't seem to
1874 work for stdio output files. */
1875 bzero(zeroes, 1024);
1876 while (num > sizeof(zeroes)) {
1877 fwrite(zeroes, sizeof(zeroes), 1, stream);
1878 num -= sizeof(zeroes);
1881 fwrite(zeroes, num, 1, stream);
1886 int main(int argc, char *argv[])
1889 bfd *rel_bfd, *abs_bfd;
1891 char *ofile=NULL, *pfile=NULL, *abs_file = NULL, *rel_file = NULL;
1899 asymbol **symbol_table;
1900 long number_of_symbols;
1902 unsigned long data_len = 0;
1903 unsigned long bss_len = 0;
1904 unsigned long text_len = 0;
1905 unsigned long reloc_len;
1907 unsigned long data_vma = ~0;
1908 unsigned long bss_vma = ~0;
1909 unsigned long text_vma = ~0;
1911 unsigned long text_offs;
1917 struct flat_hdr hdr;
1927 if (sizeof(hdr) != 64) {
1929 "Potential flat header incompatibility detected\n"
1930 "header size should be 64 but is %d\n",
1937 #else /* We need plenty of stack for both of them (Aggregate and Register) */
1941 while ((opt = getopt(argc, argv, "avzdrkp:s:o:R:")) != -1) {
1968 stack = atoi(optarg);
1974 fprintf(stderr, "%s Unknown option\n", argv[0]);
1981 * if neither the -r or -p options was given, default to
1982 * a RAM load as that is the only option that makes sense.
1984 if (!load_to_ram && !pfile)
1987 filename = fname = argv[argc-1];
1998 if (!(rel_bfd = bfd_openr(rel_file, 0))) {
1999 fprintf(stderr, "Can't open %s\n", rel_file);
2003 if (bfd_check_format (rel_bfd, bfd_object) == 0) {
2004 fprintf(stderr, "File is not an object file\n");
2008 if (abs_file == rel_file)
2009 abs_bfd = rel_bfd; /* one file does all */
2011 if (!(abs_bfd = bfd_openr(abs_file, 0))) {
2012 fprintf(stderr, "Can't open %s\n", abs_file);
2016 if (bfd_check_format (abs_bfd, bfd_object) == 0) {
2017 fprintf(stderr, "File is not an object file\n");
2022 if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC)) {
2023 fprintf (stderr, "%s: Input file contains no relocation info\n", rel_file);
2027 if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P)) {
2028 /* `Absolute' file is not absolute, so neither are address
2029 contained therein. */
2031 "%s: `-a' option specified with non-fully-resolved input file\n",
2032 bfd_get_filename (abs_bfd));
2036 symbol_table = get_symbols(abs_bfd, &number_of_symbols);
2038 /* Group output sections into text, data, and bss, and calc their sizes. */
2039 for (s = abs_bfd->sections; s != NULL; s = s->next) {
2040 unsigned long *vma, *len;
2041 bfd_size_type sec_size;
2044 if (s->flags & SEC_CODE) {
2047 } else if (s->flags & SEC_DATA) {
2050 } else if (s->flags & SEC_ALLOC) {
2056 sec_size = bfd_section_size(abs_bfd, s);
2057 sec_vma = bfd_section_vma(abs_bfd, s);
2059 if (sec_vma < *vma) {
2061 *len += sec_vma - *vma;
2065 } else if (sec_vma + sec_size > *vma + *len)
2066 *len = sec_vma + sec_size - *vma;
2069 if (text_len == 0) {
2070 fprintf (stderr, "%s: no .text section", abs_file);
2074 text = malloc(text_len);
2077 printf("TEXT -> vma=0x%x len=0x%x\n", text_vma, text_len);
2079 /* Read in all text sections. */
2080 for (s = abs_bfd->sections; s != NULL; s = s->next)
2081 if (s->flags & SEC_CODE)
2082 if (!bfd_get_section_contents(abs_bfd, s,
2083 text + (s->vma - text_vma), 0,
2084 bfd_section_size(abs_bfd, s)))
2086 fprintf(stderr, "read error section %s\n", s->name);
2090 if (data_len == 0) {
2091 fprintf (stderr, "%s: no .data section", abs_file);
2094 data = malloc(data_len);
2097 printf("DATA -> vma=0x%x len=0x%x\n", data_vma, data_len);
2099 if ((text_vma + text_len) != data_vma) {
2100 if ((text_vma + text_len) > data_vma) {
2101 printf("ERROR: text=0x%x overlaps data=0x%x ?\n", text_len, data_vma);
2105 printf("WARNING: data=0x%x does not directly follow text=0x%x\n",
2106 data_vma, text_len);
2107 text_len = data_vma - text_vma;
2110 /* Read in all data sections. */
2111 for (s = abs_bfd->sections; s != NULL; s = s->next)
2112 if (s->flags & SEC_DATA)
2113 if (!bfd_get_section_contents(abs_bfd, s,
2114 data + (s->vma - data_vma), 0,
2115 bfd_section_size(abs_bfd, s)))
2117 fprintf(stderr, "read error section %s\n", s->name);
2121 /* Put common symbols in bss. */
2122 bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len);
2125 printf("BSS -> vma=0x%x len=0x%x\n", bss_vma, bss_len);
2127 if ((data_vma + data_len) != bss_vma) {
2128 if ((data_vma + data_len) > bss_vma) {
2129 printf("ERROR: text=0x%x + data=0x%x overlaps bss=0x%x ?\n", text_len,
2134 printf("WARNING: bss=0x%x does not directly follow text=0x%x + data=0x%x(0x%x)\n",
2135 bss_vma, text_len, data_len, text_len + data_len);
2136 data_len = bss_vma - data_vma;
2139 reloc = output_relocs(abs_bfd, symbol_table, number_of_symbols, &reloc_len,
2140 text, text_len, text_vma, data, data_len, data_vma,
2144 printf("No relocations in code!\n");
2146 text_offs = real_address_bits(text_vma);
2148 /* Fill in the binflt_flat header */
2149 memcpy(hdr.magic,"bFLT",4);
2150 hdr.rev = htonl(FLAT_VERSION);
2151 hdr.entry = htonl(sizeof(hdr) + bfd_get_start_address(abs_bfd));
2152 hdr.data_start = htonl(sizeof(hdr) + text_offs + text_len);
2153 hdr.data_end = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2154 hdr.bss_end = htonl(sizeof(hdr) + text_offs + text_len +data_len+bss_len);
2155 hdr.stack_size = htonl(stack); /* FIXME */
2156 hdr.reloc_start = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2157 hdr.reloc_count = htonl(reloc_len);
2159 | (load_to_ram ? FLAT_FLAG_RAM : 0)
2160 | (ktrace ? FLAT_FLAG_KTRACE : 0)
2161 | (pic_with_got ? FLAT_FLAG_GOTPIC : 0)
2162 | (compress ? (compress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
2164 hdr.build_date = htonl((unsigned long)time(NULL));
2165 bzero(hdr.filler, sizeof(hdr.filler));
2167 for (i=0; i<reloc_len; i++) reloc[i] = htonl(reloc[i]);
2170 printf("SIZE: .text=0x%04x, .data=0x%04x, .bss=0x%04x",
2171 text_len, data_len, bss_len);
2173 printf(", relocs=0x%04x", reloc_len);
2178 ofile = malloc(strlen(fname) + 5 + 1); /* 5 to add suffix */
2179 strcpy(ofile, fname);
2180 strcat(ofile, ".bflt");
2183 if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0) {
2184 fprintf (stderr, "Can't open output file %s\n", ofile);
2188 write(fd, &hdr, sizeof(hdr));
2192 * get the compression command ready
2194 sprintf(cmd, "gzip -f -9 >> %s", ofile);
2196 #define START_COMPRESSOR do { \
2202 if (!(gf = popen(cmd, "w" BINARY_FILE_OPTS))) { \
2203 fprintf(stderr, "Can't run cmd %s\n", cmd); \
2209 gf = fopen(ofile, "ab"); /* Add 'b' to support non-posix (ie windows) */
2211 fprintf(stderr, "Can't open file %s for writing\n", ofile); \
2218 /* Fill in any hole at the beginning of the text segment. */
2220 printf("ZERO before text len=0x%x\n", text_offs);
2221 write_zeroes(text_offs, gf);
2223 /* Write the text segment. */
2224 fwrite(text, text_len, 1, gf);
2229 /* Write the data segment. */
2230 fwrite(data, data_len, 1, gf);
2233 fwrite(reloc, reloc_len * 4, 1, gf);
2245 * this __MUST__ be at the VERY end of the file - do NOT move!!
2251 * vi: tabstop=8 shiftwidth=4 textwidth=79 noexpandtab