OSDN Git Service

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