OSDN Git Service

Make varargs debug macros GCC-2.x compatible.
[uclinux-h8/elf2flt.git] / elf2flt.c
1 /*
2  * elf2flt.c: Convert ELF (or any BFD format) to FLAT binary format
3  *
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.
8  *
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>
20  *
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.
25  *
26  * Originally obj-res.c
27  *
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>
32  *
33  * This is Free Software, under the GNU Public Licence v2 or greater.
34  *
35  * Relocation added March 1997, Kresten Krab Thorup 
36  * krab@california.daimi.aau.dk
37  */
38  
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
48 /* from $(INSTALLDIR)/include       */
49 #include <bfd.h>      /* Main header file for the BFD library                */
50 #include <libiberty.h>
51
52 #include "stubs.h"
53 const char *elf2flt_progname;
54
55 #if defined(TARGET_h8300)
56 #include <elf/h8.h>      /* TARGET_* ELF support for the BFD library            */
57 #elif defined(__CYGWIN__) || defined(__MINGW32__) || defined(TARGET_nios) || defined(TARGET_nios2)
58 #include "cygwin-elf.h" /* Cygwin uses a local copy */
59 #elif defined(TARGET_microblaze)
60 #include <elf/microblaze.h>     /* TARGET_* ELF support for the BFD library */
61 #else
62 #include <elf.h>      /* TARGET_* ELF support for the BFD library            */
63 #endif
64
65 /* Always include Blackfin-specific defines in addition to common ELF stuff
66  * above as the common elf headers often do not have our relocs.
67  */
68 #if defined(TARGET_bfin) && !defined(R_BFIN_RIMM16)
69 #include "elf/bfin.h"
70 #endif
71
72 #if defined(__MINGW32__)
73 #include <getopt.h>
74 #endif
75
76 /* from uClinux-x.x.x/include/linux */
77 #include "flat.h"     /* Binary flat header description                      */
78 #include "compress.h"
79
80 #ifdef TARGET_e1
81 #include <e1.h>
82 #endif
83
84 #ifdef TARGET_v850e
85 #define TARGET_v850
86 #endif
87
88 #if defined(TARGET_m68k)
89 #define ARCH    "m68k/coldfire"
90 #elif defined(TARGET_arm)
91 #define ARCH    "arm"
92 #elif defined(TARGET_sparc)
93 #define ARCH    "sparc"
94 #elif defined(TARGET_v850)
95 #define ARCH    "v850"
96 #elif defined(TARGET_sh)
97 #define ARCH    "sh"
98 #elif defined(TARGET_h8300)
99 #define ARCH    "h8300"
100 #elif defined(TARGET_microblaze)
101 #define ARCH    "microblaze"
102 #elif defined(TARGET_e1)
103 #define ARCH    "e1-coff"
104 #elif defined(TARGET_bfin)
105 #define ARCH    "bfin"
106 #elif defined(TARGET_nios)
107 #define ARCH    "nios"
108 #elif defined(TARGET_nios2)
109 #define ARCH    "nios2"
110 #else
111 #error "Don't know how to support your CPU architecture??"
112 #endif
113
114 #if defined(TARGET_m68k) || defined(TARGET_h8300) || defined(TARGET_bfin)
115 /*
116  * Define a maximum number of bytes allowed in the offset table.
117  * We'll fail if the table is larger than this.
118  *
119  * This limit may be different for platforms other than m68k, but
120  * 8000 entries is a lot,  trust me :-) (davidm)
121  */
122 #define GOT_LIMIT 32767
123 /*
124  * we have to mask out the shared library id here and there,  this gives
125  * us the real address bits when needed
126  */
127 #define real_address_bits(x)    (pic_with_got ? ((x) & 0xffffff) : (x))
128 #else
129 #define real_address_bits(x)    (x)
130 #endif
131
132 #ifndef O_BINARY
133 #define O_BINARY 0
134 #endif
135
136
137 int verbose = 0;      /* extra output when running */
138 int pic_with_got = 0; /* do elf/got processing with PIC code */
139 int load_to_ram = 0;  /* instruct loader to allocate everything into RAM */
140 int ktrace = 0;       /* instruct loader output kernel trace on load */
141 int docompress = 0;   /* 1 = compress everything, 2 = compress data only */
142 int use_resolved = 0; /* If true, get the value of symbol references from */
143                       /* the program contents, not from the relocation table. */
144                       /* In this case, the input ELF file must be already */
145                       /* fully resolved (using the `-q' flag with recent */
146                       /* versions of GNU ld will give you a fully resolved */
147                       /* output file with relocation entries).  */
148
149 /* Set if the text section contains any relocations.  If it does, we must
150    set the load_to_ram flag.  */
151 int text_has_relocs = 0;
152
153 asymbol**
154 get_symbols (bfd *abfd, long *num)
155 {
156   int32_t storage_needed;
157   asymbol **symbol_table;
158   long number_of_symbols;
159   
160   storage_needed = bfd_get_symtab_upper_bound (abfd);
161           
162   if (storage_needed < 0)
163     abort ();
164       
165   if (storage_needed == 0)
166     return NULL;
167
168   symbol_table = xmalloc (storage_needed);
169
170   number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
171   
172   if (number_of_symbols < 0) 
173     abort ();
174
175   *num = number_of_symbols;
176   return symbol_table;
177 }
178
179
180
181 int
182 dump_symbols(asymbol **symbol_table, long number_of_symbols)
183 {
184   long i;
185   printf("SYMBOL TABLE:\n");
186   for (i=0; i<number_of_symbols; i++) {
187         printf("  NAME=%s  VALUE=0x%x\n", symbol_table[i]->name,
188                 symbol_table[i]->value);
189   }
190   printf("\n");
191   return(0);
192 }  
193
194
195
196 long
197 get_symbol_offset(char *name, asection *sec, asymbol **symbol_table, long number_of_symbols)
198 {
199   long i;
200   for (i=0; i<number_of_symbols; i++) {
201     if (symbol_table[i]->section == sec) {
202       if (!strcmp(symbol_table[i]->name, name)) {
203         return symbol_table[i]->value;
204       }
205     }
206   }
207   return -1;
208 }  
209
210
211
212 #ifdef TARGET_nios2
213 long
214 get_gp_value(asymbol **symbol_table, long number_of_symbols)
215 {
216   long i;
217   for (i=0; i<number_of_symbols; i++) {
218       if (!strcmp(symbol_table[i]->name, "_gp"))
219                 return symbol_table[i]->value;
220   }
221   return -1;
222 }
223 #endif
224
225
226
227 int32_t
228 add_com_to_bss(asymbol **symbol_table, int32_t number_of_symbols, int32_t bss_len)
229 {
230   int32_t i, comsize;
231   int32_t offset;
232
233   comsize = 0;
234   for (i=0; i<number_of_symbols; i++) {
235     if (strcmp("*COM*", symbol_table[i]->section->name) == 0) {
236       offset = bss_len + comsize;
237       comsize += symbol_table[i]->value;
238       symbol_table[i]->value = offset;
239     }
240   }
241   return comsize;
242 }  
243
244 #ifdef TARGET_bfin
245 /* FUNCTION : weak_und_symbol
246    ABSTRACT : return true if symbol is weak and undefined.
247 */
248 static int
249 weak_und_symbol(const char *reloc_section_name,
250                 struct bfd_symbol *symbol)
251 {
252     if (!(strstr (reloc_section_name, "text")
253           || strstr (reloc_section_name, "data")
254           || strstr (reloc_section_name, "bss"))) {
255         if (symbol->flags & BSF_WEAK) {
256 #ifdef DEBUG_BFIN
257             fprintf(stderr, "found weak undefined symbol %s\n", symbol->name);
258 #endif
259             return TRUE;
260         }
261     }
262     return FALSE;
263 }
264
265 static int
266 bfin_set_reloc (uint32_t *reloc,
267                 const char *reloc_section_name,
268                 const char *sym_name,
269                 struct bfd_symbol *symbol,
270                 int sp, int32_t offset)
271 {
272     unsigned int type = 0;
273     uint32_t val;
274
275     if (strstr (reloc_section_name, "stack")) {
276             if (verbose)
277                     printf ("Stack-relative reloc, offset %08lx\n", offset);
278             /* This must be a stack_start reloc for stack checking.  */
279             type = 1;
280     }
281     val = (offset & ((1 << 26) - 1));
282     val |= (sp & (1 << 3) - 1) << 26;
283     val |= type << 29;
284     *reloc = val;
285     return 0;
286 }
287
288 static bfd *compare_relocs_bfd;
289
290 static int
291 compare_relocs (const void *pa, const void *pb)
292 {
293         const arelent *const *a = pa, *const *b = pb;
294         const arelent *ra = *a, *rb = *b;
295         unsigned long va, vb;
296         uint32_t a_vma, b_vma;
297
298         if (!ra->sym_ptr_ptr || !*ra->sym_ptr_ptr)
299                 return -1;
300         else if (!rb->sym_ptr_ptr || !*rb->sym_ptr_ptr)
301                 return 1;
302
303         a_vma = bfd_section_vma(compare_relocs_bfd,
304                                 (*(ra->sym_ptr_ptr))->section);
305         b_vma = bfd_section_vma(compare_relocs_bfd,
306                                 (*(rb->sym_ptr_ptr))->section);
307         va = (*(ra->sym_ptr_ptr))->value + a_vma + ra->addend;
308         vb = (*(rb->sym_ptr_ptr))->value + b_vma + rb->addend;
309         return va - vb;
310 }
311 #endif
312
313 uint32_t *
314 output_relocs (
315   bfd *abs_bfd,
316   asymbol **symbols,
317   int number_of_symbols,
318   uint32_t *n_relocs,
319   unsigned char *text, int text_len, uint32_t text_vma,
320   unsigned char *data, int data_len, uint32_t data_vma,
321   bfd *rel_bfd)
322 {
323   uint32_t              *flat_relocs;
324   asection              *a, *sym_section, *r;
325   arelent               **relpp, **p, *q;
326   const char            *sym_name, *section_name;
327   unsigned char         *sectionp;
328   unsigned long         pflags;
329   char                  addstr[16];
330   uint32_t              sym_addr, sym_vma, section_vma;
331   int                   relsize, relcount;
332   int                   flat_reloc_count;
333   int                   sym_reloc_size, rc;
334   int                   got_size = 0;
335   int                   bad_relocs = 0;
336   asymbol               **symb;
337   long                  nsymb;
338 #ifdef TARGET_bfin
339   unsigned long         persistent_data = 0;
340 #endif
341   
342 #if 0
343   printf("%s(%d): output_relocs(abs_bfd=%d,synbols=0x%x,number_of_symbols=%d"
344         "n_relocs=0x%x,text=0x%x,text_len=%d,data=0x%x,data_len=%d)\n",
345         __FILE__, __LINE__, abs_bfd, symbols, number_of_symbols, n_relocs,
346         text, text_len, data, data_len);
347 #endif
348
349 #if 0
350 dump_symbols(symbols, number_of_symbols);
351 #endif
352
353   *n_relocs = 0;
354   flat_relocs = NULL;
355   flat_reloc_count = 0;
356   rc = 0;
357   pflags = 0;
358
359   /* Determine how big our offset table is in bytes.
360    * This isn't too difficult as we've terminated the table with -1.
361    * Also note that both the relocatable and absolute versions have this
362    * terminator even though the relocatable one doesn't have the GOT!
363    */
364   if (pic_with_got && !use_resolved) {
365     uint32_t *lp = (uint32_t *)data;
366     /* Should call ntohl(*lp) here but is isn't going to matter */
367     while (*lp != 0xffffffff) lp++;
368     got_size = ((unsigned char *)lp) - data;
369     if (verbose)
370             printf("GOT table contains %d entries (%d bytes)\n",
371                             got_size/sizeof(uint32_t), got_size);
372 #ifdef TARGET_m68k
373     if (got_size > GOT_LIMIT)
374             fatal("GOT too large: %d bytes (limit = %d bytes)",
375                         got_size, GOT_LIMIT);
376 #endif
377   }
378
379   for (a = abs_bfd->sections; (a != (asection *) NULL); a = a->next) {
380         section_vma = bfd_section_vma(abs_bfd, a);
381
382         if (verbose)
383                 printf("SECTION: %s [0x%x]: flags=0x%x vma=0x%x\n", a->name, a,
384                         a->flags, section_vma);
385
386 //      if (bfd_is_abs_section(a))
387 //              continue;
388         if (bfd_is_und_section(a))
389                 continue;
390         if (bfd_is_com_section(a))
391                 continue;
392 //      if ((a->flags & SEC_RELOC) == 0)
393 //              continue;
394
395         /*
396          *      Only relocate things in the data sections if we are PIC/GOT.
397          *      otherwise do text as well
398          */
399         if (!pic_with_got && (a->flags & SEC_CODE))
400                 sectionp = text + (a->vma - text_vma);
401         else if (a->flags & SEC_DATA)
402                 sectionp = data + (a->vma - data_vma);
403         else
404                 continue;
405
406         /* Now search for the equivalent section in the relocation binary
407          * and use that relocation information to build reloc entries
408          * for this one.
409          */
410         for (r=rel_bfd->sections; r != NULL; r=r->next)
411                 if (strcmp(a->name, r->name) == 0)
412                         break;
413         if (r == NULL)
414           continue;
415         if (verbose)
416           printf(" RELOCS: %s [0x%x]: flags=0x%x vma=0x%x\n", r->name, r,
417                         r->flags, bfd_section_vma(abs_bfd, r));
418         if ((r->flags & SEC_RELOC) == 0)
419           continue;
420         relsize = bfd_get_reloc_upper_bound(rel_bfd, r);
421         if (relsize <= 0) {
422                 if (verbose)
423                         printf("%s(%d): no relocation entries section=0x%x\n",
424                                 __FILE__, __LINE__, r->name);
425                 continue;
426         }
427
428         symb = get_symbols(rel_bfd, &nsymb);
429         relpp = xmalloc(relsize);
430
431         relcount = bfd_canonicalize_reloc(rel_bfd, r, relpp, symb);
432         if (relcount <= 0) {
433                 if (verbose)
434                         printf("%s(%d): no relocation entries section=%s\n",
435                         __FILE__, __LINE__, r->name);
436                 continue;
437         } else {
438 #ifdef TARGET_bfin
439                 compare_relocs_bfd = abs_bfd;
440                 qsort (relpp, relcount, sizeof *relpp, compare_relocs);
441 #endif
442                 for (p = relpp; (relcount && (*p != NULL)); p++, relcount--) {
443                         unsigned char *r_mem;
444                         int relocation_needed = 0;
445
446 #ifdef TARGET_microblaze
447                         /* The MICROBLAZE_XX_NONE relocs can be skipped.
448                            They represent PC relative branches that the
449                            linker has already resolved */
450                                 
451                         switch ((*p)->howto->type) 
452                         {
453                         case R_MICROBLAZE_NONE:
454                         case R_MICROBLAZE_64_NONE:
455                         case R_MICROBLAZE_32_PCREL_LO:
456                                 continue;
457                         }
458 #endif /* TARGET_microblaze */
459
460 #ifdef TARGET_v850
461                         /* Skip this relocation entirely if possible (we
462                            do this early, before doing any other
463                            processing on it).  */
464                         switch ((*p)->howto->type) {
465 #ifdef R_V850_9_PCREL
466                         case R_V850_9_PCREL:
467 #endif
468 #ifdef R_V850_22_PCREL
469                         case R_V850_22_PCREL:
470 #endif
471 #ifdef R_V850_SDA_16_16_OFFSET
472                         case R_V850_SDA_16_16_OFFSET:
473 #endif
474 #ifdef R_V850_SDA_15_16_OFFSET
475                         case R_V850_SDA_15_16_OFFSET:
476 #endif
477 #ifdef R_V850_ZDA_15_16_OFFSET
478                         case R_V850_ZDA_15_16_OFFSET:
479 #endif
480 #ifdef R_V850_TDA_6_8_OFFSET
481                         case R_V850_TDA_6_8_OFFSET:
482 #endif
483 #ifdef R_V850_TDA_7_8_OFFSET
484                         case R_V850_TDA_7_8_OFFSET:
485 #endif
486 #ifdef R_V850_TDA_7_7_OFFSET
487                         case R_V850_TDA_7_7_OFFSET:
488 #endif
489 #ifdef R_V850_TDA_16_16_OFFSET
490                         case R_V850_TDA_16_16_OFFSET:
491 #endif
492 #ifdef R_V850_TDA_4_5_OFFSET
493                         case R_V850_TDA_4_5_OFFSET:
494 #endif
495 #ifdef R_V850_TDA_4_4_OFFSET
496                         case R_V850_TDA_4_4_OFFSET:
497 #endif
498 #ifdef R_V850_SDA_16_16_SPLIT_OFFSET
499                         case R_V850_SDA_16_16_SPLIT_OFFSET:
500 #endif
501 #ifdef R_V850_CALLT_6_7_OFFSET
502                         case R_V850_CALLT_6_7_OFFSET:
503 #endif
504 #ifdef R_V850_CALLT_16_16_OFFSET
505                         case R_V850_CALLT_16_16_OFFSET:
506 #endif
507                                 /* These are relative relocations, which
508                                    have already been fixed up by the
509                                    linker at this point, so just ignore
510                                    them.  */ 
511                                 continue;
512                         }
513 #endif /* USE_V850_RELOCS */
514
515                         q = *p;
516                         if (q->sym_ptr_ptr && *q->sym_ptr_ptr) {
517                                 sym_name = (*(q->sym_ptr_ptr))->name;
518                                 sym_section = (*(q->sym_ptr_ptr))->section;
519                                 section_name=(*(q->sym_ptr_ptr))->section->name;
520                         } else {
521                                 printf("ERROR: undefined relocation entry\n");
522                                 rc = -1;
523                                 continue;
524                         }
525 #ifndef TARGET_bfin
526                         /* Adjust the address to account for the GOT table which wasn't
527                          * present in the relative file link.
528                          */
529                         if (pic_with_got && !use_resolved)
530                           q->address += got_size;
531 #endif
532
533                         /* A pointer to what's being relocated, used often
534                            below.  */
535                         r_mem = sectionp + q->address;
536
537                         /*
538                          *      Fixup offset in the actual section.
539                          */
540                         addstr[0] = 0;
541 #if !defined TARGET_e1 && !defined TARGET_bfin
542                         if ((sym_addr = get_symbol_offset((char *) sym_name,
543                             sym_section, symbols, number_of_symbols)) == -1) {
544                                 sym_addr = 0;
545                         }
546 #else
547                         sym_addr = (*(q->sym_ptr_ptr))->value;
548 #endif                  
549                         if (use_resolved) {
550                                 /* Use the address of the symbol already in
551                                    the program text.  How this is handled may
552                                    still depend on the particular relocation
553                                    though.  */
554                                 switch (q->howto->type) {
555                                         int r2_type;
556 #ifdef TARGET_v850
557                                 case R_V850_HI16_S:
558                                         /* We specially handle adjacent
559                                            HI16_S/ZDA_15_16_OFFSET and
560                                            HI16_S/LO16 pairs that reference the
561                                            same address (these are usually
562                                            movhi/ld and movhi/movea pairs,
563                                            respectively).  */
564                                         if (relcount == 0)
565                                                 r2_type = R_V850_NONE;
566                                         else
567                                                 r2_type = p[1]->howto->type;
568                                         if ((r2_type == R_V850_ZDA_15_16_OFFSET
569                                              || r2_type == R_V850_LO16)
570                                             && (p[0]->sym_ptr_ptr
571                                                 == p[1]->sym_ptr_ptr)
572                                             && (p[0]->addend == p[1]->addend))
573                                         {
574                                                 relocation_needed = 1;
575
576                                                 switch (r2_type) {
577                                                 case R_V850_ZDA_15_16_OFFSET:
578                                                         pflags = 0x10000000;
579                                                         break;
580                                                 case R_V850_LO16:
581                                                         pflags = 0x20000000;
582                                                         break;
583                                                 }
584
585                                                 /* We don't really need the
586                                                    actual value -- the bits
587                                                    produced by the linker are
588                                                    what we want in the final
589                                                    flat file -- but get it
590                                                    anyway if useful for
591                                                    debugging.  */
592                                                 if (verbose) {
593                                                         unsigned char *r2_mem =
594                                                                 sectionp
595                                                                 + p[1]->address;
596                                                         /* little-endian */
597                                                         int hi = r_mem[0]
598                                                                 + (r_mem[1] << 8);
599                                                         int lo = r2_mem[0]
600                                                                 + (r2_mem[1] << 8);
601                                                         /* Sign extend LO.  */
602                                                         lo = (lo ^ 0x8000)
603                                                                 - 0x8000;
604
605                                                         /* Maybe ignore the LSB
606                                                            of LO, which is
607                                                            actually part of the
608                                                            instruction.  */
609                                                         if (r2_type != R_V850_LO16)
610                                                                 lo &= ~1;
611
612                                                         sym_addr =
613                                                                 (hi << 16)
614                                                                 + lo;
615                                                 }
616                                         } else
617                                                 goto bad_resolved_reloc;
618                                         break;
619
620                                 case R_V850_LO16:
621                                         /* See if this is actually the
622                                            2nd half of a pair.  */
623                                         if (p > relpp
624                                             && (p[-1]->howto->type
625                                                 == R_V850_HI16_S)
626                                             && (p[-1]->sym_ptr_ptr
627                                                 == p[0]->sym_ptr_ptr)
628                                             && (p[-1]->addend == p[0]->addend))
629                                                 break; /* not an error */
630                                         else
631                                                 goto bad_resolved_reloc;
632
633                                 case R_V850_HI16:
634                                         goto bad_resolved_reloc;
635                                 default:
636                                         goto good_32bit_resolved_reloc;
637 #elif defined(TARGET_arm)
638                                 case R_ARM_ABS32:
639                                         relocation_needed = 1;
640                                         break;
641                                 case R_ARM_REL32:
642                                 case R_ARM_THM_PC11:
643                                 case R_ARM_THM_PC22:
644                                 case R_ARM_PC24:
645                                 case R_ARM_PLT32:
646                                 case R_ARM_GOTPC:
647                                 case R_ARM_GOT32:
648                                         relocation_needed = 0;
649                                         break;
650                                 default:
651                                         goto bad_resolved_reloc;
652 #elif defined(TARGET_m68k)
653                                 case R_68K_32:
654                                         goto good_32bit_resolved_reloc;
655                                 case R_68K_PC32:
656                                 case R_68K_PC16:
657                                         /* The linker has already resolved
658                                            PC relocs for us.  In PIC links,
659                                            the symbol must be in the data
660                                            segment.  */
661                                 case R_68K_NONE:
662                                         continue;
663                                 default:
664                                         goto bad_resolved_reloc;
665 #elif defined TARGET_bfin
666                                 case R_BFIN_RIMM16:
667                                 case R_BFIN_LUIMM16:
668                                 case R_BFIN_HUIMM16:
669                                     sym_vma = bfd_section_vma(abs_bfd, sym_section);
670                                     sym_addr += sym_vma + q->addend;
671
672                                     if (weak_und_symbol(sym_section->name, (*(q->sym_ptr_ptr))))
673                                         continue;
674                                     if (q->howto->type == R_BFIN_RIMM16 && (0xFFFF0000 & sym_addr)) {
675                                         fprintf (stderr, "Relocation overflow for rN = %s\n",sym_name);
676                                         bad_relocs++;
677                                     }
678                                     if ((0xFFFF0000 & sym_addr) != persistent_data) {
679                                     flat_relocs = (uint32_t *)
680                                         (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
681                                             if (verbose)
682                                                     printf ("New persistent data for %08lx\n", sym_addr);
683                                             persistent_data = 0xFFFF0000 & sym_addr;
684                                             flat_relocs[flat_reloc_count++]
685                                                     = (sym_addr >> 16) | (3 << 26);
686                                     }
687
688                                     flat_relocs = (uint32_t *)
689                                         (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
690                                     if (bfin_set_reloc (flat_relocs + flat_reloc_count,
691                                                         sym_section->name, sym_name,
692                                                         (*(q->sym_ptr_ptr)),
693                                                         q->howto->type == R_BFIN_HUIMM16 ? 1 : 0,
694                                                         section_vma + q->address))
695                                         bad_relocs++;
696                                     if (a->flags & SEC_CODE)
697                                         text_has_relocs = 1;
698                                     flat_reloc_count++;
699                                     break;
700
701                                 case R_BFIN_BYTE4_DATA:
702                                     sym_vma = bfd_section_vma(abs_bfd, sym_section);
703                                     sym_addr += sym_vma + q->addend;
704
705                                     if (weak_und_symbol (sym_section->name, (*(q->sym_ptr_ptr))))
706                                         continue;
707
708                                     flat_relocs = (uint32_t *)
709                                         (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
710                                     if (bfin_set_reloc (flat_relocs + flat_reloc_count,
711                                                         sym_section->name, sym_name,
712                                                         (*(q->sym_ptr_ptr)),
713                                                         2, section_vma + q->address))
714                                         bad_relocs++;
715                                     if (a->flags & SEC_CODE)
716                                         text_has_relocs = 1;
717
718                                     flat_reloc_count++;
719                                     break;
720 #else
721                                 default:
722                                         /* The default is to assume that the
723                                            relocation is relative and has
724                                            already been fixed up by the
725                                            linker (perhaps we ought to make
726                                            give an error by default, and
727                                            require `safe' relocations to be
728                                            enumberated explicitly?).  */
729                                         goto good_32bit_resolved_reloc;
730 #endif
731                                 good_32bit_resolved_reloc:
732                                         if (bfd_big_endian (abs_bfd))
733                                                 sym_addr =
734                                                         (r_mem[0] << 24)
735                                                         + (r_mem[1] << 16)
736                                                         + (r_mem[2] << 8) 
737                                                         + r_mem[3];
738                                         else
739                                                 sym_addr =
740                                                         r_mem[0]
741                                                         + (r_mem[1] << 8)
742                                                         + (r_mem[2] << 16)
743                                                         + (r_mem[3] << 24);
744                                         relocation_needed = 1;
745                                         break;
746
747                                 bad_resolved_reloc:
748                                         printf("ERROR: reloc type %s unsupported in this context\n",
749                                                q->howto->name);
750                                         bad_relocs++;
751                                         break;
752                                 }
753                         } else {
754                                 /* Calculate the sym address ourselves.  */
755                                 sym_reloc_size = bfd_get_reloc_size(q->howto);
756
757 #if !defined(TARGET_h8300) && !defined(TARGET_e1) && !defined(TARGET_bfin) && !defined(TARGET_m68k)
758                                 if (sym_reloc_size != 4) {
759                                         printf("ERROR: bad reloc type %d size=%d for symbol=%s\n",
760                                                         (*p)->howto->type, sym_reloc_size, sym_name);
761                                         bad_relocs++;
762                                         rc = -1;
763                                         continue;
764                                 }
765 #endif
766
767                                 switch ((*p)->howto->type) {
768
769 #if defined(TARGET_m68k)
770                                 case R_68K_32:
771                                         relocation_needed = 1;
772                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
773                                         sym_addr += sym_vma + q->addend;
774                                         break;
775                                 case R_68K_PC16:
776                                 case R_68K_PC32:
777                                         sym_vma = 0;
778                                         sym_addr += sym_vma + q->addend;
779                                         sym_addr -= q->address;
780                                         break;
781 #endif
782
783 #if defined(TARGET_arm)
784                                 case R_ARM_ABS32:
785                                         relocation_needed = 1;
786                                         if (verbose)
787                                                 fprintf(stderr,
788                                                         "%s vma=0x%x, value=0x%x, address=0x%x "
789                                                         "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
790                                                         "ABS32",
791                                                         sym_vma, (*(q->sym_ptr_ptr))->value,
792                                                         q->address, sym_addr,
793                                                         (*p)->howto->rightshift,
794                                                         *(uint32_t *)r_mem);
795                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
796                                         sym_addr += sym_vma + q->addend;
797                                         break;
798                                 case R_ARM_GOT32:
799                                 case R_ARM_GOTPC:
800                                         /* Should be fine as is */
801                                         break;
802                                 case R_ARM_PLT32:
803                                         if (verbose)
804                                                 fprintf(stderr,
805                                                         "%s vma=0x%x, value=0x%x, address=0x%x "
806                                                         "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
807                                                         "PLT32",
808                                                         sym_vma, (*(q->sym_ptr_ptr))->value,
809                                                         q->address, sym_addr,
810                                                         (*p)->howto->rightshift,
811                                                         *(uint32_t *)r_mem);
812                                 case R_ARM_PC24:
813                                         sym_vma = 0;
814                                         sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift;
815                                         break;
816 #endif
817
818 #ifdef TARGET_v850
819                                 case R_V850_32:
820                                         relocation_needed = 1;
821                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
822                                         sym_addr += sym_vma + q->addend;
823                                         break;
824 #if defined(R_V850_ZDA_16_16_OFFSET) || defined(R_V850_ZDA_16_16_SPLIT_OFFSET)
825 #ifdef R_V850_ZDA_16_16_OFFSET
826                                 case R_V850_ZDA_16_16_OFFSET:
827 #endif
828 #ifdef R_V850_ZDA_16_16_SPLIT_OFFSET
829                                 case R_V850_ZDA_16_16_SPLIT_OFFSET:
830 #endif
831                                         /* Can't support zero-relocations.  */
832                                         printf ("ERROR: %s+0x%x: zero relocations not supported\n",
833                                                         sym_name, q->addend);
834                                         continue;
835 #endif /* R_V850_ZDA_16_16_OFFSET || R_V850_ZDA_16_16_SPLIT_OFFSET */
836 #endif /* TARGET_v850 */
837
838 #ifdef TARGET_h8300
839                                 case R_H8_DIR24R8:
840                                         if (sym_reloc_size != 4) {
841                                                 printf("R_H8_DIR24R8 size %d\n", sym_reloc_size);
842                                                 bad_relocs++;
843                                                 continue;
844                                         }
845                                         relocation_needed = 1;
846                                         sym_addr = (*(q->sym_ptr_ptr))->value;
847                                         q->address -= 1;
848                                         r_mem -= 1; /* tracks q->address */
849                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
850                                         sym_addr += sym_vma + q->addend;
851                                         sym_addr |= (*(unsigned char *)r_mem<<24);
852                                         break;
853                                 case R_H8_DIR24A8:
854                                         if (sym_reloc_size != 4) {
855                                                 printf("R_H8_DIR24A8 size %d\n", sym_reloc_size);
856                                                 bad_relocs++;
857                                                 continue;
858                                         }
859                                         /* Absolute symbol done not relocation */
860                                         relocation_needed = !bfd_is_abs_section(sym_section);
861                                         sym_addr = (*(q->sym_ptr_ptr))->value;
862                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
863                                         sym_addr += sym_vma + q->addend;
864                                         break;
865                                 case R_H8_DIR32:
866                                 case R_H8_DIR32A16: /* currently 32,  could be made 16 */
867                                         if (sym_reloc_size != 4) {
868                                                 printf("R_H8_DIR32 size %d\n", sym_reloc_size);
869                                                 bad_relocs++;
870                                                 continue;
871                                         }
872                                         relocation_needed = 1;
873                                         sym_addr = (*(q->sym_ptr_ptr))->value;
874                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
875                                         sym_addr += sym_vma + q->addend;
876                                         break;
877                                 case R_H8_PCREL16:
878                                         sym_vma = 0;
879                                         sym_addr = (*(q->sym_ptr_ptr))->value;
880                                         sym_addr += sym_vma + q->addend;
881                                         sym_addr -= (q->address + 2);
882                                         if (bfd_big_endian(abs_bfd))
883                                         *(unsigned short *)r_mem =
884                                                 bfd_big_endian(abs_bfd) ? htons(sym_addr) : sym_addr;
885                                         continue;
886                                 case R_H8_PCREL8:
887                                         sym_vma = 0;
888                                         sym_addr = (*(q->sym_ptr_ptr))->value;
889                                         sym_addr += sym_vma + q->addend;
890                                         sym_addr -= (q->address + 1);
891                                         *(unsigned char *)r_mem = sym_addr;
892                                         continue;
893 #endif
894
895 #ifdef TARGET_microblaze
896                                 case R_MICROBLAZE_64:
897                 /* The symbol is split over two consecutive instructions.  
898                    Flag this to the flat loader by setting the high bit of 
899                    the relocation symbol. */
900                                 {
901                                         unsigned char *p = r_mem;
902                                         pflags=0x80000000;
903
904                                         /* work out the relocation */
905                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
906                                         sym_addr += sym_vma + q->addend;
907                                         /* Write relocated pointer back */
908                                         p[2] = (sym_addr >> 24) & 0xff;
909                                         p[3] = (sym_addr >> 16) & 0xff;
910                                         p[6] = (sym_addr >>  8) & 0xff;
911                                         p[7] =  sym_addr        & 0xff;
912
913                                         /* create a new reloc entry */
914                                         flat_relocs = realloc(flat_relocs,
915                                                 (flat_reloc_count + 1) * sizeof(uint32_t));
916                                         flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address);
917                                         flat_reloc_count++;
918                                         relocation_needed = 0;
919                                         pflags = 0;
920                         sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
921                                          bfd_section_vma(abs_bfd, sym_section));
922                         if (verbose)
923                                 printf("  RELOC[%d]: offset=0x%x symbol=%s%s "
924                                         "section=%s size=%d "
925                                         "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
926                                         q->address, sym_name, addstr,
927                                         section_name, sym_reloc_size,
928                                         sym_addr, section_vma + q->address);
929                         if (verbose)
930                                 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
931                                          section_vma + q->address);
932
933                                         continue;
934                                 }
935                                 case R_MICROBLAZE_32:
936                                 {       
937                                         unsigned char *p = r_mem;
938
939                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
940                                         sym_addr += sym_vma + q->addend;
941                                         relocation_needed = 1;
942                                         break;
943                                 }
944                                 case R_MICROBLAZE_64_PCREL:
945                                         sym_vma = 0;
946                                         sym_addr += sym_vma + q->addend;
947                                         sym_addr -= (q->address + 4);
948                                         sym_addr = htonl(sym_addr);
949                                         /* insert 16 MSB */
950                                         * ((unsigned short *) (r_mem+2)) = (sym_addr) & 0xFFFF;
951                                         /* then 16 LSB */
952                                         * ((unsigned short *) (r_mem+6)) = (sym_addr >> 16) & 0xFFFF;
953                                         /* We've done all the work, so continue
954                                            to next reloc instead of break */
955                                         continue;
956
957 #endif /* TARGET_microblaze */
958                                         
959 #ifdef TARGET_nios2
960 #define  htoniosl(x)    (x)
961 #define  niostohl(x)    (x)
962                                 case R_NIOS2_BFD_RELOC_32:
963                                         relocation_needed = 1;
964                                         pflags = (FLAT_NIOS2_R_32 << 28);
965                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
966                                         sym_addr += sym_vma + q->addend;
967                                         /* modify target, in target order */
968                                         *(unsigned long *)r_mem = htoniosl(sym_addr);
969                                         break;
970                                 case R_NIOS2_CALL26:
971                                 {
972                                         unsigned long exist_val;
973                                         relocation_needed = 1;
974                                         pflags = (FLAT_NIOS2_R_CALL26 << 28);
975                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
976                                         sym_addr += sym_vma + q->addend;
977                                         
978                                         /* modify target, in target order */
979                                         // exist_val = niostohl(*(unsigned long *)r_mem);
980                                         exist_val = ((sym_addr >> 2) << 6);
981                                         *(unsigned long *)r_mem = htoniosl(exist_val);
982                                         break;
983                                 }
984                                 case R_NIOS2_HIADJ16:
985                                 case R_NIOS2_HI16:
986                                 {
987                                         unsigned long exist_val;
988                                         int r2_type;
989                                         /* handle the adjacent HI/LO pairs */
990                                         if (relcount == 0)
991                                                 r2_type = R_NIOS2_NONE;
992                                         else
993                                                 r2_type = p[1]->howto->type;
994                                         if ((r2_type == R_NIOS2_LO16)
995                                             && (p[0]->sym_ptr_ptr == p[1]->sym_ptr_ptr)
996                                             && (p[0]->addend == p[1]->addend)) 
997                                             {
998                                                         unsigned char * r2_mem = sectionp + p[1]->address;
999                                                         if (p[1]->address - q->address!=4)
1000                                                                 printf("Err: HI/LO not adjacent %d\n", p[1]->address - q->address);
1001                                                         relocation_needed = 1;
1002                                                         pflags = (q->howto->type == R_NIOS2_HIADJ16) 
1003                                                                 ? FLAT_NIOS2_R_HIADJ_LO : FLAT_NIOS2_R_HI_LO;
1004                                                         pflags <<= 28;
1005                                                 
1006                                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
1007                                                         sym_addr += sym_vma + q->addend;
1008
1009                                                         /* modify high 16 bits, in target order */
1010                                                         exist_val = niostohl(*(unsigned long *)r_mem);
1011                                                         exist_val =  ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1012                                                         if (q->howto->type == R_NIOS2_HIADJ16)
1013                                                                 exist_val |= ((((sym_addr >> 16) + ((sym_addr >> 15) & 1)) & 0xFFFF) << 6);
1014                                                         else
1015                                                                 exist_val |= (((sym_addr >> 16) & 0xFFFF) << 6);
1016                                                         *(unsigned long *)r_mem = htoniosl(exist_val);
1017
1018                                                         /* modify low 16 bits, in target order */
1019                                                         exist_val = niostohl(*(unsigned long *)r2_mem);
1020                                                         exist_val =  ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1021                                                         exist_val |= ((sym_addr & 0xFFFF) << 6);
1022                                                         *(unsigned long *)r2_mem = htoniosl(exist_val);
1023                                                 
1024                                                 } else 
1025                                                         goto NIOS2_RELOC_ERR;
1026                                         }
1027                                         break;
1028
1029                                 case R_NIOS2_GPREL:
1030                                 {
1031                                         unsigned long exist_val, temp;
1032                                         //long gp = get_symbol_offset("_gp", sym_section, symbols, number_of_symbols);
1033                                         long gp = get_gp_value(symbols, number_of_symbols);
1034                                         if (gp == -1) {
1035                                                 printf("Err: unresolved symbol _gp when relocating %s\n", sym_name);
1036                                                 goto NIOS2_RELOC_ERR;
1037                                         }
1038                                         /* _gp holds a absolute value, otherwise the ld cannot generate correct code */
1039                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
1040                                         //printf("sym=%x, %d, _gp=%x, %d\n", sym_addr+sym_vma, sym_addr+sym_vma, gp, gp);
1041                                         sym_addr += sym_vma + q->addend;
1042                                         sym_addr -= gp;
1043                                         //printf("sym - _gp=%x, %d\n", sym_addr, sym_addr);
1044                                         /* modify the target, in target order (little_endian) */
1045                                         exist_val = niostohl(*(unsigned long *)r_mem);
1046                                         temp = ((exist_val >> 6) & 0x3ff0000) | (sym_addr & 0xffff);
1047                                         temp <<= 6;
1048                                         temp |= (exist_val & 0x3f);
1049                                         *(unsigned long *)r_mem = htoniosl(temp);
1050                                         if (verbose)
1051                                                 printf("omit: offset=0x%x symbol=%s%s "
1052                                                                 "section=%s size=%d "
1053                                                                 "fixup=0x%x (reloc=0x%x) GPREL\n", 
1054                                                                 q->address, sym_name, addstr,
1055                                                                 section_name, sym_reloc_size,
1056                                                                 sym_addr, section_vma + q->address);
1057                                         continue;
1058                                 }
1059                                 case R_NIOS2_PCREL16:
1060                                 {
1061                                         unsigned long exist_val;
1062                                         sym_vma = 0;
1063                                         sym_addr += sym_vma + q->addend;
1064                                         sym_addr -= (q->address + 4);
1065                                         /* modify the target, in target order (little_endian) */
1066                                         exist_val = niostohl(*(unsigned long *)r_mem);
1067                                         exist_val =  ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1068                                         exist_val |= ((sym_addr & 0xFFFF) << 6);
1069                                         *(unsigned long *)r_mem = htoniosl(exist_val);
1070                                         if (verbose)
1071                                                 printf("omit: offset=0x%x symbol=%s%s "
1072                                                                 "section=%s size=%d "
1073                                                                 "fixup=0x%x (reloc=0x%x) PCREL\n", 
1074                                                                 q->address, sym_name, addstr,
1075                                                                 section_name, sym_reloc_size,
1076                                                                 sym_addr, section_vma + q->address);
1077                                         continue;
1078                                 }
1079
1080                                 case R_NIOS2_LO16:
1081                                         /* check if this is actually the 2nd half of a pair */
1082                                         if ((p > relpp)
1083                                                 && ((p[-1]->howto->type == R_NIOS2_HIADJ16) 
1084                                                         || (p[-1]->howto->type == R_NIOS2_HI16))
1085                                             && (p[-1]->sym_ptr_ptr == p[0]->sym_ptr_ptr)
1086                                             && (p[-1]->addend == p[0]->addend)) {
1087                                                 if (verbose)
1088                                                         printf("omit: offset=0x%x symbol=%s%s "
1089                                                                 "section=%s size=%d LO16\n", 
1090                                                                 q->address, sym_name, addstr,
1091                                                                 section_name, sym_reloc_size);
1092                                                 continue;
1093                                         }
1094
1095                                         /* error, fall through */
1096
1097                                 case R_NIOS2_S16:
1098                                 case R_NIOS2_U16:
1099                                 case R_NIOS2_CACHE_OPX:
1100                                 case R_NIOS2_IMM5:
1101                                 case R_NIOS2_IMM6:
1102                                 case R_NIOS2_IMM8:
1103                                 case R_NIOS2_BFD_RELOC_16:
1104                                 case R_NIOS2_BFD_RELOC_8:
1105                                 case R_NIOS2_GNU_VTINHERIT:
1106                                 case R_NIOS2_GNU_VTENTRY:
1107                                 case R_NIOS2_UJMP:
1108                                 case R_NIOS2_CJMP:
1109                                 case R_NIOS2_CALLR:
1110 NIOS2_RELOC_ERR:
1111                                         printf("Err: unexpected reloc type %s(%d)\n", q->howto->name, q->howto->type);
1112                                         bad_relocs++;
1113                                         continue;
1114 #endif /* TARGET_nios2 */
1115
1116 #ifdef TARGET_sparc
1117                                 case R_SPARC_32:
1118                                 case R_SPARC_UA32:
1119                                         relocation_needed = 1;
1120                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
1121                                         sym_addr += sym_vma + q->addend;
1122                                         break;
1123                                 case R_SPARC_PC22:
1124                                         sym_vma = 0;
1125                                         sym_addr += sym_vma + q->addend;
1126                                         sym_addr -= q->address;
1127                                         break;
1128                                 case R_SPARC_WDISP30:
1129                                         sym_addr = (((*(q->sym_ptr_ptr))->value-
1130                                                 q->address) >> 2) & 0x3fffffff;
1131                                         sym_addr |= (
1132                                                 ntohl(*(uint32_t *)r_mem)
1133                                                 & 0xc0000000
1134                                                 );
1135                                         break;
1136                                 case R_SPARC_HI22:
1137                                         relocation_needed = 1;
1138                                         pflags = 0x80000000;
1139                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
1140                                         sym_addr += sym_vma + q->addend;
1141                                         sym_addr |= (
1142                                                 htonl(*(uint32_t *)r_mem)
1143                                                 & 0xffc00000
1144                                                 );
1145                                         break;
1146                                 case R_SPARC_LO10:
1147                                         relocation_needed = 1;
1148                                         pflags = 0x40000000;
1149                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
1150                                         sym_addr += sym_vma + q->addend;
1151                                         sym_addr &= 0x000003ff;
1152                                         sym_addr |= (
1153                                                 htonl(*(uint32_t *)r_mem)
1154                                                 & 0xfffffc00
1155                                                 );
1156                                         break;
1157 #endif /* TARGET_sparc */
1158
1159
1160 #ifdef TARGET_sh
1161                                 case R_SH_DIR32:
1162                                         relocation_needed = 1;
1163                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
1164                                         sym_addr += sym_vma + q->addend;
1165                                         break;
1166                                 case R_SH_REL32:
1167                                         sym_vma = 0;
1168                                         sym_addr += sym_vma + q->addend;
1169                                         sym_addr -= q->address;
1170                                         break;
1171 #endif /* TARGET_sh */
1172
1173 #ifdef TARGET_e1
1174 #define  htoe1l(x)              htonl(x)
1175                                         
1176 #if 0 
1177 #define  DEBUG_E1
1178 #endif
1179
1180 #ifdef   DEBUG_E1
1181 #define  DBG_E1                 printf
1182 #else
1183 #define  DBG_E1(x, ...  )
1184 #endif
1185
1186 #define _32BITS_RELOC 0x00000000
1187 #define _30BITS_RELOC 0x80000000
1188 #define _28BITS_RELOC 0x40000000
1189                                         {
1190                                 char *p;
1191                                 unsigned long   sec_vma, exist_val, S;
1192                                 case R_E1_CONST31:
1193                                                 relocation_needed = 1;
1194                                                 DBG_E1("Handling Reloc <CONST31>\n");
1195                                                 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1196                                                 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1197                                                                                 sec_vma, sym_addr, q->address);
1198                                                 sym_addr = sec_vma + sym_addr;
1199                                                 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);        
1200                                                 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1201                                                 exist_val = htoe1l(exist_val);
1202                                                 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1203                                                 sym_addr += exist_val;
1204                                                 pflags = _30BITS_RELOC;
1205                                                 break;
1206                                 case R_E1_CONST31_PCREL:
1207                                                 relocation_needed = 0;
1208                                                 DBG_E1("Handling Reloc <CONST31_PCREL>\n");
1209                                                 DBG_E1("DONT RELOCATE AT LOADING\n");
1210                                                 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1211                                                 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1212                                                                                 sec_vma, sym_addr, q->address);
1213                                                 sym_addr =  sec_vma + sym_addr;
1214                                                 DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%x]\n", sym_addr );
1215
1216                                                 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1217                                                                                                                                                 section_vma );
1218                                                 q->address = q->address + section_vma;
1219                                                 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1220
1221                                                 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1222                                                                 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1223                                                 DBG_E1( "sym_addr := sym_addr - q->address  - "
1224                                                                 "sizeof(CONST31_PCREL): [0x%x]\n",
1225                                                                 sym_addr );
1226                                                 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);              
1227                                                 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1228                                                 exist_val = htoe1l(exist_val);
1229                                                 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1230                                                 sym_addr |= exist_val;
1231                                                 DBG_E1("sym_addr |=  exist_val) : [0x%x]\n", sym_addr );
1232                                                 break;
1233                                 case R_E1_DIS29W_PCREL:
1234                                                 relocation_needed = 0;
1235                                                 DBG_E1("Handling Reloc <DIS29W_PCREL>\n");
1236                                                 DBG_E1("DONT RELOCATE AT LOADING\n");
1237                                                 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1238                                                 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1239                                                                                 sec_vma, sym_addr, q->address);
1240                                                 sym_addr =  sec_vma + sym_addr;
1241                                                 DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%x]\n", sym_addr );
1242
1243                                                 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1244                                                                                                                                                 section_vma );
1245                                                 q->address = q->address + section_vma;
1246                                                 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1247
1248                                                 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1249                                                                 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1250                                                 DBG_E1( "sym_addr := sym_addr - q->address  - "
1251                                                                 "sizeof(CONST31_PCREL): [0x%x]\n",
1252                                                                 sym_addr );
1253                                                 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1254                                                 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);       
1255                                                 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1256                                                 exist_val = htoe1l(exist_val);
1257                                                 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1258                                                 sym_addr += exist_val;
1259                                                 break;
1260                                 case R_E1_DIS29W:
1261                                                 DBG_E1("Handling Reloc <DIS29W>\n");
1262                                                 goto DIS29_RELOCATION;
1263                                 case R_E1_DIS29H:
1264                                                 DBG_E1("Handling Reloc <DIS29H>\n");
1265                                                 goto DIS29_RELOCATION;
1266                                 case R_E1_DIS29B:
1267                                                 DBG_E1("Handling Reloc <DIS29B>\n");
1268 DIS29_RELOCATION:
1269                                                 relocation_needed = 1;
1270                                                 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1271                                                 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%08x]\n",
1272                                                                                 sec_vma, sym_addr);
1273                                                 sym_addr =  sec_vma + sym_addr;
1274                                                 DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%08x]\n", sym_addr);
1275                                                 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);                
1276                                                 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1277                                                 exist_val = htoe1l(exist_val);
1278                                                 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1279                                                 sym_addr +=  exist_val;
1280                                                 DBG_E1("sym_addr +=  exist_val : [0x%08x]\n", sym_addr);
1281                                                 pflags = _28BITS_RELOC;
1282                                                 break;
1283                                 case R_E1_IMM32_PCREL:
1284                                                 relocation_needed = 0;
1285                                                 DBG_E1("Handling Reloc <IMM32_PCREL>\n");
1286                                                 DBG_E1("DONT RELOCATE AT LOADING\n");
1287                                                 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1288                                                 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1289                                                                                 sec_vma, sym_addr);
1290                                                 sym_addr =  sec_vma + sym_addr;
1291
1292                                                 DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%x]\n", sym_addr );
1293                                                 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1294                                                                                                                                                 section_vma );
1295                                                 q->address = q->address + section_vma;
1296                                                 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1297
1298                                                 if( (sym_addr = (sym_addr - q->address - 6 )) < 0 )
1299                                                                 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1300                                                 DBG_E1( "sym_addr := sym_addr - q->address  - "
1301                                                                 "sizeof(CONST31_PCREL): [0x%x]\n",
1302                                                                 sym_addr );
1303                                                 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1304                                                 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);                 
1305                                                 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1306                                                 exist_val = htoe1l(exist_val);
1307                                                 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1308                                                 sym_addr += exist_val;
1309                                                 break;
1310                                 case R_E1_IMM32:
1311                                                 relocation_needed = 1;
1312                                                 DBG_E1("Handling Reloc <IMM32>\n");
1313                                                 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1314                                                 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1315                                                                                 sec_vma, sym_addr);
1316                                                 sym_addr =  sec_vma + sym_addr;
1317                                                 DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%x]\n", sym_addr );
1318                                                 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1319                                                 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);                     
1320                                                 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1321                                                 exist_val = htoe1l(exist_val);
1322                                                 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1323                                                 sym_addr += exist_val;
1324                                                 pflags = _32BITS_RELOC;
1325                                                 break;
1326                                 case R_E1_WORD:
1327                                                 relocation_needed = 1;
1328                                                 DBG_E1("Handling Reloc <WORD>\n");
1329                                                 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1330                                                 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1331                                                                                 sec_vma, sym_addr);
1332                                                 sym_addr =  sec_vma + sym_addr;
1333                                                 DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%x]\n", sym_addr );
1334                                                 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address );
1335                                                 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1336                                                 exist_val = htoe1l(exist_val);
1337                                                 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1338                                                 sym_addr +=  exist_val;
1339                                                 DBG_E1("sym_addr +=  exist_val : [0x%08x]\n", sym_addr);
1340                                                 pflags = _32BITS_RELOC;
1341                                                 break;
1342                                 }
1343 #undef _32BITS_RELOC
1344 #undef _30BITS_RELOC
1345 #undef _28BITS_RELOC
1346 #endif
1347                                 default:
1348                                         /* missing support for other types of relocs */
1349                                         printf("ERROR: bad reloc type %d\n", (*p)->howto->type);
1350                                         bad_relocs++;
1351                                         continue;
1352                                 }
1353                         }
1354
1355                         sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
1356                                          bfd_section_vma(abs_bfd, sym_section));
1357
1358
1359                         /*
1360                          * for full elf relocation we have to write back the
1361                          * start_code relative value to use.
1362                          */
1363                         if (!pic_with_got) {
1364 #if defined(TARGET_arm)
1365                                 union {
1366                                         unsigned char c[4];
1367                                         uint32_t l;
1368                                 } tmp;
1369                                 int32_t hl;
1370                                 int i0, i1, i2, i3;
1371
1372                                 /*
1373                                  * horrible nasty hack to support different endianess
1374                                  */
1375                                 if (!bfd_big_endian(abs_bfd)) {
1376                                         i0 = 0;
1377                                         i1 = 1;
1378                                         i2 = 2;
1379                                         i3 = 3;
1380                                 } else {
1381                                         i0 = 3;
1382                                         i1 = 2;
1383                                         i2 = 1;
1384                                         i3 = 0;
1385                                 }
1386
1387                                 tmp.l = *(uint32_t *)r_mem;
1388                                 hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16);
1389                                 if (use_resolved ||
1390                                         (((*p)->howto->type != R_ARM_PC24) &&
1391                                         ((*p)->howto->type != R_ARM_PLT32)))
1392                                         hl |= (tmp.c[i3] << 24);
1393                                 else if (tmp.c[i2] & 0x80)
1394                                         hl |= 0xff000000; /* sign extend */
1395                                 if (!use_resolved)
1396                                         hl += sym_addr;
1397                                 tmp.c[i0] = hl & 0xff;
1398                                 tmp.c[i1] = (hl >> 8) & 0xff;
1399                                 tmp.c[i2] = (hl >> 16) & 0xff;
1400                                 if (use_resolved ||
1401                                         (((*p)->howto->type != R_ARM_PC24) &&
1402                                         ((*p)->howto->type != R_ARM_PLT32)))
1403                                         tmp.c[i3] = (hl >> 24) & 0xff;
1404                                 if ((*p)->howto->type == R_ARM_ABS32)
1405                                         *(uint32_t *)r_mem = htonl(hl);
1406                                 else
1407                                         *(uint32_t *)r_mem = tmp.l;
1408 #elif defined(TARGET_e1)
1409 #define OPCODE_SIZE 2           /* Add 2 bytes, counting the opcode size*/
1410                                 switch ((*p)->howto->type) {
1411                                 case R_E1_CONST31:
1412                                 case R_E1_CONST31_PCREL:
1413                                 case R_E1_DIS29W_PCREL:
1414                                 case R_E1_DIS29W:
1415                                 case R_E1_DIS29H:
1416                                 case R_E1_DIS29B:
1417                                 case R_E1_IMM32_PCREL:
1418                                 case R_E1_IMM32:
1419                                                 DBG_E1("In addr + 2:[0x%x] <- write [0x%x]\n",
1420                                                                 (sectionp + q->address + 2), sym_addr );
1421                                                 *((unsigned long *) (sectionp + q->address + OPCODE_SIZE)) =
1422                                                 htonl(sym_addr);
1423                                 break;
1424                                 case R_E1_WORD:
1425                                                 DBG_E1("In addr : [0x%x] <- write [0x%x]\n",
1426                                                                 (sectionp + q->address), sym_addr );
1427                                                 *((unsigned long *) (sectionp + q->address )) = htonl(sym_addr);
1428                                 break;
1429                                 default:
1430                                                 printf("ERROR:Unhandled Relocation. Exiting...\n");
1431                                                 exit(0);
1432                                 break;
1433                                 }
1434 #elif defined TARGET_bfin
1435                                 if ((*p)->howto->type == R_BFIN_RIMM16
1436                                     || (*p)->howto->type == R_BFIN_HUIMM16
1437                                     || (*p)->howto->type == R_BFIN_LUIMM16)
1438                                 {
1439                                         /* for l and h we set the lower 16 bits which is only when it will be used */
1440                                         bfd_putl16 (sym_addr, sectionp + q->address);
1441                                 } else if ((*p)->howto->type == R_BFIN_BYTE4_DATA) {
1442                                         bfd_putl32 (sym_addr, sectionp + q->address);
1443                                 }
1444 #else /* ! TARGET_arm && ! TARGET_e1 && ! TARGET_bfin */
1445
1446                                 switch (q->howto->type) {
1447 #ifdef TARGET_v850
1448                                 case R_V850_HI16_S:
1449                                 case R_V850_HI16:
1450                                 case R_V850_LO16:
1451                                         /* Do nothing -- for cases we handle,
1452                                            the bits produced by the linker are
1453                                            what we want in the final flat file
1454                                            (and other cases are errors).  Note
1455                                            that unlike most relocated values,
1456                                            it is stored in little-endian order,
1457                                            but this is necessary to avoid
1458                                            trashing the low-bit, and the float
1459                                            loaders knows about it.  */
1460                                         break;
1461 #endif /* TARGET_V850 */
1462
1463 #ifdef TARGET_nios2
1464                                 case R_NIOS2_BFD_RELOC_32:
1465                                 case R_NIOS2_CALL26:
1466                                 case R_NIOS2_HIADJ16:
1467                                 case R_NIOS2_HI16:
1468                                         /* do nothing */
1469                                         break;
1470 #endif /* TARGET_nios2 */
1471
1472 #if defined(TARGET_m68k)
1473                                 case R_68K_PC16:
1474                                         if (sym_addr < -0x8000 || sym_addr > 0x7fff) {
1475                                                 fprintf (stderr, "Relocation overflow for R_68K_PC16 relocation against %s\n", sym_name);
1476                                                 bad_relocs++;
1477                                         } else {
1478                                                 r_mem[0] = (sym_addr >>  8) & 0xff;
1479                                                 r_mem[1] =  sym_addr        & 0xff;
1480                                         }
1481                                         break;
1482 #endif
1483
1484                                 default:
1485                                         /* The alignment of the build host
1486                                            might be stricter than that of the
1487                                            target, so be careful.  We store in
1488                                            network byte order. */
1489                                         r_mem[0] = (sym_addr >> 24) & 0xff;
1490                                         r_mem[1] = (sym_addr >> 16) & 0xff;
1491                                         r_mem[2] = (sym_addr >>  8) & 0xff;
1492                                         r_mem[3] =  sym_addr        & 0xff;
1493                                 }
1494 #endif /* !TARGET_arm */
1495                         }
1496
1497                         if (verbose)
1498                                 printf("  RELOC[%d]: offset=0x%x symbol=%s%s "
1499                                         "section=%s size=%d "
1500                                         "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
1501                                         q->address, sym_name, addstr,
1502                                         section_name, sym_reloc_size,
1503                                         sym_addr, section_vma + q->address);
1504
1505                         /*
1506                          *      Create relocation entry (PC relative doesn't need this).
1507                          */
1508                         if (relocation_needed) {
1509 #ifndef TARGET_bfin
1510                                 flat_relocs = realloc(flat_relocs,
1511                                         (flat_reloc_count + 1) * sizeof(uint32_t));
1512 #ifndef TARGET_e1
1513                                 flat_relocs[flat_reloc_count] = pflags |
1514                                         (section_vma + q->address);
1515
1516                                 if (verbose)
1517                                         printf("reloc[%d] = 0x%x\n", flat_reloc_count,
1518                                                         section_vma + q->address);
1519 #else
1520                                 switch ((*p)->howto->type) {
1521                                 case R_E1_CONST31:
1522                                 case R_E1_CONST31_PCREL:
1523                                 case R_E1_DIS29W_PCREL:
1524                                 case R_E1_DIS29W:
1525                                 case R_E1_DIS29H:
1526                                 case R_E1_DIS29B:
1527                                 case R_E1_IMM32_PCREL:
1528                                 case R_E1_IMM32:
1529                                 flat_relocs[flat_reloc_count] = pflags |
1530                                                 (section_vma + q->address + OPCODE_SIZE);
1531                                 if (verbose)
1532                                                 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1533                                                                                  flat_relocs[flat_reloc_count] );
1534                                 break;
1535                                 case R_E1_WORD:
1536                                 flat_relocs[flat_reloc_count] = pflags |
1537                                                 (section_vma + q->address);
1538                                 if (verbose)
1539                                                 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1540                                                                                  flat_relocs[flat_reloc_count] );
1541                                 break;
1542                                 }
1543 #endif
1544                                 flat_reloc_count++;
1545 #endif //TARGET_bfin
1546                                 relocation_needed = 0;
1547                                 pflags = 0;
1548                         }
1549
1550 #if 0
1551 printf("%s(%d): symbol name=%s address=0x%x section=%s -> RELOC=0x%x\n",
1552         __FILE__, __LINE__, sym_name, q->address, section_name,
1553         flat_relocs[flat_reloc_count]);
1554 #endif
1555                 }
1556         }
1557   }
1558
1559   if (bad_relocs) {
1560           printf("%d bad relocs\n", bad_relocs);
1561           exit(1);
1562   }
1563
1564   if (rc < 0)
1565         return(0);
1566
1567   *n_relocs = flat_reloc_count;
1568   return flat_relocs;
1569 }
1570
1571
1572
1573 static void usage(void)
1574 {
1575     fprintf(stderr, "Usage: %s [vrzd] [-p <abs-pic-file>] [-s stack-size] "
1576         "[-o <output-file>] <elf-file>\n\n"
1577         "       -v              : verbose operation\n"
1578         "       -r              : force load to RAM\n"
1579         "       -k              : enable kernel trace on load (for debug)\n"
1580         "       -z              : compress code/data/relocs\n"
1581         "       -d              : compress data/relocs\n"
1582         "       -a              : use existing symbol references\n"
1583         "                         instead of recalculating from\n"
1584         "                         relocation info\n"
1585         "       -R reloc-file   : read relocations from a separate file\n"
1586         "       -p abs-pic-file : GOT/PIC processing with files\n"
1587         "       -s stacksize    : set application stack size\n"
1588         "       -o output-file  : output file name\n\n",
1589         elf2flt_progname);
1590         fprintf(stderr, "Compiled for " ARCH " architecture\n\n");
1591     exit(2);
1592 }
1593
1594
1595 /* Write NUM zeroes to STREAM.  */
1596 static void write_zeroes (unsigned long num, stream *stream)
1597 {
1598   char zeroes[1024];
1599   if (num > 0) {
1600     /* It'd be nice if we could just use fseek, but that doesn't seem to
1601        work for stdio output files.  */
1602     memset(zeroes, 0x00, 1024);
1603     while (num > sizeof(zeroes)) {
1604       fwrite_stream(zeroes, sizeof(zeroes), 1, stream);
1605       num -= sizeof(zeroes);
1606     }
1607     if (num > 0)
1608       fwrite_stream(zeroes, num, 1, stream);
1609   }
1610 }
1611
1612
1613 int main(int argc, char *argv[])
1614 {
1615   int fd;
1616   bfd *rel_bfd, *abs_bfd;
1617   asection *s;
1618   char *ofile=NULL, *pfile=NULL, *abs_file = NULL, *rel_file = NULL;
1619   char *fname = NULL;
1620   int opt;
1621   int i;
1622   int stack;
1623   stream gf;
1624
1625   asymbol **symbol_table;
1626   long number_of_symbols;
1627
1628   uint32_t data_len = 0;
1629   uint32_t bss_len = 0;
1630   uint32_t text_len = 0;
1631   uint32_t reloc_len;
1632
1633   uint32_t data_vma = ~0;
1634   uint32_t bss_vma = ~0;
1635   uint32_t text_vma = ~0;
1636
1637   uint32_t text_offs;
1638
1639   void *text;
1640   void *data;
1641   uint32_t *reloc;
1642
1643   struct flat_hdr hdr;
1644
1645   elf2flt_progname = argv[0];
1646   xmalloc_set_program_name(elf2flt_progname);
1647
1648   if (argc < 2)
1649         usage();
1650
1651   if (sizeof(hdr) != 64)
1652     fatal(
1653             "Potential flat header incompatibility detected\n"
1654             "header size should be 64 but is %d",
1655             sizeof(hdr));
1656
1657 #ifndef TARGET_e1
1658   stack = 4096;
1659 #else /* We need plenty of stack for both of them (Aggregate and Register) */
1660   stack = 0x2020;
1661 #endif
1662
1663   while ((opt = getopt(argc, argv, "avzdrkp:s:o:R:")) != -1) {
1664     switch (opt) {
1665     case 'v':
1666       verbose++;
1667       break;
1668     case 'r':
1669       load_to_ram++;
1670       break;
1671     case 'k':
1672       ktrace++;
1673       break;
1674     case 'z':
1675       docompress = 1;
1676       break;
1677     case 'd':
1678       docompress = 2;
1679       break;
1680     case 'p':
1681       pfile = optarg;
1682       break;
1683     case 'o':
1684       ofile = optarg;
1685       break;
1686     case 'a':
1687       use_resolved = 1;
1688       break;
1689     case 's':
1690       if (sscanf(optarg, "%i", &stack) != 1) {
1691         fprintf(stderr, "%s invalid stack size %s\n", argv[0], optarg);
1692         usage();
1693       }
1694       break;
1695     case 'R':
1696       rel_file = optarg;
1697       break;
1698     default:
1699       fprintf(stderr, "%s Unknown option\n", argv[0]);
1700       usage();
1701       break;
1702     }
1703   }
1704   
1705   /*
1706    * if neither the -r or -p options was given,  default to
1707    * a RAM load as that is the only option that makes sense.
1708    */
1709   if (!load_to_ram && !pfile)
1710     load_to_ram = 1;
1711
1712   fname = argv[argc-1];
1713
1714   if (pfile) {
1715     pic_with_got = 1;
1716     abs_file = pfile;
1717   } else
1718     abs_file = fname;
1719
1720   if (! rel_file)
1721     rel_file = fname;
1722
1723   if (!(rel_bfd = bfd_openr(rel_file, 0)))
1724     fatal_perror("Can't open '%s'", rel_file);
1725
1726   if (bfd_check_format (rel_bfd, bfd_object) == 0)
1727     fatal("File is not an object file");
1728
1729   if (abs_file == rel_file)
1730     abs_bfd = rel_bfd; /* one file does all */
1731   else {
1732     if (!(abs_bfd = bfd_openr(abs_file, 0)))
1733       fatal_perror("Can't open '%s'", abs_file);
1734
1735     if (bfd_check_format (abs_bfd, bfd_object) == 0)
1736       fatal("File is not an object file");
1737   }
1738
1739   if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC))
1740     fatal("%s: Input file contains no relocation info", rel_file);
1741
1742   if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P))
1743     /* `Absolute' file is not absolute, so neither are address
1744        contained therein.  */
1745     fatal("%s: `-a' option specified with non-fully-resolved input file",
1746              bfd_get_filename (abs_bfd));
1747
1748   symbol_table = get_symbols(abs_bfd, &number_of_symbols);
1749
1750   /* Group output sections into text, data, and bss, and calc their sizes.  */
1751   for (s = abs_bfd->sections; s != NULL; s = s->next) {
1752     uint32_t *vma, *len;
1753     bfd_size_type sec_size;
1754     bfd_vma sec_vma;
1755
1756     if (s->flags & SEC_CODE) {
1757       vma = &text_vma;
1758       len = &text_len;
1759     } else if (s->flags & SEC_DATA) {
1760       vma = &data_vma;
1761       len = &data_len;
1762     } else if (s->flags & SEC_ALLOC) {
1763       vma = &bss_vma;
1764       len = &bss_len;
1765     } else
1766       continue;
1767
1768     sec_size = bfd_section_size(abs_bfd, s);
1769     sec_vma  = bfd_section_vma(abs_bfd, s);
1770
1771     if (sec_vma < *vma) {
1772       if (*len > 0)
1773         *len += sec_vma - *vma;
1774       else
1775         *len = sec_size;
1776       *vma = sec_vma;
1777     } else if (sec_vma + sec_size > *vma + *len)
1778       *len = sec_vma + sec_size - *vma;
1779   }
1780
1781   if (text_len == 0)
1782     fatal("%s: no .text section", abs_file);
1783
1784   text = xmalloc(text_len);
1785
1786   if (verbose)
1787     printf("TEXT -> vma=0x%x len=0x%x\n", text_vma, text_len);
1788
1789   /* Read in all text sections.  */
1790   for (s = abs_bfd->sections; s != NULL; s = s->next)
1791     if (s->flags & SEC_CODE) 
1792       if (!bfd_get_section_contents(abs_bfd, s,
1793                                    text + (s->vma - text_vma), 0,
1794                                    bfd_section_size(abs_bfd, s)))
1795       {
1796         fatal("read error section %s", s->name);
1797       }
1798
1799   if (data_len == 0)
1800     fatal("%s: no .data section", abs_file);
1801   data = xmalloc(data_len);
1802
1803   if (verbose)
1804     printf("DATA -> vma=0x%x len=0x%x\n", data_vma, data_len);
1805
1806   if ((text_vma + text_len) != data_vma) {
1807     if ((text_vma + text_len) > data_vma) {
1808       printf("ERROR: text=0x%x overlaps data=0x%x ?\n", text_len, data_vma);
1809       exit(1);
1810     }
1811     if (verbose)
1812       printf("WARNING: data=0x%x does not directly follow text=0x%x\n",
1813                         data_vma, text_len);
1814     text_len = data_vma - text_vma;
1815   }
1816
1817   /* Read in all data sections.  */
1818   for (s = abs_bfd->sections; s != NULL; s = s->next)
1819     if (s->flags & SEC_DATA) 
1820       if (!bfd_get_section_contents(abs_bfd, s,
1821                                    data + (s->vma - data_vma), 0,
1822                                    bfd_section_size(abs_bfd, s)))
1823       {
1824         fatal("read error section %s", s->name);
1825       }
1826
1827   if (bss_vma == ~0)
1828     bss_vma = data_vma + data_len;
1829
1830   /* Put common symbols in bss.  */
1831   bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len);
1832
1833   if (verbose)
1834     printf("BSS  -> vma=0x%x len=0x%x\n", bss_vma, bss_len);
1835
1836   if ((data_vma + data_len) != bss_vma) {
1837     if ((data_vma + data_len) > bss_vma) {
1838       printf("ERROR: text=0x%x + data=0x%x overlaps bss=0x%x ?\n", text_len,
1839                         data_len, bss_vma);
1840       exit(1);
1841     }
1842     if (verbose)
1843       printf("WARNING: bss=0x%x does not directly follow text=0x%x + data=0x%x(0x%x)\n",
1844                 bss_vma, text_len, data_len, text_len + data_len);
1845     data_len = bss_vma - data_vma;
1846   }
1847
1848   reloc = (uint32_t *)
1849     output_relocs(abs_bfd, symbol_table, number_of_symbols, &reloc_len,
1850                   text, text_len, text_vma, data, data_len, data_vma, rel_bfd);
1851
1852   if (reloc == NULL && verbose)
1853     printf("No relocations in code!\n");
1854
1855   text_offs = real_address_bits(text_vma);
1856
1857   /* Fill in the binflt_flat header */
1858   memcpy(hdr.magic,"bFLT",4);
1859   hdr.rev         = htonl(FLAT_VERSION);
1860   hdr.entry       = htonl(sizeof(hdr) + bfd_get_start_address(abs_bfd));
1861   hdr.data_start  = htonl(sizeof(hdr) + text_offs + text_len);
1862   hdr.data_end    = htonl(sizeof(hdr) + text_offs + text_len +data_len);
1863   hdr.bss_end     = htonl(sizeof(hdr) + text_offs + text_len +data_len+bss_len);
1864   hdr.stack_size  = htonl(stack); /* FIXME */
1865   hdr.reloc_start = htonl(sizeof(hdr) + text_offs + text_len +data_len);
1866   hdr.reloc_count = htonl(reloc_len);
1867   hdr.flags       = htonl(0
1868           | (load_to_ram || text_has_relocs ? FLAT_FLAG_RAM : 0)
1869           | (ktrace ? FLAT_FLAG_KTRACE : 0)
1870           | (pic_with_got ? FLAT_FLAG_GOTPIC : 0)
1871           | (docompress ? (docompress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
1872           );
1873   hdr.build_date = htonl((uint32_t)time(NULL));
1874   memset(hdr.filler, 0x00, sizeof(hdr.filler));
1875
1876   for (i=0; i<reloc_len; i++) reloc[i] = htonl(reloc[i]);
1877
1878   if (verbose) {
1879     printf("SIZE: .text=0x%04x, .data=0x%04x, .bss=0x%04x",
1880         text_len, data_len, bss_len);
1881     if (reloc)
1882       printf(", relocs=0x%04x", reloc_len);
1883     printf("\n");
1884   }
1885   
1886   if (!ofile) {
1887     ofile = xmalloc(strlen(fname) + 5 + 1); /* 5 to add suffix */
1888     strcpy(ofile, fname);
1889     strcat(ofile, ".bflt");
1890   }
1891
1892   if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0)
1893     fatal_perror("Can't open output file %s", ofile);
1894
1895   write(fd, &hdr, sizeof(hdr));
1896   close(fd);
1897
1898   if (fopen_stream_u(&gf, ofile, "a" BINARY_FILE_OPTS))
1899     fatal_perror("Can't open file %s for writing", ofile);
1900
1901   if (docompress == 1)
1902     reopen_stream_compressed(&gf);
1903
1904   /* Fill in any hole at the beginning of the text segment.  */
1905   if (verbose)
1906     printf("ZERO before text len=0x%x\n", text_offs);
1907   write_zeroes(text_offs, &gf);
1908
1909   /* Write the text segment.  */
1910   fwrite_stream(text, text_len, 1, &gf);
1911
1912   if (docompress == 2)
1913     reopen_stream_compressed(&gf);
1914
1915   /* Write the data segment.  */
1916   fwrite_stream(data, data_len, 1, &gf);
1917
1918   if (reloc)
1919     fwrite_stream(reloc, reloc_len * 4, 1, &gf);
1920
1921   fclose_stream(&gf);
1922
1923   exit(0);
1924 }
1925
1926
1927 /*
1928  * this __MUST__ be at the VERY end of the file - do NOT move!!
1929  *
1930  * Local Variables:
1931  * c-basic-offset: 4
1932  * tab-width: 8
1933  * end:
1934  * vi: tabstop=8 shiftwidth=4 textwidth=79 noexpandtab
1935  */