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