OSDN Git Service

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