OSDN Git Service

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