2 * elf2flt.c: Convert ELF (or any BFD format) to FLAT binary format
4 * (c) 1999-2002, Greg Ungerer <gerg@snapgear.com>
5 * Created elf2flt from coff2flt (see copyrights below). Added all the
6 * ELF format file handling. Extended relocation support for all of
9 * (c) 2006 Support the -a (use_resolved) option for TARGET_arm.
10 * Shaun Jackman <sjackman@gmail.com>
11 * (c) 2004, Nios II support, Wentao Xu <wentao@microtronix.com>
12 * (c) 2003, H8 support, ktrace <davidm@snapgear.com>
13 * (c) 2003-2004, MicroBlaze support, John Williams <jwilliams@itee.uq.edu.au>
14 * (c) 2001-2003, arm/arm-pic/arm-big-endian support <davidm@snapgear.com>
15 * (c) 2001, v850 changes, Mile Bader <miles@lsi.nec.co.jp>
16 * (c) 2003, SuperH support, Paul Mundt <lethal@linux-sh.org>
17 * (c) 2001, zflat support <davidm@snapgear.com>
18 * (c) 2001, Changes for GOT entries Paul Dale <pauli@snapgear.com> and
19 * David McCullough <davidm@snapgear.com>
21 * Now supports PIC with GOT tables. This works by taking a '.elf' file
22 * and a fully linked elf executable (at address 0) and produces a flat
23 * file that can be loaded with some fixups. It still supports the old
24 * style fully relocatable elf format files.
26 * Originally obj-res.c
28 * (c) 1998, Kenneth Albanowski <kjahds@kjahds.com>
29 * (c) 1998, D. Jeff Dionne
30 * (c) 1998, The Silver Hammer Group Ltd.
31 * (c) 1996, 1997 Dionne & Associates <jeff@ryeham.ee.ryerson.ca>
33 * This is Free Software, under the GNU Public Licence v2 or greater.
35 * Relocation added March 1997, Kresten Krab Thorup
36 * krab@california.daimi.aau.dk
39 #include <stdio.h> /* Userland pieces of the ANSI C standard I/O package */
40 #include <stdlib.h> /* Userland prototypes of the ANSI C std lib functions */
41 #include <stdarg.h> /* Allows va_list to exist in the these namespaces */
42 #include <string.h> /* Userland prototypes of the string handling funcs */
44 #include <unistd.h> /* Userland prototypes of the Unix std system calls */
45 #include <fcntl.h> /* Flag value for file handling functions */
48 #include <netinet/in.h> /* Consts and structs defined by the internet system */
49 #define BINARY_FILE_OPTS
52 #define BINARY_FILE_OPTS "b"
55 /* from $(INSTALLDIR)/include */
56 #include <bfd.h> /* Main header file for the BFD library */
58 #if defined(TARGET_h8300)
59 #include <elf/h8.h> /* TARGET_* ELF support for the BFD library */
60 #elif defined(__CYGWIN__) || defined(__MINGW32__) || defined(TARGET_nios) || defined(TARGET_nios2)
61 #include "cygwin-elf.h" /* Cygwin uses a local copy */
62 #elif defined(TARGET_microblaze)
63 #include <elf/microblaze.h> /* TARGET_* ELF support for the BFD library */
64 #elif defined(TARGET_bfin)
67 #include <elf.h> /* TARGET_* ELF support for the BFD library */
70 #if defined(__MINGW32__)
74 /* from uClinux-x.x.x/include/linux */
75 #include "flat.h" /* Binary flat header description */
85 #if defined(TARGET_m68k)
86 #define ARCH "m68k/coldfire"
87 #elif defined(TARGET_arm)
89 #elif defined(TARGET_sparc)
91 #elif defined(TARGET_v850)
93 #elif defined(TARGET_sh)
95 #elif defined(TARGET_h8300)
97 #elif defined(TARGET_microblaze)
98 #define ARCH "microblaze"
99 #elif defined(TARGET_e1)
100 #define ARCH "e1-coff"
101 #elif defined(TARGET_bfin)
103 #define FLAT_RELOC_TYPE_TEXT 0
104 #define FLAT_RELOC_TYPE_DATA 1
105 #define FLAT_RELOC_TYPE_BSS 2
106 #define FLAT_RELOC_TYPE_STACK 3
107 #define FLAT_RELOC_PART_LO 0
108 #define FLAT_RELOC_PART_HI 1
109 #define PCREL24_MAGIC_OFFSET -1
110 #elif defined(TARGET_nios)
112 #elif defined(TARGET_nios2)
115 #error "Don't know how to support your CPU architecture??"
118 #if defined(TARGET_m68k) || defined(TARGET_h8300) || defined(TARGET_bfin)
120 * Define a maximum number of bytes allowed in the offset table.
121 * We'll fail if the table is larger than this.
123 * This limit may be different for platforms other than m68k, but
124 * 8000 entries is a lot, trust me :-) (davidm)
126 #define GOT_LIMIT 32767
128 * we have to mask out the shared library id here and there, this gives
129 * us the real address bits when needed
131 #define real_address_bits(x) (pic_with_got ? ((x) & 0xffffff) : (x))
133 #define real_address_bits(x) (x)
141 int verbose = 0; /* extra output when running */
142 int pic_with_got = 0; /* do elf/got processing with PIC code */
143 int load_to_ram = 0; /* instruct loader to allocate everything into RAM */
144 int ktrace = 0; /* instruct loader output kernel trace on load */
145 int compress = 0; /* 1 = compress everything, 2 = compress data only */
146 int use_resolved = 0; /* If true, get the value of symbol references from */
147 /* the program contents, not from the relocation table. */
148 /* In this case, the input ELF file must be already */
149 /* fully resolved (using the `-q' flag with recent */
150 /* versions of GNU ld will give you a fully resolved */
151 /* output file with relocation entries). */
153 const char *progname, *filename;
159 static char where[200];
162 /* Use exactly one of these: */
163 E_NOFILE = 0, /* "progname: " */
164 E_FILE = 1, /* "filename: " */
165 E_FILELINE = 2, /* "filename:lineno: " */
166 E_FILEWHERE = 3, /* "filename:%s: " -- set %s with ewhere() */
168 /* Add in any of these with |': */
173 void ewhere (const char *format, ...);
174 void einfo (int type, const char *format, ...);
178 ewhere (const char *format, ...) {
180 va_start (args, format);
181 vsprintf (where, format, args);
187 einfo (int type, const char *format, ...) {
190 switch (type & 0x0f) {
192 fprintf (stderr, "%s: ", progname);
195 fprintf (stderr, "%s: ", filename);
198 ewhere ("%d", lineno);
201 fprintf (stderr, "%s:%s: ", filename, where);
205 if (type & E_WARNING) {
206 fprintf (stderr, "warning: ");
212 va_start (args, format);
213 vfprintf (stderr, format, args);
219 fprintf (stderr, "\n");
224 get_symbols (bfd *abfd, long *num)
227 asymbol **symbol_table;
228 long number_of_symbols;
230 storage_needed = bfd_get_symtab_upper_bound (abfd);
232 if (storage_needed < 0)
235 if (storage_needed == 0)
238 symbol_table = (asymbol **) malloc (storage_needed);
239 if (symbol_table == NULL) {
244 number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
246 if (number_of_symbols < 0)
249 *num = number_of_symbols;
256 dump_symbols(asymbol **symbol_table, long number_of_symbols)
259 printf("SYMBOL TABLE:\n");
260 for (i=0; i<number_of_symbols; i++) {
261 printf(" NAME=%s VALUE=0x%x\n", symbol_table[i]->name,
262 symbol_table[i]->value);
271 get_symbol_offset(char *name, asection *sec, asymbol **symbol_table, long number_of_symbols)
274 for (i=0; i<number_of_symbols; i++) {
275 if (symbol_table[i]->section == sec) {
276 if (!strcmp(symbol_table[i]->name, name)) {
277 return symbol_table[i]->value;
287 get_gp_value(asymbol **symbol_table, long number_of_symbols)
290 for (i=0; i<number_of_symbols; i++) {
291 if (!strcmp(symbol_table[i]->name, "_gp"))
292 return symbol_table[i]->value;
300 add_com_to_bss(asymbol **symbol_table, long number_of_symbols, long bss_len)
306 for (i=0; i<number_of_symbols; i++) {
307 if (strcmp("*COM*", symbol_table[i]->section->name) == 0) {
308 offset = bss_len + comsize;
309 comsize += symbol_table[i]->value;
310 symbol_table[i]->value = offset;
317 /* FUNCTION : weak_und_symbol
318 ABSTRACT : return true if symbol is weak and undefined.
321 weak_und_symbol(const char *reloc_section_name,
322 struct bfd_symbol *symbol)
324 if (!(strstr (reloc_section_name, "text")
325 || strstr (reloc_section_name, "data")
326 || strstr (reloc_section_name, "bss"))) {
327 if (symbol->flags & BSF_WEAK) {
329 fprintf(stderr, "found weak undefined symbol %s\n", symbol->name);
338 bfin_set_reloc (uint32_t *reloc,
339 const char *reloc_section_name,
340 const char *sym_name,
341 struct bfd_symbol *symbol,
342 int sp, int hilo, int32_t offset)
347 if (strstr (reloc_section_name, "text"))
348 type = FLAT_RELOC_TYPE_TEXT;
349 else if (strstr (reloc_section_name, "data"))
350 type = FLAT_RELOC_TYPE_DATA;
351 else if (strstr (reloc_section_name, "bss"))
352 type = FLAT_RELOC_TYPE_BSS;
353 else if (strstr (reloc_section_name, "stack"))
354 type = FLAT_RELOC_TYPE_STACK;
355 else if (symbol->flags & BSF_WEAK){
356 /* weak symbol support ... if a weak symbol is undefined at the
357 end of a final link, it should return 0 rather than error
358 We will assume text section for the moment.
360 type = FLAT_RELOC_TYPE_TEXT;
361 } else if (strstr (reloc_section_name, "*ABS*")){
362 /* (A data section initialization of something in the shared libc's text section
363 does not resolve - i.e. a global pointer to function initialized with
365 The text section here is appropriate as the section information
366 of the shared library is lost. The loader will do some calcs.
368 type = FLAT_RELOC_TYPE_TEXT;
370 printf ("Unknown Type - relocation for %s in bad section - %s\n", sym_name, reloc_section_name);
374 val = (offset & ((1 << 26) - 1)) << 6;
375 val |= (sp & (1 << 3) - 1) << 3;
376 val |= (hilo & 1) << 2;
377 val |= (type & (1 << 2) - 1);
388 int number_of_symbols,
389 unsigned long *n_relocs,
390 unsigned char *text, int text_len, unsigned long text_vma,
391 unsigned char *data, int data_len, unsigned long data_vma,
394 uint32_t *flat_relocs;
395 asection *a, *sym_section, *r;
396 arelent **relpp, **p, *q;
397 const char *sym_name, *section_name;
398 unsigned char *sectionp;
399 unsigned long pflags;
401 long sym_addr, sym_vma, section_vma;
402 int relsize, relcount;
403 int flat_reloc_count;
404 int sym_reloc_size, rc;
411 printf("%s(%d): output_relocs(abs_bfd=%d,synbols=0x%x,number_of_symbols=%d"
412 "n_relocs=0x%x,text=0x%x,text_len=%d,data=0x%x,data_len=%d)\n",
413 __FILE__, __LINE__, abs_bfd, symbols, number_of_symbols, n_relocs,
414 text, text_len, data, data_len);
418 dump_symbols(symbols, number_of_symbols);
423 flat_reloc_count = 0;
427 /* Determine how big our offset table is in bytes.
428 * This isn't too difficult as we've terminated the table with -1.
429 * Also note that both the relocatable and absolute versions have this
430 * terminator even though the relocatable one doesn't have the GOT!
432 if (pic_with_got && !use_resolved) {
433 unsigned long *lp = (unsigned long *)data;
434 /* Should call ntohl(*lp) here but is isn't going to matter */
435 while (*lp != 0xffffffff) lp++;
436 got_size = ((unsigned char *)lp) - data;
438 printf("GOT table contains %d entries (%d bytes)\n",
439 got_size/sizeof(unsigned long), got_size);
441 if (got_size > GOT_LIMIT) {
442 fprintf(stderr, "GOT too large: %d bytes (limit = %d bytes)\n",
443 got_size, GOT_LIMIT);
449 for (a = abs_bfd->sections; (a != (asection *) NULL); a = a->next) {
450 section_vma = bfd_section_vma(abs_bfd, a);
453 printf("SECTION: %s [0x%x]: flags=0x%x vma=0x%x\n", a->name, a,
454 a->flags, section_vma);
456 // if (bfd_is_abs_section(a))
458 if (bfd_is_und_section(a))
460 if (bfd_is_com_section(a))
462 // if ((a->flags & SEC_RELOC) == 0)
466 * Only relocate things in the data sections if we are PIC/GOT.
467 * otherwise do text as well
469 if (!pic_with_got && (a->flags & SEC_CODE))
470 sectionp = text + (a->vma - text_vma);
471 else if (a->flags & SEC_DATA)
472 sectionp = data + (a->vma - data_vma);
476 /* Now search for the equivalent section in the relocation binary
477 * and use that relocation information to build reloc entries
480 for (r=rel_bfd->sections; r != NULL; r=r->next)
481 if (strcmp(a->name, r->name) == 0)
486 printf(" RELOCS: %s [0x%x]: flags=0x%x vma=0x%x\n", r->name, r,
487 r->flags, bfd_section_vma(abs_bfd, r));
488 if ((r->flags & SEC_RELOC) == 0)
490 relsize = bfd_get_reloc_upper_bound(rel_bfd, r);
493 printf("%s(%d): no relocation entries section=0x%x\n",
494 __FILE__, __LINE__, r->name);
498 symb = get_symbols(rel_bfd, &nsymb);
499 relpp = (arelent **) malloc(relsize);
505 relcount = bfd_canonicalize_reloc(rel_bfd, r, relpp, symb);
508 printf("%s(%d): no relocation entries section=%s\n",
509 __FILE__, __LINE__, r->name);
512 for (p = relpp; (relcount && (*p != NULL)); p++, relcount--) {
513 unsigned char *r_mem;
514 int relocation_needed = 0;
516 #ifdef TARGET_microblaze
517 /* The MICROBLAZE_XX_NONE relocs can be skipped.
518 They represent PC relative branches that the
519 linker has already resolved */
521 switch ((*p)->howto->type)
523 case R_MICROBLAZE_NONE:
524 case R_MICROBLAZE_64_NONE:
527 #endif /* TARGET_microblaze */
530 /* Skip this relocation entirely if possible (we
531 do this early, before doing any other
532 processing on it). */
533 switch ((*p)->howto->type) {
534 #ifdef R_V850_9_PCREL
537 #ifdef R_V850_22_PCREL
538 case R_V850_22_PCREL:
540 #ifdef R_V850_SDA_16_16_OFFSET
541 case R_V850_SDA_16_16_OFFSET:
543 #ifdef R_V850_SDA_15_16_OFFSET
544 case R_V850_SDA_15_16_OFFSET:
546 #ifdef R_V850_ZDA_15_16_OFFSET
547 case R_V850_ZDA_15_16_OFFSET:
549 #ifdef R_V850_TDA_6_8_OFFSET
550 case R_V850_TDA_6_8_OFFSET:
552 #ifdef R_V850_TDA_7_8_OFFSET
553 case R_V850_TDA_7_8_OFFSET:
555 #ifdef R_V850_TDA_7_7_OFFSET
556 case R_V850_TDA_7_7_OFFSET:
558 #ifdef R_V850_TDA_16_16_OFFSET
559 case R_V850_TDA_16_16_OFFSET:
561 #ifdef R_V850_TDA_4_5_OFFSET
562 case R_V850_TDA_4_5_OFFSET:
564 #ifdef R_V850_TDA_4_4_OFFSET
565 case R_V850_TDA_4_4_OFFSET:
567 #ifdef R_V850_SDA_16_16_SPLIT_OFFSET
568 case R_V850_SDA_16_16_SPLIT_OFFSET:
570 #ifdef R_V850_CALLT_6_7_OFFSET
571 case R_V850_CALLT_6_7_OFFSET:
573 #ifdef R_V850_CALLT_16_16_OFFSET
574 case R_V850_CALLT_16_16_OFFSET:
576 /* These are relative relocations, which
577 have already been fixed up by the
578 linker at this point, so just ignore
582 #endif /* USE_V850_RELOCS */
585 if (q->sym_ptr_ptr && *q->sym_ptr_ptr) {
586 sym_name = (*(q->sym_ptr_ptr))->name;
587 sym_section = (*(q->sym_ptr_ptr))->section;
588 section_name=(*(q->sym_ptr_ptr))->section->name;
590 printf("ERROR: undefined relocation entry\n");
595 /* Adjust the address to account for the GOT table which wasn't
596 * present in the relative file link.
598 if (pic_with_got && !use_resolved)
599 q->address += got_size;
602 /* A pointer to what's being relocated, used often
604 r_mem = sectionp + q->address;
607 * Fixup offset in the actual section.
611 if ((sym_addr = get_symbol_offset((char *) sym_name,
612 sym_section, symbols, number_of_symbols)) == -1) {
616 sym_addr = (*(q->sym_ptr_ptr))->value;
619 /* Use the address of the symbol already in
620 the program text. How this is handled may
621 still depend on the particular relocation
623 switch (q->howto->type) {
627 /* We specially handle adjacent
628 HI16_S/ZDA_15_16_OFFSET and
629 HI16_S/LO16 pairs that reference the
630 same address (these are usually
631 movhi/ld and movhi/movea pairs,
634 r2_type = R_V850_NONE;
636 r2_type = p[1]->howto->type;
637 if ((r2_type == R_V850_ZDA_15_16_OFFSET
638 || r2_type == R_V850_LO16)
639 && (p[0]->sym_ptr_ptr
640 == p[1]->sym_ptr_ptr)
641 && (p[0]->addend == p[1]->addend))
643 relocation_needed = 1;
646 case R_V850_ZDA_15_16_OFFSET:
654 /* We don't really need the
655 actual value -- the bits
656 produced by the linker are
657 what we want in the final
658 flat file -- but get it
662 unsigned char *r2_mem =
670 /* Sign extend LO. */
674 /* Maybe ignore the LSB
678 if (r2_type != R_V850_LO16)
686 goto bad_resolved_reloc;
690 /* See if this is actually the
691 2nd half of a pair. */
693 && (p[-1]->howto->type
695 && (p[-1]->sym_ptr_ptr
696 == p[0]->sym_ptr_ptr)
697 && (p[-1]->addend == p[0]->addend))
698 break; /* not an error */
700 goto bad_resolved_reloc;
703 goto bad_resolved_reloc;
705 goto good_32bit_resolved_reloc;
706 #elif defined(TARGET_arm)
708 relocation_needed = 1;
713 relocation_needed = 0;
716 goto bad_resolved_reloc;
717 #elif defined(TARGET_m68k)
719 goto good_32bit_resolved_reloc;
722 /* The linker has already resolved
723 PC relocs for us. In PIC links,
724 the symbol must be in the data
729 goto bad_resolved_reloc;
732 /* The default is to assume that the
733 relocation is relative and has
734 already been fixed up by the
735 linker (perhaps we ought to make
736 give an error by default, and
737 require `safe' relocations to be
738 enumberated explicitly?). */
739 goto good_32bit_resolve_reloc;
741 good_32bit_resolved_reloc:
742 if (bfd_big_endian (abs_bfd))
754 relocation_needed = 1;
758 printf("ERROR: reloc type %s unsupported in this context\n",
764 /* Calculate the sym address ourselves. */
765 sym_reloc_size = bfd_get_reloc_size(q->howto);
767 #if !defined(TARGET_h8300) && !defined(TARGET_e1) && !defined(TARGET_bfin) && !defined(TARGET_m68k)
768 if (sym_reloc_size != 4) {
769 printf("ERROR: bad reloc type %d size=%d for symbol=%s\n",
770 (*p)->howto->type, sym_reloc_size, sym_name);
777 switch ((*p)->howto->type) {
779 #if defined(TARGET_m68k)
781 relocation_needed = 1;
782 sym_vma = bfd_section_vma(abs_bfd, sym_section);
783 sym_addr += sym_vma + q->addend;
788 sym_addr += sym_vma + q->addend;
789 sym_addr -= q->address;
793 #if defined(TARGET_arm)
795 relocation_needed = 1;
798 "%s vma=0x%x, value=0x%x, address=0x%x "
799 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
801 sym_vma, (*(q->sym_ptr_ptr))->value,
802 q->address, sym_addr,
803 (*p)->howto->rightshift,
804 *(unsigned long *)r_mem);
805 sym_vma = bfd_section_vma(abs_bfd, sym_section);
806 sym_addr += sym_vma + q->addend;
810 /* Should be fine as is */
815 "%s vma=0x%x, value=0x%x, address=0x%x "
816 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
818 sym_vma, (*(q->sym_ptr_ptr))->value,
819 q->address, sym_addr,
820 (*p)->howto->rightshift,
821 *(unsigned long *)r_mem);
824 sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift;
830 relocation_needed = 1;
831 sym_vma = bfd_section_vma(abs_bfd, sym_section);
832 sym_addr += sym_vma + q->addend;
834 #if defined(R_V850_ZDA_16_16_OFFSET) || defined(R_V850_ZDA_16_16_SPLIT_OFFSET)
835 #ifdef R_V850_ZDA_16_16_OFFSET
836 case R_V850_ZDA_16_16_OFFSET:
838 #ifdef R_V850_ZDA_16_16_SPLIT_OFFSET
839 case R_V850_ZDA_16_16_SPLIT_OFFSET:
841 /* Can't support zero-relocations. */
842 printf ("ERROR: %s+0x%x: zero relocations not supported\n",
843 sym_name, q->addend);
845 #endif /* R_V850_ZDA_16_16_OFFSET || R_V850_ZDA_16_16_SPLIT_OFFSET */
846 #endif /* TARGET_v850 */
850 if (sym_reloc_size != 4) {
851 printf("R_H8_DIR24R8 size %d\n", sym_reloc_size);
855 relocation_needed = 1;
856 sym_addr = (*(q->sym_ptr_ptr))->value;
858 r_mem -= 1; /* tracks q->address */
859 sym_vma = bfd_section_vma(abs_bfd, sym_section);
860 sym_addr += sym_vma + q->addend;
861 sym_addr |= (*(unsigned char *)r_mem<<24);
864 if (sym_reloc_size != 4) {
865 printf("R_H8_DIR24A8 size %d\n", sym_reloc_size);
869 /* Absolute symbol done not relocation */
870 relocation_needed = !bfd_is_abs_section(sym_section);
871 sym_addr = (*(q->sym_ptr_ptr))->value;
872 sym_vma = bfd_section_vma(abs_bfd, sym_section);
873 sym_addr += sym_vma + q->addend;
876 case R_H8_DIR32A16: /* currently 32, could be made 16 */
877 if (sym_reloc_size != 4) {
878 printf("R_H8_DIR32 size %d\n", sym_reloc_size);
882 relocation_needed = 1;
883 sym_addr = (*(q->sym_ptr_ptr))->value;
884 sym_vma = bfd_section_vma(abs_bfd, sym_section);
885 sym_addr += sym_vma + q->addend;
889 sym_addr = (*(q->sym_ptr_ptr))->value;
890 sym_addr += sym_vma + q->addend;
891 sym_addr -= (q->address + 2);
892 if (bfd_big_endian(abs_bfd))
893 *(unsigned short *)r_mem =
894 bfd_big_endian(abs_bfd) ? htons(sym_addr) : sym_addr;
898 sym_addr = (*(q->sym_ptr_ptr))->value;
899 sym_addr += sym_vma + q->addend;
900 sym_addr -= (q->address + 1);
901 *(unsigned char *)r_mem = sym_addr;
905 #ifdef TARGET_microblaze
906 case R_MICROBLAZE_64:
907 /* The symbol is split over two consecutive instructions.
908 Flag this to the flat loader by setting the high bit of
909 the relocation symbol. */
911 unsigned char *p = r_mem;
912 unsigned long offset;
915 /* work out the relocation */
916 sym_vma = bfd_section_vma(abs_bfd, sym_section);
917 /* grab any offset from the text */
918 offset = (p[2]<<24) + (p[3] << 16) + (p[6] << 8) + (p[7]);
919 /* Update the address */
920 sym_addr += offset + sym_vma + q->addend;
921 /* Write relocated pointer back */
922 p[2] = (sym_addr >> 24) & 0xff;
923 p[3] = (sym_addr >> 16) & 0xff;
924 p[6] = (sym_addr >> 8) & 0xff;
925 p[7] = sym_addr & 0xff;
927 /* create a new reloc entry */
928 flat_relocs = realloc(flat_relocs,
929 (flat_reloc_count + 1) * sizeof(uint32_t));
930 flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address);
932 relocation_needed = 0;
934 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
935 bfd_section_vma(abs_bfd, sym_section));
937 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
938 "section=%s size=%d "
939 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
940 q->address, sym_name, addstr,
941 section_name, sym_reloc_size,
942 sym_addr, section_vma + q->address);
944 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
945 section_vma + q->address);
949 case R_MICROBLAZE_32:
951 unsigned char *p = r_mem;
952 unsigned long offset;
954 /* grab any offset from the text */
955 offset = (p[0]<<24) + (p[1] << 16) + (p[2] << 8) + (p[3]);
956 sym_vma = bfd_section_vma(abs_bfd, sym_section);
957 /* This is a horrible kludge. For some
958 reason, *sometimes* the offset is in
959 both addend and the code. Detect
960 it, and cancel the effect. Otherwise
961 the offset gets added twice - ouch.
962 There should be a better test
963 for this condition, based on the
964 BFD data structures */
965 if(offset==q->addend)
968 sym_addr += offset + sym_vma + q->addend;
969 relocation_needed = 1;
972 case R_MICROBLAZE_64_PCREL:
974 //sym_addr = (*(q->sym_ptr_ptr))->value;
975 sym_addr += sym_vma + q->addend;
976 sym_addr -= (q->address + 4);
977 sym_addr = htonl(sym_addr);
979 * ((unsigned short *) (r_mem+2)) |= (sym_addr) & 0xFFFF;
981 * ((unsigned short *) (r_mem+6)) |= (sym_addr >> 16) & 0xFFFF;
982 /* We've done all the work, so continue
983 to next reloc instead of break */
986 #endif /* TARGET_microblaze */
989 #define htoniosl(x) (x)
990 #define niostohl(x) (x)
991 switch ((*p)->howto->type)
993 case R_NIOS2_BFD_RELOC_32:
994 relocation_needed = 1;
995 pflags = (FLAT_NIOS2_R_32 << 28);
996 sym_vma = bfd_section_vma(abs_bfd, sym_section);
997 sym_addr += sym_vma + q->addend;
998 /* modify target, in target order */
999 *(unsigned long *)r_mem = htoniosl(sym_addr);
1001 case R_NIOS2_CALL26:
1003 unsigned long exist_val;
1004 relocation_needed = 1;
1005 pflags = (FLAT_NIOS2_R_CALL26 << 28);
1006 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1007 sym_addr += sym_vma + q->addend;
1009 /* modify target, in target order */
1010 // exist_val = niostohl(*(unsigned long *)r_mem);
1011 exist_val = ((sym_addr >> 2) << 6);
1012 *(unsigned long *)r_mem = htoniosl(exist_val);
1015 case R_NIOS2_HIADJ16:
1018 unsigned long exist_val;
1020 /* handle the adjacent HI/LO pairs */
1022 r2_type = R_NIOS2_NONE;
1024 r2_type = p[1]->howto->type;
1025 if ((r2_type == R_NIOS2_LO16)
1026 && (p[0]->sym_ptr_ptr == p[1]->sym_ptr_ptr)
1027 && (p[0]->addend == p[1]->addend))
1029 unsigned char * r2_mem = sectionp + p[1]->address;
1030 if (p[1]->address - q->address!=4)
1031 printf("Err: HI/LO not adjacent %d\n", p[1]->address - q->address);
1032 relocation_needed = 1;
1033 pflags = (q->howto->type == R_NIOS2_HIADJ16)
1034 ? FLAT_NIOS2_R_HIADJ_LO : FLAT_NIOS2_R_HI_LO;
1037 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1038 sym_addr += sym_vma + q->addend;
1040 /* modify high 16 bits, in target order */
1041 exist_val = niostohl(*(unsigned long *)r_mem);
1042 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1043 if (q->howto->type == R_NIOS2_HIADJ16)
1044 exist_val |= ((((sym_addr >> 16) + ((sym_addr >> 15) & 1)) & 0xFFFF) << 6);
1046 exist_val |= (((sym_addr >> 16) & 0xFFFF) << 6);
1047 *(unsigned long *)r_mem = htoniosl(exist_val);
1049 /* modify low 16 bits, in target order */
1050 exist_val = niostohl(*(unsigned long *)r2_mem);
1051 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1052 exist_val |= ((sym_addr & 0xFFFF) << 6);
1053 *(unsigned long *)r2_mem = htoniosl(exist_val);
1056 goto NIOS2_RELOC_ERR;
1062 unsigned long exist_val, temp;
1063 //long gp = get_symbol_offset("_gp", sym_section, symbols, number_of_symbols);
1064 long gp = get_gp_value(symbols, number_of_symbols);
1066 printf("Err: unresolved symbol _gp when relocating %s\n", sym_name);
1067 goto NIOS2_RELOC_ERR;
1069 /* _gp holds a absolute value, otherwise the ld cannot generate correct code */
1070 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1071 //printf("sym=%x, %d, _gp=%x, %d\n", sym_addr+sym_vma, sym_addr+sym_vma, gp, gp);
1072 sym_addr += sym_vma + q->addend;
1074 //printf("sym - _gp=%x, %d\n", sym_addr, sym_addr);
1075 /* modify the target, in target order (little_endian) */
1076 exist_val = niostohl(*(unsigned long *)r_mem);
1077 temp = ((exist_val >> 6) & 0x3ff0000) | (sym_addr & 0xffff);
1079 temp |= (exist_val & 0x3f);
1080 *(unsigned long *)r_mem = htoniosl(temp);
1082 printf("omit: offset=0x%x symbol=%s%s "
1083 "section=%s size=%d "
1084 "fixup=0x%x (reloc=0x%x) GPREL\n",
1085 q->address, sym_name, addstr,
1086 section_name, sym_reloc_size,
1087 sym_addr, section_vma + q->address);
1090 case R_NIOS2_PCREL16:
1092 unsigned long exist_val;
1094 sym_addr += sym_vma + q->addend;
1095 sym_addr -= (q->address + 4);
1096 /* modify the target, in target order (little_endian) */
1097 exist_val = niostohl(*(unsigned long *)r_mem);
1098 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1099 exist_val |= ((sym_addr & 0xFFFF) << 6);
1100 *(unsigned long *)r_mem = htoniosl(exist_val);
1102 printf("omit: offset=0x%x symbol=%s%s "
1103 "section=%s size=%d "
1104 "fixup=0x%x (reloc=0x%x) PCREL\n",
1105 q->address, sym_name, addstr,
1106 section_name, sym_reloc_size,
1107 sym_addr, section_vma + q->address);
1112 /* check if this is actually the 2nd half of a pair */
1114 && ((p[-1]->howto->type == R_NIOS2_HIADJ16)
1115 || (p[-1]->howto->type == R_NIOS2_HI16))
1116 && (p[-1]->sym_ptr_ptr == p[0]->sym_ptr_ptr)
1117 && (p[-1]->addend == p[0]->addend)) {
1119 printf("omit: offset=0x%x symbol=%s%s "
1120 "section=%s size=%d LO16\n",
1121 q->address, sym_name, addstr,
1122 section_name, sym_reloc_size);
1126 /* error, fall through */
1130 case R_NIOS2_CACHE_OPX:
1134 case R_NIOS2_BFD_RELOC_16:
1135 case R_NIOS2_BFD_RELOC_8:
1136 case R_NIOS2_GNU_VTINHERIT:
1137 case R_NIOS2_GNU_VTENTRY:
1142 printf("Err: unexpected reloc type %s(%d)\n", q->howto->name, q->howto->type);
1146 #endif /* TARGET_nios2 */
1151 relocation_needed = 1;
1152 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1153 sym_addr += sym_vma + q->addend;
1157 sym_addr += sym_vma + q->addend;
1158 sym_addr -= q->address;
1160 case R_SPARC_WDISP30:
1161 sym_addr = (((*(q->sym_ptr_ptr))->value-
1162 q->address) >> 2) & 0x3fffffff;
1164 ntohl(*(unsigned long *)r_mem)
1169 relocation_needed = 1;
1170 pflags = 0x80000000;
1171 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1172 sym_addr += sym_vma + q->addend;
1174 htonl(*(unsigned long *)r_mem)
1179 relocation_needed = 1;
1180 pflags = 0x40000000;
1181 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1182 sym_addr += sym_vma + q->addend;
1183 sym_addr &= 0x000003ff;
1185 htonl(*(unsigned long *)r_mem)
1189 #endif /* TARGET_sparc */
1192 case R_pcrel12_jump:
1193 case R_pcrel12_jump_s:
1195 case R_pcrel24_jump_l:
1196 case R_pcrel24_jump_x:
1197 case R_pcrel24_call_x:
1201 sym_addr += q->addend;// get the symbol addr
1202 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1203 sym_addr -= q->address; // make it PC relative
1204 // implicitly assumes code section and symbol section are same
1211 sym_addr += q->addend;
1212 if(weak_und_symbol(sym_section->name, (*(q->sym_ptr_ptr))))
1214 if(0xFFFF0000 & sym_addr){
1215 fprintf (stderr, "Relocation overflow for rN = %s\n",sym_name);
1218 flat_relocs = (uint32_t *)
1219 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1220 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1221 sym_section->name, sym_name,
1222 (*(q->sym_ptr_ptr)),
1223 0, FLAT_RELOC_PART_LO,
1224 section_vma + q->address))
1233 unsigned int reloc_count_incr;
1236 if (q->howto->type == R_luimm16)
1237 hi_lo = FLAT_RELOC_PART_LO;
1239 hi_lo = FLAT_RELOC_PART_HI;
1241 sym_addr += q->addend;
1243 flat_relocs = (uint32_t *)
1244 (realloc (flat_relocs, (flat_reloc_count + 2) * sizeof (uint32_t)));
1245 reloc_count_incr = 1;
1246 if (weak_und_symbol (sym_section->name, (*(q->sym_ptr_ptr))))
1248 if (0xFFFF0000 & sym_addr) {
1249 /* value is > 16 bits - use an extra field */
1250 /* see if we have already output that symbol */
1251 /* reloc may be addend from symbol and */
1252 /* we can only store 16 bit offsets */
1254 if ((*(q->sym_ptr_ptr))->udata.i == 0
1255 || flat_relocs[(*(q->sym_ptr_ptr))->udata.i] != sym_addr
1256 || ((*(q->sym_ptr_ptr))->udata.i & 0xFFFF0000))
1258 reloc_count_incr = 2;
1259 flat_relocs[flat_reloc_count + 1] = sym_addr;
1260 (*(q->sym_ptr_ptr))->udata.i = flat_reloc_count + 1;
1261 sym_addr = 0; // indication to loader to read next
1263 sym_addr = (*(q->sym_ptr_ptr))->udata.i;
1269 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1270 sym_section->name, sym_name,
1271 (*(q->sym_ptr_ptr)),
1273 section_vma + q->address))
1275 flat_reloc_count += reloc_count_incr;
1279 sym_addr += q->addend;
1281 if (weak_und_symbol (sym_section->name, *q->sym_ptr_ptr))
1284 flat_relocs = (uint32_t *)
1285 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1286 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1287 sym_section->name, sym_name,
1288 (*(q->sym_ptr_ptr)),
1289 2, FLAT_RELOC_PART_LO,
1290 section_vma + q->address))
1296 #endif //TARGET_bfin
1300 relocation_needed = 1;
1301 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1302 sym_addr += sym_vma + q->addend;
1306 sym_addr += sym_vma + q->addend;
1307 sym_addr -= q->address;
1309 #endif /* TARGET_sh */
1312 #define htoe1l(x) htonl(x)
1319 #define DBG_E1 printf
1321 #define DBG_E1(x, ... )
1324 #define _32BITS_RELOC 0x00000000
1325 #define _30BITS_RELOC 0x80000000
1326 #define _28BITS_RELOC 0x40000000
1329 unsigned long sec_vma, exist_val, S;
1331 relocation_needed = 1;
1332 DBG_E1("Handling Reloc <CONST31>\n");
1333 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1334 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1335 sec_vma, sym_addr, q->address);
1336 sym_addr = sec_vma + sym_addr;
1337 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1338 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1339 exist_val = htoe1l(exist_val);
1340 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1341 sym_addr += exist_val;
1342 pflags = _30BITS_RELOC;
1344 case R_E1_CONST31_PCREL:
1345 relocation_needed = 0;
1346 DBG_E1("Handling Reloc <CONST31_PCREL>\n");
1347 DBG_E1("DONT RELOCATE AT LOADING\n");
1348 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1349 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1350 sec_vma, sym_addr, q->address);
1351 sym_addr = sec_vma + sym_addr;
1352 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1354 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1356 q->address = q->address + section_vma;
1357 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1359 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1360 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1361 DBG_E1( "sym_addr := sym_addr - q->address - "
1362 "sizeof(CONST31_PCREL): [0x%x]\n",
1364 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1365 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1366 exist_val = htoe1l(exist_val);
1367 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1368 sym_addr |= exist_val;
1369 DBG_E1("sym_addr |= exist_val) : [0x%x]\n", sym_addr );
1371 case R_E1_DIS29W_PCREL:
1372 relocation_needed = 0;
1373 DBG_E1("Handling Reloc <DIS29W_PCREL>\n");
1374 DBG_E1("DONT RELOCATE AT LOADING\n");
1375 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1376 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1377 sec_vma, sym_addr, q->address);
1378 sym_addr = sec_vma + sym_addr;
1379 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1381 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1383 q->address = q->address + section_vma;
1384 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1386 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1387 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1388 DBG_E1( "sym_addr := sym_addr - q->address - "
1389 "sizeof(CONST31_PCREL): [0x%x]\n",
1391 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1392 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1393 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1394 exist_val = htoe1l(exist_val);
1395 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1396 sym_addr += exist_val;
1399 DBG_E1("Handling Reloc <DIS29W>\n");
1400 goto DIS29_RELOCATION;
1402 DBG_E1("Handling Reloc <DIS29H>\n");
1403 goto DIS29_RELOCATION;
1405 DBG_E1("Handling Reloc <DIS29B>\n");
1407 relocation_needed = 1;
1408 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1409 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%08x]\n",
1411 sym_addr = sec_vma + sym_addr;
1412 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%08x]\n", sym_addr);
1413 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1414 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1415 exist_val = htoe1l(exist_val);
1416 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1417 sym_addr += exist_val;
1418 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1419 pflags = _28BITS_RELOC;
1421 case R_E1_IMM32_PCREL:
1422 relocation_needed = 0;
1423 DBG_E1("Handling Reloc <IMM32_PCREL>\n");
1424 DBG_E1("DONT RELOCATE AT LOADING\n");
1425 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1426 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1428 sym_addr = sec_vma + sym_addr;
1430 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1431 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1433 q->address = q->address + section_vma;
1434 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1436 if( (sym_addr = (sym_addr - q->address - 6 )) < 0 )
1437 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1438 DBG_E1( "sym_addr := sym_addr - q->address - "
1439 "sizeof(CONST31_PCREL): [0x%x]\n",
1441 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1442 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1443 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1444 exist_val = htoe1l(exist_val);
1445 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1446 sym_addr += exist_val;
1449 relocation_needed = 1;
1450 DBG_E1("Handling Reloc <IMM32>\n");
1451 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1452 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1454 sym_addr = sec_vma + sym_addr;
1455 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1456 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1457 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1458 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1459 exist_val = htoe1l(exist_val);
1460 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1461 sym_addr += exist_val;
1462 pflags = _32BITS_RELOC;
1465 relocation_needed = 1;
1466 DBG_E1("Handling Reloc <WORD>\n");
1467 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1468 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1470 sym_addr = sec_vma + sym_addr;
1471 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1472 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address );
1473 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1474 exist_val = htoe1l(exist_val);
1475 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1476 sym_addr += exist_val;
1477 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1478 pflags = _32BITS_RELOC;
1481 #undef _32BITS_RELOC
1482 #undef _30BITS_RELOC
1483 #undef _28BITS_RELOC
1486 /* missing support for other types of relocs */
1487 printf("ERROR: bad reloc type %d\n", (*p)->howto->type);
1493 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
1494 bfd_section_vma(abs_bfd, sym_section));
1498 * for full elf relocation we have to write back the
1499 * start_code relative value to use.
1501 if (!pic_with_got) {
1502 #if defined(TARGET_arm)
1511 * horrible nasty hack to support different endianess
1513 if (!bfd_big_endian(abs_bfd)) {
1525 tmp.l = *(unsigned long *)r_mem;
1526 hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16);
1528 (((*p)->howto->type != R_ARM_PC24) &&
1529 ((*p)->howto->type != R_ARM_PLT32)))
1530 hl |= (tmp.c[i3] << 24);
1531 else if (tmp.c[i2] & 0x80)
1532 hl |= 0xff000000; /* sign extend */
1535 tmp.c[i0] = hl & 0xff;
1536 tmp.c[i1] = (hl >> 8) & 0xff;
1537 tmp.c[i2] = (hl >> 16) & 0xff;
1539 (((*p)->howto->type != R_ARM_PC24) &&
1540 ((*p)->howto->type != R_ARM_PLT32)))
1541 tmp.c[i3] = (hl >> 24) & 0xff;
1542 if ((*p)->howto->type == R_ARM_ABS32)
1543 *(unsigned long *)r_mem = htonl(hl);
1545 *(unsigned long *)r_mem = tmp.l;
1547 #elif defined(TARGET_bfin)
1548 if ((*p)->howto->type == R_pcrel24
1549 || (*p)->howto->type == R_pcrel24_jump_l
1550 || (*p)->howto->type == R_pcrel24_jump_x
1551 || (*p)->howto->type == R_pcrel24_call_x)
1553 sym_addr += 2*-1*PCREL24_MAGIC_OFFSET;
1554 *((unsigned short *)(sectionp + q->address) + 1 + PCREL24_MAGIC_OFFSET)
1555 = (sym_addr >> 1) & 0xffff;
1556 *((unsigned short *)(sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1557 = (0xff00 & *((unsigned short *) (sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1558 | ((sym_addr >> 17) & 0xff));
1559 } else if ((*p)->howto->type == R_byte4_data) {
1560 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1561 } else if ((*p)->howto->type == R_pcrel12_jump
1562 || (*p)->howto->type == R_pcrel12_jump_s) {
1563 *((unsigned short *)(sectionp + q->address))
1564 = (0xf000 & *((unsigned short *)(sectionp + q->address))
1565 | ((sym_addr >> 1) & 0xfff));
1566 } else if ((*p)->howto->type == R_pcrel10) {
1567 *((unsigned short *)(sectionp + q->address))
1568 = (~0x3ff & *((unsigned short *)(sectionp + q->address))
1569 | ((sym_addr >> 1) & 0x3ff));
1570 } else if ((*p)->howto->type == R_rimm16
1571 || (*p)->howto->type == R_huimm16
1572 || (*p)->howto->type == R_luimm16) {
1573 /* for l and h we set the lower 16 bits which is only when it will be used */
1574 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1575 } else if ((*p)->howto->type == R_pcrel5m2) {
1576 *((unsigned short *)(sectionp + q->address))
1577 = (0xfff0 & *((unsigned short *)(sectionp + q->address))
1578 | ((sym_addr >> 1) & 0xf));
1579 } else if ((*p)->howto->type == R_pcrel11){
1580 *((unsigned short *)(sectionp + q->address))
1581 = (0xfc00 & *((unsigned short *)(sectionp + q->address))
1582 | ((sym_addr >> 1) & 0x3ff));
1583 } else if (0xE0 <= (*p)->howto->type && 0xF3 >= (*p)->howto->type) {
1584 //arith relocs dont generate a real relocation
1586 printf("Blackfin relocation fail for reloc type: 0x%x\n", (*p)->howto->type);
1588 #elif defined(TARGET_e1)
1589 #define OPCODE_SIZE 2 /* Add 2 bytes, counting the opcode size*/
1590 switch ((*p)->howto->type) {
1592 case R_E1_CONST31_PCREL:
1593 case R_E1_DIS29W_PCREL:
1597 case R_E1_IMM32_PCREL:
1599 DBG_E1("In addr + 2:[0x%x] <- write [0x%x]\n",
1600 (sectionp + q->address + 2), sym_addr );
1601 *((unsigned long *) (sectionp + q->address + OPCODE_SIZE)) =
1605 DBG_E1("In addr : [0x%x] <- write [0x%x]\n",
1606 (sectionp + q->address), sym_addr );
1607 *((unsigned long *) (sectionp + q->address )) = htonl(sym_addr);
1610 printf("ERROR:Unhandled Relocation. Exiting...\n");
1614 #else /* ! TARGET_arm && ! TARGET_e1 */
1616 switch (q->howto->type) {
1621 /* Do nothing -- for cases we handle,
1622 the bits produced by the linker are
1623 what we want in the final flat file
1624 (and other cases are errors). Note
1625 that unlike most relocated values,
1626 it is stored in little-endian order,
1627 but this is necessary to avoid
1628 trashing the low-bit, and the float
1629 loaders knows about it. */
1631 #endif /* TARGET_V850 */
1634 case R_NIOS2_BFD_RELOC_32:
1635 case R_NIOS2_CALL26:
1636 case R_NIOS2_HIADJ16:
1640 #endif /* TARGET_nios2 */
1642 #if defined(TARGET_m68k)
1644 if (sym_addr < -0x8000 || sym_addr > 0x7fff) {
1645 fprintf (stderr, "Relocation overflow for R_68K_PC16 relocation against %s\n", sym_name);
1648 r_mem[0] = (sym_addr >> 8) & 0xff;
1649 r_mem[1] = sym_addr & 0xff;
1655 /* The alignment of the build host
1656 might be stricter than that of the
1657 target, so be careful. We store in
1658 network byte order. */
1659 r_mem[0] = (sym_addr >> 24) & 0xff;
1660 r_mem[1] = (sym_addr >> 16) & 0xff;
1661 r_mem[2] = (sym_addr >> 8) & 0xff;
1662 r_mem[3] = sym_addr & 0xff;
1664 #endif /* !TARGET_arm */
1669 if ((*p)->howto->type == R_rimm16
1670 || (*p)->howto->type == R_huimm16
1671 || (*p)->howto->type == R_luimm16)
1673 /* for l and h we set the lower 16 bits which is only when it will be used */
1674 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1675 } else if ((*p)->howto->type == R_byte4_data) {
1676 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1681 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
1682 "section=%s size=%d "
1683 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
1684 q->address, sym_name, addstr,
1685 section_name, sym_reloc_size,
1686 sym_addr, section_vma + q->address);
1689 * Create relocation entry (PC relative doesn't need this).
1691 if (relocation_needed) {
1693 flat_relocs = realloc(flat_relocs,
1694 (flat_reloc_count + 1) * sizeof(uint32_t));
1696 flat_relocs[flat_reloc_count] = pflags |
1697 (section_vma + q->address);
1700 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
1701 section_vma + q->address);
1703 switch ((*p)->howto->type) {
1705 case R_E1_CONST31_PCREL:
1706 case R_E1_DIS29W_PCREL:
1710 case R_E1_IMM32_PCREL:
1712 flat_relocs[flat_reloc_count] = pflags |
1713 (section_vma + q->address + OPCODE_SIZE);
1715 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1716 flat_relocs[flat_reloc_count] );
1719 flat_relocs[flat_reloc_count] = pflags |
1720 (section_vma + q->address);
1722 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1723 flat_relocs[flat_reloc_count] );
1729 relocation_needed = 0;
1734 printf("%s(%d): symbol name=%s address=0x%x section=%s -> RELOC=0x%x\n",
1735 __FILE__, __LINE__, sym_name, q->address, section_name,
1736 flat_relocs[flat_reloc_count]);
1743 printf("%d bad relocs\n", bad_relocs);
1750 *n_relocs = flat_reloc_count;
1756 static char * program;
1758 static void usage(void)
1760 fprintf(stderr, "Usage: %s [vrzd] [-p <abs-pic-file>] [-s stack-size] "
1761 "[-o <output-file>] <elf-file>\n\n"
1762 " -v : verbose operation\n"
1763 " -r : force load to RAM\n"
1764 " -k : enable kernel trace on load (for debug)\n"
1765 " -z : compress code/data/relocs\n"
1766 " -d : compress data/relocs\n"
1767 " -a : use existing symbol references\n"
1768 " instead of recalculating from\n"
1769 " relocation info\n"
1770 " -R reloc-file : read relocations from a separate file\n"
1771 " -p abs-pic-file : GOT/PIC processing with files\n"
1772 " -s stacksize : set application stack size\n"
1773 " -o output-file : output file name\n\n",
1775 fprintf(stderr, "Compiled for " ARCH " architecture\n\n");
1780 /* Write NUM zeroes to STREAM. */
1781 static void write_zeroes (unsigned long num, FILE *stream)
1785 /* It'd be nice if we could just use fseek, but that doesn't seem to
1786 work for stdio output files. */
1787 memset(zeroes, 0x00, 1024);
1788 while (num > sizeof(zeroes)) {
1789 fwrite(zeroes, sizeof(zeroes), 1, stream);
1790 num -= sizeof(zeroes);
1793 fwrite(zeroes, num, 1, stream);
1798 int main(int argc, char *argv[])
1801 bfd *rel_bfd, *abs_bfd;
1803 char *ofile=NULL, *pfile=NULL, *abs_file = NULL, *rel_file = NULL;
1811 asymbol **symbol_table;
1812 long number_of_symbols;
1814 unsigned long data_len = 0;
1815 unsigned long bss_len = 0;
1816 unsigned long text_len = 0;
1817 unsigned long reloc_len;
1819 unsigned long data_vma = ~0;
1820 unsigned long bss_vma = ~0;
1821 unsigned long text_vma = ~0;
1823 unsigned long text_offs;
1829 struct flat_hdr hdr;
1839 if (sizeof(hdr) != 64) {
1841 "Potential flat header incompatibility detected\n"
1842 "header size should be 64 but is %d\n",
1849 #else /* We need plenty of stack for both of them (Aggregate and Register) */
1853 while ((opt = getopt(argc, argv, "avzdrkp:s:o:R:")) != -1) {
1880 if (sscanf(optarg, "%i", &stack) != 1) {
1881 fprintf(stderr, "%s invalid stack size %s\n", argv[0], optarg);
1889 fprintf(stderr, "%s Unknown option\n", argv[0]);
1896 * if neither the -r or -p options was given, default to
1897 * a RAM load as that is the only option that makes sense.
1899 if (!load_to_ram && !pfile)
1902 filename = fname = argv[argc-1];
1913 if (!(rel_bfd = bfd_openr(rel_file, 0))) {
1914 fprintf(stderr, "Can't open %s\n", rel_file);
1918 if (bfd_check_format (rel_bfd, bfd_object) == 0) {
1919 fprintf(stderr, "File is not an object file\n");
1923 if (abs_file == rel_file)
1924 abs_bfd = rel_bfd; /* one file does all */
1926 if (!(abs_bfd = bfd_openr(abs_file, 0))) {
1927 fprintf(stderr, "Can't open %s\n", abs_file);
1931 if (bfd_check_format (abs_bfd, bfd_object) == 0) {
1932 fprintf(stderr, "File is not an object file\n");
1937 if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC)) {
1938 fprintf (stderr, "%s: Input file contains no relocation info\n", rel_file);
1942 if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P)) {
1943 /* `Absolute' file is not absolute, so neither are address
1944 contained therein. */
1946 "%s: `-a' option specified with non-fully-resolved input file\n",
1947 bfd_get_filename (abs_bfd));
1951 symbol_table = get_symbols(abs_bfd, &number_of_symbols);
1953 /* Group output sections into text, data, and bss, and calc their sizes. */
1954 for (s = abs_bfd->sections; s != NULL; s = s->next) {
1955 unsigned long *vma, *len;
1956 bfd_size_type sec_size;
1959 if (s->flags & SEC_CODE) {
1962 } else if (s->flags & SEC_DATA) {
1965 } else if (s->flags & SEC_ALLOC) {
1971 sec_size = bfd_section_size(abs_bfd, s);
1972 sec_vma = bfd_section_vma(abs_bfd, s);
1974 if (sec_vma < *vma) {
1976 *len += sec_vma - *vma;
1980 } else if (sec_vma + sec_size > *vma + *len)
1981 *len = sec_vma + sec_size - *vma;
1984 if (text_len == 0) {
1985 fprintf (stderr, "%s: no .text section", abs_file);
1989 text = malloc(text_len);
1996 printf("TEXT -> vma=0x%x len=0x%x\n", text_vma, text_len);
1998 /* Read in all text sections. */
1999 for (s = abs_bfd->sections; s != NULL; s = s->next)
2000 if (s->flags & SEC_CODE)
2001 if (!bfd_get_section_contents(abs_bfd, s,
2002 text + (s->vma - text_vma), 0,
2003 bfd_section_size(abs_bfd, s)))
2005 fprintf(stderr, "read error section %s\n", s->name);
2009 if (data_len == 0) {
2010 fprintf (stderr, "%s: no .data section", abs_file);
2013 data = malloc(data_len);
2020 printf("DATA -> vma=0x%x len=0x%x\n", data_vma, data_len);
2022 if ((text_vma + text_len) != data_vma) {
2023 if ((text_vma + text_len) > data_vma) {
2024 printf("ERROR: text=0x%x overlaps data=0x%x ?\n", text_len, data_vma);
2028 printf("WARNING: data=0x%x does not directly follow text=0x%x\n",
2029 data_vma, text_len);
2030 text_len = data_vma - text_vma;
2033 /* Read in all data sections. */
2034 for (s = abs_bfd->sections; s != NULL; s = s->next)
2035 if (s->flags & SEC_DATA)
2036 if (!bfd_get_section_contents(abs_bfd, s,
2037 data + (s->vma - data_vma), 0,
2038 bfd_section_size(abs_bfd, s)))
2040 fprintf(stderr, "read error section %s\n", s->name);
2044 /* Put common symbols in bss. */
2045 bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len);
2048 printf("BSS -> vma=0x%x len=0x%x\n", bss_vma, bss_len);
2050 if ((data_vma + data_len) != bss_vma) {
2051 if ((data_vma + data_len) > bss_vma) {
2052 printf("ERROR: text=0x%x + data=0x%x overlaps bss=0x%x ?\n", text_len,
2057 printf("WARNING: bss=0x%x does not directly follow text=0x%x + data=0x%x(0x%x)\n",
2058 bss_vma, text_len, data_len, text_len + data_len);
2059 data_len = bss_vma - data_vma;
2062 reloc = output_relocs(abs_bfd, symbol_table, number_of_symbols, &reloc_len,
2063 text, text_len, text_vma, data, data_len, data_vma,
2067 printf("No relocations in code!\n");
2069 text_offs = real_address_bits(text_vma);
2071 /* Fill in the binflt_flat header */
2072 memcpy(hdr.magic,"bFLT",4);
2073 hdr.rev = htonl(FLAT_VERSION);
2074 hdr.entry = htonl(sizeof(hdr) + bfd_get_start_address(abs_bfd));
2075 hdr.data_start = htonl(sizeof(hdr) + text_offs + text_len);
2076 hdr.data_end = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2077 hdr.bss_end = htonl(sizeof(hdr) + text_offs + text_len +data_len+bss_len);
2078 hdr.stack_size = htonl(stack); /* FIXME */
2079 hdr.reloc_start = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2080 hdr.reloc_count = htonl(reloc_len);
2082 | (load_to_ram ? FLAT_FLAG_RAM : 0)
2083 | (ktrace ? FLAT_FLAG_KTRACE : 0)
2084 | (pic_with_got ? FLAT_FLAG_GOTPIC : 0)
2085 | (compress ? (compress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
2087 hdr.build_date = htonl((unsigned long)time(NULL));
2088 memset(hdr.filler, 0x00, sizeof(hdr.filler));
2090 for (i=0; i<reloc_len; i++) reloc[i] = htonl(reloc[i]);
2093 printf("SIZE: .text=0x%04x, .data=0x%04x, .bss=0x%04x",
2094 text_len, data_len, bss_len);
2096 printf(", relocs=0x%04x", reloc_len);
2101 ofile = malloc(strlen(fname) + 5 + 1); /* 5 to add suffix */
2102 if (ofile == NULL) {
2106 strcpy(ofile, fname);
2107 strcat(ofile, ".bflt");
2110 if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0) {
2111 fprintf (stderr, "Can't open output file %s\n", ofile);
2115 write(fd, &hdr, sizeof(hdr));
2119 * get the compression command ready
2121 sprintf(cmd, "gzip -f -9 >> %s", ofile);
2123 #define START_COMPRESSOR do { \
2129 if (!(gf = popen(cmd, "w" BINARY_FILE_OPTS))) { \
2130 fprintf(stderr, "Can't run cmd %s\n", cmd); \
2136 gf = fopen(ofile, "ab"); /* Add 'b' to support non-posix (ie windows) */
2138 fprintf(stderr, "Can't open file %s for writing\n", ofile); \
2145 /* Fill in any hole at the beginning of the text segment. */
2147 printf("ZERO before text len=0x%x\n", text_offs);
2148 write_zeroes(text_offs, gf);
2150 /* Write the text segment. */
2151 fwrite(text, text_len, 1, gf);
2156 /* Write the data segment. */
2157 fwrite(data, data_len, 1, gf);
2160 fwrite(reloc, reloc_len * 4, 1, gf);
2172 * this __MUST__ be at the VERY end of the file - do NOT move!!
2178 * vi: tabstop=8 shiftwidth=4 textwidth=79 noexpandtab