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) && !defined(TARGET_m68k)
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;
869 sym_addr += sym_vma + q->addend;
870 sym_addr -= q->address;
874 #if defined(TARGET_arm)
876 relocation_needed = 1;
879 "%s vma=0x%x, value=0x%x, address=0x%x "
880 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
882 sym_vma, (*(q->sym_ptr_ptr))->value,
883 q->address, sym_addr,
884 (*p)->howto->rightshift,
885 *(unsigned long *)r_mem);
886 sym_vma = bfd_section_vma(abs_bfd, sym_section);
887 sym_addr += sym_vma + q->addend;
891 /* Should be fine as is */
896 "%s vma=0x%x, value=0x%x, address=0x%x "
897 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
899 sym_vma, (*(q->sym_ptr_ptr))->value,
900 q->address, sym_addr,
901 (*p)->howto->rightshift,
902 *(unsigned long *)r_mem);
905 sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift;
911 relocation_needed = 1;
912 sym_vma = bfd_section_vma(abs_bfd, sym_section);
913 sym_addr += sym_vma + q->addend;
915 #if defined(R_V850_ZDA_16_16_OFFSET) || defined(R_V850_ZDA_16_16_SPLIT_OFFSET)
916 #ifdef R_V850_ZDA_16_16_OFFSET
917 case R_V850_ZDA_16_16_OFFSET:
919 #ifdef R_V850_ZDA_16_16_SPLIT_OFFSET
920 case R_V850_ZDA_16_16_SPLIT_OFFSET:
922 /* Can't support zero-relocations. */
923 printf ("ERROR: %s+0x%x: zero relocations not supported\n",
924 sym_name, q->addend);
926 #endif /* R_V850_ZDA_16_16_OFFSET || R_V850_ZDA_16_16_SPLIT_OFFSET */
927 #endif /* TARGET_v850 */
931 if (sym_reloc_size != 4) {
932 printf("R_H8_DIR24R8 size %d\n", sym_reloc_size);
936 relocation_needed = 1;
937 sym_addr = (*(q->sym_ptr_ptr))->value;
939 r_mem -= 1; /* tracks q->address */
940 sym_vma = bfd_section_vma(abs_bfd, sym_section);
941 sym_addr += sym_vma + q->addend;
942 sym_addr |= (*(unsigned char *)r_mem<<24);
945 if (sym_reloc_size != 4) {
946 printf("R_H8_DIR24A8 size %d\n", sym_reloc_size);
950 /* Absolute symbol done not relocation */
951 relocation_needed = !bfd_is_abs_section(sym_section);
952 sym_addr = (*(q->sym_ptr_ptr))->value;
953 sym_vma = bfd_section_vma(abs_bfd, sym_section);
954 sym_addr += sym_vma + q->addend;
957 case R_H8_DIR32A16: /* currently 32, could be made 16 */
958 if (sym_reloc_size != 4) {
959 printf("R_H8_DIR32 size %d\n", sym_reloc_size);
963 relocation_needed = 1;
964 sym_addr = (*(q->sym_ptr_ptr))->value;
965 sym_vma = bfd_section_vma(abs_bfd, sym_section);
966 sym_addr += sym_vma + q->addend;
970 sym_addr = (*(q->sym_ptr_ptr))->value;
971 sym_addr += sym_vma + q->addend;
972 sym_addr -= (q->address + 2);
973 if (bfd_big_endian(abs_bfd))
974 *(unsigned short *)r_mem =
975 bfd_big_endian(abs_bfd) ? htons(sym_addr) : sym_addr;
979 sym_addr = (*(q->sym_ptr_ptr))->value;
980 sym_addr += sym_vma + q->addend;
981 sym_addr -= (q->address + 1);
982 *(unsigned char *)r_mem = sym_addr;
986 #ifdef TARGET_microblaze
987 case R_MICROBLAZE_64:
988 /* The symbol is split over two consecutive instructions.
989 Flag this to the flat loader by setting the high bit of
990 the relocation symbol. */
992 unsigned char *p = r_mem;
993 unsigned long offset;
996 /* work out the relocation */
997 sym_vma = bfd_section_vma(abs_bfd, sym_section);
998 /* grab any offset from the text */
999 offset = (p[2]<<24) + (p[3] << 16) + (p[6] << 8) + (p[7]);
1000 /* Update the address */
1001 sym_addr += offset + sym_vma + q->addend;
1002 /* Write relocated pointer back */
1003 p[2] = (sym_addr >> 24) & 0xff;
1004 p[3] = (sym_addr >> 16) & 0xff;
1005 p[6] = (sym_addr >> 8) & 0xff;
1006 p[7] = sym_addr & 0xff;
1008 /* create a new reloc entry */
1009 flat_relocs = realloc(flat_relocs,
1010 (flat_reloc_count + 1) * sizeof(uint32_t));
1011 flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address);
1013 relocation_needed = 0;
1015 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
1016 bfd_section_vma(abs_bfd, sym_section));
1018 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
1019 "section=%s size=%d "
1020 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
1021 q->address, sym_name, addstr,
1022 section_name, sym_reloc_size,
1023 sym_addr, section_vma + q->address);
1025 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
1026 section_vma + q->address);
1030 case R_MICROBLAZE_32:
1032 unsigned char *p = r_mem;
1033 unsigned long offset;
1035 /* grab any offset from the text */
1036 offset = (p[0]<<24) + (p[1] << 16) + (p[2] << 8) + (p[3]);
1037 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1038 /* This is a horrible kludge. For some
1039 reason, *sometimes* the offset is in
1040 both addend and the code. Detect
1041 it, and cancel the effect. Otherwise
1042 the offset gets added twice - ouch.
1043 There should be a better test
1044 for this condition, based on the
1045 BFD data structures */
1046 if(offset==q->addend)
1049 sym_addr += offset + sym_vma + q->addend;
1050 relocation_needed = 1;
1053 case R_MICROBLAZE_64_PCREL:
1055 //sym_addr = (*(q->sym_ptr_ptr))->value;
1056 sym_addr += sym_vma + q->addend;
1057 sym_addr -= (q->address + 4);
1058 sym_addr = htonl(sym_addr);
1060 * ((unsigned short *) (r_mem+2)) |= (sym_addr) & 0xFFFF;
1062 * ((unsigned short *) (r_mem+6)) |= (sym_addr >> 16) & 0xFFFF;
1063 /* We've done all the work, so continue
1064 to next reloc instead of break */
1067 #endif /* TARGET_microblaze */
1070 #define htoniosl(x) (x)
1071 #define niostohl(x) (x)
1072 switch ((*p)->howto->type)
1074 case R_NIOS2_BFD_RELOC_32:
1075 relocation_needed = 1;
1076 pflags = (FLAT_NIOS2_R_32 << 28);
1077 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1078 sym_addr += sym_vma + q->addend;
1079 /* modify target, in target order */
1080 *(unsigned long *)r_mem = htoniosl(sym_addr);
1082 case R_NIOS2_CALL26:
1084 unsigned long exist_val;
1085 relocation_needed = 1;
1086 pflags = (FLAT_NIOS2_R_CALL26 << 28);
1087 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1088 sym_addr += sym_vma + q->addend;
1090 /* modify target, in target order */
1091 // exist_val = niostohl(*(unsigned long *)r_mem);
1092 exist_val = ((sym_addr >> 2) << 6);
1093 *(unsigned long *)r_mem = htoniosl(exist_val);
1096 case R_NIOS2_HIADJ16:
1099 unsigned long exist_val;
1101 /* handle the adjacent HI/LO pairs */
1103 r2_type = R_NIOS2_NONE;
1105 r2_type = p[1]->howto->type;
1106 if ((r2_type == R_NIOS2_LO16)
1107 && (p[0]->sym_ptr_ptr == p[1]->sym_ptr_ptr)
1108 && (p[0]->addend == p[1]->addend))
1110 unsigned char * r2_mem = sectionp + p[1]->address;
1111 if (p[1]->address - q->address!=4)
1112 printf("Err: HI/LO not adjacent %d\n", p[1]->address - q->address);
1113 relocation_needed = 1;
1114 pflags = (q->howto->type == R_NIOS2_HIADJ16)
1115 ? FLAT_NIOS2_R_HIADJ_LO : FLAT_NIOS2_R_HI_LO;
1118 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1119 sym_addr += sym_vma + q->addend;
1121 /* modify high 16 bits, in target order */
1122 exist_val = niostohl(*(unsigned long *)r_mem);
1123 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1124 if (q->howto->type == R_NIOS2_HIADJ16)
1125 exist_val |= ((((sym_addr >> 16) + ((sym_addr >> 15) & 1)) & 0xFFFF) << 6);
1127 exist_val |= (((sym_addr >> 16) & 0xFFFF) << 6);
1128 *(unsigned long *)r_mem = htoniosl(exist_val);
1130 /* modify low 16 bits, in target order */
1131 exist_val = niostohl(*(unsigned long *)r2_mem);
1132 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1133 exist_val |= ((sym_addr & 0xFFFF) << 6);
1134 *(unsigned long *)r2_mem = htoniosl(exist_val);
1137 goto NIOS2_RELOC_ERR;
1143 unsigned long exist_val, temp;
1144 //long gp = get_symbol_offset("_gp", sym_section, symbols, number_of_symbols);
1145 long gp = get_gp_value(symbols, number_of_symbols);
1147 printf("Err: unresolved symbol _gp when relocating %s\n", sym_name);
1148 goto NIOS2_RELOC_ERR;
1150 /* _gp holds a absolute value, otherwise the ld cannot generate correct code */
1151 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1152 //printf("sym=%x, %d, _gp=%x, %d\n", sym_addr+sym_vma, sym_addr+sym_vma, gp, gp);
1153 sym_addr += sym_vma + q->addend;
1155 //printf("sym - _gp=%x, %d\n", sym_addr, sym_addr);
1156 /* modify the target, in target order (little_endian) */
1157 exist_val = niostohl(*(unsigned long *)r_mem);
1158 temp = ((exist_val >> 6) & 0x3ff0000) | (sym_addr & 0xffff);
1160 temp |= (exist_val & 0x3f);
1161 *(unsigned long *)r_mem = htoniosl(temp);
1163 printf("omit: offset=0x%x symbol=%s%s "
1164 "section=%s size=%d "
1165 "fixup=0x%x (reloc=0x%x) GPREL\n",
1166 q->address, sym_name, addstr,
1167 section_name, sym_reloc_size,
1168 sym_addr, section_vma + q->address);
1171 case R_NIOS2_PCREL16:
1173 unsigned long exist_val;
1175 sym_addr += sym_vma + q->addend;
1176 sym_addr -= (q->address + 4);
1177 /* modify the target, in target order (little_endian) */
1178 exist_val = niostohl(*(unsigned long *)r_mem);
1179 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1180 exist_val |= ((sym_addr & 0xFFFF) << 6);
1181 *(unsigned long *)r_mem = htoniosl(exist_val);
1183 printf("omit: offset=0x%x symbol=%s%s "
1184 "section=%s size=%d "
1185 "fixup=0x%x (reloc=0x%x) PCREL\n",
1186 q->address, sym_name, addstr,
1187 section_name, sym_reloc_size,
1188 sym_addr, section_vma + q->address);
1193 /* check if this is actually the 2nd half of a pair */
1195 && ((p[-1]->howto->type == R_NIOS2_HIADJ16)
1196 || (p[-1]->howto->type == R_NIOS2_HI16))
1197 && (p[-1]->sym_ptr_ptr == p[0]->sym_ptr_ptr)
1198 && (p[-1]->addend == p[0]->addend)) {
1200 printf("omit: offset=0x%x symbol=%s%s "
1201 "section=%s size=%d LO16\n",
1202 q->address, sym_name, addstr,
1203 section_name, sym_reloc_size);
1207 /* error, fall through */
1211 case R_NIOS2_CACHE_OPX:
1215 case R_NIOS2_BFD_RELOC_16:
1216 case R_NIOS2_BFD_RELOC_8:
1217 case R_NIOS2_GNU_VTINHERIT:
1218 case R_NIOS2_GNU_VTENTRY:
1223 printf("Err: unexpected reloc type %s(%d)\n", q->howto->name, q->howto->type);
1227 #endif /* TARGET_nios2 */
1232 relocation_needed = 1;
1233 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1234 sym_addr += sym_vma + q->addend;
1238 sym_addr += sym_vma + q->addend;
1239 sym_addr -= q->address;
1241 case R_SPARC_WDISP30:
1242 sym_addr = (((*(q->sym_ptr_ptr))->value-
1243 q->address) >> 2) & 0x3fffffff;
1245 ntohl(*(unsigned long *)r_mem)
1250 relocation_needed = 1;
1251 pflags = 0x80000000;
1252 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1253 sym_addr += sym_vma + q->addend;
1255 htonl(*(unsigned long *)r_mem)
1260 relocation_needed = 1;
1261 pflags = 0x40000000;
1262 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1263 sym_addr += sym_vma + q->addend;
1264 sym_addr &= 0x000003ff;
1266 htonl(*(unsigned long *)r_mem)
1270 #endif /* TARGET_sparc */
1273 case R_pcrel12_jump:
1274 case R_pcrel12_jump_s:
1276 case R_pcrel24_jump_l:
1277 case R_pcrel24_jump_x:
1278 case R_pcrel24_call_x:
1282 sym_addr += q->addend;// get the symbol addr
1283 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1284 sym_addr -= q->address; // make it PC relative
1285 // implicitly assumes code section and symbol section are same
1289 if (is_reloc_stack_empty ())
1291 sym_addr += q->addend;
1293 sym_addr = reloc_stack_pop ();
1295 if(weak_und_symbol(sym_section->name, (*(q->sym_ptr_ptr))))
1297 if(0xFFFF0000 & sym_addr){
1298 fprintf (stderr, "Relocation overflow for rN = %s\n",sym_name);
1301 flat_relocs = (uint32_t *)
1302 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1303 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1304 sym_section->name, sym_name,
1305 (*(q->sym_ptr_ptr)),
1306 0, FLAT_RELOC_PART_LO,
1307 section_vma + q->address))
1316 unsigned int reloc_count_incr;
1319 if (q->howto->type == R_luimm16)
1320 hi_lo = FLAT_RELOC_PART_LO;
1322 hi_lo = FLAT_RELOC_PART_HI;
1324 if (is_reloc_stack_empty ())
1325 sym_addr += q->addend;
1327 sym_addr = reloc_stack_pop ();
1329 flat_relocs = (uint32_t *)
1330 (realloc (flat_relocs, (flat_reloc_count + 2) * sizeof (uint32_t)));
1331 reloc_count_incr = 1;
1332 if (weak_und_symbol (sym_section->name, (*(q->sym_ptr_ptr))))
1334 if (0xFFFF0000 & sym_addr) {
1335 /* value is > 16 bits - use an extra field */
1336 /* see if we have already output that symbol */
1337 /* reloc may be addend from symbol and */
1338 /* we can only store 16 bit offsets */
1340 if ((*(q->sym_ptr_ptr))->udata.i == 0
1341 || flat_relocs[(*(q->sym_ptr_ptr))->udata.i] != sym_addr
1342 || ((*(q->sym_ptr_ptr))->udata.i & 0xFFFF0000))
1344 reloc_count_incr = 2;
1345 flat_relocs[flat_reloc_count + 1] = sym_addr;
1346 (*(q->sym_ptr_ptr))->udata.i = flat_reloc_count + 1;
1347 sym_addr = 0; // indication to loader to read next
1349 sym_addr = (*(q->sym_ptr_ptr))->udata.i;
1355 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1356 sym_section->name, sym_name,
1357 (*(q->sym_ptr_ptr)),
1359 section_vma + q->address))
1361 flat_reloc_count += reloc_count_incr;
1365 if (is_reloc_stack_empty ())
1366 sym_addr += q->addend;
1368 sym_addr = reloc_stack_pop ();
1369 if (weak_und_symbol (sym_section->name, *q->sym_ptr_ptr))
1372 flat_relocs = (uint32_t *)
1373 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1374 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1375 sym_section->name, sym_name,
1376 (*(q->sym_ptr_ptr)),
1377 2, FLAT_RELOC_PART_LO,
1378 section_vma + q->address))
1386 sym_addr += q->addend;
1387 reloc_stack_push(sym_addr);
1388 reloc_stack_set_section(sym_section, section_name);
1393 reloc_stack_push(q->addend);
1397 reloc_stack_operate((*p)->howto->type);
1400 #endif //TARGET_bfin
1404 relocation_needed = 1;
1405 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1406 sym_addr += sym_vma + q->addend;
1410 sym_addr += sym_vma + q->addend;
1411 sym_addr -= q->address;
1413 #endif /* TARGET_sh */
1416 #define htoe1l(x) htonl(x)
1423 #define DBG_E1 printf
1425 #define DBG_E1(x, ... )
1428 #define _32BITS_RELOC 0x00000000
1429 #define _30BITS_RELOC 0x80000000
1430 #define _28BITS_RELOC 0x40000000
1433 unsigned long sec_vma, exist_val, S;
1435 relocation_needed = 1;
1436 DBG_E1("Handling Reloc <CONST31>\n");
1437 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1438 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1439 sec_vma, sym_addr, q->address);
1440 sym_addr = sec_vma + sym_addr;
1441 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1442 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1443 exist_val = htoe1l(exist_val);
1444 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1445 sym_addr += exist_val;
1446 pflags = _30BITS_RELOC;
1448 case R_E1_CONST31_PCREL:
1449 relocation_needed = 0;
1450 DBG_E1("Handling Reloc <CONST31_PCREL>\n");
1451 DBG_E1("DONT RELOCATE AT LOADING\n");
1452 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1453 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1454 sec_vma, sym_addr, q->address);
1455 sym_addr = sec_vma + sym_addr;
1456 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1458 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1460 q->address = q->address + section_vma;
1461 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1463 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1464 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1465 DBG_E1( "sym_addr := sym_addr - q->address - "
1466 "sizeof(CONST31_PCREL): [0x%x]\n",
1468 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1469 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1470 exist_val = htoe1l(exist_val);
1471 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1472 sym_addr |= exist_val;
1473 DBG_E1("sym_addr |= exist_val) : [0x%x]\n", sym_addr );
1475 case R_E1_DIS29W_PCREL:
1476 relocation_needed = 0;
1477 DBG_E1("Handling Reloc <DIS29W_PCREL>\n");
1478 DBG_E1("DONT RELOCATE AT LOADING\n");
1479 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1480 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1481 sec_vma, sym_addr, q->address);
1482 sym_addr = sec_vma + sym_addr;
1483 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1485 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1487 q->address = q->address + section_vma;
1488 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1490 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1491 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1492 DBG_E1( "sym_addr := sym_addr - q->address - "
1493 "sizeof(CONST31_PCREL): [0x%x]\n",
1495 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1496 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1497 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1498 exist_val = htoe1l(exist_val);
1499 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1500 sym_addr += exist_val;
1503 DBG_E1("Handling Reloc <DIS29W>\n");
1504 goto DIS29_RELOCATION;
1506 DBG_E1("Handling Reloc <DIS29H>\n");
1507 goto DIS29_RELOCATION;
1509 DBG_E1("Handling Reloc <DIS29B>\n");
1511 relocation_needed = 1;
1512 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1513 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%08x]\n",
1515 sym_addr = sec_vma + sym_addr;
1516 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%08x]\n", sym_addr);
1517 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1518 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1519 exist_val = htoe1l(exist_val);
1520 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1521 sym_addr += exist_val;
1522 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1523 pflags = _28BITS_RELOC;
1525 case R_E1_IMM32_PCREL:
1526 relocation_needed = 0;
1527 DBG_E1("Handling Reloc <IMM32_PCREL>\n");
1528 DBG_E1("DONT RELOCATE AT LOADING\n");
1529 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1530 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1532 sym_addr = sec_vma + sym_addr;
1534 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1535 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1537 q->address = q->address + section_vma;
1538 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1540 if( (sym_addr = (sym_addr - q->address - 6 )) < 0 )
1541 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1542 DBG_E1( "sym_addr := sym_addr - q->address - "
1543 "sizeof(CONST31_PCREL): [0x%x]\n",
1545 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1546 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1547 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1548 exist_val = htoe1l(exist_val);
1549 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1550 sym_addr += exist_val;
1553 relocation_needed = 1;
1554 DBG_E1("Handling Reloc <IMM32>\n");
1555 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1556 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1558 sym_addr = sec_vma + sym_addr;
1559 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1560 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1561 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1562 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1563 exist_val = htoe1l(exist_val);
1564 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1565 sym_addr += exist_val;
1566 pflags = _32BITS_RELOC;
1569 relocation_needed = 1;
1570 DBG_E1("Handling Reloc <WORD>\n");
1571 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1572 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1574 sym_addr = sec_vma + sym_addr;
1575 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1576 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address );
1577 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1578 exist_val = htoe1l(exist_val);
1579 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1580 sym_addr += exist_val;
1581 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1582 pflags = _32BITS_RELOC;
1585 #undef _32BITS_RELOC
1586 #undef _30BITS_RELOC
1587 #undef _28BITS_RELOC
1590 /* missing support for other types of relocs */
1591 printf("ERROR: bad reloc type %d\n", (*p)->howto->type);
1597 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
1598 bfd_section_vma(abs_bfd, sym_section));
1602 * for full elf relocation we have to write back the
1603 * start_code relative value to use.
1605 if (!pic_with_got) {
1606 #if defined(TARGET_arm)
1615 * horrible nasty hack to support different endianess
1617 if (!bfd_big_endian(abs_bfd)) {
1629 tmp.l = *(unsigned long *)r_mem;
1630 hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16);
1631 if (((*p)->howto->type != R_ARM_PC24) &&
1632 ((*p)->howto->type != R_ARM_PLT32))
1633 hl |= (tmp.c[i3] << 24);
1634 else if (tmp.c[i2] & 0x80)
1635 hl |= 0xff000000; /* sign extend */
1637 tmp.c[i0] = hl & 0xff;
1638 tmp.c[i1] = (hl >> 8) & 0xff;
1639 tmp.c[i2] = (hl >> 16) & 0xff;
1640 if (((*p)->howto->type != R_ARM_PC24) &&
1641 ((*p)->howto->type != R_ARM_PLT32))
1642 tmp.c[i3] = (hl >> 24) & 0xff;
1643 if ((*p)->howto->type == R_ARM_ABS32)
1644 *(unsigned long *)r_mem = htonl(hl);
1646 *(unsigned long *)r_mem = tmp.l;
1648 #elif defined(TARGET_bfin)
1649 if ((*p)->howto->type == R_pcrel24
1650 || (*p)->howto->type == R_pcrel24_jump_l
1651 || (*p)->howto->type == R_pcrel24_jump_x
1652 || (*p)->howto->type == R_pcrel24_call_x)
1654 sym_addr += 2*-1*PCREL24_MAGIC_OFFSET;
1655 *((unsigned short *)(sectionp + q->address) + 1 + PCREL24_MAGIC_OFFSET)
1656 = (sym_addr >> 1) & 0xffff;
1657 *((unsigned short *)(sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1658 = (0xff00 & *((unsigned short *) (sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1659 | ((sym_addr >> 17) & 0xff));
1660 } else if ((*p)->howto->type == R_byte4_data) {
1661 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1662 } else if ((*p)->howto->type == R_pcrel12_jump
1663 || (*p)->howto->type == R_pcrel12_jump_s) {
1664 *((unsigned short *)(sectionp + q->address))
1665 = (0xf000 & *((unsigned short *)(sectionp + q->address))
1666 | ((sym_addr >> 1) & 0xfff));
1667 } else if ((*p)->howto->type == R_pcrel10) {
1668 *((unsigned short *)(sectionp + q->address))
1669 = (~0x3ff & *((unsigned short *)(sectionp + q->address))
1670 | ((sym_addr >> 1) & 0x3ff));
1671 } else if ((*p)->howto->type == R_rimm16
1672 || (*p)->howto->type == R_huimm16
1673 || (*p)->howto->type == R_luimm16) {
1674 /* for l and h we set the lower 16 bits which is only when it will be used */
1675 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1676 } else if ((*p)->howto->type == R_pcrel5m2) {
1677 *((unsigned short *)(sectionp + q->address))
1678 = (0xfff0 & *((unsigned short *)(sectionp + q->address))
1679 | ((sym_addr >> 1) & 0xf));
1680 } else if ((*p)->howto->type == R_pcrel11){
1681 *((unsigned short *)(sectionp + q->address))
1682 = (0xfc00 & *((unsigned short *)(sectionp + q->address))
1683 | ((sym_addr >> 1) & 0x3ff));
1684 } else if (0xE0 <= (*p)->howto->type && 0xF3 >= (*p)->howto->type) {
1685 //arith relocs dont generate a real relocation
1687 printf("Blackfin relocation fail for reloc type: 0x%x\n", (*p)->howto->type);
1689 #elif defined(TARGET_e1)
1690 #define OPCODE_SIZE 2 /* Add 2 bytes, counting the opcode size*/
1691 switch ((*p)->howto->type) {
1693 case R_E1_CONST31_PCREL:
1694 case R_E1_DIS29W_PCREL:
1698 case R_E1_IMM32_PCREL:
1700 DBG_E1("In addr + 2:[0x%x] <- write [0x%x]\n",
1701 (sectionp + q->address + 2), sym_addr );
1702 *((unsigned long *) (sectionp + q->address + OPCODE_SIZE)) =
1706 DBG_E1("In addr : [0x%x] <- write [0x%x]\n",
1707 (sectionp + q->address), sym_addr );
1708 *((unsigned long *) (sectionp + q->address )) = htonl(sym_addr);
1711 printf("ERROR:Unhandled Relocation. Exiting...\n");
1715 #else /* ! TARGET_arm && ! TARGET_e1 */
1717 switch (q->howto->type) {
1722 /* Do nothing -- for cases we handle,
1723 the bits produced by the linker are
1724 what we want in the final flat file
1725 (and other cases are errors). Note
1726 that unlike most relocated values,
1727 it is stored in little-endian order,
1728 but this is necessary to avoid
1729 trashing the low-bit, and the float
1730 loaders knows about it. */
1732 #endif /* TARGET_V850 */
1735 case R_NIOS2_BFD_RELOC_32:
1736 case R_NIOS2_CALL26:
1737 case R_NIOS2_HIADJ16:
1741 #endif /* TARGET_nios2 */
1743 #if defined(TARGET_m68k)
1745 if (sym_addr < -0x8000 || sym_addr > 0x7fff) {
1746 fprintf (stderr, "Relocation overflow for R_68K_PC16 relocation against %s\n", sym_name);
1749 r_mem[0] = (sym_addr >> 8) & 0xff;
1750 r_mem[1] = sym_addr & 0xff;
1756 /* The alignment of the build host
1757 might be stricter than that of the
1758 target, so be careful. We store in
1759 network byte order. */
1760 r_mem[0] = (sym_addr >> 24) & 0xff;
1761 r_mem[1] = (sym_addr >> 16) & 0xff;
1762 r_mem[2] = (sym_addr >> 8) & 0xff;
1763 r_mem[3] = sym_addr & 0xff;
1765 #endif /* !TARGET_arm */
1770 if ((*p)->howto->type == R_rimm16
1771 || (*p)->howto->type == R_huimm16
1772 || (*p)->howto->type == R_luimm16)
1774 /* for l and h we set the lower 16 bits which is only when it will be used */
1775 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1776 } else if ((*p)->howto->type == R_byte4_data) {
1777 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1782 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
1783 "section=%s size=%d "
1784 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
1785 q->address, sym_name, addstr,
1786 section_name, sym_reloc_size,
1787 sym_addr, section_vma + q->address);
1790 * Create relocation entry (PC relative doesn't need this).
1792 if (relocation_needed) {
1794 flat_relocs = realloc(flat_relocs,
1795 (flat_reloc_count + 1) * sizeof(uint32_t));
1797 flat_relocs[flat_reloc_count] = pflags |
1798 (section_vma + q->address);
1801 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
1802 section_vma + q->address);
1804 switch ((*p)->howto->type) {
1806 case R_E1_CONST31_PCREL:
1807 case R_E1_DIS29W_PCREL:
1811 case R_E1_IMM32_PCREL:
1813 flat_relocs[flat_reloc_count] = pflags |
1814 (section_vma + q->address + OPCODE_SIZE);
1816 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1817 flat_relocs[flat_reloc_count] );
1820 flat_relocs[flat_reloc_count] = pflags |
1821 (section_vma + q->address);
1823 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1824 flat_relocs[flat_reloc_count] );
1830 relocation_needed = 0;
1835 printf("%s(%d): symbol name=%s address=0x%x section=%s -> RELOC=0x%x\n",
1836 __FILE__, __LINE__, sym_name, q->address, section_name,
1837 flat_relocs[flat_reloc_count]);
1844 printf("%d bad relocs\n", bad_relocs);
1851 *n_relocs = flat_reloc_count;
1857 static char * program;
1859 static void usage(void)
1861 fprintf(stderr, "Usage: %s [vrzd] [-p <abs-pic-file>] [-s stack-size] "
1862 "[-o <output-file>] <elf-file>\n\n"
1863 " -v : verbose operation\n"
1864 " -r : force load to RAM\n"
1865 " -k : enable kernel trace on load (for debug)\n"
1866 " -z : compress code/data/relocs\n"
1867 " -d : compress data/relocs\n"
1868 " -a : use existing symbol references\n"
1869 " instead of recalculating from\n"
1870 " relocation info\n"
1871 " -R reloc-file : read relocations from a separate file\n"
1872 " -p abs-pic-file : GOT/PIC processing with files\n"
1873 " -s stacksize : set application stack size\n"
1874 " -o output-file : output file name\n\n",
1876 fprintf(stderr, "Compiled for " ARCH " architecture\n\n");
1881 /* Write NUM zeroes to STREAM. */
1882 static void write_zeroes (unsigned long num, FILE *stream)
1886 /* It'd be nice if we could just use fseek, but that doesn't seem to
1887 work for stdio output files. */
1888 bzero(zeroes, 1024);
1889 while (num > sizeof(zeroes)) {
1890 fwrite(zeroes, sizeof(zeroes), 1, stream);
1891 num -= sizeof(zeroes);
1894 fwrite(zeroes, num, 1, stream);
1899 int main(int argc, char *argv[])
1902 bfd *rel_bfd, *abs_bfd;
1904 char *ofile=NULL, *pfile=NULL, *abs_file = NULL, *rel_file = NULL;
1912 asymbol **symbol_table;
1913 long number_of_symbols;
1915 unsigned long data_len = 0;
1916 unsigned long bss_len = 0;
1917 unsigned long text_len = 0;
1918 unsigned long reloc_len;
1920 unsigned long data_vma = ~0;
1921 unsigned long bss_vma = ~0;
1922 unsigned long text_vma = ~0;
1924 unsigned long text_offs;
1930 struct flat_hdr hdr;
1940 if (sizeof(hdr) != 64) {
1942 "Potential flat header incompatibility detected\n"
1943 "header size should be 64 but is %d\n",
1950 #else /* We need plenty of stack for both of them (Aggregate and Register) */
1954 while ((opt = getopt(argc, argv, "avzdrkp:s:o:R:")) != -1) {
1981 stack = atoi(optarg);
1987 fprintf(stderr, "%s Unknown option\n", argv[0]);
1994 * if neither the -r or -p options was given, default to
1995 * a RAM load as that is the only option that makes sense.
1997 if (!load_to_ram && !pfile)
2000 filename = fname = argv[argc-1];
2011 if (!(rel_bfd = bfd_openr(rel_file, 0))) {
2012 fprintf(stderr, "Can't open %s\n", rel_file);
2016 if (bfd_check_format (rel_bfd, bfd_object) == 0) {
2017 fprintf(stderr, "File is not an object file\n");
2021 if (abs_file == rel_file)
2022 abs_bfd = rel_bfd; /* one file does all */
2024 if (!(abs_bfd = bfd_openr(abs_file, 0))) {
2025 fprintf(stderr, "Can't open %s\n", abs_file);
2029 if (bfd_check_format (abs_bfd, bfd_object) == 0) {
2030 fprintf(stderr, "File is not an object file\n");
2035 if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC)) {
2036 fprintf (stderr, "%s: Input file contains no relocation info\n", rel_file);
2040 if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P)) {
2041 /* `Absolute' file is not absolute, so neither are address
2042 contained therein. */
2044 "%s: `-a' option specified with non-fully-resolved input file\n",
2045 bfd_get_filename (abs_bfd));
2049 symbol_table = get_symbols(abs_bfd, &number_of_symbols);
2051 /* Group output sections into text, data, and bss, and calc their sizes. */
2052 for (s = abs_bfd->sections; s != NULL; s = s->next) {
2053 unsigned long *vma, *len;
2054 bfd_size_type sec_size;
2057 if (s->flags & SEC_CODE) {
2060 } else if (s->flags & SEC_DATA) {
2063 } else if (s->flags & SEC_ALLOC) {
2069 sec_size = bfd_section_size(abs_bfd, s);
2070 sec_vma = bfd_section_vma(abs_bfd, s);
2072 if (sec_vma < *vma) {
2074 *len += sec_vma - *vma;
2078 } else if (sec_vma + sec_size > *vma + *len)
2079 *len = sec_vma + sec_size - *vma;
2082 if (text_len == 0) {
2083 fprintf (stderr, "%s: no .text section", abs_file);
2087 text = malloc(text_len);
2090 printf("TEXT -> vma=0x%x len=0x%x\n", text_vma, text_len);
2092 /* Read in all text sections. */
2093 for (s = abs_bfd->sections; s != NULL; s = s->next)
2094 if (s->flags & SEC_CODE)
2095 if (!bfd_get_section_contents(abs_bfd, s,
2096 text + (s->vma - text_vma), 0,
2097 bfd_section_size(abs_bfd, s)))
2099 fprintf(stderr, "read error section %s\n", s->name);
2103 if (data_len == 0) {
2104 fprintf (stderr, "%s: no .data section", abs_file);
2107 data = malloc(data_len);
2110 printf("DATA -> vma=0x%x len=0x%x\n", data_vma, data_len);
2112 if ((text_vma + text_len) != data_vma) {
2113 if ((text_vma + text_len) > data_vma) {
2114 printf("ERROR: text=0x%x overlaps data=0x%x ?\n", text_len, data_vma);
2118 printf("WARNING: data=0x%x does not directly follow text=0x%x\n",
2119 data_vma, text_len);
2120 text_len = data_vma - text_vma;
2123 /* Read in all data sections. */
2124 for (s = abs_bfd->sections; s != NULL; s = s->next)
2125 if (s->flags & SEC_DATA)
2126 if (!bfd_get_section_contents(abs_bfd, s,
2127 data + (s->vma - data_vma), 0,
2128 bfd_section_size(abs_bfd, s)))
2130 fprintf(stderr, "read error section %s\n", s->name);
2134 /* Put common symbols in bss. */
2135 bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len);
2138 printf("BSS -> vma=0x%x len=0x%x\n", bss_vma, bss_len);
2140 if ((data_vma + data_len) != bss_vma) {
2141 if ((data_vma + data_len) > bss_vma) {
2142 printf("ERROR: text=0x%x + data=0x%x overlaps bss=0x%x ?\n", text_len,
2147 printf("WARNING: bss=0x%x does not directly follow text=0x%x + data=0x%x(0x%x)\n",
2148 bss_vma, text_len, data_len, text_len + data_len);
2149 data_len = bss_vma - data_vma;
2152 reloc = output_relocs(abs_bfd, symbol_table, number_of_symbols, &reloc_len,
2153 text, text_len, text_vma, data, data_len, data_vma,
2157 printf("No relocations in code!\n");
2159 text_offs = real_address_bits(text_vma);
2161 /* Fill in the binflt_flat header */
2162 memcpy(hdr.magic,"bFLT",4);
2163 hdr.rev = htonl(FLAT_VERSION);
2164 hdr.entry = htonl(sizeof(hdr) + bfd_get_start_address(abs_bfd));
2165 hdr.data_start = htonl(sizeof(hdr) + text_offs + text_len);
2166 hdr.data_end = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2167 hdr.bss_end = htonl(sizeof(hdr) + text_offs + text_len +data_len+bss_len);
2168 hdr.stack_size = htonl(stack); /* FIXME */
2169 hdr.reloc_start = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2170 hdr.reloc_count = htonl(reloc_len);
2172 | (load_to_ram ? FLAT_FLAG_RAM : 0)
2173 | (ktrace ? FLAT_FLAG_KTRACE : 0)
2174 | (pic_with_got ? FLAT_FLAG_GOTPIC : 0)
2175 | (compress ? (compress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
2177 hdr.build_date = htonl((unsigned long)time(NULL));
2178 bzero(hdr.filler, sizeof(hdr.filler));
2180 for (i=0; i<reloc_len; i++) reloc[i] = htonl(reloc[i]);
2183 printf("SIZE: .text=0x%04x, .data=0x%04x, .bss=0x%04x",
2184 text_len, data_len, bss_len);
2186 printf(", relocs=0x%04x", reloc_len);
2191 ofile = malloc(strlen(fname) + 5 + 1); /* 5 to add suffix */
2192 strcpy(ofile, fname);
2193 strcat(ofile, ".bflt");
2196 if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0) {
2197 fprintf (stderr, "Can't open output file %s\n", ofile);
2201 write(fd, &hdr, sizeof(hdr));
2205 * get the compression command ready
2207 sprintf(cmd, "gzip -f -9 >> %s", ofile);
2209 #define START_COMPRESSOR do { \
2215 if (!(gf = popen(cmd, "w" BINARY_FILE_OPTS))) { \
2216 fprintf(stderr, "Can't run cmd %s\n", cmd); \
2222 gf = fopen(ofile, "ab"); /* Add 'b' to support non-posix (ie windows) */
2224 fprintf(stderr, "Can't open file %s for writing\n", ofile); \
2231 /* Fill in any hole at the beginning of the text segment. */
2233 printf("ZERO before text len=0x%x\n", text_offs);
2234 write_zeroes(text_offs, gf);
2236 /* Write the text segment. */
2237 fwrite(text, text_len, 1, gf);
2242 /* Write the data segment. */
2243 fwrite(data, data_len, 1, gf);
2246 fwrite(reloc, reloc_len * 4, 1, gf);
2258 * this __MUST__ be at the VERY end of the file - do NOT move!!
2264 * vi: tabstop=8 shiftwidth=4 textwidth=79 noexpandtab