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) 2003, H8 support <davidm@snapgear.com>
10 * (c) 2001-2003, arm/arm-pic/arm-big-endian support <davidm@snapgear.com>
11 * (c) 2001, v850 changes, Mile Bader <miles@lsi.nec.co.jp>
12 * (c) 2001, zflat support <davidm@snapgear.com>
13 * (c) 2001, Changes for GOT entries
14 * (Pale Dale, pauli@lineo.com, David McCullough davidm@lineo.com)
16 * Now supports PIC with GOT tables. This works by taking a '.elf' file
17 * and a fully linked elf executable (at address 0) and produces a flat
18 * file that can be loaded with some fixups. It still supports the old
19 * style fully relocatable elf format files.
21 * Originally obj-res.c
23 * (c) 1998, Kenneth Albanowski <kjahds@kjahds.com>
24 * (c) 1998, D. Jeff Dionne
25 * (c) 1998, The Silver Hammer Group Ltd.
26 * (c) 1996, 1997 Dionne & Associates
27 * jeff@ryeham.ee.ryerson.ca
29 * This is Free Software, under the GNU Public Licence v2 or greater.
31 * Relocation added March 1997, Kresten Krab Thorup
32 * krab@california.daimi.aau.dk
35 #include <stdio.h> /* Userland pieces of the ANSI C standard I/O package */
36 #include <stdlib.h> /* Userland prototypes of the ANSI C std lib functions */
37 #include <stdarg.h> /* Allows va_list to exist in the these namespaces */
38 #include <string.h> /* Userland prototypes of the string handling funcs */
40 #include <unistd.h> /* Userland prototypes of the Unix std system calls */
41 #include <fcntl.h> /* Flag value for file handling functions */
44 #include <netinet/in.h> /* Consts and structs defined by the internet system */
46 /* from $(INSTALLDIR)/include */
47 #include <bfd.h> /* Main header file for the BFD library */
49 #if defined(TARGET_h8300)
50 #include <elf/h8.h> /* TARGET_* ELF support for the BFD library */
52 #include <elf.h> /* TARGET_* ELF support for the BFD library */
55 /* from uClinux-x.x.x/include/linux */
56 #include "flat.h" /* Binary flat header description */
63 #if defined(TARGET_m68k)
64 #define ARCH "m68k/coldfire"
65 #elif defined(TARGET_arm)
67 #elif defined(TARGET_sparc)
69 #elif defined(TARGET_v850)
71 #elif defined(TARGET_h8300)
74 #error "Don't know how to support your CPU architecture??"
78 * Define a maximum number of bytes allowed in the offset table.
79 * We'll fail if the table is larger than this.
81 * This limit may be different for platforms other than m68k, but
82 * 8000 entries is a lot, trust me :-) (davidm)
84 #define GOT_LIMIT 32767
91 int verbose = 0; /* extra output when running */
92 int pic_with_got = 0; /* do elf/got processing with PIC code */
93 int load_to_ram = 0; /* instruct loader to allocate everything into RAM */
94 int compress = 0; /* 1 = compress everything, 2 = compress data only */
95 int use_resolved = 0; /* If true, get the value of symbol references from */
96 /* the program contents, not from the relocation table. */
97 /* In this case, the input ELF file must be already */
98 /* fully resolved (using the `-q' flag with recent */
99 /* versions of GNU ld will give you a fully resolved */
100 /* output file with relocation entries). */
102 const char *progname, *filename;
108 static char where[200];
111 /* Use exactly one of these: */
112 E_NOFILE = 0, /* "progname: " */
113 E_FILE = 1, /* "filename: " */
114 E_FILELINE = 2, /* "filename:lineno: " */
115 E_FILEWHERE = 3, /* "filename:%s: " -- set %s with ewhere() */
117 /* Add in any of these with |': */
122 void ewhere (const char *format, ...);
123 void einfo (int type, const char *format, ...);
127 ewhere (const char *format, ...) {
129 va_start (args, format);
130 vsprintf (where, format, args);
136 einfo (int type, const char *format, ...) {
139 switch (type & 0x0f) {
141 fprintf (stderr, "%s: ", progname);
144 fprintf (stderr, "%s: ", filename);
147 ewhere ("%d", lineno);
150 fprintf (stderr, "%s:%s: ", filename, where);
154 if (type & E_WARNING) {
155 fprintf (stderr, "warning: ");
161 va_start (args, format);
162 vfprintf (stderr, format, args);
168 fprintf (stderr, "\n");
173 get_symbols (bfd *abfd, long *num)
176 asymbol **symbol_table;
177 long number_of_symbols;
179 storage_needed = bfd_get_symtab_upper_bound (abfd);
181 if (storage_needed < 0)
184 if (storage_needed == 0)
187 symbol_table = (asymbol **) malloc (storage_needed);
189 number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
191 if (number_of_symbols < 0)
194 *num = number_of_symbols;
201 dump_symbols(asymbol **symbol_table, long number_of_symbols)
204 printf("SYMBOL TABLE:\n");
205 for (i=0; i<number_of_symbols; i++) {
206 printf(" NAME=%s VALUE=0x%x\n", symbol_table[i]->name,
207 symbol_table[i]->value);
216 get_symbol_offset(char *name, asection *sec, asymbol **symbol_table, long number_of_symbols)
219 for (i=0; i<number_of_symbols; i++) {
220 if (symbol_table[i]->section == sec) {
221 if (!strcmp(symbol_table[i]->name, name)) {
222 return symbol_table[i]->value;
232 add_com_to_bss(asymbol **symbol_table, long number_of_symbols, long bss_len)
238 for (i=0; i<number_of_symbols; i++) {
239 if (strcmp("*COM*", symbol_table[i]->section->name) == 0) {
240 offset = bss_len + comsize;
241 comsize += symbol_table[i]->value;
242 symbol_table[i]->value = offset;
254 int number_of_symbols,
255 unsigned long *n_relocs,
256 unsigned char *text, int text_len, unsigned char *data, int data_len,
259 unsigned long *flat_relocs;
260 asection *a, *sym_section, *r;
261 arelent **relpp, **p, *q;
262 const char *sym_name, *section_name;
263 unsigned char *sectionp;
264 unsigned long pflags;
266 long sym_addr, sym_vma, section_vma;
267 int relsize, relcount;
268 int flat_reloc_count;
269 int sym_reloc_size, rc;
276 printf("%s(%d): output_relocs(abs_bfd=%d,synbols=%x,number_of_symbols=%d"
277 "n_relocs=%x,text=%x,text_len=%d,data=%x,data_len=%d)\n",
278 __FILE__, __LINE__, abs_bfd, symbols, number_of_symbols, n_relocs,
279 text, text_len, data, data_len);
283 dump_symbols(symbols, number_of_symbols);
288 flat_reloc_count = 0;
292 /* Determine how big our offset table is in bytes.
293 * This isn't too difficult as we've terminated the table with -1.
294 * Also note that both the relocatable and absolute versions have this
295 * terminator even though the relocatable one doesn't have the GOT!
298 unsigned long *lp = (unsigned long *)data;
299 /* Should call ntohl(*lp) here but is isn't going to matter */
300 while (*lp != 0xffffffff) lp++;
301 got_size = ((unsigned char *)lp) - data;
303 printf("GOT table contains %d entries (%d bytes)\n",
304 got_size/sizeof(unsigned long), got_size);
306 if (got_size > GOT_LIMIT) {
307 fprintf(stderr, "GOT too large: %d bytes (limit = %d bytes)\n",
308 got_size, GOT_LIMIT);
314 for (a = abs_bfd->sections; (a != (asection *) NULL); a = a->next) {
315 section_vma = bfd_section_vma(abs_bfd, a);
318 printf("SECTION: %s [%x]: flags=%x vma=%x\n", a->name, a,
319 a->flags, section_vma);
321 // if (bfd_is_abs_section(a))
323 if (bfd_is_und_section(a))
325 if (bfd_is_com_section(a))
327 // if ((a->flags & SEC_RELOC) == 0)
331 * Only relocate things in the data sections if we are PIC/GOT.
332 * otherwise do text as well
334 if (!pic_with_got && strcmp(".text", a->name) == 0)
336 else if (strcmp(".data", a->name) == 0)
341 /* Now search for the equivalent section in the relocation binary
342 * and use that relocation information to build reloc entries
345 for (r=rel_bfd->sections; r != NULL; r=r->next)
346 if (strcmp(a->name, r->name) == 0)
351 printf(" RELOCS: %s [%x]: flags=%x vma=%x\n", r->name, r,
352 r->flags, bfd_section_vma(abs_bfd, r));
353 if ((r->flags & SEC_RELOC) == 0)
355 relsize = bfd_get_reloc_upper_bound(rel_bfd, r);
358 printf("%s(%d): no relocation entries section=%x\n",
359 __FILE__, __LINE__, r->name);
363 symb = get_symbols(rel_bfd, &nsymb);
364 relpp = (arelent **) xmalloc(relsize);
365 relcount = bfd_canonicalize_reloc(rel_bfd, r, relpp, symb);
368 printf("%s(%d): no relocation entries section=%s\n",
369 __FILE__, __LINE__, r->name);
372 for (p = relpp; (relcount && (*p != NULL)); p++, relcount--) {
373 int relocation_needed = 0;
376 /* Skip this relocation entirely if possible (we
377 do this early, before doing any other
378 processing on it). */
379 switch ((*p)->howto->type) {
380 #ifdef R_V850_9_PCREL
383 #ifdef R_V850_22_PCREL
384 case R_V850_22_PCREL:
386 #ifdef R_V850_SDA_16_16_OFFSET
387 case R_V850_SDA_16_16_OFFSET:
389 #ifdef R_V850_SDA_15_16_OFFSET
390 case R_V850_SDA_15_16_OFFSET:
392 #ifdef R_V850_ZDA_15_16_OFFSET
393 case R_V850_ZDA_15_16_OFFSET:
395 #ifdef R_V850_TDA_6_8_OFFSET
396 case R_V850_TDA_6_8_OFFSET:
398 #ifdef R_V850_TDA_7_8_OFFSET
399 case R_V850_TDA_7_8_OFFSET:
401 #ifdef R_V850_TDA_7_7_OFFSET
402 case R_V850_TDA_7_7_OFFSET:
404 #ifdef R_V850_TDA_16_16_OFFSET
405 case R_V850_TDA_16_16_OFFSET:
407 #ifdef R_V850_TDA_4_5_OFFSET
408 case R_V850_TDA_4_5_OFFSET:
410 #ifdef R_V850_TDA_4_4_OFFSET
411 case R_V850_TDA_4_4_OFFSET:
413 #ifdef R_V850_SDA_16_16_SPLIT_OFFSET
414 case R_V850_SDA_16_16_SPLIT_OFFSET:
416 #ifdef R_V850_CALLT_6_7_OFFSET
417 case R_V850_CALLT_6_7_OFFSET:
419 #ifdef R_V850_CALLT_16_16_OFFSET
420 case R_V850_CALLT_16_16_OFFSET:
422 /* These are relative relocations, which
423 have already been fixed up by the
424 linker at this point, so just ignore
428 #endif /* USE_V850_RELOCS */
431 if (q->sym_ptr_ptr && *q->sym_ptr_ptr) {
432 sym_name = (*(q->sym_ptr_ptr))->name;
433 sym_section = (*(q->sym_ptr_ptr))->section;
434 section_name=(*(q->sym_ptr_ptr))->section->name;
436 printf("ERROR: undefined relocation entry\n");
440 /* Adjust the address to account for the GOT table which wasn't
441 * present in the relative file link.
444 q->address += got_size;
447 * Fixup offset in the actual section.
450 if ((sym_addr = get_symbol_offset((char *) sym_name,
451 sym_section, symbols, number_of_symbols)) == -1) {
456 /* Use the address of the symbol already in
458 sym_addr = *((unsigned long *)
459 (sectionp + q->address));
460 relocation_needed = 1;
462 /* Calculate the sym address ourselves. */
463 sym_reloc_size = bfd_get_reloc_size(q->howto);
466 if (sym_reloc_size != 4) {
467 printf("ERROR: bad reloc type %d size=%d for symbol=%s\n",
468 (*p)->howto->type, sym_reloc_size, sym_name);
475 switch ((*p)->howto->type) {
477 #if defined(TARGET_m68k)
479 relocation_needed = 1;
480 sym_vma = bfd_section_vma(abs_bfd, sym_section);
481 sym_addr += sym_vma + q->addend;
485 sym_addr += sym_vma + q->addend;
486 sym_addr -= q->address;
490 #if defined(TARGET_arm)
492 relocation_needed = 1;
495 "%s vma=0x%x, value=0x%x, address=0x%x "
496 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
498 sym_vma, (*(q->sym_ptr_ptr))->value,
499 q->address, sym_addr,
500 (*p)->howto->rightshift,
501 *((unsigned long *) (sectionp + q->address)));
502 sym_vma = bfd_section_vma(abs_bfd, sym_section);
503 sym_addr += sym_vma + q->addend;
507 /* Should be fine as is */
512 "%s vma=0x%x, value=0x%x, address=0x%x "
513 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
515 sym_vma, (*(q->sym_ptr_ptr))->value,
516 q->address, sym_addr,
517 (*p)->howto->rightshift,
518 *((unsigned long *) (sectionp + q->address)));
521 sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift;
527 relocation_needed = 1;
528 sym_vma = bfd_section_vma(abs_bfd, sym_section);
529 sym_addr += sym_vma + q->addend;
531 #if defined(R_V850_ZDA_16_16_OFFSET) || defined(R_V850_ZDA_16_16_SPLIT_OFFSET)
532 #ifdef R_V850_ZDA_16_16_OFFSET
533 case R_V850_ZDA_16_16_OFFSET:
535 #ifdef R_V850_ZDA_16_16_SPLIT_OFFSET
536 case R_V850_ZDA_16_16_SPLIT_OFFSET:
538 /* Can't support zero-relocations. */
539 printf ("ERROR: %s+0x%x: zero relocations not supported\n",
540 sym_name, q->addend);
542 #endif /* R_V850_ZDA_16_16_OFFSET || R_V850_ZDA_16_16_SPLIT_OFFSET */
543 #endif /* TARGET_v850 */
547 if (sym_reloc_size != 4) {
548 printf("R_H8_DIR24R8 size %d\n", sym_reloc_size);
552 relocation_needed = 1;
553 sym_addr = (*(q->sym_ptr_ptr))->value;
555 sym_vma = bfd_section_vma(abs_bfd, sym_section);
556 sym_addr += sym_vma + q->addend;
557 sym_addr |= (*((unsigned char *)(sectionp+q->address))<<24);
560 if (sym_reloc_size != 4) {
561 printf("R_H8_DIR24A8 size %d\n", sym_reloc_size);
565 relocation_needed = 1;
566 sym_addr = (*(q->sym_ptr_ptr))->value;
567 sym_vma = bfd_section_vma(abs_bfd, sym_section);
568 sym_addr += sym_vma + q->addend;
571 case R_H8_DIR32A16: /* currently 32, could be made 16 */
572 if (sym_reloc_size != 4) {
573 printf("R_H8_DIR32 size %d\n", sym_reloc_size);
577 relocation_needed = 1;
578 sym_addr = (*(q->sym_ptr_ptr))->value;
579 sym_vma = bfd_section_vma(abs_bfd, sym_section);
580 sym_addr += sym_vma + q->addend;
584 sym_addr = (*(q->sym_ptr_ptr))->value;
585 sym_addr += sym_vma + q->addend;
586 sym_addr -= (q->address + 2);
587 if (bfd_big_endian(abs_bfd))
588 * ((unsigned short *) (sectionp + q->address)) =
589 bfd_big_endian(abs_bfd) ? htons(sym_addr) : sym_addr;
593 sym_addr = (*(q->sym_ptr_ptr))->value;
594 sym_addr += sym_vma + q->addend;
595 sym_addr -= (q->address + 1);
596 * ((unsigned char *) (sectionp + q->address)) = sym_addr;
603 relocation_needed = 1;
604 sym_vma = bfd_section_vma(abs_bfd, sym_section);
605 sym_addr += sym_vma + q->addend;
609 sym_addr += sym_vma + q->addend;
610 sym_addr -= q->address;
612 case R_SPARC_WDISP30:
613 sym_addr = (((*(q->sym_ptr_ptr))->value-
614 q->address) >> 2) & 0x3fffffff;
616 ntohl(*((unsigned long *) (sectionp + q->address))) &
621 relocation_needed = 1;
623 sym_vma = bfd_section_vma(abs_bfd, sym_section);
624 sym_addr += sym_vma + q->addend;
626 htonl(* ((unsigned long *) (sectionp + q->address))) &
631 relocation_needed = 1;
633 sym_vma = bfd_section_vma(abs_bfd, sym_section);
634 sym_addr += sym_vma + q->addend;
635 sym_addr &= 0x000003ff;
637 htonl(* ((unsigned long *) (sectionp + q->address))) &
641 #endif /* TARGET_sparc */
644 /* missing support for other types of relocs */
645 printf("ERROR: bad reloc type %d\n", (*p)->howto->type);
651 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
652 bfd_section_vma(abs_bfd, sym_section));
656 * for full elf relocation we have to write back the start_code
657 * relative value to use.
660 #if defined(TARGET_arm)
669 * horrible nasty hack to support different endianess
671 if (!bfd_big_endian(abs_bfd)) {
683 tmp.l = *((unsigned long *) (sectionp + q->address));
684 hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16);
685 if (((*p)->howto->type != R_ARM_PC24) &&
686 ((*p)->howto->type != R_ARM_PLT32))
687 hl |= (tmp.c[i3] << 24);
688 else if (tmp.c[i2] & 0x80)
689 hl |= 0xff000000; /* sign extend */
691 tmp.c[i0] = hl & 0xff;
692 tmp.c[i1] = (hl >> 8) & 0xff;
693 tmp.c[i2] = (hl >> 16) & 0xff;
694 if (((*p)->howto->type != R_ARM_PC24) &&
695 ((*p)->howto->type != R_ARM_PLT32))
696 tmp.c[i3] = (hl >> 24) & 0xff;
697 if ((*p)->howto->type == R_ARM_ABS32)
698 *((unsigned long *) (sectionp + q->address)) = htonl(hl);
700 *((unsigned long *) (sectionp + q->address)) = tmp.l;
701 #else /* ! TARGET_arm */
702 *((unsigned long *) (sectionp + q->address)) = htonl(sym_addr);
707 printf(" RELOC[%d]: offset=%x symbol=%s%s "
708 "section=%s size=%d "
709 "fixup=%x (reloc=0x%x)\n", flat_reloc_count,
710 q->address, sym_name, addstr,
711 section_name, sym_reloc_size,
712 sym_addr, section_vma + q->address);
715 * Create relocation entry (PC relative doesn't need this).
717 if (relocation_needed) {
718 flat_relocs = realloc(flat_relocs,
719 (flat_reloc_count + 1) * sizeof(unsigned long));
720 flat_relocs[flat_reloc_count] = pflags |
721 (section_vma + q->address);
724 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
725 section_vma + q->address);
727 relocation_needed = 0;
732 printf("%s(%d): symbol name=%s address=%x section=%s -> RELOC=%x\n",
733 __FILE__, __LINE__, sym_name, q->address, section_name,
734 flat_relocs[flat_reloc_count]);
741 printf("%d bad relocs\n", bad_relocs);
748 *n_relocs = flat_reloc_count;
755 /* shared lib symbols stuff */
758 get_symbol(char *name, asection *sec, asymbol **symbol_table, long number_of_symbols)
761 for (i=0; i<number_of_symbols; i++) {
762 if (symbol_table[i]->section == sec) {
763 if (!strcmp(symbol_table[i]->name, name)) {
764 return symbol_table[i]->value;
772 output_offset_table(int fd, char *ename, bfd *abfd, asymbol **symbol_table, long number_of_symbols)
783 signed short *tab = malloc(32768); /* we don't know how many yet*/
785 asection *text_section = bfd_get_section_by_name (abfd, ".text");
787 if (!(ef = fopen(ename, "r"))) {
788 fprintf (stderr,"Can't open %s\n",ename);
792 fgets(libname, 80, ef);
794 if (number_of_symbols < 0) {
795 fprintf (stderr,"Corrupt symbol table!\n");
799 if ((etext_addr = get_symbol("etext",
802 number_of_symbols)) == -1) {
803 fprintf (stderr,"Can't find the symbol etext\n");
809 buf[strlen(buf)-1] = 0; /* Arrrgh! linefeeds */
811 if ((sym_addr = get_symbol(buf,
814 number_of_symbols)) == -1) {
815 fprintf (stderr,"Can't find the symbol %s\n",buf);
818 tab[++count] = htons(sym_addr - etext_addr);
826 fprintf (stderr,"*** %d symbols not found\n",foobar);
830 strcpy((char *)&tab[++count],libname);
831 tab[0] = htons(count * 2);
832 write(fd, tab, count * 2 + strlen(libname) + 2);
838 static char * program;
840 static void usage(void)
842 fprintf(stderr, "Usage: %s [vrzd] [-p <abs-pic-file>] [-s stack-size] "
843 "[-o <output-file>] <elf-file>\n\n"
844 " -v : verbose operation\n"
845 " -r : force load to RAM\n"
846 " -z : compress code/data/relocs\n"
847 " -d : compress data/relocs\n"
848 " -a : use existing symbol references\n"
849 " instead of recalculating from\n"
851 " -p abs-pic-file : GOT/PIC processing with files\n"
852 " -s stacksize : set application stack size\n"
853 " -o output-file : output file name\n\n",
855 fprintf(stderr, "Compiled for " ARCH " architecture\n\n");
861 int main(int argc, char *argv[])
864 bfd *rel_bfd, *abs_bfd;
866 char *ofile=NULL, *pfile=NULL;
875 asymbol **symbol_table;
876 long number_of_symbols;
878 unsigned long data_len;
879 unsigned long bss_len;
880 unsigned long text_len;
881 unsigned long reloc_len;
883 unsigned long data_vma;
884 unsigned long bss_vma;
885 unsigned long text_vma;
889 unsigned long *reloc;
902 while ((opt = getopt(argc, argv, "avzdrp:s:o:")) != -1) {
926 stack = atoi(optarg);
929 fprintf(stderr, "%s Unknown option\n", argv[0]);
936 * if neither the -r or -p options was given, default to
937 * a RAM load as that is the only option that makes sense.
939 if (!load_to_ram && !pfile)
942 filename = fname = argv[argc-1];
944 if (!(rel_bfd = bfd_openr(fname, 0))) {
945 fprintf(stderr, "Can't open %s\n", fname);
949 if (bfd_check_format (rel_bfd, bfd_object) == 0) {
950 fprintf(stderr, "File is not an object file\n");
957 if (!(abs_bfd = bfd_openr(pfile, 0))) {
958 fprintf(stderr, "Can't open %s\n", pfile);
962 if (bfd_check_format (abs_bfd, bfd_object) == 0) {
963 fprintf(stderr, "File is not an object file\n");
967 abs_bfd = rel_bfd; /* one file does all */
970 if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC)) {
971 fprintf (stderr, "%s: Input file contains no relocation info\n", fname);
975 if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P)) {
976 /* `Absolute' file is not absolute, so neither are address
977 contained therein. */
979 "%s: `-a' option specified with non-fully-resolved input file\n",
980 bfd_get_filename (abs_bfd));
984 symbol_table = get_symbols(abs_bfd, &number_of_symbols);
986 s = bfd_get_section_by_name (abs_bfd, ".text");
988 text_len = s->_raw_size;
989 text = malloc(text_len);
992 printf("TEXT -> vma=%x len=%x\n", text_vma, text_len);
993 printf(" lma=%x clen=%x oo=%x ap=%x fp=%x\n",
994 s->lma, s->_cooked_size, s->output_offset,
995 s->alignment_power, s->filepos);
998 if (bfd_get_section_contents(abs_bfd,
1002 s->_raw_size) == false) {
1003 fprintf(stderr, "read error section %s\n", s->name);
1007 s = bfd_get_section_by_name (abs_bfd, ".data");
1009 data_len = s->_raw_size;
1010 data = malloc(data_len);
1013 printf("DATA -> vma=%x len=%x\n", data_vma, data_len);
1014 printf(" lma=%x clen=%x oo=%x ap=%x fp=%x\n",
1015 s->lma, s->_cooked_size, s->output_offset,
1016 s->alignment_power, s->filepos);
1018 if ((text_vma + text_len) != data_vma) {
1019 if ((text_vma + text_len) > data_vma) {
1020 printf("ERROR: text=%x overlaps data=%x ?\n", text_len, data_vma);
1024 printf("WARNING: data=%x does not directly follow text=%x\n",
1025 data_vma, text_len);
1026 text_len = data_vma - text_vma;
1029 if (bfd_get_section_contents(abs_bfd,
1033 s->_raw_size) == false) {
1034 fprintf(stderr, "read error section %s\n", s->name);
1038 s = bfd_get_section_by_name (abs_bfd, ".bss");
1039 bss_len = s->_raw_size;
1041 bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len);
1044 printf("BSS -> vma=%x len=%x\n", bss_vma, bss_len);
1045 printf(" lma=%x clen=%x oo=%x ap=%x fp=%x\n",
1046 s->lma, s->_cooked_size, s->output_offset,
1047 s->alignment_power, s->filepos);
1050 if ((text_vma + text_len + data_len) != bss_vma) {
1051 if ((text_vma + text_len + data_len) > bss_vma) {
1052 printf("ERROR: text=%x + data=%x overlaps bss=%x ?\n", text_len,
1057 printf("WARNING: bss=%x does not directly follow text=%x + data=%x(%x)\n",
1058 bss_vma, text_len, data_len, text_len + data_len);
1059 data_len = bss_vma - data_vma;
1062 reloc = (unsigned long *) output_relocs (abs_bfd, symbol_table,
1063 number_of_symbols, &reloc_len, text, text_len, data, data_len, rel_bfd);
1066 printf("No relocations in code!\n");
1068 /* Fill in the binflt_flat header */
1069 memcpy(hdr.magic,"bFLT",4);
1070 hdr.rev = htonl(FLAT_VERSION);
1071 hdr.entry = htonl(16 * 4 + bfd_get_start_address(abs_bfd));
1072 hdr.data_start = htonl(16 * 4 + text_len);
1073 hdr.data_end = htonl(16 * 4 + text_len + data_len);
1074 hdr.bss_end = htonl(16 * 4 + text_len + data_len + bss_len);
1075 hdr.stack_size = htonl(stack); /* FIXME */
1076 hdr.reloc_start = htonl(16 * 4 + text_len + data_len);
1077 hdr.reloc_count = htonl(reloc_len);
1079 | (load_to_ram ? FLAT_FLAG_RAM : 0)
1080 | (pic_with_got ? FLAT_FLAG_GOTPIC : 0)
1081 | (compress ? (compress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
1083 hdr.build_date = htonl((unsigned long)time(NULL));
1084 bzero(hdr.filler, sizeof(hdr.filler));
1086 for (i=0; i<reloc_len; i++) reloc[i] = htonl(reloc[i]);
1089 printf("SIZE: .text=0x%04x, .data=0x%04x, .bss=0x%04x",
1090 text_len, data_len, bss_len);
1092 printf(", relocs=0x%04x", reloc_len);
1097 ofile = malloc(strlen(fname) + 5 + 1); /* 5 to add suffix */
1098 strcpy(ofile, fname);
1099 strcat(ofile, ".bflt");
1102 if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0) {
1103 fprintf (stderr, "Can't open output file %s\n", ofile);
1107 write(fd, &hdr, sizeof(hdr));
1111 * get the compression command ready
1113 sprintf(cmd, "gzip -f -9 >> %s", ofile);
1115 #define START_COMPRESSOR do { \
1116 if (gf) fclose(gf); \
1117 if (!(gf = popen(cmd, "w"))) { \
1118 fprintf(stderr, "Can't run cmd %s\n", cmd); \
1123 gf = fopen(ofile, "a");
1125 fprintf(stderr, "Can't opne file %s for writing\n", ofile); \
1132 fwrite(text, text_len, 1, gf);
1137 fwrite(data, data_len, 1, gf);
1139 fwrite(reloc, reloc_len*4, 1, gf);