OSDN Git Service

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