OSDN Git Service

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