OSDN Git Service

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