Fix building with --enable-targets=all
[external/binutils.git] / bfd / coff-mcore.c
1 /* BFD back-end for Motorola MCore COFF/PE
2    Copyright (C) 1999 Free Software Foundation, Inc.
3
4 This file is part of BFD, the Binary File Descriptor library.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24 #include "coff/mcore.h"
25 #include "coff/internal.h"
26 #include "coff/pe.h"
27 #include "libcoff.h"
28
29 #ifdef BADMAG
30 #undef BADMAG
31 #endif
32 #define BADMAG(x) MCOREBADMAG(x)
33
34 #ifndef NUM_ELEM
35 #define NUM_ELEM(A) (sizeof (A) / sizeof (A)[0])
36 #endif
37
38 /* This file is compiled more than once, but we only compile the
39    final_link routine once.  */
40 extern boolean mcore_bfd_coff_final_link
41   PARAMS ((bfd *, struct bfd_link_info *));
42
43 static struct bfd_link_hash_table * coff_mcore_link_hash_table_create
44   PARAMS ((bfd *));
45 static bfd_reloc_status_type        mcore_coff_unsupported_reloc 
46   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
47 static boolean                      coff_mcore_relocate_section
48   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
49            struct internal_reloc *, struct internal_syment *, asection **));
50 static reloc_howto_type *           mcore_coff_reloc_type_lookup
51   PARAMS ((bfd *, bfd_reloc_code_real_type));
52 static reloc_howto_type *           coff_mcore_rtype_to_howto
53   PARAMS ((bfd *, asection *, struct internal_reloc *,
54            struct coff_link_hash_entry *, struct internal_syment *, bfd_vma *));
55 \f
56 /* The NT loader points the toc register to &toc + 32768, in order to
57    use the complete range of a 16-bit displacement. We have to adjust
58    for this when we fix up loads displaced off the toc reg.  */
59 #define TOC_LOAD_ADJUSTMENT (-32768)
60 #define TOC_SECTION_NAME ".private.toc"
61
62 /* The main body of code is in coffcode.h.  */
63 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 2
64
65 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
66    from smaller values.  Start with zero, widen, *then* decrement.  */
67 #define MINUS_ONE       (((bfd_vma)0) - 1)
68
69 \f
70 static reloc_howto_type mcore_coff_howto_table[] =
71 {
72   /* Unused: */
73   HOWTO (IMAGE_REL_MCORE_ABSOLUTE,/* type */                                 
74          0,                      /* rightshift */                           
75          0,                      /* size (0 = byte, 1 = short, 2 = long) */ 
76          0,                      /* bitsize */                   
77          false,                  /* pc_relative */                          
78          0,                      /* bitpos */                               
79          complain_overflow_dont, /* dont complain_on_overflow */
80          NULL,                   /* special_function */                     
81          "ABSOLUTE",             /* name */
82          false,                  /* partial_inplace */                      
83          0x00,                   /* src_mask */                             
84          0x00,                   /* dst_mask */                             
85          false),                 /* pcrel_offset */
86   
87   HOWTO (IMAGE_REL_MCORE_ADDR32,/* type */
88          0,                     /* rightshift */                           
89          2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
90          32,                    /* bitsize */                   
91          false,                 /* pc_relative */                          
92          0,                     /* bitpos */                               
93          complain_overflow_bitfield, /* complain_on_overflow */
94          NULL,                  /* special_function */                     
95          "ADDR32",              /* name */
96          true,                  /* partial_inplace */                      
97          0xffffffff,            /* src_mask */                             
98          0xffffffff,            /* dst_mask */                             
99          false),                /* pcrel_offset */
100   
101   /* 8 bits + 2 zero bits; jmpi/jsri/lrw instructions.
102      Should not appear in object files. */
103   HOWTO (IMAGE_REL_MCORE_PCREL_IMM8BY4, /* type */
104          2,                     /* rightshift */
105          1,                     /* size (0 = byte, 1 = short, 2 = long) */
106          8,                     /* bitsize */
107          true,                  /* pc_relative */
108          0,                     /* bitpos */
109          complain_overflow_bitfield, /* complain_on_overflow */
110          mcore_coff_unsupported_reloc, /* special_function */
111          "IMM8BY4",             /* name */
112          false,                 /* partial_inplace */
113          0,                     /* src_mask */
114          0,                     /* dst_mask */
115          true),                 /* pcrel_offset */
116
117   /* bsr/bt/bf/br instructions; 11 bits + 1 zero bit 
118      Span 2k instructions == 4k bytes.
119      Only useful pieces at the relocated address are the opcode (5 bits) */
120   HOWTO (IMAGE_REL_MCORE_PCREL_IMM11BY2,/* type */
121          1,                     /* rightshift */
122          1,                     /* size (0 = byte, 1 = short, 2 = long) */
123          11,                    /* bitsize */
124          true,                  /* pc_relative */
125          0,                     /* bitpos */
126          complain_overflow_signed, /* complain_on_overflow */
127          NULL,                  /* special_function */
128          "IMM11BY2",            /* name */
129          false,                 /* partial_inplace */
130          0x0,                   /* src_mask */
131          0x7ff,                 /* dst_mask */
132          true),                 /* pcrel_offset */
133
134   /* 4 bits + 1 zero bit; 'loopt' instruction only; unsupported. */
135   HOWTO (IMAGE_REL_MCORE_PCREL_IMM4BY2, /* type */
136          1,                     /* rightshift */
137          1,                     /* size (0 = byte, 1 = short, 2 = long) */
138          4,                     /* bitsize */
139          true,                  /* pc_relative */
140          0,                     /* bitpos */
141          complain_overflow_bitfield, /* complain_on_overflow */
142          mcore_coff_unsupported_reloc, /* special_function */
143          "IMM4BY2",              /* name */
144          false,                 /* partial_inplace */
145          0,                     /* src_mask */
146          0,                     /* dst_mask */
147          true),                 /* pcrel_offset */
148
149   /* 32-bit pc-relative. Eventually this will help support PIC code. */
150   HOWTO (IMAGE_REL_MCORE_PCREL_32,/* type */
151          0,                     /* rightshift */
152          2,                     /* size (0 = byte, 1 = short, 2 = long) */
153          32,                    /* bitsize */
154          true,                  /* pc_relative */
155          0,                     /* bitpos */
156          complain_overflow_bitfield, /* complain_on_overflow */
157          NULL,                  /* special_function */
158          "PCREL_32",            /* name */
159          false,                 /* partial_inplace */
160          0x0,                   /* src_mask */
161          0xffffffff,            /* dst_mask */
162          true),                 /* pcrel_offset */
163
164   /* Like PCREL_IMM11BY2, this relocation indicates that there is a
165      'jsri' at the specified address. There is a separate relocation
166      entry for the literal pool entry that it references, but we 
167      might be able to change the jsri to a bsr if the target turns out
168      to be close enough [even though we won't reclaim the literal pool
169      entry, we'll get some runtime efficiency back]. Note that this
170      is a relocation that we are allowed to safely ignore.  */ 
171   HOWTO (IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2,/* type */
172          1,                     /* rightshift */
173          1,                     /* size (0 = byte, 1 = short, 2 = long) */
174          11,                    /* bitsize */
175          true,                  /* pc_relative */
176          0,                     /* bitpos */
177          complain_overflow_signed, /* complain_on_overflow */
178          NULL,                  /* special_function */
179          "JSR_IMM11BY2",        /* name */
180          false,                 /* partial_inplace */
181          0x0,                   /* src_mask */
182          0x7ff,                 /* dst_mask */
183          true),                 /* pcrel_offset */
184   
185   HOWTO (IMAGE_REL_MCORE_RVA,   /* type */
186          0,                     /* rightshift */
187          2,                     /* size (0 = byte, 1 = short, 2 = long) */
188          32,                    /* bitsize */
189          false,                 /* pc_relative */
190          0,                     /* bitpos */
191          complain_overflow_signed, /* complain_on_overflow */
192          NULL,                  /* special_function */
193          "MCORE_RVA",           /* name */
194          true,                  /* partial_inplace */
195          0xffffffff,            /* src_mask */
196          0xffffffff,            /* dst_mask */
197          true)                  /* pcrel_offset */
198 };
199 \f
200 /* Extend the coff_link_hash_table structure with a few M*Core specific fields.
201    This allows us to store global data here without actually creating any
202    global variables, which is a no-no in the BFD world.  */
203 typedef struct coff_mcore_link_hash_table
204 {
205   /* The original coff_link_hash_table structure.  MUST be first field.  */
206   struct coff_link_hash_table   root;
207
208   bfd *                         bfd_of_toc_owner;
209   long int                      global_toc_size;
210   long int                      import_table_size;
211   long int                      first_thunk_address;
212   long int                      thunk_size;
213 }
214 mcore_hash_table;
215
216 /* Get the MCore coff linker hash table from a link_info structure.  */
217 #define coff_mcore_hash_table(info) \
218   ((mcore_hash_table *) ((info)->hash))
219
220 /* Create an MCore coff linker hash table.  */
221 static struct bfd_link_hash_table *
222 coff_mcore_link_hash_table_create (abfd)
223      bfd * abfd;
224 {
225   mcore_hash_table * ret;
226
227   ret = ((mcore_hash_table *) bfd_alloc (abfd, sizeof (* ret)));
228   if (ret == (mcore_hash_table *) NULL)
229     return NULL;
230
231   if (! _bfd_coff_link_hash_table_init
232       (& ret->root, abfd, _bfd_coff_link_hash_newfunc))
233     {
234       bfd_release (abfd, ret);
235       return (struct bfd_link_hash_table *) NULL;
236     }
237
238   ret->bfd_of_toc_owner = NULL;
239   ret->global_toc_size  = 0;
240   ret->import_table_size = 0;
241   ret->first_thunk_address = 0;
242   ret->thunk_size = 0;
243
244   return & ret->root.root;
245 }
246 \f
247 /* Add an entry to the base file.  */
248 static void
249 mcore_emit_base_file_entry (info, output_bfd, input_section, reloc_offset)
250       struct bfd_link_info * info;
251       bfd *                  output_bfd;
252       asection *             input_section;
253       bfd_vma                reloc_offset;
254 {
255   bfd_vma addr = reloc_offset
256                  - input_section->vma
257                  + input_section->output_offset
258                  + input_section->output_section->vma;
259
260   if (coff_data (output_bfd)->pe)
261      addr -= pe_data (output_bfd)->pe_opthdr.ImageBase;
262   
263   fwrite (&addr, 1, sizeof (addr), (FILE *) info->base_file);
264 }
265 \f
266 /*ARGSUSED*/
267 static bfd_reloc_status_type
268 mcore_coff_unsupported_reloc (abfd, reloc_entry, symbol, data, input_section,
269                            output_bfd, error_message)
270      bfd * abfd;
271      arelent * reloc_entry;
272      asymbol * symbol ATTRIBUTE_UNUSED;
273      PTR data ATTRIBUTE_UNUSED;
274      asection * input_section ATTRIBUTE_UNUSED;
275      bfd * output_bfd ATTRIBUTE_UNUSED;
276      char ** error_message ATTRIBUTE_UNUSED;
277 {
278   BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0);
279   
280   _bfd_error_handler (_("%s: Relocation %s (%d) is not currently supported.\n"),
281                       bfd_get_filename (abfd),
282                       reloc_entry->howto->name,
283                       reloc_entry->howto->type);
284   
285   return bfd_reloc_notsupported;
286 }
287
288 \f
289 /* A cheesy little macro to make the code a little more readable. */
290 #define HOW2MAP(bfd_rtype, mcore_rtype)  \
291  case bfd_rtype: return & mcore_coff_howto_table [mcore_rtype]
292
293 static reloc_howto_type *
294 mcore_coff_reloc_type_lookup (abfd, code)
295      bfd * abfd ATTRIBUTE_UNUSED;
296      bfd_reloc_code_real_type code;
297 {
298   switch (code)
299     { 
300       HOW2MAP (BFD_RELOC_32,                       IMAGE_REL_MCORE_ADDR32);
301       HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM8BY4,      IMAGE_REL_MCORE_PCREL_IMM8BY4);
302       HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM11BY2,     IMAGE_REL_MCORE_PCREL_IMM11BY2);
303       HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM4BY2,      IMAGE_REL_MCORE_PCREL_IMM4BY2);
304       HOW2MAP (BFD_RELOC_32_PCREL,                 IMAGE_REL_MCORE_PCREL_32);
305       HOW2MAP (BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2, IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2);
306       HOW2MAP (BFD_RELOC_RVA,                      IMAGE_REL_MCORE_RVA);
307    default: 
308       return NULL;
309     }
310   /*NOTREACHED*/
311 }
312
313 #undef HOW2MAP
314
315 #define RTYPE2HOWTO(cache_ptr, dst) \
316   (cache_ptr)->howto = mcore_coff_howto_table + (dst)->r_type;
317
318 static reloc_howto_type *
319 coff_mcore_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
320      bfd * abfd ATTRIBUTE_UNUSED;
321      asection * sec;
322      struct internal_reloc * rel;
323      struct coff_link_hash_entry * h ATTRIBUTE_UNUSED;
324      struct internal_syment * sym;
325      bfd_vma * addendp;
326 {
327   reloc_howto_type * howto;
328
329
330   if (rel->r_type >= NUM_ELEM (mcore_coff_howto_table))
331     return NULL;
332   
333   howto = mcore_coff_howto_table + rel->r_type;
334
335   if (rel->r_type == IMAGE_REL_MCORE_RVA)
336     * addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
337   
338   else if (howto->pc_relative)
339     {
340       * addendp = sec->vma - 2; /* XXX guess - is this right ? */
341       
342       /* If the symbol is defined, then the generic code is going to
343          add back the symbol value in order to cancel out an
344          adjustment it made to the addend.  However, we set the addend
345          to 0 at the start of this function.  We need to adjust here,
346          to avoid the adjustment the generic code will make.  FIXME:
347          This is getting a bit hackish.  */
348       if (sym != NULL && sym->n_scnum != 0)
349         * addendp -= sym->n_value;
350     }
351   else
352     * addendp = 0;
353   
354   return howto;
355 }
356
357 /* Return true if this relocation should appear in the output .reloc section.
358    This function is referenced in pe_mkobject in peicode.h.  */
359 static boolean
360 in_reloc_p (abfd, howto)
361      bfd * abfd ATTRIBUTE_UNUSED;
362      reloc_howto_type * howto;
363 {
364   return ! howto->pc_relative && howto->type != IMAGE_REL_MCORE_RVA;
365 }     
366
367 \f
368 /* The reloc processing routine for the optimized COFF linker.  */
369 static boolean
370 coff_mcore_relocate_section (output_bfd, info, input_bfd, input_section,
371                            contents, relocs, syms, sections)
372      bfd * output_bfd;
373      struct bfd_link_info * info;
374      bfd * input_bfd;
375      asection * input_section;
376      bfd_byte * contents;
377      struct internal_reloc * relocs;
378      struct internal_syment * syms;
379      asection ** sections;
380 {
381   struct internal_reloc * rel;
382   struct internal_reloc * relend;
383   boolean hihalf;
384   bfd_vma hihalf_val;
385   
386   /* If we are performing a relocateable link, we don't need to do a
387      thing.  The caller will take care of adjusting the reloc
388      addresses and symbol indices.  */
389   if (info->relocateable)
390     return true;
391   
392   /* Check if we have the same endianess */
393   if (   input_bfd->xvec->byteorder != output_bfd->xvec->byteorder
394       && output_bfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
395     {
396       (*_bfd_error_handler)
397         (_("%s: compiled for a %s endian system and target is %s endian.\n"),
398          bfd_get_filename (input_bfd),
399          bfd_big_endian (input_bfd) ? "big" : "little",
400          bfd_big_endian (output_bfd) ? "big" : "little");
401
402       bfd_set_error (bfd_error_wrong_format);
403       return false;
404     }
405
406   hihalf = false;
407   hihalf_val = 0;
408
409   rel = relocs;
410   relend = rel + input_section->reloc_count;
411   
412   for (; rel < relend; rel++)
413     {
414       long                           symndx;
415       struct internal_syment *       sym;
416       bfd_vma                        val;
417       bfd_vma                        addend;
418       bfd_reloc_status_type          rstat;
419       bfd_byte *                     loc;
420       unsigned short                 r_type = rel->r_type;
421       reloc_howto_type *             howto = NULL;
422       struct coff_link_hash_entry *  h;
423       const char *                   my_name;
424   
425       symndx = rel->r_symndx;
426       loc = contents + rel->r_vaddr - input_section->vma;
427
428       if (symndx == -1)
429         {
430           h = NULL;
431           sym = NULL;
432         }
433       else
434         {
435           h = obj_coff_sym_hashes (input_bfd)[symndx];
436           sym = syms + symndx;
437         }
438
439       addend = 0;
440       
441       /* Get the howto and initialise the addend.  */
442       howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
443                                        sym, & addend);
444       if (howto == NULL)
445         return false;
446
447       val = 0;
448       
449       if (h == NULL)
450         {
451           if (symndx == -1)
452             my_name = "*ABS*";
453           else
454             {
455               asection * sec = sections[symndx];
456               
457               val = (sym->n_value 
458                      + sec->output_section->vma
459                      + sec->output_offset);
460
461               if (sym == NULL)
462                 my_name = "*unknown*";
463               else if (   sym->_n._n_n._n_zeroes == 0
464                        && sym->_n._n_n._n_offset != 0)
465                 my_name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset;
466               else 
467                 {
468                   static char buf [SYMNMLEN + 1];
469                   
470                   strncpy (buf, sym->_n._n_name, SYMNMLEN);
471                   buf[SYMNMLEN] = '\0';
472                   my_name = buf;
473                 }
474             }
475         }
476       else
477         {
478           if (   h->root.type == bfd_link_hash_defined
479               || h->root.type == bfd_link_hash_defweak)
480             {
481               asection * sec = h->root.u.def.section;
482               
483               val = (h->root.u.def.value
484                      + sec->output_section->vma
485                      + sec->output_offset);
486             }
487           else
488             {
489               if (! ((*info->callbacks->undefined_symbol)
490                      (info, h->root.root.string, input_bfd, input_section,
491                       rel->r_vaddr - input_section->vma, true)))
492                 return false;
493             }
494           
495           my_name = h->root.root.string;
496         }       
497
498       rstat = bfd_reloc_ok;
499       
500       /* Each case must do its own relocation, setting rstat appropriately.  */
501       switch (r_type)
502         {
503         default:
504           _bfd_error_handler (_("%s: unsupported relocation type 0x%02x"),
505                               bfd_get_filename (input_bfd), r_type);
506           bfd_set_error (bfd_error_bad_value);
507           return false;
508           
509         case IMAGE_REL_MCORE_ABSOLUTE:
510           fprintf (stderr, 
511                    _("Warning: unsupported reloc %s <file %s, section %s>\n"), 
512                    howto->name,
513                    bfd_get_filename (input_bfd),
514                    input_section->name);
515           
516           fprintf (stderr,"sym %ld (%s), r_vaddr %ld (%lx)\n", 
517                    rel->r_symndx, my_name, (long) rel->r_vaddr,
518                    (unsigned long) rel->r_vaddr);  
519           break;
520           
521         case IMAGE_REL_MCORE_PCREL_IMM8BY4:
522         case IMAGE_REL_MCORE_PCREL_IMM11BY2:
523         case IMAGE_REL_MCORE_PCREL_IMM4BY2:
524         case IMAGE_REL_MCORE_PCREL_32:
525         case IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2:
526         case IMAGE_REL_MCORE_ADDR32:
527           /* XXX fixme - shouldn't this be like the code for the RVA reloc ? */
528           rstat = _bfd_relocate_contents (howto, input_bfd, val, loc);
529           break;
530           
531         case IMAGE_REL_MCORE_RVA:
532           rstat = _bfd_final_link_relocate
533             (howto, input_bfd,
534              input_section, contents, rel->r_vaddr - input_section->vma,
535              val, addend);
536           break;
537         }
538       
539       if (info->base_file)
540         {
541           /* Emit a reloc if the backend thinks it needs it.  */
542           if (sym && pe_data (output_bfd)->in_reloc_p (output_bfd, howto))
543             mcore_emit_base_file_entry (info, output_bfd, input_section, rel->r_vaddr);
544         }
545   
546       switch (rstat)
547         {
548         default:
549           abort ();
550           
551         case bfd_reloc_ok:
552           break;
553           
554         case bfd_reloc_overflow:
555           if (! ((*info->callbacks->reloc_overflow)
556                  (info, my_name, howto->name, 
557                   (bfd_vma) 0, input_bfd,
558                   input_section, rel->r_vaddr - input_section->vma)))
559             return false;
560         }
561     }     
562
563   return true;
564 }
565
566 \f
567 /* Tailor coffcode.h -- macro heaven. */
568
569 /* We use the special COFF backend linker, with our own special touch.  */
570
571 #define coff_bfd_reloc_type_lookup   mcore_coff_reloc_type_lookup
572 #define coff_relocate_section        coff_mcore_relocate_section
573 #define coff_rtype_to_howto          coff_mcore_rtype_to_howto
574
575 #define SELECT_RELOC(internal, howto) {internal.r_type = howto->type;}
576
577 #define COFF_PAGE_SIZE               0x1000
578
579 #include "coffcode.h"
580 \f
581 /* Forward declaration to initialise alterbative_target field.  */
582 extern const bfd_target TARGET_LITTLE_SYM;
583
584 /* The transfer vectors that lead the outside world to all of the above. */
585 CREATE_BIG_COFF_TARGET_VEC (TARGET_BIG_SYM, TARGET_BIG_NAME, D_PAGED, (SEC_LINK_ONCE | SEC_LINK_DUPLICATES), 0, & TARGET_LITTLE_SYM)
586 CREATE_LITTLE_COFF_TARGET_VEC (TARGET_LITTLE_SYM, TARGET_LITTLE_NAME, D_PAGED, (SEC_LINK_ONCE | SEC_LINK_DUPLICATES), 0, & TARGET_BIG_SYM)