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