OSDN Git Service

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