bump version
[buildroot.git] / toolchain / elf2flt / elf2flt / elf2flt.c
blob546305f6b95835a5eade341aca1883800c9ed5d6
1 /*
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
7 * text and data.
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 */
43 #include <strings.h>
44 #include <unistd.h> /* Userland prototypes of the Unix std system calls */
45 #include <fcntl.h> /* Flag value for file handling functions */
46 #include <time.h>
47 #ifndef WIN32
48 #include <netinet/in.h> /* Consts and structs defined by the internet system */
49 #define BINARY_FILE_OPTS
50 #else
51 #include <winsock2.h>
52 #define BINARY_FILE_OPTS "b"
53 #endif
55 /* from $(INSTALLDIR)/include */
56 #include <bfd.h> /* Main header file for the BFD library */
57 #include <libiberty.h>
59 #if defined(TARGET_h8300)
60 #include <elf/h8.h> /* TARGET_* ELF support for the BFD library */
61 #elif defined(__CYGWIN__) || defined(__MINGW32__) || defined(TARGET_nios) || defined(TARGET_nios2)
62 #include "cygwin-elf.h" /* Cygwin uses a local copy */
63 #elif defined(TARGET_microblaze)
64 #include <elf/microblaze.h> /* TARGET_* ELF support for the BFD library */
65 #elif defined(TARGET_bfin)
66 #include "elf/bfin.h"
67 #else
68 #include <elf.h> /* TARGET_* ELF support for the BFD library */
69 #endif
71 #if defined(__MINGW32__)
72 #include <getopt.h>
73 #endif
75 /* from uClinux-x.x.x/include/linux */
76 #include "flat.h" /* Binary flat header description */
77 #include "compress.h"
79 #ifdef TARGET_e1
80 #include <e1.h>
81 #endif
83 #ifdef TARGET_v850e
84 #define TARGET_v850
85 #endif
87 #if defined(TARGET_m68k)
88 #define ARCH "m68k/coldfire"
89 #elif defined(TARGET_arm)
90 #define ARCH "arm"
91 #elif defined(TARGET_sparc)
92 #define ARCH "sparc"
93 #elif defined(TARGET_v850)
94 #define ARCH "v850"
95 #elif defined(TARGET_sh)
96 #define ARCH "sh"
97 #elif defined(TARGET_h8300)
98 #define ARCH "h8300"
99 #elif defined(TARGET_microblaze)
100 #define ARCH "microblaze"
101 #elif defined(TARGET_e1)
102 #define ARCH "e1-coff"
103 #elif defined(TARGET_bfin)
104 #define ARCH "bfin"
105 #define FLAT_RELOC_TYPE_TEXT 0
106 #define FLAT_RELOC_TYPE_DATA 1
107 #define FLAT_RELOC_TYPE_BSS 2
108 #define FLAT_RELOC_TYPE_STACK 3
109 #define FLAT_RELOC_PART_LO 0
110 #define FLAT_RELOC_PART_HI 1
111 #define PCREL24_MAGIC_OFFSET -1
112 #elif defined(TARGET_nios)
113 #define ARCH "nios"
114 #elif defined(TARGET_nios2)
115 #define ARCH "nios2"
116 #else
117 #error "Don't know how to support your CPU architecture??"
118 #endif
120 #if defined(TARGET_m68k) || defined(TARGET_h8300) || defined(TARGET_bfin)
122 * Define a maximum number of bytes allowed in the offset table.
123 * We'll fail if the table is larger than this.
125 * This limit may be different for platforms other than m68k, but
126 * 8000 entries is a lot, trust me :-) (davidm)
128 #define GOT_LIMIT 32767
130 * we have to mask out the shared library id here and there, this gives
131 * us the real address bits when needed
133 #define real_address_bits(x) (pic_with_got ? ((x) & 0xffffff) : (x))
134 #else
135 #define real_address_bits(x) (x)
136 #endif
138 #ifndef O_BINARY
139 #define O_BINARY 0
140 #endif
143 int verbose = 0; /* extra output when running */
144 int pic_with_got = 0; /* do elf/got processing with PIC code */
145 int load_to_ram = 0; /* instruct loader to allocate everything into RAM */
146 int ktrace = 0; /* instruct loader output kernel trace on load */
147 int docompress = 0; /* 1 = compress everything, 2 = compress data only */
148 int use_resolved = 0; /* If true, get the value of symbol references from */
149 /* the program contents, not from the relocation table. */
150 /* In this case, the input ELF file must be already */
151 /* fully resolved (using the `-q' flag with recent */
152 /* versions of GNU ld will give you a fully resolved */
153 /* output file with relocation entries). */
155 const char *progname, *filename;
156 int lineno;
158 int nerrors = 0;
159 int nwarnings = 0;
161 static char where[200];
163 enum {
164 /* Use exactly one of these: */
165 E_NOFILE = 0, /* "progname: " */
166 E_FILE = 1, /* "filename: " */
167 E_FILELINE = 2, /* "filename:lineno: " */
168 E_FILEWHERE = 3, /* "filename:%s: " -- set %s with ewhere() */
170 /* Add in any of these with |': */
171 E_WARNING = 0x10,
172 E_PERROR = 0x20
175 void ewhere (const char *format, ...);
176 void einfo (int type, const char *format, ...);
179 void
180 ewhere (const char *format, ...) {
181 va_list args;
182 va_start (args, format);
183 vsprintf (where, format, args);
184 va_end (args);
188 void
189 einfo (int type, const char *format, ...) {
190 va_list args;
192 switch (type & 0x0f) {
193 case E_NOFILE:
194 fprintf (stderr, "%s: ", progname);
195 break;
196 case E_FILE:
197 fprintf (stderr, "%s: ", filename);
198 break;
199 case E_FILELINE:
200 ewhere ("%d", lineno);
201 /* fall-through */
202 case E_FILEWHERE:
203 fprintf (stderr, "%s:%s: ", filename, where);
204 break;
207 if (type & E_WARNING) {
208 fprintf (stderr, "warning: ");
209 nwarnings++;
210 } else {
211 nerrors++;
214 va_start (args, format);
215 vfprintf (stderr, format, args);
216 va_end (args);
218 if (type & E_PERROR)
219 perror ("");
220 else
221 fprintf (stderr, "\n");
225 asymbol**
226 get_symbols (bfd *abfd, long *num)
228 long storage_needed;
229 asymbol **symbol_table;
230 long number_of_symbols;
232 storage_needed = bfd_get_symtab_upper_bound (abfd);
234 if (storage_needed < 0)
235 abort ();
237 if (storage_needed == 0)
238 return NULL;
240 symbol_table = xmalloc (storage_needed);
242 number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
244 if (number_of_symbols < 0)
245 abort ();
247 *num = number_of_symbols;
248 return symbol_table;
254 dump_symbols(asymbol **symbol_table, long number_of_symbols)
256 long i;
257 printf("SYMBOL TABLE:\n");
258 for (i=0; i<number_of_symbols; i++) {
259 printf(" NAME=%s VALUE=0x%x\n", symbol_table[i]->name,
260 symbol_table[i]->value);
262 printf("\n");
263 return(0);
268 long
269 get_symbol_offset(char *name, asection *sec, asymbol **symbol_table, long number_of_symbols)
271 long i;
272 for (i=0; i<number_of_symbols; i++) {
273 if (symbol_table[i]->section == sec) {
274 if (!strcmp(symbol_table[i]->name, name)) {
275 return symbol_table[i]->value;
279 return -1;
284 long
285 get_gp_value(asymbol **symbol_table, long number_of_symbols)
287 long i;
288 for (i=0; i<number_of_symbols; i++) {
289 if (!strcmp(symbol_table[i]->name, "_gp"))
290 return symbol_table[i]->value;
292 return -1;
297 long
298 add_com_to_bss(asymbol **symbol_table, long number_of_symbols, long bss_len)
300 long i, comsize;
301 long offset;
303 comsize = 0;
304 for (i=0; i<number_of_symbols; i++) {
305 if (strcmp("*COM*", symbol_table[i]->section->name) == 0) {
306 offset = bss_len + comsize;
307 comsize += symbol_table[i]->value;
308 symbol_table[i]->value = offset;
311 return comsize;
314 #ifdef TARGET_bfin
315 /* FUNCTION : weak_und_symbol
316 ABSTRACT : return true if symbol is weak and undefined.
318 static int
319 weak_und_symbol(const char *reloc_section_name,
320 struct bfd_symbol *symbol)
322 if (!(strstr (reloc_section_name, "text")
323 || strstr (reloc_section_name, "data")
324 || strstr (reloc_section_name, "bss"))) {
325 if (symbol->flags & BSF_WEAK) {
326 #ifdef DEBUG_BFIN
327 fprintf(stderr, "found weak undefined symbol %s\n", symbol->name);
328 #endif
329 return TRUE;
332 return FALSE;
335 static int
336 bfin_set_reloc (uint32_t *reloc,
337 const char *reloc_section_name,
338 const char *sym_name,
339 struct bfd_symbol *symbol,
340 int sp, int hilo, int32_t offset)
342 unsigned int type;
343 uint32_t val;
345 if (strstr (reloc_section_name, "text"))
346 type = FLAT_RELOC_TYPE_TEXT;
347 else if (strstr (reloc_section_name, "data"))
348 type = FLAT_RELOC_TYPE_DATA;
349 else if (strstr (reloc_section_name, "bss"))
350 type = FLAT_RELOC_TYPE_BSS;
351 else if (strstr (reloc_section_name, "stack"))
352 type = FLAT_RELOC_TYPE_STACK;
353 else if (symbol->flags & BSF_WEAK){
354 /* weak symbol support ... if a weak symbol is undefined at the
355 end of a final link, it should return 0 rather than error
356 We will assume text section for the moment.
358 type = FLAT_RELOC_TYPE_TEXT;
359 } else if (strstr (reloc_section_name, "*ABS*")){
360 /* (A data section initialization of something in the shared libc's text section
361 does not resolve - i.e. a global pointer to function initialized with
362 a libc function).
363 The text section here is appropriate as the section information
364 of the shared library is lost. The loader will do some calcs.
366 type = FLAT_RELOC_TYPE_TEXT;
367 } else {
368 printf ("Unknown Type - relocation for %s in bad section - %s\n", sym_name, reloc_section_name);
369 return 1;
372 val = (offset & ((1 << 26) - 1)) << 6;
373 val |= (sp & (1 << 3) - 1) << 3;
374 val |= (hilo & 1) << 2;
375 val |= (type & (1 << 2) - 1);
376 *reloc = val;
377 return 0;
379 #endif
382 uint32_t *
383 output_relocs (
384 bfd *abs_bfd,
385 asymbol **symbols,
386 int number_of_symbols,
387 unsigned long *n_relocs,
388 unsigned char *text, int text_len, unsigned long text_vma,
389 unsigned char *data, int data_len, unsigned long data_vma,
390 bfd *rel_bfd)
392 uint32_t *flat_relocs;
393 asection *a, *sym_section, *r;
394 arelent **relpp, **p, *q;
395 const char *sym_name, *section_name;
396 unsigned char *sectionp;
397 unsigned long pflags;
398 char addstr[16];
399 long sym_addr, sym_vma, section_vma;
400 int relsize, relcount;
401 int flat_reloc_count;
402 int sym_reloc_size, rc;
403 int got_size = 0;
404 int bad_relocs = 0;
405 asymbol **symb;
406 long nsymb;
408 #if 0
409 printf("%s(%d): output_relocs(abs_bfd=%d,synbols=0x%x,number_of_symbols=%d"
410 "n_relocs=0x%x,text=0x%x,text_len=%d,data=0x%x,data_len=%d)\n",
411 __FILE__, __LINE__, abs_bfd, symbols, number_of_symbols, n_relocs,
412 text, text_len, data, data_len);
413 #endif
415 #if 0
416 dump_symbols(symbols, number_of_symbols);
417 #endif
419 *n_relocs = 0;
420 flat_relocs = NULL;
421 flat_reloc_count = 0;
422 rc = 0;
423 pflags = 0;
425 /* Determine how big our offset table is in bytes.
426 * This isn't too difficult as we've terminated the table with -1.
427 * Also note that both the relocatable and absolute versions have this
428 * terminator even though the relocatable one doesn't have the GOT!
430 if (pic_with_got && !use_resolved) {
431 unsigned long *lp = (unsigned long *)data;
432 /* Should call ntohl(*lp) here but is isn't going to matter */
433 while (*lp != 0xffffffff) lp++;
434 got_size = ((unsigned char *)lp) - data;
435 if (verbose)
436 printf("GOT table contains %d entries (%d bytes)\n",
437 got_size/sizeof(unsigned long), got_size);
438 #ifdef TARGET_m68k
439 if (got_size > GOT_LIMIT) {
440 fprintf(stderr, "GOT too large: %d bytes (limit = %d bytes)\n",
441 got_size, GOT_LIMIT);
442 exit(1);
444 #endif
447 for (a = abs_bfd->sections; (a != (asection *) NULL); a = a->next) {
448 section_vma = bfd_section_vma(abs_bfd, a);
450 if (verbose)
451 printf("SECTION: %s [0x%x]: flags=0x%x vma=0x%x\n", a->name, a,
452 a->flags, section_vma);
454 // if (bfd_is_abs_section(a))
455 // continue;
456 if (bfd_is_und_section(a))
457 continue;
458 if (bfd_is_com_section(a))
459 continue;
460 // if ((a->flags & SEC_RELOC) == 0)
461 // continue;
464 * Only relocate things in the data sections if we are PIC/GOT.
465 * otherwise do text as well
467 if (!pic_with_got && (a->flags & SEC_CODE))
468 sectionp = text + (a->vma - text_vma);
469 else if (a->flags & SEC_DATA)
470 sectionp = data + (a->vma - data_vma);
471 else
472 continue;
474 /* Now search for the equivalent section in the relocation binary
475 * and use that relocation information to build reloc entries
476 * for this one.
478 for (r=rel_bfd->sections; r != NULL; r=r->next)
479 if (strcmp(a->name, r->name) == 0)
480 break;
481 if (r == NULL)
482 continue;
483 if (verbose)
484 printf(" RELOCS: %s [0x%x]: flags=0x%x vma=0x%x\n", r->name, r,
485 r->flags, bfd_section_vma(abs_bfd, r));
486 if ((r->flags & SEC_RELOC) == 0)
487 continue;
488 relsize = bfd_get_reloc_upper_bound(rel_bfd, r);
489 if (relsize <= 0) {
490 if (verbose)
491 printf("%s(%d): no relocation entries section=0x%x\n",
492 __FILE__, __LINE__, r->name);
493 continue;
496 symb = get_symbols(rel_bfd, &nsymb);
497 relpp = xmalloc(relsize);
499 relcount = bfd_canonicalize_reloc(rel_bfd, r, relpp, symb);
500 if (relcount <= 0) {
501 if (verbose)
502 printf("%s(%d): no relocation entries section=%s\n",
503 __FILE__, __LINE__, r->name);
504 continue;
505 } else {
506 for (p = relpp; (relcount && (*p != NULL)); p++, relcount--) {
507 unsigned char *r_mem;
508 int relocation_needed = 0;
510 #ifdef TARGET_microblaze
511 /* The MICROBLAZE_XX_NONE relocs can be skipped.
512 They represent PC relative branches that the
513 linker has already resolved */
515 switch ((*p)->howto->type)
517 case R_MICROBLAZE_NONE:
518 case R_MICROBLAZE_64_NONE:
519 continue;
521 #endif /* TARGET_microblaze */
523 #ifdef TARGET_v850
524 /* Skip this relocation entirely if possible (we
525 do this early, before doing any other
526 processing on it). */
527 switch ((*p)->howto->type) {
528 #ifdef R_V850_9_PCREL
529 case R_V850_9_PCREL:
530 #endif
531 #ifdef R_V850_22_PCREL
532 case R_V850_22_PCREL:
533 #endif
534 #ifdef R_V850_SDA_16_16_OFFSET
535 case R_V850_SDA_16_16_OFFSET:
536 #endif
537 #ifdef R_V850_SDA_15_16_OFFSET
538 case R_V850_SDA_15_16_OFFSET:
539 #endif
540 #ifdef R_V850_ZDA_15_16_OFFSET
541 case R_V850_ZDA_15_16_OFFSET:
542 #endif
543 #ifdef R_V850_TDA_6_8_OFFSET
544 case R_V850_TDA_6_8_OFFSET:
545 #endif
546 #ifdef R_V850_TDA_7_8_OFFSET
547 case R_V850_TDA_7_8_OFFSET:
548 #endif
549 #ifdef R_V850_TDA_7_7_OFFSET
550 case R_V850_TDA_7_7_OFFSET:
551 #endif
552 #ifdef R_V850_TDA_16_16_OFFSET
553 case R_V850_TDA_16_16_OFFSET:
554 #endif
555 #ifdef R_V850_TDA_4_5_OFFSET
556 case R_V850_TDA_4_5_OFFSET:
557 #endif
558 #ifdef R_V850_TDA_4_4_OFFSET
559 case R_V850_TDA_4_4_OFFSET:
560 #endif
561 #ifdef R_V850_SDA_16_16_SPLIT_OFFSET
562 case R_V850_SDA_16_16_SPLIT_OFFSET:
563 #endif
564 #ifdef R_V850_CALLT_6_7_OFFSET
565 case R_V850_CALLT_6_7_OFFSET:
566 #endif
567 #ifdef R_V850_CALLT_16_16_OFFSET
568 case R_V850_CALLT_16_16_OFFSET:
569 #endif
570 /* These are relative relocations, which
571 have already been fixed up by the
572 linker at this point, so just ignore
573 them. */
574 continue;
576 #endif /* USE_V850_RELOCS */
578 q = *p;
579 if (q->sym_ptr_ptr && *q->sym_ptr_ptr) {
580 sym_name = (*(q->sym_ptr_ptr))->name;
581 sym_section = (*(q->sym_ptr_ptr))->section;
582 section_name=(*(q->sym_ptr_ptr))->section->name;
583 } else {
584 printf("ERROR: undefined relocation entry\n");
585 rc = -1;
586 continue;
588 #ifndef TARGET_bfin
589 /* Adjust the address to account for the GOT table which wasn't
590 * present in the relative file link.
592 if (pic_with_got && !use_resolved)
593 q->address += got_size;
594 #endif
596 /* A pointer to what's being relocated, used often
597 below. */
598 r_mem = sectionp + q->address;
601 * Fixup offset in the actual section.
603 addstr[0] = 0;
604 #ifndef TARGET_e1
605 if ((sym_addr = get_symbol_offset((char *) sym_name,
606 sym_section, symbols, number_of_symbols)) == -1) {
607 sym_addr = 0;
609 #else
610 sym_addr = (*(q->sym_ptr_ptr))->value;
611 #endif
612 if (use_resolved) {
613 /* Use the address of the symbol already in
614 the program text. How this is handled may
615 still depend on the particular relocation
616 though. */
617 switch (q->howto->type) {
618 int r2_type;
619 #ifdef TARGET_v850
620 case R_V850_HI16_S:
621 /* We specially handle adjacent
622 HI16_S/ZDA_15_16_OFFSET and
623 HI16_S/LO16 pairs that reference the
624 same address (these are usually
625 movhi/ld and movhi/movea pairs,
626 respectively). */
627 if (relcount == 0)
628 r2_type = R_V850_NONE;
629 else
630 r2_type = p[1]->howto->type;
631 if ((r2_type == R_V850_ZDA_15_16_OFFSET
632 || r2_type == R_V850_LO16)
633 && (p[0]->sym_ptr_ptr
634 == p[1]->sym_ptr_ptr)
635 && (p[0]->addend == p[1]->addend))
637 relocation_needed = 1;
639 switch (r2_type) {
640 case R_V850_ZDA_15_16_OFFSET:
641 pflags = 0x10000000;
642 break;
643 case R_V850_LO16:
644 pflags = 0x20000000;
645 break;
648 /* We don't really need the
649 actual value -- the bits
650 produced by the linker are
651 what we want in the final
652 flat file -- but get it
653 anyway if useful for
654 debugging. */
655 if (verbose) {
656 unsigned char *r2_mem =
657 sectionp
658 + p[1]->address;
659 /* little-endian */
660 int hi = r_mem[0]
661 + (r_mem[1] << 8);
662 int lo = r2_mem[0]
663 + (r2_mem[1] << 8);
664 /* Sign extend LO. */
665 lo = (lo ^ 0x8000)
666 - 0x8000;
668 /* Maybe ignore the LSB
669 of LO, which is
670 actually part of the
671 instruction. */
672 if (r2_type != R_V850_LO16)
673 lo &= ~1;
675 sym_addr =
676 (hi << 16)
677 + lo;
679 } else
680 goto bad_resolved_reloc;
681 break;
683 case R_V850_LO16:
684 /* See if this is actually the
685 2nd half of a pair. */
686 if (p > relpp
687 && (p[-1]->howto->type
688 == R_V850_HI16_S)
689 && (p[-1]->sym_ptr_ptr
690 == p[0]->sym_ptr_ptr)
691 && (p[-1]->addend == p[0]->addend))
692 break; /* not an error */
693 else
694 goto bad_resolved_reloc;
696 case R_V850_HI16:
697 goto bad_resolved_reloc;
698 default:
699 goto good_32bit_resolved_reloc;
700 #elif defined(TARGET_arm)
701 case R_ARM_ABS32:
702 relocation_needed = 1;
703 break;
704 case R_ARM_REL32:
705 case R_ARM_THM_PC11:
706 case R_ARM_THM_PC22:
707 relocation_needed = 0;
708 break;
709 default:
710 goto bad_resolved_reloc;
711 #elif defined(TARGET_m68k)
712 case R_68K_32:
713 goto good_32bit_resolved_reloc;
714 case R_68K_PC32:
715 case R_68K_PC16:
716 /* The linker has already resolved
717 PC relocs for us. In PIC links,
718 the symbol must be in the data
719 segment. */
720 case R_68K_NONE:
721 continue;
722 default:
723 goto bad_resolved_reloc;
724 #else
725 default:
726 /* The default is to assume that the
727 relocation is relative and has
728 already been fixed up by the
729 linker (perhaps we ought to make
730 give an error by default, and
731 require `safe' relocations to be
732 enumberated explicitly?). */
733 goto good_32bit_resolved_reloc;
734 #endif
735 good_32bit_resolved_reloc:
736 if (bfd_big_endian (abs_bfd))
737 sym_addr =
738 (r_mem[0] << 24)
739 + (r_mem[1] << 16)
740 + (r_mem[2] << 8)
741 + r_mem[3];
742 else
743 sym_addr =
744 r_mem[0]
745 + (r_mem[1] << 8)
746 + (r_mem[2] << 16)
747 + (r_mem[3] << 24);
748 relocation_needed = 1;
749 break;
751 bad_resolved_reloc:
752 printf("ERROR: reloc type %s unsupported in this context\n",
753 q->howto->name);
754 bad_relocs++;
755 break;
757 } else {
758 /* Calculate the sym address ourselves. */
759 sym_reloc_size = bfd_get_reloc_size(q->howto);
761 #if !defined(TARGET_h8300) && !defined(TARGET_e1) && !defined(TARGET_bfin) && !defined(TARGET_m68k)
762 if (sym_reloc_size != 4) {
763 printf("ERROR: bad reloc type %d size=%d for symbol=%s\n",
764 (*p)->howto->type, sym_reloc_size, sym_name);
765 bad_relocs++;
766 rc = -1;
767 continue;
769 #endif
771 switch ((*p)->howto->type) {
773 #if defined(TARGET_m68k)
774 case R_68K_32:
775 relocation_needed = 1;
776 sym_vma = bfd_section_vma(abs_bfd, sym_section);
777 sym_addr += sym_vma + q->addend;
778 break;
779 case R_68K_PC16:
780 case R_68K_PC32:
781 sym_vma = 0;
782 sym_addr += sym_vma + q->addend;
783 sym_addr -= q->address;
784 break;
785 #endif
787 #if defined(TARGET_arm)
788 case R_ARM_ABS32:
789 relocation_needed = 1;
790 if (verbose)
791 fprintf(stderr,
792 "%s vma=0x%x, value=0x%x, address=0x%x "
793 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
794 "ABS32",
795 sym_vma, (*(q->sym_ptr_ptr))->value,
796 q->address, sym_addr,
797 (*p)->howto->rightshift,
798 *(unsigned long *)r_mem);
799 sym_vma = bfd_section_vma(abs_bfd, sym_section);
800 sym_addr += sym_vma + q->addend;
801 break;
802 case R_ARM_GOT32:
803 case R_ARM_GOTPC:
804 /* Should be fine as is */
805 break;
806 case R_ARM_PLT32:
807 if (verbose)
808 fprintf(stderr,
809 "%s vma=0x%x, value=0x%x, address=0x%x "
810 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
811 "PLT32",
812 sym_vma, (*(q->sym_ptr_ptr))->value,
813 q->address, sym_addr,
814 (*p)->howto->rightshift,
815 *(unsigned long *)r_mem);
816 case R_ARM_PC24:
817 sym_vma = 0;
818 sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift;
819 break;
820 #endif
822 #ifdef TARGET_v850
823 case R_V850_32:
824 relocation_needed = 1;
825 sym_vma = bfd_section_vma(abs_bfd, sym_section);
826 sym_addr += sym_vma + q->addend;
827 break;
828 #if defined(R_V850_ZDA_16_16_OFFSET) || defined(R_V850_ZDA_16_16_SPLIT_OFFSET)
829 #ifdef R_V850_ZDA_16_16_OFFSET
830 case R_V850_ZDA_16_16_OFFSET:
831 #endif
832 #ifdef R_V850_ZDA_16_16_SPLIT_OFFSET
833 case R_V850_ZDA_16_16_SPLIT_OFFSET:
834 #endif
835 /* Can't support zero-relocations. */
836 printf ("ERROR: %s+0x%x: zero relocations not supported\n",
837 sym_name, q->addend);
838 continue;
839 #endif /* R_V850_ZDA_16_16_OFFSET || R_V850_ZDA_16_16_SPLIT_OFFSET */
840 #endif /* TARGET_v850 */
842 #ifdef TARGET_h8300
843 case R_H8_DIR24R8:
844 if (sym_reloc_size != 4) {
845 printf("R_H8_DIR24R8 size %d\n", sym_reloc_size);
846 bad_relocs++;
847 continue;
849 relocation_needed = 1;
850 sym_addr = (*(q->sym_ptr_ptr))->value;
851 q->address -= 1;
852 r_mem -= 1; /* tracks q->address */
853 sym_vma = bfd_section_vma(abs_bfd, sym_section);
854 sym_addr += sym_vma + q->addend;
855 sym_addr |= (*(unsigned char *)r_mem<<24);
856 break;
857 case R_H8_DIR24A8:
858 if (sym_reloc_size != 4) {
859 printf("R_H8_DIR24A8 size %d\n", sym_reloc_size);
860 bad_relocs++;
861 continue;
863 /* Absolute symbol done not relocation */
864 relocation_needed = !bfd_is_abs_section(sym_section);
865 sym_addr = (*(q->sym_ptr_ptr))->value;
866 sym_vma = bfd_section_vma(abs_bfd, sym_section);
867 sym_addr += sym_vma + q->addend;
868 break;
869 case R_H8_DIR32:
870 case R_H8_DIR32A16: /* currently 32, could be made 16 */
871 if (sym_reloc_size != 4) {
872 printf("R_H8_DIR32 size %d\n", sym_reloc_size);
873 bad_relocs++;
874 continue;
876 relocation_needed = 1;
877 sym_addr = (*(q->sym_ptr_ptr))->value;
878 sym_vma = bfd_section_vma(abs_bfd, sym_section);
879 sym_addr += sym_vma + q->addend;
880 break;
881 case R_H8_PCREL16:
882 sym_vma = 0;
883 sym_addr = (*(q->sym_ptr_ptr))->value;
884 sym_addr += sym_vma + q->addend;
885 sym_addr -= (q->address + 2);
886 if (bfd_big_endian(abs_bfd))
887 *(unsigned short *)r_mem =
888 bfd_big_endian(abs_bfd) ? htons(sym_addr) : sym_addr;
889 continue;
890 case R_H8_PCREL8:
891 sym_vma = 0;
892 sym_addr = (*(q->sym_ptr_ptr))->value;
893 sym_addr += sym_vma + q->addend;
894 sym_addr -= (q->address + 1);
895 *(unsigned char *)r_mem = sym_addr;
896 continue;
897 #endif
899 #ifdef TARGET_microblaze
900 case R_MICROBLAZE_64:
901 /* The symbol is split over two consecutive instructions.
902 Flag this to the flat loader by setting the high bit of
903 the relocation symbol. */
905 unsigned char *p = r_mem;
906 unsigned long offset;
907 pflags=0x80000000;
909 /* work out the relocation */
910 sym_vma = bfd_section_vma(abs_bfd, sym_section);
911 /* grab any offset from the text */
912 offset = (p[2]<<24) + (p[3] << 16) + (p[6] << 8) + (p[7]);
913 /* Update the address */
914 sym_addr += offset + sym_vma + q->addend;
915 /* Write relocated pointer back */
916 p[2] = (sym_addr >> 24) & 0xff;
917 p[3] = (sym_addr >> 16) & 0xff;
918 p[6] = (sym_addr >> 8) & 0xff;
919 p[7] = sym_addr & 0xff;
921 /* create a new reloc entry */
922 flat_relocs = realloc(flat_relocs,
923 (flat_reloc_count + 1) * sizeof(uint32_t));
924 flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address);
925 flat_reloc_count++;
926 relocation_needed = 0;
927 pflags = 0;
928 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
929 bfd_section_vma(abs_bfd, sym_section));
930 if (verbose)
931 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
932 "section=%s size=%d "
933 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
934 q->address, sym_name, addstr,
935 section_name, sym_reloc_size,
936 sym_addr, section_vma + q->address);
937 if (verbose)
938 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
939 section_vma + q->address);
941 continue;
943 case R_MICROBLAZE_32:
945 unsigned char *p = r_mem;
946 unsigned long offset;
948 /* grab any offset from the text */
949 offset = (p[0]<<24) + (p[1] << 16) + (p[2] << 8) + (p[3]);
950 sym_vma = bfd_section_vma(abs_bfd, sym_section);
951 /* This is a horrible kludge. For some
952 reason, *sometimes* the offset is in
953 both addend and the code. Detect
954 it, and cancel the effect. Otherwise
955 the offset gets added twice - ouch.
956 There should be a better test
957 for this condition, based on the
958 BFD data structures */
959 if(offset==q->addend)
960 offset=0;
962 sym_addr += offset + sym_vma + q->addend;
963 relocation_needed = 1;
964 break;
966 case R_MICROBLAZE_64_PCREL:
967 sym_vma = 0;
968 //sym_addr = (*(q->sym_ptr_ptr))->value;
969 sym_addr += sym_vma + q->addend;
970 sym_addr -= (q->address + 4);
971 sym_addr = htonl(sym_addr);
972 /* insert 16 MSB */
973 * ((unsigned short *) (r_mem+2)) |= (sym_addr) & 0xFFFF;
974 /* then 16 LSB */
975 * ((unsigned short *) (r_mem+6)) |= (sym_addr >> 16) & 0xFFFF;
976 /* We've done all the work, so continue
977 to next reloc instead of break */
978 continue;
980 #endif /* TARGET_microblaze */
982 #ifdef TARGET_nios2
983 #define htoniosl(x) (x)
984 #define niostohl(x) (x)
985 case R_NIOS2_BFD_RELOC_32:
986 relocation_needed = 1;
987 pflags = (FLAT_NIOS2_R_32 << 28);
988 sym_vma = bfd_section_vma(abs_bfd, sym_section);
989 sym_addr += sym_vma + q->addend;
990 /* modify target, in target order */
991 *(unsigned long *)r_mem = htoniosl(sym_addr);
992 break;
993 case R_NIOS2_CALL26:
995 unsigned long exist_val;
996 relocation_needed = 1;
997 pflags = (FLAT_NIOS2_R_CALL26 << 28);
998 sym_vma = bfd_section_vma(abs_bfd, sym_section);
999 sym_addr += sym_vma + q->addend;
1001 /* modify target, in target order */
1002 // exist_val = niostohl(*(unsigned long *)r_mem);
1003 exist_val = ((sym_addr >> 2) << 6);
1004 *(unsigned long *)r_mem = htoniosl(exist_val);
1005 break;
1007 case R_NIOS2_HIADJ16:
1008 case R_NIOS2_HI16:
1010 unsigned long exist_val;
1011 int r2_type;
1012 /* handle the adjacent HI/LO pairs */
1013 if (relcount == 0)
1014 r2_type = R_NIOS2_NONE;
1015 else
1016 r2_type = p[1]->howto->type;
1017 if ((r2_type == R_NIOS2_LO16)
1018 && (p[0]->sym_ptr_ptr == p[1]->sym_ptr_ptr)
1019 && (p[0]->addend == p[1]->addend))
1021 unsigned char * r2_mem = sectionp + p[1]->address;
1022 if (p[1]->address - q->address!=4)
1023 printf("Err: HI/LO not adjacent %d\n", p[1]->address - q->address);
1024 relocation_needed = 1;
1025 pflags = (q->howto->type == R_NIOS2_HIADJ16)
1026 ? FLAT_NIOS2_R_HIADJ_LO : FLAT_NIOS2_R_HI_LO;
1027 pflags <<= 28;
1029 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1030 sym_addr += sym_vma + q->addend;
1032 /* modify high 16 bits, in target order */
1033 exist_val = niostohl(*(unsigned long *)r_mem);
1034 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1035 if (q->howto->type == R_NIOS2_HIADJ16)
1036 exist_val |= ((((sym_addr >> 16) + ((sym_addr >> 15) & 1)) & 0xFFFF) << 6);
1037 else
1038 exist_val |= (((sym_addr >> 16) & 0xFFFF) << 6);
1039 *(unsigned long *)r_mem = htoniosl(exist_val);
1041 /* modify low 16 bits, in target order */
1042 exist_val = niostohl(*(unsigned long *)r2_mem);
1043 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1044 exist_val |= ((sym_addr & 0xFFFF) << 6);
1045 *(unsigned long *)r2_mem = htoniosl(exist_val);
1047 } else
1048 goto NIOS2_RELOC_ERR;
1050 break;
1052 case R_NIOS2_GPREL:
1054 unsigned long exist_val, temp;
1055 //long gp = get_symbol_offset("_gp", sym_section, symbols, number_of_symbols);
1056 long gp = get_gp_value(symbols, number_of_symbols);
1057 if (gp == -1) {
1058 printf("Err: unresolved symbol _gp when relocating %s\n", sym_name);
1059 goto NIOS2_RELOC_ERR;
1061 /* _gp holds a absolute value, otherwise the ld cannot generate correct code */
1062 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1063 //printf("sym=%x, %d, _gp=%x, %d\n", sym_addr+sym_vma, sym_addr+sym_vma, gp, gp);
1064 sym_addr += sym_vma + q->addend;
1065 sym_addr -= gp;
1066 //printf("sym - _gp=%x, %d\n", sym_addr, sym_addr);
1067 /* modify the target, in target order (little_endian) */
1068 exist_val = niostohl(*(unsigned long *)r_mem);
1069 temp = ((exist_val >> 6) & 0x3ff0000) | (sym_addr & 0xffff);
1070 temp <<= 6;
1071 temp |= (exist_val & 0x3f);
1072 *(unsigned long *)r_mem = htoniosl(temp);
1073 if (verbose)
1074 printf("omit: offset=0x%x symbol=%s%s "
1075 "section=%s size=%d "
1076 "fixup=0x%x (reloc=0x%x) GPREL\n",
1077 q->address, sym_name, addstr,
1078 section_name, sym_reloc_size,
1079 sym_addr, section_vma + q->address);
1080 continue;
1082 case R_NIOS2_PCREL16:
1084 unsigned long exist_val;
1085 sym_vma = 0;
1086 sym_addr += sym_vma + q->addend;
1087 sym_addr -= (q->address + 4);
1088 /* modify the target, in target order (little_endian) */
1089 exist_val = niostohl(*(unsigned long *)r_mem);
1090 exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1091 exist_val |= ((sym_addr & 0xFFFF) << 6);
1092 *(unsigned long *)r_mem = htoniosl(exist_val);
1093 if (verbose)
1094 printf("omit: offset=0x%x symbol=%s%s "
1095 "section=%s size=%d "
1096 "fixup=0x%x (reloc=0x%x) PCREL\n",
1097 q->address, sym_name, addstr,
1098 section_name, sym_reloc_size,
1099 sym_addr, section_vma + q->address);
1100 continue;
1103 case R_NIOS2_LO16:
1104 /* check if this is actually the 2nd half of a pair */
1105 if ((p > relpp)
1106 && ((p[-1]->howto->type == R_NIOS2_HIADJ16)
1107 || (p[-1]->howto->type == R_NIOS2_HI16))
1108 && (p[-1]->sym_ptr_ptr == p[0]->sym_ptr_ptr)
1109 && (p[-1]->addend == p[0]->addend)) {
1110 if (verbose)
1111 printf("omit: offset=0x%x symbol=%s%s "
1112 "section=%s size=%d LO16\n",
1113 q->address, sym_name, addstr,
1114 section_name, sym_reloc_size);
1115 continue;
1118 /* error, fall through */
1120 case R_NIOS2_S16:
1121 case R_NIOS2_U16:
1122 case R_NIOS2_CACHE_OPX:
1123 case R_NIOS2_IMM5:
1124 case R_NIOS2_IMM6:
1125 case R_NIOS2_IMM8:
1126 case R_NIOS2_BFD_RELOC_16:
1127 case R_NIOS2_BFD_RELOC_8:
1128 case R_NIOS2_GNU_VTINHERIT:
1129 case R_NIOS2_GNU_VTENTRY:
1130 case R_NIOS2_UJMP:
1131 case R_NIOS2_CJMP:
1132 case R_NIOS2_CALLR:
1133 NIOS2_RELOC_ERR:
1134 printf("Err: unexpected reloc type %s(%d)\n", q->howto->name, q->howto->type);
1135 bad_relocs++;
1136 continue;
1137 #endif /* TARGET_nios2 */
1139 #ifdef TARGET_sparc
1140 case R_SPARC_32:
1141 case R_SPARC_UA32:
1142 relocation_needed = 1;
1143 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1144 sym_addr += sym_vma + q->addend;
1145 break;
1146 case R_SPARC_PC22:
1147 sym_vma = 0;
1148 sym_addr += sym_vma + q->addend;
1149 sym_addr -= q->address;
1150 break;
1151 case R_SPARC_WDISP30:
1152 sym_addr = (((*(q->sym_ptr_ptr))->value-
1153 q->address) >> 2) & 0x3fffffff;
1154 sym_addr |= (
1155 ntohl(*(unsigned long *)r_mem)
1156 & 0xc0000000
1158 break;
1159 case R_SPARC_HI22:
1160 relocation_needed = 1;
1161 pflags = 0x80000000;
1162 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1163 sym_addr += sym_vma + q->addend;
1164 sym_addr |= (
1165 htonl(*(unsigned long *)r_mem)
1166 & 0xffc00000
1168 break;
1169 case R_SPARC_LO10:
1170 relocation_needed = 1;
1171 pflags = 0x40000000;
1172 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1173 sym_addr += sym_vma + q->addend;
1174 sym_addr &= 0x000003ff;
1175 sym_addr |= (
1176 htonl(*(unsigned long *)r_mem)
1177 & 0xfffffc00
1179 break;
1180 #endif /* TARGET_sparc */
1182 #ifdef TARGET_bfin
1183 case R_pcrel12_jump:
1184 case R_pcrel12_jump_s:
1185 case R_pcrel24:
1186 case R_pcrel24_jump_l:
1187 case R_pcrel24_jump_x:
1188 case R_pcrel24_call_x:
1189 case R_pcrel10:
1190 case R_pcrel11:
1191 case R_pcrel5m2:
1192 sym_addr += q->addend;// get the symbol addr
1193 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1194 sym_addr -= q->address; // make it PC relative
1195 // implicitly assumes code section and symbol section are same
1196 break;
1197 case R_got:
1198 /* Ignore these. */
1199 break;
1201 case R_rimm16:
1202 sym_addr += q->addend;
1203 if(weak_und_symbol(sym_section->name, (*(q->sym_ptr_ptr))))
1204 continue;
1205 if(0xFFFF0000 & sym_addr){
1206 fprintf (stderr, "Relocation overflow for rN = %s\n",sym_name);
1207 bad_relocs++;
1209 flat_relocs = (uint32_t *)
1210 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1211 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1212 sym_section->name, sym_name,
1213 (*(q->sym_ptr_ptr)),
1214 0, FLAT_RELOC_PART_LO,
1215 section_vma + q->address))
1216 bad_relocs++;
1217 flat_reloc_count++;
1218 break;
1220 case R_luimm16:
1221 case R_huimm16:
1223 unsigned int sp;
1224 unsigned int reloc_count_incr;
1225 unsigned int hi_lo;
1227 if (q->howto->type == R_luimm16)
1228 hi_lo = FLAT_RELOC_PART_LO;
1229 else
1230 hi_lo = FLAT_RELOC_PART_HI;
1232 sym_addr += q->addend;
1234 flat_relocs = (uint32_t *)
1235 (realloc (flat_relocs, (flat_reloc_count + 2) * sizeof (uint32_t)));
1236 reloc_count_incr = 1;
1237 if (weak_und_symbol (sym_section->name, (*(q->sym_ptr_ptr))))
1238 continue;
1239 if (0xFFFF0000 & sym_addr) {
1240 /* value is > 16 bits - use an extra field */
1241 /* see if we have already output that symbol */
1242 /* reloc may be addend from symbol and */
1243 /* we can only store 16 bit offsets */
1244 sp = 1;
1245 if ((*(q->sym_ptr_ptr))->udata.i == 0
1246 || flat_relocs[(*(q->sym_ptr_ptr))->udata.i] != sym_addr
1247 || ((*(q->sym_ptr_ptr))->udata.i & 0xFFFF0000))
1249 reloc_count_incr = 2;
1250 flat_relocs[flat_reloc_count + 1] = sym_addr;
1251 (*(q->sym_ptr_ptr))->udata.i = flat_reloc_count + 1;
1252 sym_addr = 0; // indication to loader to read next
1253 } else{
1254 sym_addr = (*(q->sym_ptr_ptr))->udata.i;
1256 } else {
1257 sp = 0;
1260 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1261 sym_section->name, sym_name,
1262 (*(q->sym_ptr_ptr)),
1263 sp, hi_lo,
1264 section_vma + q->address))
1265 bad_relocs++;
1266 flat_reloc_count += reloc_count_incr;
1267 break;
1269 case R_byte4_data:
1270 sym_addr += q->addend;
1272 if (weak_und_symbol (sym_section->name, *q->sym_ptr_ptr))
1273 continue;
1275 flat_relocs = (uint32_t *)
1276 (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1277 if (bfin_set_reloc (flat_relocs + flat_reloc_count,
1278 sym_section->name, sym_name,
1279 (*(q->sym_ptr_ptr)),
1280 2, FLAT_RELOC_PART_LO,
1281 section_vma + q->address))
1282 bad_relocs++;
1284 flat_reloc_count++;
1285 break;
1287 #endif //TARGET_bfin
1289 #ifdef TARGET_sh
1290 case R_SH_DIR32:
1291 relocation_needed = 1;
1292 sym_vma = bfd_section_vma(abs_bfd, sym_section);
1293 sym_addr += sym_vma + q->addend;
1294 break;
1295 case R_SH_REL32:
1296 sym_vma = 0;
1297 sym_addr += sym_vma + q->addend;
1298 sym_addr -= q->address;
1299 break;
1300 #endif /* TARGET_sh */
1302 #ifdef TARGET_e1
1303 #define htoe1l(x) htonl(x)
1305 #if 0
1306 #define DEBUG_E1
1307 #endif
1309 #ifdef DEBUG_E1
1310 #define DBG_E1 printf
1311 #else
1312 #define DBG_E1(x, ... )
1313 #endif
1315 #define _32BITS_RELOC 0x00000000
1316 #define _30BITS_RELOC 0x80000000
1317 #define _28BITS_RELOC 0x40000000
1319 char *p;
1320 unsigned long sec_vma, exist_val, S;
1321 case R_E1_CONST31:
1322 relocation_needed = 1;
1323 DBG_E1("Handling Reloc <CONST31>\n");
1324 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1325 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1326 sec_vma, sym_addr, q->address);
1327 sym_addr = sec_vma + sym_addr;
1328 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1329 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1330 exist_val = htoe1l(exist_val);
1331 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1332 sym_addr += exist_val;
1333 pflags = _30BITS_RELOC;
1334 break;
1335 case R_E1_CONST31_PCREL:
1336 relocation_needed = 0;
1337 DBG_E1("Handling Reloc <CONST31_PCREL>\n");
1338 DBG_E1("DONT RELOCATE AT LOADING\n");
1339 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1340 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1341 sec_vma, sym_addr, q->address);
1342 sym_addr = sec_vma + sym_addr;
1343 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1345 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1346 section_vma );
1347 q->address = q->address + section_vma;
1348 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1350 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1351 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1352 DBG_E1( "sym_addr := sym_addr - q->address - "
1353 "sizeof(CONST31_PCREL): [0x%x]\n",
1354 sym_addr );
1355 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1356 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1357 exist_val = htoe1l(exist_val);
1358 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1359 sym_addr |= exist_val;
1360 DBG_E1("sym_addr |= exist_val) : [0x%x]\n", sym_addr );
1361 break;
1362 case R_E1_DIS29W_PCREL:
1363 relocation_needed = 0;
1364 DBG_E1("Handling Reloc <DIS29W_PCREL>\n");
1365 DBG_E1("DONT RELOCATE AT LOADING\n");
1366 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1367 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1368 sec_vma, sym_addr, q->address);
1369 sym_addr = sec_vma + sym_addr;
1370 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1372 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1373 section_vma );
1374 q->address = q->address + section_vma;
1375 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1377 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1378 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1379 DBG_E1( "sym_addr := sym_addr - q->address - "
1380 "sizeof(CONST31_PCREL): [0x%x]\n",
1381 sym_addr );
1382 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1383 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1384 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1385 exist_val = htoe1l(exist_val);
1386 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1387 sym_addr += exist_val;
1388 break;
1389 case R_E1_DIS29W:
1390 DBG_E1("Handling Reloc <DIS29W>\n");
1391 goto DIS29_RELOCATION;
1392 case R_E1_DIS29H:
1393 DBG_E1("Handling Reloc <DIS29H>\n");
1394 goto DIS29_RELOCATION;
1395 case R_E1_DIS29B:
1396 DBG_E1("Handling Reloc <DIS29B>\n");
1397 DIS29_RELOCATION:
1398 relocation_needed = 1;
1399 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1400 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%08x]\n",
1401 sec_vma, sym_addr);
1402 sym_addr = sec_vma + sym_addr;
1403 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%08x]\n", sym_addr);
1404 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1405 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1406 exist_val = htoe1l(exist_val);
1407 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1408 sym_addr += exist_val;
1409 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1410 pflags = _28BITS_RELOC;
1411 break;
1412 case R_E1_IMM32_PCREL:
1413 relocation_needed = 0;
1414 DBG_E1("Handling Reloc <IMM32_PCREL>\n");
1415 DBG_E1("DONT RELOCATE AT LOADING\n");
1416 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1417 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1418 sec_vma, sym_addr);
1419 sym_addr = sec_vma + sym_addr;
1421 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1422 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1423 section_vma );
1424 q->address = q->address + section_vma;
1425 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1427 if( (sym_addr = (sym_addr - q->address - 6 )) < 0 )
1428 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1429 DBG_E1( "sym_addr := sym_addr - q->address - "
1430 "sizeof(CONST31_PCREL): [0x%x]\n",
1431 sym_addr );
1432 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1433 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1434 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1435 exist_val = htoe1l(exist_val);
1436 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1437 sym_addr += exist_val;
1438 break;
1439 case R_E1_IMM32:
1440 relocation_needed = 1;
1441 DBG_E1("Handling Reloc <IMM32>\n");
1442 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1443 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1444 sec_vma, sym_addr);
1445 sym_addr = sec_vma + sym_addr;
1446 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1447 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1448 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);
1449 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1450 exist_val = htoe1l(exist_val);
1451 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1452 sym_addr += exist_val;
1453 pflags = _32BITS_RELOC;
1454 break;
1455 case R_E1_WORD:
1456 relocation_needed = 1;
1457 DBG_E1("Handling Reloc <WORD>\n");
1458 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1459 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1460 sec_vma, sym_addr);
1461 sym_addr = sec_vma + sym_addr;
1462 DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr );
1463 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address );
1464 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1465 exist_val = htoe1l(exist_val);
1466 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1467 sym_addr += exist_val;
1468 DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr);
1469 pflags = _32BITS_RELOC;
1470 break;
1472 #undef _32BITS_RELOC
1473 #undef _30BITS_RELOC
1474 #undef _28BITS_RELOC
1475 #endif
1476 default:
1477 /* missing support for other types of relocs */
1478 printf("ERROR: bad reloc type %d\n", (*p)->howto->type);
1479 bad_relocs++;
1480 continue;
1484 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
1485 bfd_section_vma(abs_bfd, sym_section));
1489 * for full elf relocation we have to write back the
1490 * start_code relative value to use.
1492 if (!pic_with_got) {
1493 #if defined(TARGET_arm)
1494 union {
1495 unsigned char c[4];
1496 unsigned long l;
1497 } tmp;
1498 long hl;
1499 int i0, i1, i2, i3;
1502 * horrible nasty hack to support different endianess
1504 if (!bfd_big_endian(abs_bfd)) {
1505 i0 = 0;
1506 i1 = 1;
1507 i2 = 2;
1508 i3 = 3;
1509 } else {
1510 i0 = 3;
1511 i1 = 2;
1512 i2 = 1;
1513 i3 = 0;
1516 tmp.l = *(unsigned long *)r_mem;
1517 hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16);
1518 if (use_resolved ||
1519 (((*p)->howto->type != R_ARM_PC24) &&
1520 ((*p)->howto->type != R_ARM_PLT32)))
1521 hl |= (tmp.c[i3] << 24);
1522 else if (tmp.c[i2] & 0x80)
1523 hl |= 0xff000000; /* sign extend */
1524 if (!use_resolved)
1525 hl += sym_addr;
1526 tmp.c[i0] = hl & 0xff;
1527 tmp.c[i1] = (hl >> 8) & 0xff;
1528 tmp.c[i2] = (hl >> 16) & 0xff;
1529 if (use_resolved ||
1530 (((*p)->howto->type != R_ARM_PC24) &&
1531 ((*p)->howto->type != R_ARM_PLT32)))
1532 tmp.c[i3] = (hl >> 24) & 0xff;
1533 if ((*p)->howto->type == R_ARM_ABS32)
1534 *(unsigned long *)r_mem = htonl(hl);
1535 else
1536 *(unsigned long *)r_mem = tmp.l;
1538 #elif defined(TARGET_bfin)
1539 if ((*p)->howto->type == R_pcrel24
1540 || (*p)->howto->type == R_pcrel24_jump_l
1541 || (*p)->howto->type == R_pcrel24_jump_x
1542 || (*p)->howto->type == R_pcrel24_call_x)
1544 sym_addr += 2*-1*PCREL24_MAGIC_OFFSET;
1545 *((unsigned short *)(sectionp + q->address) + 1 + PCREL24_MAGIC_OFFSET)
1546 = (sym_addr >> 1) & 0xffff;
1547 *((unsigned short *)(sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1548 = (0xff00 & *((unsigned short *) (sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1549 | ((sym_addr >> 17) & 0xff));
1550 } else if ((*p)->howto->type == R_byte4_data) {
1551 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1552 } else if ((*p)->howto->type == R_pcrel12_jump
1553 || (*p)->howto->type == R_pcrel12_jump_s) {
1554 *((unsigned short *)(sectionp + q->address))
1555 = (0xf000 & *((unsigned short *)(sectionp + q->address))
1556 | ((sym_addr >> 1) & 0xfff));
1557 } else if ((*p)->howto->type == R_pcrel10) {
1558 *((unsigned short *)(sectionp + q->address))
1559 = (~0x3ff & *((unsigned short *)(sectionp + q->address))
1560 | ((sym_addr >> 1) & 0x3ff));
1561 } else if ((*p)->howto->type == R_rimm16
1562 || (*p)->howto->type == R_huimm16
1563 || (*p)->howto->type == R_luimm16) {
1564 /* for l and h we set the lower 16 bits which is only when it will be used */
1565 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1566 } else if ((*p)->howto->type == R_pcrel5m2) {
1567 *((unsigned short *)(sectionp + q->address))
1568 = (0xfff0 & *((unsigned short *)(sectionp + q->address))
1569 | ((sym_addr >> 1) & 0xf));
1570 } else if ((*p)->howto->type == R_pcrel11){
1571 *((unsigned short *)(sectionp + q->address))
1572 = (0xfc00 & *((unsigned short *)(sectionp + q->address))
1573 | ((sym_addr >> 1) & 0x3ff));
1574 } else if (0xE0 <= (*p)->howto->type && 0xF3 >= (*p)->howto->type) {
1575 //arith relocs dont generate a real relocation
1576 } else {
1577 printf("Blackfin relocation fail for reloc type: 0x%x\n", (*p)->howto->type);
1579 #elif defined(TARGET_e1)
1580 #define OPCODE_SIZE 2 /* Add 2 bytes, counting the opcode size*/
1581 switch ((*p)->howto->type) {
1582 case R_E1_CONST31:
1583 case R_E1_CONST31_PCREL:
1584 case R_E1_DIS29W_PCREL:
1585 case R_E1_DIS29W:
1586 case R_E1_DIS29H:
1587 case R_E1_DIS29B:
1588 case R_E1_IMM32_PCREL:
1589 case R_E1_IMM32:
1590 DBG_E1("In addr + 2:[0x%x] <- write [0x%x]\n",
1591 (sectionp + q->address + 2), sym_addr );
1592 *((unsigned long *) (sectionp + q->address + OPCODE_SIZE)) =
1593 htonl(sym_addr);
1594 break;
1595 case R_E1_WORD:
1596 DBG_E1("In addr : [0x%x] <- write [0x%x]\n",
1597 (sectionp + q->address), sym_addr );
1598 *((unsigned long *) (sectionp + q->address )) = htonl(sym_addr);
1599 break;
1600 default:
1601 printf("ERROR:Unhandled Relocation. Exiting...\n");
1602 exit(0);
1603 break;
1605 #else /* ! TARGET_arm && ! TARGET_e1 */
1607 switch (q->howto->type) {
1608 #ifdef TARGET_v850
1609 case R_V850_HI16_S:
1610 case R_V850_HI16:
1611 case R_V850_LO16:
1612 /* Do nothing -- for cases we handle,
1613 the bits produced by the linker are
1614 what we want in the final flat file
1615 (and other cases are errors). Note
1616 that unlike most relocated values,
1617 it is stored in little-endian order,
1618 but this is necessary to avoid
1619 trashing the low-bit, and the float
1620 loaders knows about it. */
1621 break;
1622 #endif /* TARGET_V850 */
1624 #ifdef TARGET_nios2
1625 case R_NIOS2_BFD_RELOC_32:
1626 case R_NIOS2_CALL26:
1627 case R_NIOS2_HIADJ16:
1628 case R_NIOS2_HI16:
1629 /* do nothing */
1630 break;
1631 #endif /* TARGET_nios2 */
1633 #if defined(TARGET_m68k)
1634 case R_68K_PC16:
1635 if (sym_addr < -0x8000 || sym_addr > 0x7fff) {
1636 fprintf (stderr, "Relocation overflow for R_68K_PC16 relocation against %s\n", sym_name);
1637 bad_relocs++;
1638 } else {
1639 r_mem[0] = (sym_addr >> 8) & 0xff;
1640 r_mem[1] = sym_addr & 0xff;
1642 break;
1643 #endif
1645 default:
1646 /* The alignment of the build host
1647 might be stricter than that of the
1648 target, so be careful. We store in
1649 network byte order. */
1650 r_mem[0] = (sym_addr >> 24) & 0xff;
1651 r_mem[1] = (sym_addr >> 16) & 0xff;
1652 r_mem[2] = (sym_addr >> 8) & 0xff;
1653 r_mem[3] = sym_addr & 0xff;
1655 #endif /* !TARGET_arm */
1658 #ifdef TARGET_bfin
1659 else {
1660 if ((*p)->howto->type == R_rimm16
1661 || (*p)->howto->type == R_huimm16
1662 || (*p)->howto->type == R_luimm16)
1664 /* for l and h we set the lower 16 bits which is only when it will be used */
1665 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1666 } else if ((*p)->howto->type == R_byte4_data) {
1667 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1670 #endif
1671 if (verbose)
1672 printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
1673 "section=%s size=%d "
1674 "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
1675 q->address, sym_name, addstr,
1676 section_name, sym_reloc_size,
1677 sym_addr, section_vma + q->address);
1680 * Create relocation entry (PC relative doesn't need this).
1682 if (relocation_needed) {
1683 #ifndef TARGET_bfin
1684 flat_relocs = realloc(flat_relocs,
1685 (flat_reloc_count + 1) * sizeof(uint32_t));
1686 #ifndef TARGET_e1
1687 flat_relocs[flat_reloc_count] = pflags |
1688 (section_vma + q->address);
1690 if (verbose)
1691 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
1692 section_vma + q->address);
1693 #else
1694 switch ((*p)->howto->type) {
1695 case R_E1_CONST31:
1696 case R_E1_CONST31_PCREL:
1697 case R_E1_DIS29W_PCREL:
1698 case R_E1_DIS29W:
1699 case R_E1_DIS29H:
1700 case R_E1_DIS29B:
1701 case R_E1_IMM32_PCREL:
1702 case R_E1_IMM32:
1703 flat_relocs[flat_reloc_count] = pflags |
1704 (section_vma + q->address + OPCODE_SIZE);
1705 if (verbose)
1706 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1707 flat_relocs[flat_reloc_count] );
1708 break;
1709 case R_E1_WORD:
1710 flat_relocs[flat_reloc_count] = pflags |
1711 (section_vma + q->address);
1712 if (verbose)
1713 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1714 flat_relocs[flat_reloc_count] );
1715 break;
1717 #endif
1718 flat_reloc_count++;
1719 #endif
1720 relocation_needed = 0;
1721 pflags = 0;
1724 #if 0
1725 printf("%s(%d): symbol name=%s address=0x%x section=%s -> RELOC=0x%x\n",
1726 __FILE__, __LINE__, sym_name, q->address, section_name,
1727 flat_relocs[flat_reloc_count]);
1728 #endif
1733 if (bad_relocs) {
1734 printf("%d bad relocs\n", bad_relocs);
1735 exit(1);
1738 if (rc < 0)
1739 return(0);
1741 *n_relocs = flat_reloc_count;
1742 return flat_relocs;
1747 static char * program;
1749 static void usage(void)
1751 fprintf(stderr, "Usage: %s [vrzd] [-p <abs-pic-file>] [-s stack-size] "
1752 "[-o <output-file>] <elf-file>\n\n"
1753 " -v : verbose operation\n"
1754 " -r : force load to RAM\n"
1755 " -k : enable kernel trace on load (for debug)\n"
1756 " -z : compress code/data/relocs\n"
1757 " -d : compress data/relocs\n"
1758 " -a : use existing symbol references\n"
1759 " instead of recalculating from\n"
1760 " relocation info\n"
1761 " -R reloc-file : read relocations from a separate file\n"
1762 " -p abs-pic-file : GOT/PIC processing with files\n"
1763 " -s stacksize : set application stack size\n"
1764 " -o output-file : output file name\n\n",
1765 program);
1766 fprintf(stderr, "Compiled for " ARCH " architecture\n\n");
1767 exit(2);
1771 /* Write NUM zeroes to STREAM. */
1772 static void write_zeroes (unsigned long num, stream *stream)
1774 char zeroes[1024];
1775 if (num > 0) {
1776 /* It'd be nice if we could just use fseek, but that doesn't seem to
1777 work for stdio output files. */
1778 memset(zeroes, 0x00, 1024);
1779 while (num > sizeof(zeroes)) {
1780 fwrite_stream(zeroes, sizeof(zeroes), 1, stream);
1781 num -= sizeof(zeroes);
1783 if (num > 0)
1784 fwrite_stream(zeroes, num, 1, stream);
1789 int main(int argc, char *argv[])
1791 int fd;
1792 bfd *rel_bfd, *abs_bfd;
1793 asection *s;
1794 char *ofile=NULL, *pfile=NULL, *abs_file = NULL, *rel_file = NULL;
1795 char *fname = NULL;
1796 int opt;
1797 int i;
1798 int stack;
1799 stream gf;
1801 asymbol **symbol_table;
1802 long number_of_symbols;
1804 unsigned long data_len = 0;
1805 unsigned long bss_len = 0;
1806 unsigned long text_len = 0;
1807 unsigned long reloc_len;
1809 unsigned long data_vma = ~0;
1810 unsigned long bss_vma = ~0;
1811 unsigned long text_vma = ~0;
1813 unsigned long text_offs;
1815 void *text;
1816 void *data;
1817 uint32_t *reloc;
1819 struct flat_hdr hdr;
1821 program = argv[0];
1822 progname = argv[0];
1823 xmalloc_set_program_name(program);
1825 if (argc < 2)
1826 usage();
1828 if (sizeof(hdr) != 64) {
1829 fprintf(stderr,
1830 "Potential flat header incompatibility detected\n"
1831 "header size should be 64 but is %d\n",
1832 sizeof(hdr));
1833 exit(64);
1836 #ifndef TARGET_e1
1837 stack = 4096;
1838 #else /* We need plenty of stack for both of them (Aggregate and Register) */
1839 stack = 0x2020;
1840 #endif
1842 while ((opt = getopt(argc, argv, "avzdrkp:s:o:R:")) != -1) {
1843 switch (opt) {
1844 case 'v':
1845 verbose++;
1846 break;
1847 case 'r':
1848 load_to_ram++;
1849 break;
1850 case 'k':
1851 ktrace++;
1852 break;
1853 case 'z':
1854 docompress = 1;
1855 break;
1856 case 'd':
1857 docompress = 2;
1858 break;
1859 case 'p':
1860 pfile = optarg;
1861 break;
1862 case 'o':
1863 ofile = optarg;
1864 break;
1865 case 'a':
1866 use_resolved = 1;
1867 break;
1868 case 's':
1869 if (sscanf(optarg, "%i", &stack) != 1) {
1870 fprintf(stderr, "%s invalid stack size %s\n", argv[0], optarg);
1871 usage();
1873 break;
1874 case 'R':
1875 rel_file = optarg;
1876 break;
1877 default:
1878 fprintf(stderr, "%s Unknown option\n", argv[0]);
1879 usage();
1880 break;
1885 * if neither the -r or -p options was given, default to
1886 * a RAM load as that is the only option that makes sense.
1888 if (!load_to_ram && !pfile)
1889 load_to_ram = 1;
1891 filename = fname = argv[argc-1];
1893 if (pfile) {
1894 pic_with_got = 1;
1895 abs_file = pfile;
1896 } else
1897 abs_file = fname;
1899 if (! rel_file)
1900 rel_file = fname;
1902 if (!(rel_bfd = bfd_openr(rel_file, 0))) {
1903 fprintf(stderr, "Can't open %s\n", rel_file);
1904 exit(1);
1907 if (bfd_check_format (rel_bfd, bfd_object) == 0) {
1908 fprintf(stderr, "File is not an object file\n");
1909 exit(2);
1912 if (abs_file == rel_file)
1913 abs_bfd = rel_bfd; /* one file does all */
1914 else {
1915 if (!(abs_bfd = bfd_openr(abs_file, 0))) {
1916 fprintf(stderr, "Can't open %s\n", abs_file);
1917 exit(1);
1920 if (bfd_check_format (abs_bfd, bfd_object) == 0) {
1921 fprintf(stderr, "File is not an object file\n");
1922 exit(2);
1926 if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC)) {
1927 fprintf (stderr, "%s: Input file contains no relocation info\n", rel_file);
1928 exit (2);
1931 if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P)) {
1932 /* `Absolute' file is not absolute, so neither are address
1933 contained therein. */
1934 fprintf (stderr,
1935 "%s: `-a' option specified with non-fully-resolved input file\n",
1936 bfd_get_filename (abs_bfd));
1937 exit (2);
1940 symbol_table = get_symbols(abs_bfd, &number_of_symbols);
1942 /* Group output sections into text, data, and bss, and calc their sizes. */
1943 for (s = abs_bfd->sections; s != NULL; s = s->next) {
1944 unsigned long *vma, *len;
1945 bfd_size_type sec_size;
1946 bfd_vma sec_vma;
1948 if (s->flags & SEC_CODE) {
1949 vma = &text_vma;
1950 len = &text_len;
1951 } else if (s->flags & SEC_DATA) {
1952 vma = &data_vma;
1953 len = &data_len;
1954 } else if (s->flags & SEC_ALLOC) {
1955 vma = &bss_vma;
1956 len = &bss_len;
1957 } else
1958 continue;
1960 sec_size = bfd_section_size(abs_bfd, s);
1961 sec_vma = bfd_section_vma(abs_bfd, s);
1963 if (sec_vma < *vma) {
1964 if (*len > 0)
1965 *len += sec_vma - *vma;
1966 else
1967 *len = sec_size;
1968 *vma = sec_vma;
1969 } else if (sec_vma + sec_size > *vma + *len)
1970 *len = sec_vma + sec_size - *vma;
1973 if (text_len == 0) {
1974 fprintf (stderr, "%s: no .text section", abs_file);
1975 exit (2);
1978 text = xmalloc(text_len);
1980 if (verbose)
1981 printf("TEXT -> vma=0x%x len=0x%x\n", text_vma, text_len);
1983 /* Read in all text sections. */
1984 for (s = abs_bfd->sections; s != NULL; s = s->next)
1985 if (s->flags & SEC_CODE)
1986 if (!bfd_get_section_contents(abs_bfd, s,
1987 text + (s->vma - text_vma), 0,
1988 bfd_section_size(abs_bfd, s)))
1990 fprintf(stderr, "read error section %s\n", s->name);
1991 exit(2);
1994 if (data_len == 0) {
1995 fprintf (stderr, "%s: no .data section", abs_file);
1996 exit (2);
1998 data = xmalloc(data_len);
2000 if (verbose)
2001 printf("DATA -> vma=0x%x len=0x%x\n", data_vma, data_len);
2003 if ((text_vma + text_len) != data_vma) {
2004 if ((text_vma + text_len) > data_vma) {
2005 printf("ERROR: text=0x%x overlaps data=0x%x ?\n", text_len, data_vma);
2006 exit(1);
2008 if (verbose)
2009 printf("WARNING: data=0x%x does not directly follow text=0x%x\n",
2010 data_vma, text_len);
2011 text_len = data_vma - text_vma;
2014 /* Read in all data sections. */
2015 for (s = abs_bfd->sections; s != NULL; s = s->next)
2016 if (s->flags & SEC_DATA)
2017 if (!bfd_get_section_contents(abs_bfd, s,
2018 data + (s->vma - data_vma), 0,
2019 bfd_section_size(abs_bfd, s)))
2021 fprintf(stderr, "read error section %s\n", s->name);
2022 exit(2);
2025 /* Put common symbols in bss. */
2026 bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len);
2028 if (verbose)
2029 printf("BSS -> vma=0x%x len=0x%x\n", bss_vma, bss_len);
2031 if ((data_vma + data_len) != bss_vma) {
2032 if ((data_vma + data_len) > bss_vma) {
2033 printf("ERROR: text=0x%x + data=0x%x overlaps bss=0x%x ?\n", text_len,
2034 data_len, bss_vma);
2035 exit(1);
2037 if (verbose)
2038 printf("WARNING: bss=0x%x does not directly follow text=0x%x + data=0x%x(0x%x)\n",
2039 bss_vma, text_len, data_len, text_len + data_len);
2040 data_len = bss_vma - data_vma;
2043 reloc = output_relocs(abs_bfd, symbol_table, number_of_symbols, &reloc_len,
2044 text, text_len, text_vma, data, data_len, data_vma,
2045 rel_bfd);
2047 if (reloc == NULL)
2048 printf("No relocations in code!\n");
2050 text_offs = real_address_bits(text_vma);
2052 /* Fill in the binflt_flat header */
2053 memcpy(hdr.magic,"bFLT",4);
2054 hdr.rev = htonl(FLAT_VERSION);
2055 hdr.entry = htonl(sizeof(hdr) + bfd_get_start_address(abs_bfd));
2056 hdr.data_start = htonl(sizeof(hdr) + text_offs + text_len);
2057 hdr.data_end = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2058 hdr.bss_end = htonl(sizeof(hdr) + text_offs + text_len +data_len+bss_len);
2059 hdr.stack_size = htonl(stack); /* FIXME */
2060 hdr.reloc_start = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2061 hdr.reloc_count = htonl(reloc_len);
2062 hdr.flags = htonl(0
2063 | (load_to_ram ? FLAT_FLAG_RAM : 0)
2064 | (ktrace ? FLAT_FLAG_KTRACE : 0)
2065 | (pic_with_got ? FLAT_FLAG_GOTPIC : 0)
2066 | (docompress ? (docompress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
2068 hdr.build_date = htonl((unsigned long)time(NULL));
2069 memset(hdr.filler, 0x00, sizeof(hdr.filler));
2071 for (i=0; i<reloc_len; i++) reloc[i] = htonl(reloc[i]);
2073 if (verbose) {
2074 printf("SIZE: .text=0x%04x, .data=0x%04x, .bss=0x%04x",
2075 text_len, data_len, bss_len);
2076 if (reloc)
2077 printf(", relocs=0x%04x", reloc_len);
2078 printf("\n");
2081 if (!ofile) {
2082 ofile = xmalloc(strlen(fname) + 5 + 1); /* 5 to add suffix */
2083 strcpy(ofile, fname);
2084 strcat(ofile, ".bflt");
2087 if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0) {
2088 fprintf (stderr, "Can't open output file %s\n", ofile);
2089 exit(4);
2092 write(fd, &hdr, sizeof(hdr));
2093 close(fd);
2095 if (fopen_stream_u(&gf, ofile, "a" BINARY_FILE_OPTS)) {
2096 fprintf(stderr, "Can't open file %s for writing\n", ofile);
2097 exit(4);
2100 if (docompress == 1)
2101 reopen_stream_compressed(&gf);
2103 /* Fill in any hole at the beginning of the text segment. */
2104 if (verbose)
2105 printf("ZERO before text len=0x%x\n", text_offs);
2106 write_zeroes(text_offs, &gf);
2108 /* Write the text segment. */
2109 fwrite_stream(text, text_len, 1, &gf);
2111 if (docompress == 2)
2112 reopen_stream_compressed(&gf);
2114 /* Write the data segment. */
2115 fwrite_stream(data, data_len, 1, &gf);
2117 if (reloc)
2118 fwrite_stream(reloc, reloc_len * 4, 1, &gf);
2120 fclose_stream(&gf);
2122 exit(0);
2127 * this __MUST__ be at the VERY end of the file - do NOT move!!
2129 * Local Variables:
2130 * c-basic-offset: 4
2131 * tab-width: 8
2132 * end:
2133 * vi: tabstop=8 shiftwidth=4 textwidth=79 noexpandtab