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