OSDN Git Service

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