OSDN Git Service

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