OSDN Git Service

0afe1242bbbef8fbfbdd4d3006dca7c87db1bb3f
[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) && !defined(TARGET_m68k)
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_PC16:
867                                 case R_68K_PC32:
868                                         sym_vma = 0;
869                                         sym_addr += sym_vma + q->addend;
870                                         sym_addr -= q->address;
871                                         break;
872 #endif
873
874 #if defined(TARGET_arm)
875                                 case R_ARM_ABS32:
876                                         relocation_needed = 1;
877                                         if (verbose)
878                                                 fprintf(stderr,
879                                                         "%s vma=0x%x, value=0x%x, address=0x%x "
880                                                         "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
881                                                         "ABS32",
882                                                         sym_vma, (*(q->sym_ptr_ptr))->value,
883                                                         q->address, sym_addr,
884                                                         (*p)->howto->rightshift,
885                                                         *(unsigned long *)r_mem);
886                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
887                                         sym_addr += sym_vma + q->addend;
888                                         break;
889                                 case R_ARM_GOT32:
890                                 case R_ARM_GOTPC:
891                                         /* Should be fine as is */
892                                         break;
893                                 case R_ARM_PLT32:
894                                         if (verbose)
895                                                 fprintf(stderr,
896                                                         "%s vma=0x%x, value=0x%x, address=0x%x "
897                                                         "sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
898                                                         "PLT32",
899                                                         sym_vma, (*(q->sym_ptr_ptr))->value,
900                                                         q->address, sym_addr,
901                                                         (*p)->howto->rightshift,
902                                                         *(unsigned long *)r_mem);
903                                 case R_ARM_PC24:
904                                         sym_vma = 0;
905                                         sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift;
906                                         break;
907 #endif
908
909 #ifdef TARGET_v850
910                                 case R_V850_32:
911                                         relocation_needed = 1;
912                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
913                                         sym_addr += sym_vma + q->addend;
914                                         break;
915 #if defined(R_V850_ZDA_16_16_OFFSET) || defined(R_V850_ZDA_16_16_SPLIT_OFFSET)
916 #ifdef R_V850_ZDA_16_16_OFFSET
917                                 case R_V850_ZDA_16_16_OFFSET:
918 #endif
919 #ifdef R_V850_ZDA_16_16_SPLIT_OFFSET
920                                 case R_V850_ZDA_16_16_SPLIT_OFFSET:
921 #endif
922                                         /* Can't support zero-relocations.  */
923                                         printf ("ERROR: %s+0x%x: zero relocations not supported\n",
924                                                         sym_name, q->addend);
925                                         continue;
926 #endif /* R_V850_ZDA_16_16_OFFSET || R_V850_ZDA_16_16_SPLIT_OFFSET */
927 #endif /* TARGET_v850 */
928
929 #ifdef TARGET_h8300
930                                 case R_H8_DIR24R8:
931                                         if (sym_reloc_size != 4) {
932                                                 printf("R_H8_DIR24R8 size %d\n", sym_reloc_size);
933                                                 bad_relocs++;
934                                                 continue;
935                                         }
936                                         relocation_needed = 1;
937                                         sym_addr = (*(q->sym_ptr_ptr))->value;
938                                         q->address -= 1;
939                                         r_mem -= 1; /* tracks q->address */
940                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
941                                         sym_addr += sym_vma + q->addend;
942                                         sym_addr |= (*(unsigned char *)r_mem<<24);
943                                         break;
944                                 case R_H8_DIR24A8:
945                                         if (sym_reloc_size != 4) {
946                                                 printf("R_H8_DIR24A8 size %d\n", sym_reloc_size);
947                                                 bad_relocs++;
948                                                 continue;
949                                         }
950                                         /* Absolute symbol done not relocation */
951                                         relocation_needed = !bfd_is_abs_section(sym_section);
952                                         sym_addr = (*(q->sym_ptr_ptr))->value;
953                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
954                                         sym_addr += sym_vma + q->addend;
955                                         break;
956                                 case R_H8_DIR32:
957                                 case R_H8_DIR32A16: /* currently 32,  could be made 16 */
958                                         if (sym_reloc_size != 4) {
959                                                 printf("R_H8_DIR32 size %d\n", sym_reloc_size);
960                                                 bad_relocs++;
961                                                 continue;
962                                         }
963                                         relocation_needed = 1;
964                                         sym_addr = (*(q->sym_ptr_ptr))->value;
965                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
966                                         sym_addr += sym_vma + q->addend;
967                                         break;
968                                 case R_H8_PCREL16:
969                                         sym_vma = 0;
970                                         sym_addr = (*(q->sym_ptr_ptr))->value;
971                                         sym_addr += sym_vma + q->addend;
972                                         sym_addr -= (q->address + 2);
973                                         if (bfd_big_endian(abs_bfd))
974                                         *(unsigned short *)r_mem =
975                                                 bfd_big_endian(abs_bfd) ? htons(sym_addr) : sym_addr;
976                                         continue;
977                                 case R_H8_PCREL8:
978                                         sym_vma = 0;
979                                         sym_addr = (*(q->sym_ptr_ptr))->value;
980                                         sym_addr += sym_vma + q->addend;
981                                         sym_addr -= (q->address + 1);
982                                         *(unsigned char *)r_mem = sym_addr;
983                                         continue;
984 #endif
985
986 #ifdef TARGET_microblaze
987                                 case R_MICROBLAZE_64:
988                 /* The symbol is split over two consecutive instructions.  
989                    Flag this to the flat loader by setting the high bit of 
990                    the relocation symbol. */
991                                 {
992                                         unsigned char *p = r_mem;
993                                         unsigned long offset;
994                                         pflags=0x80000000;
995
996                                         /* work out the relocation */
997                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
998                                         /* grab any offset from the text */
999                                         offset = (p[2]<<24) + (p[3] << 16) + (p[6] << 8) + (p[7]);
1000                                         /* Update the address */
1001                                         sym_addr += offset + sym_vma + q->addend;
1002                                         /* Write relocated pointer back */
1003                                         p[2] = (sym_addr >> 24) & 0xff;
1004                                         p[3] = (sym_addr >> 16) & 0xff;
1005                                         p[6] = (sym_addr >>  8) & 0xff;
1006                                         p[7] =  sym_addr        & 0xff;
1007
1008                                         /* create a new reloc entry */
1009                                         flat_relocs = realloc(flat_relocs,
1010                                                 (flat_reloc_count + 1) * sizeof(uint32_t));
1011                                         flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address);
1012                                         flat_reloc_count++;
1013                                         relocation_needed = 0;
1014                                         pflags = 0;
1015                         sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
1016                                          bfd_section_vma(abs_bfd, sym_section));
1017                         if (verbose)
1018                                 printf("  RELOC[%d]: offset=0x%x symbol=%s%s "
1019                                         "section=%s size=%d "
1020                                         "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
1021                                         q->address, sym_name, addstr,
1022                                         section_name, sym_reloc_size,
1023                                         sym_addr, section_vma + q->address);
1024                         if (verbose)
1025                                 printf("reloc[%d] = 0x%x\n", flat_reloc_count,
1026                                          section_vma + q->address);
1027
1028                                         continue;
1029                                 }
1030                                 case R_MICROBLAZE_32:
1031                                 {       
1032                                         unsigned char *p = r_mem;
1033                                         unsigned long offset;
1034
1035                                         /* grab any offset from the text */
1036                                         offset = (p[0]<<24) + (p[1] << 16) + (p[2] << 8) + (p[3]);
1037                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
1038                                         /* This is a horrible kludge.  For some
1039                                            reason, *sometimes* the offset is in
1040                                            both addend and the code.  Detect
1041                                            it, and cancel the effect.  Otherwise
1042                                            the offset gets added twice - ouch.
1043                                            There should be a better test
1044                                            for this condition, based on the
1045                                            BFD data structures */
1046                                         if(offset==q->addend)
1047                                                 offset=0;
1048
1049                                         sym_addr += offset + sym_vma + q->addend;
1050                                         relocation_needed = 1;
1051                                         break;
1052                                 }
1053                                 case R_MICROBLAZE_64_PCREL:
1054                                         sym_vma = 0;
1055                                         //sym_addr = (*(q->sym_ptr_ptr))->value;
1056                                         sym_addr += sym_vma + q->addend;
1057                                         sym_addr -= (q->address + 4);
1058                                         sym_addr = htonl(sym_addr);
1059                                         /* insert 16 MSB */
1060                                         * ((unsigned short *) (r_mem+2)) |= (sym_addr) & 0xFFFF;
1061                                         /* then 16 LSB */
1062                                         * ((unsigned short *) (r_mem+6)) |= (sym_addr >> 16) & 0xFFFF;
1063                                         /* We've done all the work, so continue
1064                                            to next reloc instead of break */
1065                                         continue;
1066
1067 #endif /* TARGET_microblaze */
1068                                         
1069 #ifdef TARGET_nios2
1070 #define  htoniosl(x)    (x)
1071 #define  niostohl(x)    (x)
1072                         switch ((*p)->howto->type) 
1073                         {
1074                                 case R_NIOS2_BFD_RELOC_32:
1075                                         relocation_needed = 1;
1076                                         pflags = (FLAT_NIOS2_R_32 << 28);
1077                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
1078                                         sym_addr += sym_vma + q->addend;
1079                                         /* modify target, in target order */
1080                                         *(unsigned long *)r_mem = htoniosl(sym_addr);
1081                                         break;
1082                                 case R_NIOS2_CALL26:
1083                                 {
1084                                         unsigned long exist_val;
1085                                         relocation_needed = 1;
1086                                         pflags = (FLAT_NIOS2_R_CALL26 << 28);
1087                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
1088                                         sym_addr += sym_vma + q->addend;
1089                                         
1090                                         /* modify target, in target order */
1091                                         // exist_val = niostohl(*(unsigned long *)r_mem);
1092                                         exist_val = ((sym_addr >> 2) << 6);
1093                                         *(unsigned long *)r_mem = htoniosl(exist_val);
1094                                         break;
1095                                 }
1096                                 case R_NIOS2_HIADJ16:
1097                                 case R_NIOS2_HI16:
1098                                 {
1099                                         unsigned long exist_val;
1100                                         int r2_type;
1101                                         /* handle the adjacent HI/LO pairs */
1102                                         if (relcount == 0)
1103                                                 r2_type = R_NIOS2_NONE;
1104                                         else
1105                                                 r2_type = p[1]->howto->type;
1106                                         if ((r2_type == R_NIOS2_LO16)
1107                                             && (p[0]->sym_ptr_ptr == p[1]->sym_ptr_ptr)
1108                                             && (p[0]->addend == p[1]->addend)) 
1109                                             {
1110                                                         unsigned char * r2_mem = sectionp + p[1]->address;
1111                                                         if (p[1]->address - q->address!=4)
1112                                                                 printf("Err: HI/LO not adjacent %d\n", p[1]->address - q->address);
1113                                                         relocation_needed = 1;
1114                                                         pflags = (q->howto->type == R_NIOS2_HIADJ16) 
1115                                                                 ? FLAT_NIOS2_R_HIADJ_LO : FLAT_NIOS2_R_HI_LO;
1116                                                         pflags <<= 28;
1117                                                 
1118                                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
1119                                                         sym_addr += sym_vma + q->addend;
1120
1121                                                         /* modify high 16 bits, in target order */
1122                                                         exist_val = niostohl(*(unsigned long *)r_mem);
1123                                                         exist_val =  ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1124                                                         if (q->howto->type == R_NIOS2_HIADJ16)
1125                                                                 exist_val |= ((((sym_addr >> 16) + ((sym_addr >> 15) & 1)) & 0xFFFF) << 6);
1126                                                         else
1127                                                                 exist_val |= (((sym_addr >> 16) & 0xFFFF) << 6);
1128                                                         *(unsigned long *)r_mem = htoniosl(exist_val);
1129
1130                                                         /* modify low 16 bits, in target order */
1131                                                         exist_val = niostohl(*(unsigned long *)r2_mem);
1132                                                         exist_val =  ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1133                                                         exist_val |= ((sym_addr & 0xFFFF) << 6);
1134                                                         *(unsigned long *)r2_mem = htoniosl(exist_val);
1135                                                 
1136                                                 } else 
1137                                                         goto NIOS2_RELOC_ERR;
1138                                         }
1139                                         break;
1140
1141                                 case R_NIOS2_GPREL:
1142                                 {
1143                                         unsigned long exist_val, temp;
1144                                         //long gp = get_symbol_offset("_gp", sym_section, symbols, number_of_symbols);
1145                                         long gp = get_gp_value(symbols, number_of_symbols);
1146                                         if (gp == -1) {
1147                                                 printf("Err: unresolved symbol _gp when relocating %s\n", sym_name);
1148                                                 goto NIOS2_RELOC_ERR;
1149                                         }
1150                                         /* _gp holds a absolute value, otherwise the ld cannot generate correct code */
1151                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
1152                                         //printf("sym=%x, %d, _gp=%x, %d\n", sym_addr+sym_vma, sym_addr+sym_vma, gp, gp);
1153                                         sym_addr += sym_vma + q->addend;
1154                                         sym_addr -= gp;
1155                                         //printf("sym - _gp=%x, %d\n", sym_addr, sym_addr);
1156                                         /* modify the target, in target order (little_endian) */
1157                                         exist_val = niostohl(*(unsigned long *)r_mem);
1158                                         temp = ((exist_val >> 6) & 0x3ff0000) | (sym_addr & 0xffff);
1159                                         temp <<= 6;
1160                                         temp |= (exist_val & 0x3f);
1161                                         *(unsigned long *)r_mem = htoniosl(temp);
1162                                         if (verbose)
1163                                                 printf("omit: offset=0x%x symbol=%s%s "
1164                                                                 "section=%s size=%d "
1165                                                                 "fixup=0x%x (reloc=0x%x) GPREL\n", 
1166                                                                 q->address, sym_name, addstr,
1167                                                                 section_name, sym_reloc_size,
1168                                                                 sym_addr, section_vma + q->address);
1169                                         continue;
1170                                 }
1171                                 case R_NIOS2_PCREL16:
1172                                 {
1173                                         unsigned long exist_val;
1174                                         sym_vma = 0;
1175                                         sym_addr += sym_vma + q->addend;
1176                                         sym_addr -= (q->address + 4);
1177                                         /* modify the target, in target order (little_endian) */
1178                                         exist_val = niostohl(*(unsigned long *)r_mem);
1179                                         exist_val =  ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1180                                         exist_val |= ((sym_addr & 0xFFFF) << 6);
1181                                         *(unsigned long *)r_mem = htoniosl(exist_val);
1182                                         if (verbose)
1183                                                 printf("omit: offset=0x%x symbol=%s%s "
1184                                                                 "section=%s size=%d "
1185                                                                 "fixup=0x%x (reloc=0x%x) PCREL\n", 
1186                                                                 q->address, sym_name, addstr,
1187                                                                 section_name, sym_reloc_size,
1188                                                                 sym_addr, section_vma + q->address);
1189                                         continue;
1190                                 }
1191
1192                                 case R_NIOS2_LO16:
1193                                         /* check if this is actually the 2nd half of a pair */
1194                                         if ((p > relpp)
1195                                                 && ((p[-1]->howto->type == R_NIOS2_HIADJ16) 
1196                                                         || (p[-1]->howto->type == R_NIOS2_HI16))
1197                                             && (p[-1]->sym_ptr_ptr == p[0]->sym_ptr_ptr)
1198                                             && (p[-1]->addend == p[0]->addend)) {
1199                                                 if (verbose)
1200                                                         printf("omit: offset=0x%x symbol=%s%s "
1201                                                                 "section=%s size=%d LO16\n", 
1202                                                                 q->address, sym_name, addstr,
1203                                                                 section_name, sym_reloc_size);
1204                                                 continue;
1205                                         }
1206
1207                                         /* error, fall through */
1208
1209                                 case R_NIOS2_S16:
1210                                 case R_NIOS2_U16:
1211                                 case R_NIOS2_CACHE_OPX:
1212                                 case R_NIOS2_IMM5:
1213                                 case R_NIOS2_IMM6:
1214                                 case R_NIOS2_IMM8:
1215                                 case R_NIOS2_BFD_RELOC_16:
1216                                 case R_NIOS2_BFD_RELOC_8:
1217                                 case R_NIOS2_GNU_VTINHERIT:
1218                                 case R_NIOS2_GNU_VTENTRY:
1219                                 case R_NIOS2_UJMP:
1220                                 case R_NIOS2_CJMP:
1221                                 case R_NIOS2_CALLR:
1222 NIOS2_RELOC_ERR:
1223                                         printf("Err: unexpected reloc type %s(%d)\n", q->howto->name, q->howto->type);
1224                                         bad_relocs++;
1225                                         continue;
1226                         }
1227 #endif /* TARGET_nios2 */
1228
1229 #ifdef TARGET_sparc
1230                                 case R_SPARC_32:
1231                                 case R_SPARC_UA32:
1232                                         relocation_needed = 1;
1233                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
1234                                         sym_addr += sym_vma + q->addend;
1235                                         break;
1236                                 case R_SPARC_PC22:
1237                                         sym_vma = 0;
1238                                         sym_addr += sym_vma + q->addend;
1239                                         sym_addr -= q->address;
1240                                         break;
1241                                 case R_SPARC_WDISP30:
1242                                         sym_addr = (((*(q->sym_ptr_ptr))->value-
1243                                                 q->address) >> 2) & 0x3fffffff;
1244                                         sym_addr |= (
1245                                                 ntohl(*(unsigned long *)r_mem)
1246                                                 & 0xc0000000
1247                                                 );
1248                                         break;
1249                                 case R_SPARC_HI22:
1250                                         relocation_needed = 1;
1251                                         pflags = 0x80000000;
1252                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
1253                                         sym_addr += sym_vma + q->addend;
1254                                         sym_addr |= (
1255                                                 htonl(*(unsigned long *)r_mem)
1256                                                 & 0xffc00000
1257                                                 );
1258                                         break;
1259                                 case R_SPARC_LO10:
1260                                         relocation_needed = 1;
1261                                         pflags = 0x40000000;
1262                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
1263                                         sym_addr += sym_vma + q->addend;
1264                                         sym_addr &= 0x000003ff;
1265                                         sym_addr |= (
1266                                                 htonl(*(unsigned long *)r_mem)
1267                                                 & 0xfffffc00
1268                                                 );
1269                                         break;
1270 #endif /* TARGET_sparc */
1271
1272 #ifdef TARGET_bfin
1273                                 case R_pcrel12_jump:
1274                                 case R_pcrel12_jump_s:
1275                                 case R_pcrel24:
1276                                 case R_pcrel24_jump_l:
1277                                 case R_pcrel24_jump_x:
1278                                 case R_pcrel24_call_x:
1279                                 case R_pcrel10:
1280                                 case R_pcrel11:
1281                                 case R_pcrel5m2:
1282                                   sym_addr += q->addend;// get the symbol addr
1283                                   sym_vma = bfd_section_vma(abs_bfd, sym_section);
1284                                   sym_addr -= q->address; // make it PC relative 
1285                                   // implicitly assumes code section and symbol section are same
1286                                   break;
1287                                 
1288                                 case R_rimm16:
1289                                     if (is_reloc_stack_empty ())
1290                                     {
1291                                         sym_addr += q->addend;
1292                                     } else {
1293                                         sym_addr = reloc_stack_pop ();
1294                                     }
1295                                     if(weak_und_symbol(sym_section->name, (*(q->sym_ptr_ptr))))
1296                                         continue;
1297                                     if(0xFFFF0000 & sym_addr){
1298                                         fprintf (stderr, "Relocation overflow for rN = %s\n",sym_name);
1299                                         bad_relocs++;
1300                                     }
1301                                     flat_relocs = (uint32_t *)
1302                                         (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1303                                     if (bfin_set_reloc (flat_relocs + flat_reloc_count, 
1304                                                         sym_section->name, sym_name,
1305                                                         (*(q->sym_ptr_ptr)),
1306                                                         0, FLAT_RELOC_PART_LO, 
1307                                                         section_vma + q->address))
1308                                         bad_relocs++;
1309                                     flat_reloc_count++;
1310                                     break;
1311                                     
1312                                 case R_luimm16:
1313                                 case R_huimm16:
1314                                 {
1315                                     unsigned int sp;
1316                                     unsigned int reloc_count_incr;
1317                                     unsigned int hi_lo;
1318
1319                                     if (q->howto->type == R_luimm16)
1320                                         hi_lo = FLAT_RELOC_PART_LO;
1321                                     else
1322                                         hi_lo = FLAT_RELOC_PART_HI;
1323                                 
1324                                     if (is_reloc_stack_empty ())
1325                                         sym_addr += q->addend;
1326                                     else
1327                                         sym_addr = reloc_stack_pop ();
1328                                     
1329                                     flat_relocs = (uint32_t *)
1330                                         (realloc (flat_relocs, (flat_reloc_count + 2) * sizeof (uint32_t)));
1331                                     reloc_count_incr = 1;
1332                                     if (weak_und_symbol (sym_section->name, (*(q->sym_ptr_ptr))))
1333                                         continue;
1334                                     if (0xFFFF0000 & sym_addr) {
1335                                         /* value is > 16 bits - use an extra field */
1336                                         /* see if we have already output that symbol */
1337                                         /* reloc may be addend from symbol and       */
1338                                         /* we can only store 16 bit offsets          */
1339                                         sp = 1;
1340                                         if ((*(q->sym_ptr_ptr))->udata.i == 0
1341                                             || flat_relocs[(*(q->sym_ptr_ptr))->udata.i] != sym_addr
1342                                             || ((*(q->sym_ptr_ptr))->udata.i & 0xFFFF0000))
1343                                         {
1344                                             reloc_count_incr = 2;
1345                                             flat_relocs[flat_reloc_count + 1] = sym_addr;
1346                                             (*(q->sym_ptr_ptr))->udata.i = flat_reloc_count + 1;
1347                                             sym_addr = 0; // indication to loader to read next
1348                                         } else{
1349                                             sym_addr = (*(q->sym_ptr_ptr))->udata.i;
1350                                         }
1351                                     } else {
1352                                         sp = 0;
1353                                     }
1354
1355                                     if (bfin_set_reloc (flat_relocs + flat_reloc_count, 
1356                                                         sym_section->name, sym_name,
1357                                                         (*(q->sym_ptr_ptr)),
1358                                                         sp, hi_lo,
1359                                                         section_vma + q->address))
1360                                         bad_relocs++;
1361                                     flat_reloc_count += reloc_count_incr;
1362                                     break;
1363                                 }
1364                                 case R_byte4_data:
1365                                     if (is_reloc_stack_empty ())
1366                                         sym_addr += q->addend;
1367                                     else
1368                                         sym_addr = reloc_stack_pop ();
1369                                     if (weak_und_symbol (sym_section->name, *q->sym_ptr_ptr))
1370                                         continue;
1371
1372                                     flat_relocs = (uint32_t *)
1373                                         (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
1374                                     if (bfin_set_reloc (flat_relocs + flat_reloc_count, 
1375                                                         sym_section->name, sym_name,
1376                                                         (*(q->sym_ptr_ptr)),
1377                                                         2, FLAT_RELOC_PART_LO, 
1378                                                         section_vma + q->address))
1379                                         bad_relocs++;
1380
1381                                     flat_reloc_count++;
1382                                     break;
1383
1384                                 case 0xE0: 
1385                                    /* push */
1386                                   sym_addr += q->addend;
1387                                   reloc_stack_push(sym_addr);
1388                                   reloc_stack_set_section(sym_section, section_name);
1389                                   break;
1390
1391                                 case 0xE1:
1392                                   /* const */
1393                                   reloc_stack_push(q->addend);
1394                                 break;
1395
1396                                 case 0xE2 ... 0xF2:
1397                                   reloc_stack_operate((*p)->howto->type);
1398                                   break;
1399
1400 #endif //TARGET_bfin
1401
1402 #ifdef TARGET_sh
1403                                 case R_SH_DIR32:
1404                                         relocation_needed = 1;
1405                                         sym_vma = bfd_section_vma(abs_bfd, sym_section);
1406                                         sym_addr += sym_vma + q->addend;
1407                                         break;
1408                                 case R_SH_REL32:
1409                                         sym_vma = 0;
1410                                         sym_addr += sym_vma + q->addend;
1411                                         sym_addr -= q->address;
1412                                         break;
1413 #endif /* TARGET_sh */
1414
1415 #ifdef TARGET_e1
1416 #define  htoe1l(x)              htonl(x)
1417                                         
1418 #if 0 
1419 #define  DEBUG_E1
1420 #endif
1421
1422 #ifdef   DEBUG_E1
1423 #define  DBG_E1                 printf
1424 #else
1425 #define  DBG_E1(x, ...  )
1426 #endif
1427
1428 #define _32BITS_RELOC 0x00000000
1429 #define _30BITS_RELOC 0x80000000
1430 #define _28BITS_RELOC 0x40000000
1431                                         {
1432                                 char *p;
1433                                 unsigned long   sec_vma, exist_val, S;
1434                                 case R_E1_CONST31:
1435                                                 relocation_needed = 1;
1436                                                 DBG_E1("Handling Reloc <CONST31>\n");
1437                                                 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1438                                                 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1439                                                                                 sec_vma, sym_addr, q->address);
1440                                                 sym_addr = sec_vma + sym_addr;
1441                                                 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);        
1442                                                 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1443                                                 exist_val = htoe1l(exist_val);
1444                                                 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1445                                                 sym_addr += exist_val;
1446                                                 pflags = _30BITS_RELOC;
1447                                                 break;
1448                                 case R_E1_CONST31_PCREL:
1449                                                 relocation_needed = 0;
1450                                                 DBG_E1("Handling Reloc <CONST31_PCREL>\n");
1451                                                 DBG_E1("DONT RELOCATE AT LOADING\n");
1452                                                 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1453                                                 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1454                                                                                 sec_vma, sym_addr, q->address);
1455                                                 sym_addr =  sec_vma + sym_addr;
1456                                                 DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%x]\n", sym_addr );
1457
1458                                                 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1459                                                                                                                                                 section_vma );
1460                                                 q->address = q->address + section_vma;
1461                                                 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1462
1463                                                 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1464                                                                 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1465                                                 DBG_E1( "sym_addr := sym_addr - q->address  - "
1466                                                                 "sizeof(CONST31_PCREL): [0x%x]\n",
1467                                                                 sym_addr );
1468                                                 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);              
1469                                                 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1470                                                 exist_val = htoe1l(exist_val);
1471                                                 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1472                                                 sym_addr |= exist_val;
1473                                                 DBG_E1("sym_addr |=  exist_val) : [0x%x]\n", sym_addr );
1474                                                 break;
1475                                 case R_E1_DIS29W_PCREL:
1476                                                 relocation_needed = 0;
1477                                                 DBG_E1("Handling Reloc <DIS29W_PCREL>\n");
1478                                                 DBG_E1("DONT RELOCATE AT LOADING\n");
1479                                                 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1480                                                 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1481                                                                                 sec_vma, sym_addr, q->address);
1482                                                 sym_addr =  sec_vma + sym_addr;
1483                                                 DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%x]\n", sym_addr );
1484
1485                                                 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1486                                                                                                                                                 section_vma );
1487                                                 q->address = q->address + section_vma;
1488                                                 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1489
1490                                                 if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1491                                                                 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1492                                                 DBG_E1( "sym_addr := sym_addr - q->address  - "
1493                                                                 "sizeof(CONST31_PCREL): [0x%x]\n",
1494                                                                 sym_addr );
1495                                                 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1496                                                 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);       
1497                                                 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1498                                                 exist_val = htoe1l(exist_val);
1499                                                 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1500                                                 sym_addr += exist_val;
1501                                                 break;
1502                                 case R_E1_DIS29W:
1503                                                 DBG_E1("Handling Reloc <DIS29W>\n");
1504                                                 goto DIS29_RELOCATION;
1505                                 case R_E1_DIS29H:
1506                                                 DBG_E1("Handling Reloc <DIS29H>\n");
1507                                                 goto DIS29_RELOCATION;
1508                                 case R_E1_DIS29B:
1509                                                 DBG_E1("Handling Reloc <DIS29B>\n");
1510 DIS29_RELOCATION:
1511                                                 relocation_needed = 1;
1512                                                 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1513                                                 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%08x]\n",
1514                                                                                 sec_vma, sym_addr);
1515                                                 sym_addr =  sec_vma + sym_addr;
1516                                                 DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%08x]\n", sym_addr);
1517                                                 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);                
1518                                                 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1519                                                 exist_val = htoe1l(exist_val);
1520                                                 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1521                                                 sym_addr +=  exist_val;
1522                                                 DBG_E1("sym_addr +=  exist_val : [0x%08x]\n", sym_addr);
1523                                                 pflags = _28BITS_RELOC;
1524                                                 break;
1525                                 case R_E1_IMM32_PCREL:
1526                                                 relocation_needed = 0;
1527                                                 DBG_E1("Handling Reloc <IMM32_PCREL>\n");
1528                                                 DBG_E1("DONT RELOCATE AT LOADING\n");
1529                                                 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1530                                                 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1531                                                                                 sec_vma, sym_addr);
1532                                                 sym_addr =  sec_vma + sym_addr;
1533
1534                                                 DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%x]\n", sym_addr );
1535                                                 DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1536                                                                                                                                                 section_vma );
1537                                                 q->address = q->address + section_vma;
1538                                                 DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1539
1540                                                 if( (sym_addr = (sym_addr - q->address - 6 )) < 0 )
1541                                                                 DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1542                                                 DBG_E1( "sym_addr := sym_addr - q->address  - "
1543                                                                 "sizeof(CONST31_PCREL): [0x%x]\n",
1544                                                                 sym_addr );
1545                                                 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1546                                                 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);                 
1547                                                 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1548                                                 exist_val = htoe1l(exist_val);
1549                                                 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1550                                                 sym_addr += exist_val;
1551                                                 break;
1552                                 case R_E1_IMM32:
1553                                                 relocation_needed = 1;
1554                                                 DBG_E1("Handling Reloc <IMM32>\n");
1555                                                 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1556                                                 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1557                                                                                 sec_vma, sym_addr);
1558                                                 sym_addr =  sec_vma + sym_addr;
1559                                                 DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%x]\n", sym_addr );
1560                                                 DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1561                                                 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);                     
1562                                                 DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1563                                                 exist_val = htoe1l(exist_val);
1564                                                 DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1565                                                 sym_addr += exist_val;
1566                                                 pflags = _32BITS_RELOC;
1567                                                 break;
1568                                 case R_E1_WORD:
1569                                                 relocation_needed = 1;
1570                                                 DBG_E1("Handling Reloc <WORD>\n");
1571                                                 sec_vma = bfd_section_vma(abs_bfd, sym_section);
1572                                                 DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1573                                                                                 sec_vma, sym_addr);
1574                                                 sym_addr =  sec_vma + sym_addr;
1575                                                 DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%x]\n", sym_addr );
1576                                                 exist_val = *(unsigned long*)((unsigned long)sectionp + q->address );
1577                                                 DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1578                                                 exist_val = htoe1l(exist_val);
1579                                                 DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1580                                                 sym_addr +=  exist_val;
1581                                                 DBG_E1("sym_addr +=  exist_val : [0x%08x]\n", sym_addr);
1582                                                 pflags = _32BITS_RELOC;
1583                                                 break;
1584                                 }
1585 #undef _32BITS_RELOC
1586 #undef _30BITS_RELOC
1587 #undef _28BITS_RELOC
1588 #endif
1589                                 default:
1590                                         /* missing support for other types of relocs */
1591                                         printf("ERROR: bad reloc type %d\n", (*p)->howto->type);
1592                                         bad_relocs++;
1593                                         continue;
1594                                 }
1595                         }
1596
1597                         sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
1598                                          bfd_section_vma(abs_bfd, sym_section));
1599
1600
1601                         /*
1602                          * for full elf relocation we have to write back the
1603                          * start_code relative value to use.
1604                          */
1605                         if (!pic_with_got) {
1606 #if defined(TARGET_arm)
1607                                 union {
1608                                         unsigned char c[4];
1609                                         unsigned long l;
1610                                 } tmp;
1611                                 long hl;
1612                                 int i0, i1, i2, i3;
1613
1614                                 /*
1615                                  * horrible nasty hack to support different endianess
1616                                  */
1617                                 if (!bfd_big_endian(abs_bfd)) {
1618                                         i0 = 0;
1619                                         i1 = 1;
1620                                         i2 = 2;
1621                                         i3 = 3;
1622                                 } else {
1623                                         i0 = 3;
1624                                         i1 = 2;
1625                                         i2 = 1;
1626                                         i3 = 0;
1627                                 }
1628
1629                                 tmp.l = *(unsigned long *)r_mem;
1630                                 hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16);
1631                                 if (((*p)->howto->type != R_ARM_PC24) &&
1632                                     ((*p)->howto->type != R_ARM_PLT32))
1633                                         hl |= (tmp.c[i3] << 24);
1634                                 else if (tmp.c[i2] & 0x80)
1635                                         hl |= 0xff000000; /* sign extend */
1636                                 hl += sym_addr;
1637                                 tmp.c[i0] = hl & 0xff;
1638                                 tmp.c[i1] = (hl >> 8) & 0xff;
1639                                 tmp.c[i2] = (hl >> 16) & 0xff;
1640                                 if (((*p)->howto->type != R_ARM_PC24) &&
1641                                     ((*p)->howto->type != R_ARM_PLT32))
1642                                         tmp.c[i3] = (hl >> 24) & 0xff;
1643                                 if ((*p)->howto->type == R_ARM_ABS32)
1644                                         *(unsigned long *)r_mem = htonl(hl);
1645                                 else
1646                                         *(unsigned long *)r_mem = tmp.l;
1647
1648 #elif defined(TARGET_bfin)
1649                                 if ((*p)->howto->type == R_pcrel24
1650                                     || (*p)->howto->type == R_pcrel24_jump_l
1651                                     || (*p)->howto->type == R_pcrel24_jump_x
1652                                     || (*p)->howto->type == R_pcrel24_call_x)
1653                                 {
1654                                     sym_addr += 2*-1*PCREL24_MAGIC_OFFSET;
1655                                     *((unsigned short *)(sectionp + q->address) + 1 + PCREL24_MAGIC_OFFSET)
1656                                         = (sym_addr >> 1) & 0xffff;
1657                                     *((unsigned short *)(sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1658                                         = (0xff00 & *((unsigned short *) (sectionp + q->address) + PCREL24_MAGIC_OFFSET)
1659                                            | ((sym_addr >> 17) & 0xff));
1660                                 } else if ((*p)->howto->type == R_byte4_data) {
1661                                     *((uint32_t *)(sectionp + q->address)) = sym_addr;
1662                                 } else if ((*p)->howto->type == R_pcrel12_jump
1663                                            || (*p)->howto->type == R_pcrel12_jump_s) {
1664                                     *((unsigned short *)(sectionp + q->address))
1665                                         = (0xf000 & *((unsigned short *)(sectionp + q->address))
1666                                            | ((sym_addr >> 1) & 0xfff));
1667                                 } else if ((*p)->howto->type == R_pcrel10) {
1668                                     *((unsigned short *)(sectionp + q->address))
1669                                         = (~0x3ff & *((unsigned short *)(sectionp + q->address))
1670                                            | ((sym_addr >> 1) & 0x3ff));
1671                                 } else if ((*p)->howto->type == R_rimm16
1672                                            || (*p)->howto->type == R_huimm16
1673                                            || (*p)->howto->type == R_luimm16) {
1674                                     /* for l and h we set the lower 16 bits which is only when it will be used */
1675                                     *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1676                                 } else if ((*p)->howto->type == R_pcrel5m2) {
1677                                     *((unsigned short *)(sectionp + q->address))
1678                                         = (0xfff0 & *((unsigned short *)(sectionp + q->address))
1679                                            | ((sym_addr >> 1) & 0xf));
1680                                 } else if ((*p)->howto->type == R_pcrel11){
1681                                     *((unsigned short *)(sectionp + q->address))
1682                                         = (0xfc00 & *((unsigned short *)(sectionp + q->address))
1683                                            | ((sym_addr >> 1) & 0x3ff));
1684                                 } else if (0xE0 <= (*p)->howto->type && 0xF3 >= (*p)->howto->type) {
1685                                     //arith relocs dont generate a real relocation
1686                                 } else {
1687                                     printf("Blackfin relocation fail for reloc type: 0x%x\n", (*p)->howto->type);
1688                                 }
1689 #elif defined(TARGET_e1)
1690 #define OPCODE_SIZE 2           /* Add 2 bytes, counting the opcode size*/
1691                                 switch ((*p)->howto->type) {
1692                                 case R_E1_CONST31:
1693                                 case R_E1_CONST31_PCREL:
1694                                 case R_E1_DIS29W_PCREL:
1695                                 case R_E1_DIS29W:
1696                                 case R_E1_DIS29H:
1697                                 case R_E1_DIS29B:
1698                                 case R_E1_IMM32_PCREL:
1699                                 case R_E1_IMM32:
1700                                                 DBG_E1("In addr + 2:[0x%x] <- write [0x%x]\n",
1701                                                                 (sectionp + q->address + 2), sym_addr );
1702                                                 *((unsigned long *) (sectionp + q->address + OPCODE_SIZE)) =
1703                                                 htonl(sym_addr);
1704                                 break;
1705                                 case R_E1_WORD:
1706                                                 DBG_E1("In addr : [0x%x] <- write [0x%x]\n",
1707                                                                 (sectionp + q->address), sym_addr );
1708                                                 *((unsigned long *) (sectionp + q->address )) = htonl(sym_addr);
1709                                 break;
1710                                 default:
1711                                                 printf("ERROR:Unhandled Relocation. Exiting...\n");
1712                                                 exit(0);
1713                                 break;
1714                                 }
1715 #else /* ! TARGET_arm && ! TARGET_e1 */
1716
1717                                 switch (q->howto->type) {
1718 #ifdef TARGET_v850
1719                                 case R_V850_HI16_S:
1720                                 case R_V850_HI16:
1721                                 case R_V850_LO16:
1722                                         /* Do nothing -- for cases we handle,
1723                                            the bits produced by the linker are
1724                                            what we want in the final flat file
1725                                            (and other cases are errors).  Note
1726                                            that unlike most relocated values,
1727                                            it is stored in little-endian order,
1728                                            but this is necessary to avoid
1729                                            trashing the low-bit, and the float
1730                                            loaders knows about it.  */
1731                                         break;
1732 #endif /* TARGET_V850 */
1733
1734 #ifdef TARGET_nios2
1735                                 case R_NIOS2_BFD_RELOC_32:
1736                                 case R_NIOS2_CALL26:
1737                                 case R_NIOS2_HIADJ16:
1738                                 case R_NIOS2_HI16:
1739                                         /* do nothing */
1740                                         break;
1741 #endif /* TARGET_nios2 */
1742
1743 #if defined(TARGET_m68k)
1744                                 case R_68K_PC16:
1745                                         if (sym_addr < -0x8000 || sym_addr > 0x7fff) {
1746                                                 fprintf (stderr, "Relocation overflow for R_68K_PC16 relocation against %s\n", sym_name);
1747                                                 bad_relocs++;
1748                                         } else {
1749                                                 r_mem[0] = (sym_addr >>  8) & 0xff;
1750                                                 r_mem[1] =  sym_addr        & 0xff;
1751                                         }
1752                                         break;
1753 #endif
1754
1755                                 default:
1756                                         /* The alignment of the build host
1757                                            might be stricter than that of the
1758                                            target, so be careful.  We store in
1759                                            network byte order. */
1760                                         r_mem[0] = (sym_addr >> 24) & 0xff;
1761                                         r_mem[1] = (sym_addr >> 16) & 0xff;
1762                                         r_mem[2] = (sym_addr >>  8) & 0xff;
1763                                         r_mem[3] =  sym_addr        & 0xff;
1764                                 }
1765 #endif /* !TARGET_arm */
1766                         }
1767
1768 #ifdef TARGET_bfin
1769                         else {
1770                             if ((*p)->howto->type == R_rimm16
1771                                 || (*p)->howto->type == R_huimm16
1772                                 || (*p)->howto->type == R_luimm16)
1773                             {
1774                                 /* for l and h we set the lower 16 bits which is only when it will be used */
1775                                 *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
1776                             } else if ((*p)->howto->type == R_byte4_data) {
1777                                 *((uint32_t *)(sectionp + q->address)) = sym_addr;
1778                             }
1779                         }
1780 #endif
1781                         if (verbose)
1782                                 printf("  RELOC[%d]: offset=0x%x symbol=%s%s "
1783                                         "section=%s size=%d "
1784                                         "fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
1785                                         q->address, sym_name, addstr,
1786                                         section_name, sym_reloc_size,
1787                                         sym_addr, section_vma + q->address);
1788
1789                         /*
1790                          *      Create relocation entry (PC relative doesn't need this).
1791                          */
1792                         if (relocation_needed) {
1793 #ifndef TARGET_bfin
1794                                 flat_relocs = realloc(flat_relocs,
1795                                         (flat_reloc_count + 1) * sizeof(uint32_t));
1796 #ifndef TARGET_e1
1797                                 flat_relocs[flat_reloc_count] = pflags |
1798                                         (section_vma + q->address);
1799
1800                                 if (verbose)
1801                                         printf("reloc[%d] = 0x%x\n", flat_reloc_count,
1802                                                         section_vma + q->address);
1803 #else
1804                                 switch ((*p)->howto->type) {
1805                                 case R_E1_CONST31:
1806                                 case R_E1_CONST31_PCREL:
1807                                 case R_E1_DIS29W_PCREL:
1808                                 case R_E1_DIS29W:
1809                                 case R_E1_DIS29H:
1810                                 case R_E1_DIS29B:
1811                                 case R_E1_IMM32_PCREL:
1812                                 case R_E1_IMM32:
1813                                 flat_relocs[flat_reloc_count] = pflags |
1814                                                 (section_vma + q->address + OPCODE_SIZE);
1815                                 if (verbose)
1816                                                 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1817                                                                                  flat_relocs[flat_reloc_count] );
1818                                 break;
1819                                 case R_E1_WORD:
1820                                 flat_relocs[flat_reloc_count] = pflags |
1821                                                 (section_vma + q->address);
1822                                 if (verbose)
1823                                                 printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1824                                                                                  flat_relocs[flat_reloc_count] );
1825                                 break;
1826                                 }
1827 #endif
1828                                 flat_reloc_count++;
1829 #endif
1830                                 relocation_needed = 0;
1831                                 pflags = 0;
1832                         }
1833
1834 #if 0
1835 printf("%s(%d): symbol name=%s address=0x%x section=%s -> RELOC=0x%x\n",
1836         __FILE__, __LINE__, sym_name, q->address, section_name,
1837         flat_relocs[flat_reloc_count]);
1838 #endif
1839                 }
1840         }
1841   }
1842
1843   if (bad_relocs) {
1844           printf("%d bad relocs\n", bad_relocs);
1845           exit(1);
1846   }
1847
1848   if (rc < 0)
1849         return(0);
1850
1851   *n_relocs = flat_reloc_count;
1852   return flat_relocs;
1853 }
1854
1855
1856
1857 static char * program;
1858
1859 static void usage(void)
1860 {  
1861     fprintf(stderr, "Usage: %s [vrzd] [-p <abs-pic-file>] [-s stack-size] "
1862         "[-o <output-file>] <elf-file>\n\n"
1863         "       -v              : verbose operation\n"
1864         "       -r              : force load to RAM\n"
1865         "       -k              : enable kernel trace on load (for debug)\n"
1866         "       -z              : compress code/data/relocs\n"
1867         "       -d              : compress data/relocs\n"
1868         "       -a              : use existing symbol references\n"
1869         "                         instead of recalculating from\n"
1870         "                         relocation info\n"
1871         "       -R reloc-file   : read relocations from a separate file\n"
1872         "       -p abs-pic-file : GOT/PIC processing with files\n"
1873         "       -s stacksize    : set application stack size\n"
1874         "       -o output-file  : output file name\n\n",
1875         program);
1876         fprintf(stderr, "Compiled for " ARCH " architecture\n\n");
1877     exit(2);
1878 }
1879
1880
1881 /* Write NUM zeroes to STREAM.  */
1882 static void write_zeroes (unsigned long num, FILE *stream)
1883 {
1884   char zeroes[1024];
1885   if (num > 0) {
1886     /* It'd be nice if we could just use fseek, but that doesn't seem to
1887        work for stdio output files.  */
1888     bzero(zeroes, 1024);
1889     while (num > sizeof(zeroes)) {
1890       fwrite(zeroes, sizeof(zeroes), 1, stream);
1891       num -= sizeof(zeroes);
1892     }
1893     if (num > 0)
1894       fwrite(zeroes, num, 1, stream);
1895   }
1896 }
1897
1898
1899 int main(int argc, char *argv[])
1900 {
1901   int fd;
1902   bfd *rel_bfd, *abs_bfd;
1903   asection *s;
1904   char *ofile=NULL, *pfile=NULL, *abs_file = NULL, *rel_file = NULL;
1905   char *fname = NULL;
1906   int opt;
1907   int i;
1908   int stack;
1909   char  cmd[1024];
1910   FILE *gf = NULL;
1911
1912   asymbol **symbol_table;
1913   long number_of_symbols;
1914
1915   unsigned long data_len = 0;
1916   unsigned long bss_len = 0;
1917   unsigned long text_len = 0;
1918   unsigned long reloc_len;
1919
1920   unsigned long data_vma = ~0;
1921   unsigned long bss_vma = ~0;
1922   unsigned long text_vma = ~0;
1923
1924   unsigned long text_offs;
1925
1926   void *text;
1927   void *data;
1928   uint32_t *reloc;
1929   
1930   struct flat_hdr hdr;
1931
1932   int gf_is_pipe = 0;
1933
1934   program = argv[0];
1935   progname = argv[0];
1936
1937   if (argc < 2)
1938         usage();
1939   
1940   if (sizeof(hdr) != 64) {
1941     fprintf(stderr,
1942             "Potential flat header incompatibility detected\n"
1943             "header size should be 64 but is %d\n",
1944             sizeof(hdr));
1945     exit(64);
1946   }
1947
1948 #ifndef TARGET_e1
1949   stack = 4096;
1950 #else /* We need plenty of stack for both of them (Aggregate and Register) */
1951   stack = 0x2020;
1952 #endif
1953
1954   while ((opt = getopt(argc, argv, "avzdrkp:s:o:R:")) != -1) {
1955     switch (opt) {
1956     case 'v':
1957       verbose++;
1958       break;
1959     case 'r':
1960       load_to_ram++;
1961       break;
1962     case 'k':
1963       ktrace++;
1964       break;
1965     case 'z':
1966       compress = 1;
1967       break;
1968     case 'd':
1969       compress = 2;
1970       break;
1971     case 'p':
1972       pfile = optarg;
1973       break;
1974     case 'o':
1975       ofile = optarg;
1976       break;
1977     case 'a':
1978       use_resolved = 1;
1979       break;
1980     case 's':
1981       stack = atoi(optarg);
1982       break;
1983     case 'R':
1984       rel_file = optarg;
1985       break;
1986     default:
1987       fprintf(stderr, "%s Unknown option\n", argv[0]);
1988       usage();
1989       break;
1990     }
1991   }
1992   
1993   /*
1994    * if neither the -r or -p options was given,  default to
1995    * a RAM load as that is the only option that makes sense.
1996    */
1997   if (!load_to_ram && !pfile)
1998     load_to_ram = 1;
1999
2000   filename = fname = argv[argc-1];
2001
2002   if (pfile) {
2003     pic_with_got = 1;
2004     abs_file = pfile;
2005   } else
2006     abs_file = fname;
2007
2008   if (! rel_file)
2009     rel_file = fname;
2010
2011   if (!(rel_bfd = bfd_openr(rel_file, 0))) {
2012     fprintf(stderr, "Can't open %s\n", rel_file);
2013     exit(1);
2014   }
2015
2016   if (bfd_check_format (rel_bfd, bfd_object) == 0) {
2017     fprintf(stderr, "File is not an object file\n");
2018     exit(2);
2019   }
2020
2021   if (abs_file == rel_file)
2022     abs_bfd = rel_bfd; /* one file does all */
2023   else {
2024     if (!(abs_bfd = bfd_openr(abs_file, 0))) {
2025       fprintf(stderr, "Can't open %s\n", abs_file);
2026       exit(1);
2027     }
2028
2029     if (bfd_check_format (abs_bfd, bfd_object) == 0) {
2030       fprintf(stderr, "File is not an object file\n");
2031       exit(2);
2032     }
2033   }
2034
2035   if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC)) {
2036     fprintf (stderr, "%s: Input file contains no relocation info\n", rel_file);
2037     exit (2);
2038   }
2039
2040   if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P)) {
2041     /* `Absolute' file is not absolute, so neither are address
2042        contained therein.  */
2043     fprintf (stderr,
2044              "%s: `-a' option specified with non-fully-resolved input file\n",
2045              bfd_get_filename (abs_bfd));
2046     exit (2);
2047   }
2048
2049   symbol_table = get_symbols(abs_bfd, &number_of_symbols);
2050
2051   /* Group output sections into text, data, and bss, and calc their sizes.  */
2052   for (s = abs_bfd->sections; s != NULL; s = s->next) {
2053     unsigned long *vma, *len;
2054     bfd_size_type sec_size;
2055     bfd_vma sec_vma;
2056
2057     if (s->flags & SEC_CODE) {
2058       vma = &text_vma;
2059       len = &text_len;
2060     } else if (s->flags & SEC_DATA) {
2061       vma = &data_vma;
2062       len = &data_len;
2063     } else if (s->flags & SEC_ALLOC) {
2064       vma = &bss_vma;
2065       len = &bss_len;
2066     } else
2067       continue;
2068
2069     sec_size = bfd_section_size(abs_bfd, s);
2070     sec_vma  = bfd_section_vma(abs_bfd, s);
2071
2072     if (sec_vma < *vma) {
2073       if (*len > 0)
2074         *len += sec_vma - *vma;
2075       else
2076         *len = sec_size;
2077       *vma = sec_vma;
2078     } else if (sec_vma + sec_size > *vma + *len)
2079       *len = sec_vma + sec_size - *vma;
2080   }
2081
2082   if (text_len == 0) {
2083     fprintf (stderr, "%s: no .text section", abs_file);
2084     exit (2);
2085   }
2086
2087   text = malloc(text_len);
2088
2089   if (verbose)
2090     printf("TEXT -> vma=0x%x len=0x%x\n", text_vma, text_len);
2091
2092   /* Read in all text sections.  */
2093   for (s = abs_bfd->sections; s != NULL; s = s->next)
2094     if (s->flags & SEC_CODE) 
2095       if (!bfd_get_section_contents(abs_bfd, s,
2096                                    text + (s->vma - text_vma), 0,
2097                                    bfd_section_size(abs_bfd, s)))
2098       {
2099         fprintf(stderr, "read error section %s\n", s->name);
2100         exit(2);
2101       }
2102
2103   if (data_len == 0) {
2104     fprintf (stderr, "%s: no .data section", abs_file);
2105     exit (2);
2106   }
2107   data = malloc(data_len);
2108
2109   if (verbose)
2110     printf("DATA -> vma=0x%x len=0x%x\n", data_vma, data_len);
2111
2112   if ((text_vma + text_len) != data_vma) {
2113     if ((text_vma + text_len) > data_vma) {
2114       printf("ERROR: text=0x%x overlaps data=0x%x ?\n", text_len, data_vma);
2115       exit(1);
2116     }
2117     if (verbose)
2118       printf("WARNING: data=0x%x does not directly follow text=0x%x\n",
2119                         data_vma, text_len);
2120     text_len = data_vma - text_vma;
2121   }
2122
2123   /* Read in all data sections.  */
2124   for (s = abs_bfd->sections; s != NULL; s = s->next)
2125     if (s->flags & SEC_DATA) 
2126       if (!bfd_get_section_contents(abs_bfd, s,
2127                                    data + (s->vma - data_vma), 0,
2128                                    bfd_section_size(abs_bfd, s)))
2129       {
2130         fprintf(stderr, "read error section %s\n", s->name);
2131         exit(2);
2132       }
2133
2134   /* Put common symbols in bss.  */
2135   bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len);
2136
2137   if (verbose)
2138     printf("BSS  -> vma=0x%x len=0x%x\n", bss_vma, bss_len);
2139
2140   if ((data_vma + data_len) != bss_vma) {
2141     if ((data_vma + data_len) > bss_vma) {
2142       printf("ERROR: text=0x%x + data=0x%x overlaps bss=0x%x ?\n", text_len,
2143                         data_len, bss_vma);
2144       exit(1);
2145     }
2146     if (verbose)
2147       printf("WARNING: bss=0x%x does not directly follow text=0x%x + data=0x%x(0x%x)\n",
2148                 bss_vma, text_len, data_len, text_len + data_len);
2149     data_len = bss_vma - data_vma;
2150   }
2151
2152   reloc = output_relocs(abs_bfd, symbol_table, number_of_symbols, &reloc_len,
2153                         text, text_len, text_vma, data, data_len, data_vma,
2154                         rel_bfd);
2155
2156   if (reloc == NULL)
2157     printf("No relocations in code!\n");
2158
2159   text_offs = real_address_bits(text_vma);
2160
2161   /* Fill in the binflt_flat header */
2162   memcpy(hdr.magic,"bFLT",4);
2163   hdr.rev         = htonl(FLAT_VERSION);
2164   hdr.entry       = htonl(sizeof(hdr) + bfd_get_start_address(abs_bfd));
2165   hdr.data_start  = htonl(sizeof(hdr) + text_offs + text_len);
2166   hdr.data_end    = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2167   hdr.bss_end     = htonl(sizeof(hdr) + text_offs + text_len +data_len+bss_len);
2168   hdr.stack_size  = htonl(stack); /* FIXME */
2169   hdr.reloc_start = htonl(sizeof(hdr) + text_offs + text_len +data_len);
2170   hdr.reloc_count = htonl(reloc_len);
2171   hdr.flags       = htonl(0
2172           | (load_to_ram ? FLAT_FLAG_RAM : 0)
2173           | (ktrace ? FLAT_FLAG_KTRACE : 0)
2174           | (pic_with_got ? FLAT_FLAG_GOTPIC : 0)
2175           | (compress ? (compress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
2176           );
2177   hdr.build_date = htonl((unsigned long)time(NULL));
2178   bzero(hdr.filler, sizeof(hdr.filler));
2179
2180   for (i=0; i<reloc_len; i++) reloc[i] = htonl(reloc[i]);
2181
2182   if (verbose) {
2183     printf("SIZE: .text=0x%04x, .data=0x%04x, .bss=0x%04x",
2184         text_len, data_len, bss_len);
2185     if (reloc)
2186       printf(", relocs=0x%04x", reloc_len);
2187     printf("\n");
2188   }
2189   
2190   if (!ofile) {
2191     ofile = malloc(strlen(fname) + 5 + 1); /* 5 to add suffix */
2192     strcpy(ofile, fname);
2193     strcat(ofile, ".bflt");
2194   }
2195
2196   if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0) {
2197     fprintf (stderr, "Can't open output file %s\n", ofile);
2198     exit(4);
2199   }
2200
2201   write(fd, &hdr, sizeof(hdr));
2202   close(fd);
2203
2204   /*
2205    * get the compression command ready
2206    */
2207   sprintf(cmd, "gzip -f -9 >> %s", ofile);
2208
2209 #define START_COMPRESSOR do { \
2210                 if (gf) \
2211                         if (gf_is_pipe) \
2212                                 pclose(gf); \
2213                         else \
2214                                 fclose(gf); \
2215                 if (!(gf = popen(cmd, "w" BINARY_FILE_OPTS))) { \
2216                         fprintf(stderr, "Can't run cmd %s\n", cmd); \
2217                         exit(4); \
2218                 } \
2219                 gf_is_pipe = 1; \
2220         } while (0)
2221
2222   gf = fopen(ofile, "ab");      /* Add 'b' to support non-posix (ie windows) */
2223   if (!gf) {
2224         fprintf(stderr, "Can't open file %s for writing\n", ofile); \
2225         exit(4);
2226   }
2227
2228   if (compress == 1)
2229         START_COMPRESSOR;
2230
2231   /* Fill in any hole at the beginning of the text segment.  */
2232   if (verbose)
2233           printf("ZERO before text len=0x%x\n", text_offs);
2234   write_zeroes(text_offs, gf);
2235
2236   /* Write the text segment.  */
2237   fwrite(text, text_len, 1, gf);
2238
2239   if (compress == 2)
2240         START_COMPRESSOR;
2241
2242   /* Write the data segment.  */
2243   fwrite(data, data_len, 1, gf);
2244
2245   if (reloc)
2246     fwrite(reloc, reloc_len * 4, 1, gf);
2247
2248   if(gf_is_pipe)
2249     pclose(gf);
2250   else
2251   fclose(gf);
2252
2253   exit(0);
2254 }
2255
2256
2257 /*
2258  * this __MUST__ be at the VERY end of the file - do NOT move!!
2259  *
2260  * Local Variables:
2261  * c-basic-offset: 4
2262  * tab-width: 8
2263  * end:
2264  * vi: tabstop=8 shiftwidth=4 textwidth=79 noexpandtab
2265  */