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) 2001, arm/arm-pic/arm-big-endian support <davidm@snapgear.com>
10 * (c) 2001, v850 changes, Mile Bader <miles@lsi.nec.co.jp>
11 * (c) 2001, zflat support <davidm@snapgear.com>
12 * (c) 2001, Changes for GOT entries
13 * (Pale Dale, pauli@lineo.com, David McCullough davidm@lineo.com)
15 * Now supports PIC with GOT tables. This works by taking a '.elf' file
16 * and a fully linked elf executable (at address 0) and produces a flat
17 * file that can be loaded with some fixups. It still supports the old
18 * style fully relocatable elf format files.
20 * Originally obj-res.c
22 * (c) 1998, Kenneth Albanowski <kjahds@kjahds.com>
23 * (c) 1998, D. Jeff Dionne
24 * (c) 1998, The Silver Hammer Group Ltd.
25 * (c) 1996, 1997 Dionne & Associates
26 * jeff@ryeham.ee.ryerson.ca
28 * This is Free Software, under the GNU Public Licence v2 or greater.
30 * Relocation added March 1997, Kresten Krab Thorup
31 * krab@california.daimi.aau.dk
34 #include <stdio.h> /* Userland pieces of the ANSI C standard I/O package */
35 #include <stdlib.h> /* Userland prototypes of the ANSI C std lib functions */
36 #include <stdarg.h> /* Allows va_list to exist in the these namespaces */
37 #include <string.h> /* Userland prototypes of the string handling funcs */
39 #include <unistd.h> /* Userland prototypes of the Unix std system calls */
40 #include <fcntl.h> /* Flag value for file handling functions */
43 #include <netinet/in.h> /* Consts and structs defined by the internet system */
45 /* from $(INSTALLDIR)/include */
46 #include <bfd.h> /* Main header file for the BFD library */
48 #include <elf.h> /* TARGET_* ELF support for the BFD library */
50 /* from uClinux-x.x.x/include/linux */
51 #include "flat.h" /* Binary flat header description */
58 #if defined(TARGET_m68k)
59 #define ARCH "m68k/coldfire"
60 #elif defined(TARGET_arm)
62 #elif defined(TARGET_sparc)
64 #elif defined(TARGET_v850)
67 #error "Don't know how to support your CPU architecture??"
71 * Define a maximum number of bytes allowed in the offset table.
72 * We'll fail if the table is larger than this.
74 * This limit may be different for platforms other than m68k, but
75 * 8000 entries is a lot, trust me :-) (davidm)
77 #define GOT_LIMIT 32767
84 int verbose = 0; /* extra output when running */
85 int pic_with_got = 0; /* do elf/got processing with PIC code */
86 int load_to_ram = 0; /* instruct loader to allocate everything into RAM */
87 int compress = 0; /* 1 = compress everything, 2 = compress data only */
88 int use_resolved = 0; /* If true, get the value of symbol references from */
89 /* the program contents, not from the relocation table. */
90 /* In this case, the input ELF file must be already */
91 /* fully resolved (using the `-q' flag with recent */
92 /* versions of GNU ld will give you a fully resolved */
93 /* output file with relocation entries). */
95 const char *progname, *filename;
101 static char where[200];
104 /* Use exactly one of these: */
105 E_NOFILE = 0, /* "progname: " */
106 E_FILE = 1, /* "filename: " */
107 E_FILELINE = 2, /* "filename:lineno: " */
108 E_FILEWHERE = 3, /* "filename:%s: " -- set %s with ewhere() */
110 /* Add in any of these with |': */
115 void ewhere (const char *format, ...);
116 void einfo (int type, const char *format, ...);
120 ewhere (const char *format, ...) {
122 va_start (args, format);
123 vsprintf (where, format, args);
129 einfo (int type, const char *format, ...) {
132 switch (type & 0x0f) {
134 fprintf (stderr, "%s: ", progname);
137 fprintf (stderr, "%s: ", filename);
140 ewhere ("%d", lineno);
143 fprintf (stderr, "%s:%s: ", filename, where);
147 if (type & E_WARNING) {
148 fprintf (stderr, "warning: ");
154 va_start (args, format);
155 vfprintf (stderr, format, args);
161 fprintf (stderr, "\n");
166 get_symbols (bfd *abfd, long *num)
169 asymbol **symbol_table;
170 long number_of_symbols;
172 storage_needed = bfd_get_symtab_upper_bound (abfd);
174 if (storage_needed < 0)
177 if (storage_needed == 0)
180 symbol_table = (asymbol **) malloc (storage_needed);
182 number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
184 if (number_of_symbols < 0)
187 *num = number_of_symbols;
194 dump_symbols(asymbol **symbol_table, long number_of_symbols)
197 printf("SYMBOL TABLE:\n");
198 for (i=0; i<number_of_symbols; i++) {
199 printf(" NAME=%s VALUE=0x%x\n", symbol_table[i]->name,
200 symbol_table[i]->value);
209 get_symbol_offset(char *name, asection *sec, asymbol **symbol_table, long number_of_symbols)
212 for (i=0; i<number_of_symbols; i++) {
213 if (symbol_table[i]->section == sec) {
214 if (!strcmp(symbol_table[i]->name, name)) {
215 return symbol_table[i]->value;
225 add_com_to_bss(asymbol **symbol_table, long number_of_symbols, long bss_len)
231 for (i=0; i<number_of_symbols; i++) {
232 if (strcmp("*COM*", symbol_table[i]->section->name) == 0) {
233 offset = bss_len + comsize;
234 comsize += symbol_table[i]->value;
235 symbol_table[i]->value = offset;
247 int number_of_symbols,
248 unsigned long *n_relocs,
249 unsigned char *text, int text_len, unsigned char *data, int data_len,
252 unsigned long *flat_relocs;
253 asection *a, *sym_section, *r;
254 arelent **relpp, **p, *q;
255 const char *sym_name, *section_name;
256 unsigned char *sectionp;
257 unsigned long pflags;
259 long sym_addr, sym_vma, section_vma;
260 int relsize, relcount;
261 int flat_reloc_count;
262 int sym_reloc_size, rc;
268 printf("%s(%d): output_relocs(abs_bfd=%d,synbols=%x,number_of_symbols=%d"
269 "n_relocs=%x,text=%x,text_len=%d,data=%x,data_len=%d)\n",
270 __FILE__, __LINE__, abs_bfd, symbols, number_of_symbols, n_relocs,
271 text, text_len, data, data_len);
275 dump_symbols(symbols, number_of_symbols);
280 flat_reloc_count = 0;
284 /* Determine how big our offset table is in bytes.
285 * This isn't too difficult as we've terminated the table with -1.
286 * Also note that both the relocatable and absolute versions have this
287 * terminator even though the relocatable one doesn't have the GOT!
290 unsigned long *lp = (unsigned long *)data;
291 /* Should call ntohl(*lp) here but is isn't going to matter */
292 while (*lp != 0xffffffff) lp++;
293 got_size = ((unsigned char *)lp) - data;
295 printf("GOT table contains %d entries (%d bytes)\n",
296 got_size/sizeof(unsigned long), got_size);
297 if (got_size > GOT_LIMIT) {
298 fprintf(stderr, "GOT too large: %d bytes (limit = %d bytes)\n",
299 got_size, GOT_LIMIT);
304 for (a = abs_bfd->sections; (a != (asection *) NULL); a = a->next) {
305 section_vma = bfd_section_vma(abs_bfd, a);
308 printf("SECTION: %s [%x]: flags=%x vma=%x\n", a->name, a,
309 a->flags, section_vma);
311 // if (bfd_is_abs_section(a))
313 if (bfd_is_und_section(a))
315 if (bfd_is_com_section(a))
317 // if ((a->flags & SEC_RELOC) == 0)
321 * Only relocate things in the data sections if we are PIC/GOT.
322 * otherwise do text as well
324 if (!pic_with_got && strcmp(".text", a->name) == 0)
326 else if (strcmp(".data", a->name) == 0)
331 /* Now search for the equivalent section in the relocation binary
332 * and use that relocation information to build reloc entries
335 for (r=rel_bfd->sections; r != NULL; r=r->next)
336 if (strcmp(a->name, r->name) == 0)
341 printf(" RELOCS: %s [%x]: flags=%x vma=%x\n", r->name, r,
342 r->flags, bfd_section_vma(abs_bfd, r));
343 if ((r->flags & SEC_RELOC) == 0)
345 relsize = bfd_get_reloc_upper_bound(rel_bfd, r);
348 printf("%s(%d): no relocation entries section=%x\n",
349 __FILE__, __LINE__, r->name);
353 symb = get_symbols(rel_bfd, &nsymb);
354 relpp = (arelent **) xmalloc(relsize);
355 relcount = bfd_canonicalize_reloc(rel_bfd, r, relpp, symb);
358 printf("%s(%d): no relocation entries section=%s\n",
359 __FILE__, __LINE__, r->name);
362 for (p = relpp; (relcount && (*p != NULL)); p++, relcount--) {
363 int relocation_needed = 0;
366 /* Skip this relocation entirely if possible (we
367 do this early, before doing any other
368 processing on it). */
369 switch ((*p)->howto->type) {
370 #ifdef R_V850_9_PCREL
373 #ifdef R_V850_22_PCREL
374 case R_V850_22_PCREL:
376 #ifdef R_V850_SDA_16_16_OFFSET
377 case R_V850_SDA_16_16_OFFSET:
379 #ifdef R_V850_SDA_15_16_OFFSET
380 case R_V850_SDA_15_16_OFFSET:
382 #ifdef R_V850_ZDA_15_16_OFFSET
383 case R_V850_ZDA_15_16_OFFSET:
385 #ifdef R_V850_TDA_6_8_OFFSET
386 case R_V850_TDA_6_8_OFFSET:
388 #ifdef R_V850_TDA_7_8_OFFSET
389 case R_V850_TDA_7_8_OFFSET:
391 #ifdef R_V850_TDA_7_7_OFFSET
392 case R_V850_TDA_7_7_OFFSET:
394 #ifdef R_V850_TDA_16_16_OFFSET
395 case R_V850_TDA_16_16_OFFSET:
397 #ifdef R_V850_TDA_4_5_OFFSET
398 case R_V850_TDA_4_5_OFFSET:
400 #ifdef R_V850_TDA_4_4_OFFSET
401 case R_V850_TDA_4_4_OFFSET:
403 #ifdef R_V850_SDA_16_16_SPLIT_OFFSET
404 case R_V850_SDA_16_16_SPLIT_OFFSET:
406 #ifdef R_V850_CALLT_6_7_OFFSET
407 case R_V850_CALLT_6_7_OFFSET:
409 #ifdef R_V850_CALLT_16_16_OFFSET
410 case R_V850_CALLT_16_16_OFFSET:
412 /* These are relative relocations, which
413 have already been fixed up by the
414 linker at this point, so just ignore
418 #endif /* USE_V850_RELOCS */
421 if (q->sym_ptr_ptr && *q->sym_ptr_ptr) {
422 sym_name = (*(q->sym_ptr_ptr))->name;
423 sym_section = (*(q->sym_ptr_ptr))->section;
424 section_name=(*(q->sym_ptr_ptr))->section->name;
426 printf("ERROR: undefined relocation entry\n");
430 /* Adjust the address to account for the GOT table which wasn't
431 * present in the relative file link.
434 q->address += got_size;
437 * Fixup offset in the actual section.
440 if ((sym_addr = get_symbol_offset((char *) sym_name,
441 sym_section, symbols, number_of_symbols)) == -1) {
446 /* Use the address of the symbol already in
448 sym_addr = *((unsigned long *)
449 (sectionp + q->address));
450 relocation_needed = 1;
452 /* Calculate the sym address ourselves. */
453 sym_reloc_size = bfd_get_reloc_size(q->howto);
454 if (sym_reloc_size != 4) {
455 printf("ERROR: bad reloc size=%d for symbol=%s\n",
456 sym_reloc_size, sym_name);
461 switch ((*p)->howto->type) {
463 #if defined(TARGET_m68k)
465 relocation_needed = 1;
466 sym_vma = bfd_section_vma(abs_bfd, sym_section);
467 sym_addr += sym_vma + q->addend;
471 sym_addr += sym_vma + q->addend;
472 sym_addr -= q->address;
476 #if defined(TARGET_arm)
478 relocation_needed = 1;
481 "%s vma=0x%x, value=0x%x, address=0x%x "
482 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
484 sym_vma, (*(q->sym_ptr_ptr))->value,
485 q->address, sym_addr,
486 (*p)->howto->rightshift,
487 *((unsigned long *) (sectionp + q->address)));
488 sym_vma = bfd_section_vma(abs_bfd, sym_section);
489 sym_addr += sym_vma + q->addend;
494 "%s vma=0x%x, value=0x%x, address=0x%x "
495 "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
497 sym_vma, (*(q->sym_ptr_ptr))->value,
498 q->address, sym_addr,
499 (*p)->howto->rightshift,
500 *((unsigned long *) (sectionp + q->address)));
503 sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift;
509 relocation_needed = 1;
510 sym_vma = bfd_section_vma(abs_bfd, sym_section);
511 sym_addr += sym_vma + q->addend;
513 #if defined(R_V850_ZDA_16_16_OFFSET) || defined(R_V850_ZDA_16_16_SPLIT_OFFSET)
514 #ifdef R_V850_ZDA_16_16_OFFSET
515 case R_V850_ZDA_16_16_OFFSET:
517 #ifdef R_V850_ZDA_16_16_SPLIT_OFFSET
518 case R_V850_ZDA_16_16_SPLIT_OFFSET:
520 /* Can't support zero-relocations. */
521 printf ("ERROR: %s+0x%x: zero relocations not supported\n",
522 sym_name, q->addend);
524 #endif /* R_V850_ZDA_16_16_OFFSET || R_V850_ZDA_16_16_SPLIT_OFFSET */
525 #endif /* TARGET_v850 */
530 relocation_needed = 1;
531 sym_vma = bfd_section_vma(abs_bfd, sym_section);
532 sym_addr += sym_vma + q->addend;
536 sym_addr += sym_vma + q->addend;
537 sym_addr -= q->address;
539 case R_SPARC_WDISP30:
540 sym_addr = (((*(q->sym_ptr_ptr))->value-
541 q->address) >> 2) & 0x3fffffff;
542 sym_addr |= (ntohl(*((unsigned long *) (sectionp + q->address))) & 0xc0000000);
545 relocation_needed = 1;
547 sym_vma = bfd_section_vma(abs_bfd, sym_section);
548 sym_addr += sym_vma + q->addend;
549 sym_addr |= (htonl(*((unsigned long *) (sectionp + q->address))) & 0xffc00000);
552 relocation_needed = 1;
554 sym_vma = bfd_section_vma(abs_bfd, sym_section);
555 sym_addr += sym_vma + q->addend;
556 sym_addr &= 0x000003ff;
557 sym_addr |= (htonl(*((unsigned long *) (sectionp + q->address))) & 0xfffffc00);
559 #endif /* TARGET_sparc */
562 /* missing support for other types of relocs */
563 printf("ERROR: bad reloc type %d\n", (*p)->howto->type);
568 sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
569 bfd_section_vma(abs_bfd, sym_section));
573 * for full elf relocation we have to write back the start_code
574 * relative value to use.
577 #if defined(TARGET_arm)
586 * horrible nasty hack to support different endianess
588 if (!bfd_big_endian(abs_bfd)) {
600 tmp.l = *((unsigned long *) (sectionp + q->address));
601 hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16);
602 if (((*p)->howto->type != R_ARM_PC24) &&
603 ((*p)->howto->type != R_ARM_PLT32))
604 hl |= (tmp.c[i3] << 24);
605 else if (tmp.c[i2] & 0x80)
606 hl |= 0xff000000; /* sign extend */
608 tmp.c[i0] = hl & 0xff;
609 tmp.c[i1] = (hl >> 8) & 0xff;
610 tmp.c[i2] = (hl >> 16) & 0xff;
611 if (((*p)->howto->type != R_ARM_PC24) &&
612 ((*p)->howto->type != R_ARM_PLT32))
613 tmp.c[i3] = (hl >> 24) & 0xff;
614 if ((*p)->howto->type == R_ARM_ABS32)
615 *((unsigned long *) (sectionp + q->address)) = htonl(hl);
617 *((unsigned long *) (sectionp + q->address)) = tmp.l;
618 #else /* ! TARGET_arm */
619 *((unsigned long *) (sectionp + q->address)) = htonl(sym_addr);
624 printf(" RELOC[%d]: offset=%x symbol=%s%s "
625 "section=%s size=%d "
626 "fixup=%x (reloc=0x%x)\n", flat_reloc_count,
627 q->address, sym_name, addstr,
628 section_name, sym_reloc_size,
629 sym_addr, section_vma + q->address);
632 * Create relocation entry (PC relative doesn't need this).
634 if (relocation_needed) {
635 flat_relocs = realloc(flat_relocs,
636 (flat_reloc_count + 1) * sizeof(unsigned long));
637 flat_relocs[flat_reloc_count] = pflags |
638 (section_vma + q->address);
641 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
642 section_vma + q->address);
644 relocation_needed = 0;
649 printf("%s(%d): symbol name=%s address=%x section=%s -> RELOC=%x\n",
650 __FILE__, __LINE__, sym_name, q->address, section_name,
651 flat_relocs[flat_reloc_count]);
660 *n_relocs = flat_reloc_count;
667 /* shared lib symbols stuff */
670 get_symbol(char *name, asection *sec, asymbol **symbol_table, long number_of_symbols)
673 for (i=0; i<number_of_symbols; i++) {
674 if (symbol_table[i]->section == sec) {
675 if (!strcmp(symbol_table[i]->name, name)) {
676 return symbol_table[i]->value;
684 output_offset_table(int fd, char *ename, bfd *abfd, asymbol **symbol_table, long number_of_symbols)
695 signed short *tab = malloc(32768); /* we don't know how many yet*/
697 asection *text_section = bfd_get_section_by_name (abfd, ".text");
699 if (!(ef = fopen(ename, "r"))) {
700 fprintf (stderr,"Can't open %s\n",ename);
704 fgets(libname, 80, ef);
706 if (number_of_symbols < 0) {
707 fprintf (stderr,"Corrupt symbol table!\n");
711 if ((etext_addr = get_symbol("etext",
714 number_of_symbols)) == -1) {
715 fprintf (stderr,"Can't find the symbol etext\n");
721 buf[strlen(buf)-1] = 0; /* Arrrgh! linefeeds */
723 if ((sym_addr = get_symbol(buf,
726 number_of_symbols)) == -1) {
727 fprintf (stderr,"Can't find the symbol %s\n",buf);
730 tab[++count] = htons(sym_addr - etext_addr);
738 fprintf (stderr,"*** %d symbols not found\n",foobar);
742 strcpy((char *)&tab[++count],libname);
743 tab[0] = htons(count * 2);
744 write(fd, tab, count * 2 + strlen(libname) + 2);
750 static char * program;
752 static void usage(void)
754 fprintf(stderr, "Usage: %s [vrzd] [-p <abs-pic-file>] [-s stack-size] "
755 "[-o <output-file>] <elf-file>\n\n"
756 " -v : verbose operation\n"
757 " -r : force load to RAM\n"
758 " -z : compress code/data/relocs\n"
759 " -d : compress data/relocs\n"
760 " -a : use existing symbol references\n"
761 " instead of recalculating from\n"
763 " -p abs-pic-file : GOT/PIC processing with files\n"
764 " -s stacksize : set application stack size\n"
765 " -o output-file : output file name\n\n",
767 fprintf(stderr, "Compiled for " ARCH " architecture\n\n");
773 int main(int argc, char *argv[])
776 bfd *rel_bfd, *abs_bfd;
778 char *ofile=NULL, *pfile=NULL;
787 asymbol **symbol_table;
788 long number_of_symbols;
790 unsigned long data_len;
791 unsigned long bss_len;
792 unsigned long text_len;
793 unsigned long reloc_len;
795 unsigned long data_vma;
796 unsigned long bss_vma;
797 unsigned long text_vma;
801 unsigned long *reloc;
814 while ((opt = getopt(argc, argv, "avzdrp:s:o:")) != -1) {
838 stack = atoi(optarg);
841 fprintf(stderr, "%s Unknown option\n", argv[0]);
848 * if neither the -r or -p options was given, default to
849 * a RAM load as that is the only option that makes sense.
851 if (!load_to_ram && !pfile)
854 filename = fname = argv[argc-1];
856 if (!(rel_bfd = bfd_openr(fname, 0))) {
857 fprintf(stderr, "Can't open %s\n", fname);
861 if (bfd_check_format (rel_bfd, bfd_object) == 0) {
862 fprintf(stderr, "File is not an object file\n");
869 if (!(abs_bfd = bfd_openr(pfile, 0))) {
870 fprintf(stderr, "Can't open %s\n", pfile);
874 if (bfd_check_format (abs_bfd, bfd_object) == 0) {
875 fprintf(stderr, "File is not an object file\n");
879 abs_bfd = rel_bfd; /* one file does all */
882 if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC)) {
883 fprintf (stderr, "%s: Input file contains no relocation info\n", fname);
887 if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P)) {
888 /* `Absolute' file is not absolute, so neither are address
889 contained therein. */
891 "%s: `-a' option specified with non-fully-resolved input file\n",
892 bfd_get_filename (abs_bfd));
896 symbol_table = get_symbols(abs_bfd, &number_of_symbols);
898 s = bfd_get_section_by_name (abs_bfd, ".text");
900 text_len = s->_raw_size;
901 text = malloc(text_len);
904 printf("TEXT -> vma=%x len=%x\n", text_vma, text_len);
905 printf(" lma=%x clen=%x oo=%x ap=%x fp=%x\n",
906 s->lma, s->_cooked_size, s->output_offset,
907 s->alignment_power, s->filepos);
910 if (bfd_get_section_contents(abs_bfd,
914 s->_raw_size) == false) {
915 fprintf(stderr, "read error section %s\n", s->name);
919 s = bfd_get_section_by_name (abs_bfd, ".data");
921 data_len = s->_raw_size;
922 data = malloc(data_len);
925 printf("DATA -> vma=%x len=%x\n", data_vma, data_len);
926 printf(" lma=%x clen=%x oo=%x ap=%x fp=%x\n",
927 s->lma, s->_cooked_size, s->output_offset,
928 s->alignment_power, s->filepos);
930 if ((text_vma + text_len) != data_vma) {
931 if ((text_vma + text_len) > data_vma) {
932 printf("ERROR: text=%x overlaps data=%x ?\n", text_len, data_vma);
936 printf("WARNING: data=%x does not directly follow text=%x\n",
938 text_len = data_vma - text_vma;
941 if (bfd_get_section_contents(abs_bfd,
945 s->_raw_size) == false) {
946 fprintf(stderr, "read error section %s\n", s->name);
950 s = bfd_get_section_by_name (abs_bfd, ".bss");
951 bss_len = s->_raw_size;
953 bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len);
956 printf("BSS -> vma=%x len=%x\n", bss_vma, bss_len);
957 printf(" lma=%x clen=%x oo=%x ap=%x fp=%x\n",
958 s->lma, s->_cooked_size, s->output_offset,
959 s->alignment_power, s->filepos);
962 if ((text_vma + text_len + data_len) != bss_vma) {
963 if ((text_vma + text_len + data_len) > bss_vma) {
964 printf("ERROR: text=%x + data=%x overlaps bss=%x ?\n", text_len,
969 printf("WARNING: bss=%x does not directly follow text=%x + data=%x(%x)\n",
970 bss_vma, text_len, data_len, text_len + data_len);
971 data_len = bss_vma - data_vma;
974 reloc = (unsigned long *) output_relocs (abs_bfd, symbol_table,
975 number_of_symbols, &reloc_len, text, text_len, data, data_len, rel_bfd);
978 printf("No relocations in code!\n");
980 /* Fill in the binflt_flat header */
981 memcpy(hdr.magic,"bFLT",4);
982 hdr.rev = htonl(FLAT_VERSION);
983 hdr.entry = htonl(16 * 4 + bfd_get_start_address(abs_bfd));
984 hdr.data_start = htonl(16 * 4 + text_len);
985 hdr.data_end = htonl(16 * 4 + text_len + data_len);
986 hdr.bss_end = htonl(16 * 4 + text_len + data_len + bss_len);
987 hdr.stack_size = htonl(stack); /* FIXME */
988 hdr.reloc_start = htonl(16 * 4 + text_len + data_len);
989 hdr.reloc_count = htonl(reloc_len);
991 | (load_to_ram ? FLAT_FLAG_RAM : 0)
992 | (pic_with_got ? FLAT_FLAG_GOTPIC : 0)
993 | (compress ? (compress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
995 hdr.build_date = htonl((unsigned long)time(NULL));
996 bzero(hdr.filler, sizeof(hdr.filler));
998 for (i=0; i<reloc_len; i++) reloc[i] = htonl(reloc[i]);
1001 printf("SIZE: .text=0x%04x, .data=0x%04x, .bss=0x%04x",
1002 text_len, data_len, bss_len);
1004 printf(", relocs=0x%04x", reloc_len);
1009 ofile = malloc(strlen(fname) + 5 + 1); /* 5 to add suffix */
1010 strcpy(ofile, fname);
1011 strcat(ofile, ".bflt");
1014 if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0) {
1015 fprintf (stderr, "Can't open output file %s\n", ofile);
1019 write(fd, &hdr, sizeof(hdr));
1023 * get the compression command ready
1025 sprintf(cmd, "gzip -f -9 >> %s", ofile);
1027 #define START_COMPRESSOR do { \
1028 if (gf) fclose(gf); \
1029 if (!(gf = popen(cmd, "w"))) { \
1030 fprintf(stderr, "Can't run cmd %s\n", cmd); \
1035 gf = fopen(ofile, "a");
1037 fprintf(stderr, "Can't opne file %s for writing\n", ofile); \
1044 fwrite(text, text_len, 1, gf);
1049 fwrite(data, data_len, 1, gf);
1051 fwrite(reloc, reloc_len*4, 1, gf);