1/* BFD back-end for MIPS PE COFF files.
2   Copyright (C) 1990-2017 Free Software Foundation, Inc.
3   Modified from coff-i386.c by DJ Delorie, dj@cygnus.com
4
5   This file is part of BFD, the Binary File Descriptor library.
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 3 of the License, or
10   (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program; if not, write to the Free Software
19   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20   MA 02110-1301, USA.  */
21
22#define COFF_WITH_PE
23/* pei-mips.c may have defined this to default off (0) before
24  including this file, so don't redefine if that's the case.
25  Otherwise we're generating objects, not executable images,
26  so we want to define it to default on.  */
27#ifndef COFF_LONG_SECTION_NAMES
28#define COFF_LONG_SECTION_NAMES
29#endif /* COFF_LONG_SECTION_NAMES */
30#define PCRELOFFSET TRUE
31
32#include "sysdep.h"
33#include "bfd.h"
34#include "libbfd.h"
35#include "coff/mipspe.h"
36#include "coff/internal.h"
37#include "coff/pe.h"
38#include "libcoff.h"
39
40#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 2
41/* The page size is a guess based on ELF.  */
42
43#define COFF_PAGE_SIZE 0x1000
44
45/* For some reason when using mips COFF the value stored in the .text
46   section for a reference to a common symbol is the value itself plus
47   any desired offset.  Ian Taylor, Cygnus Support.  */
48
49/* If we are producing relocatable output, we need to do some
50   adjustments to the object file that are not done by the
51   bfd_perform_relocation function.  This function is called by every
52   reloc type to make any required adjustments.  */
53
54static bfd_reloc_status_type
55coff_mips_reloc (bfd *abfd,
56		 arelent *reloc_entry,
57		 asymbol *symbol,
58		 void * data,
59		 asection *input_section ATTRIBUTE_UNUSED,
60		 bfd *output_bfd,
61		 char **error_message ATTRIBUTE_UNUSED)
62{
63  symvalue diff;
64
65  if (output_bfd == NULL)
66    return bfd_reloc_continue;
67
68  if (bfd_is_com_section (symbol->section))
69    {
70#ifndef COFF_WITH_PE
71      /* We are relocating a common symbol.  The current value in the
72	 object file is ORIG + OFFSET, where ORIG is the value of the
73	 common symbol as seen by the object file when it was compiled
74	 (this may be zero if the symbol was undefined) and OFFSET is
75	 the offset into the common symbol (normally zero, but may be
76	 non-zero when referring to a field in a common structure).
77	 ORIG is the negative of reloc_entry->addend, which is set by
78	 the CALC_ADDEND macro below.  We want to replace the value in
79	 the object file with NEW + OFFSET, where NEW is the value of
80	 the common symbol which we are going to put in the final
81	 object file.  NEW is symbol->value.  */
82      diff = symbol->value + reloc_entry->addend;
83#else
84      /* In PE mode, we do not offset the common symbol.  */
85      diff = reloc_entry->addend;
86#endif
87    }
88  else
89    /* For some reason bfd_perform_relocation always effectively
90       ignores the addend for a COFF target when producing
91       relocatable output.  This seems to be always wrong for 386
92       COFF, so we handle the addend here instead.  */
93    diff = reloc_entry->addend;
94
95#define DOIT(x) \
96  x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + (diff >> howto->rightshift)) & howto->dst_mask))
97
98  if (diff != 0)
99    {
100      reloc_howto_type *howto = reloc_entry->howto;
101      unsigned char *addr = (unsigned char *) data + reloc_entry->address;
102
103      switch (howto->size)
104	{
105	case 0:
106	  {
107	    char x = bfd_get_8 (abfd, addr);
108
109	    DOIT (x);
110	    bfd_put_8 (abfd, x, addr);
111	  }
112	  break;
113
114	case 1:
115	  {
116	    short x = bfd_get_16 (abfd, addr);
117
118	    DOIT (x);
119	    bfd_put_16 (abfd, (bfd_vma) x, addr);
120	  }
121	  break;
122
123	case 2:
124	  {
125	    long x = bfd_get_32 (abfd, addr);
126
127	    DOIT (x);
128	    bfd_put_32 (abfd, (bfd_vma) x, addr);
129	  }
130	  break;
131
132	default:
133	  abort ();
134	}
135    }
136
137  /* Now let bfd_perform_relocation finish everything up.  */
138  return bfd_reloc_continue;
139}
140
141#ifdef COFF_WITH_PE
142/* Return TRUE if this relocation should
143   appear in the output .reloc section.  */
144
145static bfd_boolean
146in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED, reloc_howto_type *howto)
147{
148  return ! howto->pc_relative && howto->type != MIPS_R_RVA;
149}
150#endif
151
152#ifndef PCRELOFFSET
153#define PCRELOFFSET FALSE
154#endif
155
156static reloc_howto_type howto_table[] =
157{
158  /* Reloc type 0 is ignored.  The reloc reading code ensures that
159     this is a reference to the .abs section, which will cause
160     bfd_perform_relocation to do nothing.  */
161  HOWTO (MIPS_R_ABSOLUTE,	/* Type.  */
162	 0,			/* Rightshift.  */
163	 0,			/* Size (0 = byte, 1 = short, 2 = long).  */
164	 8,			/* Bitsize.  */
165	 FALSE,			/* PC_relative.  */
166	 0,			/* Bitpos. */
167	 complain_overflow_dont, /* Complain_on_overflow. */
168	 0,			/* Special_function. */
169	 "IGNORE",		/* Name. */
170	 FALSE,			/* Partial_inplace. */
171	 0,			/* Src_mask. */
172	 0,			/* Dst_mask. */
173	 FALSE),		/* Pcrel_offset. */
174
175  /* A 16 bit reference to a symbol, normally from a data section.  */
176  HOWTO (MIPS_R_REFHALF,	/* Type.  */
177	 0,			/* Rightshift.  */
178	 1,			/* Size (0 = byte, 1 = short, 2 = long).  */
179	 16,			/* Bitsize.  */
180	 FALSE,			/* PC_relative.  */
181	 0,			/* Bitpos. */
182	 complain_overflow_bitfield, /* Complain_on_overflow. */
183	 coff_mips_reloc,	/* Special_function. */
184	 "REFHALF",		/* Name. */
185	 TRUE,			/* Partial_inplace. */
186	 0xffff,		/* Src_mask. */
187	 0xffff,		/* Dst_mask. */
188	 FALSE),		/* Pcrel_offset. */
189
190  /* A 32 bit reference to a symbol, normally from a data section.  */
191  HOWTO (MIPS_R_REFWORD,	/* Type.  */
192	 0,			/* Rightshift.  */
193	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
194	 32,			/* Bitsize.  */
195	 FALSE,			/* PC_relative.  */
196	 0,			/* Bitpos. */
197	 complain_overflow_bitfield, /* Complain_on_overflow. */
198	 coff_mips_reloc,	/* Special_function. */
199	 "REFWORD",		/* Name. */
200	 TRUE,			/* Partial_inplace. */
201	 0xffffffff,		/* Src_mask. */
202	 0xffffffff,		/* Dst_mask. */
203	 FALSE),		/* Pcrel_offset. */
204
205  /* A 26 bit absolute jump address.  */
206  HOWTO (MIPS_R_JMPADDR,	/* Type.  */
207	 2,			/* Rightshift.  */
208	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
209	 26,			/* Bitsize.  */
210	 FALSE,			/* PC_relative.  */
211	 0,			/* Bitpos. */
212	 complain_overflow_dont, /* Complain_on_overflow. */
213	 			/* This needs complex overflow
214				   detection, because the upper four
215				   bits must match the PC.  */
216	 coff_mips_reloc,	/* Special_function. */
217	 "JMPADDR",		/* Name. */
218	 TRUE,			/* Partial_inplace. */
219	 0x3ffffff,		/* Src_mask. */
220	 0x3ffffff,		/* Dst_mask. */
221	 FALSE),		/* Pcrel_offset. */
222
223  /* The high 16 bits of a symbol value.  Handled by the function
224     mips_refhi_reloc.  */
225  HOWTO (MIPS_R_REFHI,		/* Type.  */
226	 16,			/* Rightshift.  */
227	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
228	 16,			/* Bitsize.  */
229	 FALSE,			/* PC_relative.  */
230	 0,			/* Bitpos. */
231	 complain_overflow_bitfield, /* Complain_on_overflow. */
232	 coff_mips_reloc,	/* Special_function. */
233	 "REFHI",		/* Name. */
234	 TRUE,			/* Partial_inplace. */
235	 0xffff,		/* Src_mask. */
236	 0xffff,		/* Dst_mask. */
237	 FALSE),		/* Pcrel_offset. */
238
239  /* The low 16 bits of a symbol value.  */
240  HOWTO (MIPS_R_REFLO,		/* Type.  */
241	 0,			/* Rightshift.  */
242	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
243	 16,			/* Bitsize.  */
244	 FALSE,			/* PC_relative.  */
245	 0,			/* Bitpos. */
246	 complain_overflow_dont, /* Complain_on_overflow. */
247	 coff_mips_reloc,	/* Special_function. */
248	 "REFLO",		/* Name. */
249	 TRUE,			/* Partial_inplace. */
250	 0xffff,		/* Src_mask. */
251	 0xffff,		/* Dst_mask. */
252	 FALSE),		/* Pcrel_offset. */
253
254  /* A reference to an offset from the gp register.  Handled by the
255     function mips_gprel_reloc.  */
256  HOWTO (MIPS_R_GPREL,		/* Type.  */
257	 0,			/* Rightshift.  */
258	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
259	 16,			/* Bitsize.  */
260	 FALSE,			/* PC_relative.  */
261	 0,			/* Bitpos. */
262	 complain_overflow_signed, /* Complain_on_overflow. */
263	 coff_mips_reloc,	/* Special_function. */
264	 "GPREL",		/* Name. */
265	 TRUE,			/* Partial_inplace. */
266	 0xffff,		/* Src_mask. */
267	 0xffff,		/* Dst_mask. */
268	 FALSE),		/* Pcrel_offset. */
269
270  /* A reference to a literal using an offset from the gp register.
271     Handled by the function mips_gprel_reloc.  */
272  HOWTO (MIPS_R_LITERAL,	/* Type.  */
273	 0,			/* Rightshift.  */
274	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
275	 16,			/* Bitsize.  */
276	 FALSE,			/* PC_relative.  */
277	 0,			/* Bitpos. */
278	 complain_overflow_signed, /* Complain_on_overflow. */
279	 coff_mips_reloc,	/* Special_function. */
280	 "LITERAL",		/* Name. */
281	 TRUE,			/* Partial_inplace. */
282	 0xffff,		/* Src_mask. */
283	 0xffff,		/* Dst_mask. */
284	 FALSE),		/* Pcrel_offset. */
285
286  EMPTY_HOWTO (8),
287  EMPTY_HOWTO (9),
288  EMPTY_HOWTO (10),
289  EMPTY_HOWTO (11),
290  EMPTY_HOWTO (12),
291  EMPTY_HOWTO (13),
292  EMPTY_HOWTO (14),
293  EMPTY_HOWTO (15),
294  EMPTY_HOWTO (16),
295  EMPTY_HOWTO (17),
296  EMPTY_HOWTO (18),
297  EMPTY_HOWTO (19),
298  EMPTY_HOWTO (20),
299  EMPTY_HOWTO (21),
300  EMPTY_HOWTO (22),
301  EMPTY_HOWTO (23),
302  EMPTY_HOWTO (24),
303  EMPTY_HOWTO (25),
304  EMPTY_HOWTO (26),
305  EMPTY_HOWTO (27),
306  EMPTY_HOWTO (28),
307  EMPTY_HOWTO (29),
308  EMPTY_HOWTO (30),
309  EMPTY_HOWTO (31),
310  EMPTY_HOWTO (32),
311  EMPTY_HOWTO (33),
312  HOWTO (MIPS_R_RVA,            /* Type.  */
313	 0,	                /* Rightshift.  */
314	 2,	                /* Size (0 = byte, 1 = short, 2 = long).  */
315	 32,	                /* Bitsize.  */
316	 FALSE,	                /* PC_relative.  */
317	 0,	                /* Bitpos. */
318	 complain_overflow_bitfield, /* Complain_on_overflow. */
319	 coff_mips_reloc,       /* Special_function. */
320	 "rva32",	        /* Name. */
321	 TRUE,	                /* Partial_inplace. */
322	 0xffffffff,            /* Src_mask. */
323	 0xffffffff,            /* Dst_mask. */
324	 FALSE),                /* Pcrel_offset. */
325  EMPTY_HOWTO (35),
326  EMPTY_HOWTO (36),
327  HOWTO (MIPS_R_PAIR,           /* Type.  */
328	 0,	                /* Rightshift.  */
329	 2,	                /* Size (0 = byte, 1 = short, 2 = long).  */
330	 32,	                /* Bitsize.  */
331	 FALSE,	                /* PC_relative.  */
332	 0,	                /* Bitpos. */
333	 complain_overflow_bitfield, /* Complain_on_overflow. */
334	 coff_mips_reloc,       /* Special_function. */
335	 "PAIR",	        /* Name. */
336	 TRUE,	                /* Partial_inplace. */
337	 0xffffffff,            /* Src_mask. */
338	 0xffffffff,            /* Dst_mask. */
339	 FALSE),                /* Pcrel_offset. */
340};
341
342#define NUM_HOWTOS (sizeof (howto_table) / sizeof (howto_table[0]))
343
344/* Turn a howto into a reloc nunmber.  */
345
346#define SELECT_RELOC(x, howto) { x.r_type = howto->type; }
347#define BADMAG(x)              MIPSBADMAG (x)
348
349/* Customize coffcode.h.  */
350#define MIPS 1
351
352#define RTYPE2HOWTO(cache_ptr, dst)				\
353  ((cache_ptr)->howto =						\
354   ((dst)->r_type < NUM_HOWTOS					\
355    ? howto_table + (dst)->r_type				\
356    : NULL))
357
358/* Compute the addend of a reloc.  If the reloc is to a common symbol,
359   the object file contains the value of the common symbol.  By the
360   time this is called, the linker may be using a different symbol
361   from a different object file with a different value.  Therefore, we
362   hack wildly to locate the original symbol from this file so that we
363   can make the correct adjustment.  This macro sets coffsym to the
364   symbol from the original file, and uses it to set the addend value
365   correctly.  If this is not a common symbol, the usual addend
366   calculation is done, except that an additional tweak is needed for
367   PC relative relocs.
368   FIXME: This macro refers to symbols and asect; these are from the
369   calling function, not the macro arguments.  */
370
371#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)		\
372  {								\
373    coff_symbol_type *coffsym = NULL;				\
374    if (ptr && bfd_asymbol_bfd (ptr) != abfd)			\
375      coffsym = (obj_symbols (abfd)				\
376	         + (cache_ptr->sym_ptr_ptr - symbols));		\
377    else if (ptr)						\
378      coffsym = coff_symbol_from (ptr);				\
379    if (coffsym != NULL						\
380	&& coffsym->native->u.syment.n_scnum == 0)		\
381      cache_ptr->addend = - coffsym->native->u.syment.n_value;	\
382    else if (ptr && bfd_asymbol_bfd (ptr) == abfd		\
383	     && ptr->section != NULL)				\
384      cache_ptr->addend = - (ptr->section->vma + ptr->value);	\
385    else							\
386      cache_ptr->addend = 0;					\
387    if (ptr && reloc.r_type < NUM_HOWTOS			\
388	&& howto_table[reloc.r_type].pc_relative)		\
389      cache_ptr->addend += asect->vma;				\
390  }
391
392/* Convert an rtype to howto for the COFF backend linker.  */
393
394static reloc_howto_type *
395coff_mips_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
396			  asection *sec,
397			  struct internal_reloc *rel,
398			  struct coff_link_hash_entry *h,
399			  struct internal_syment *sym,
400			  bfd_vma *addendp)
401{
402
403  reloc_howto_type *howto;
404
405  howto = howto_table + rel->r_type;
406
407#ifdef COFF_WITH_PE
408  *addendp = 0;
409#endif
410
411  if (howto->pc_relative)
412    *addendp += sec->vma;
413
414  if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
415    {
416      /* This is a common symbol.  The section contents include the
417	 size (sym->n_value) as an addend.  The relocate_section
418	 function will be adding in the final value of the symbol.  We
419	 need to subtract out the current size in order to get the
420	 correct result.  */
421
422      BFD_ASSERT (h != NULL);
423
424#ifndef COFF_WITH_PE
425      /* I think we *do* want to bypass this.  If we don't, I have
426	 seen some data parameters get the wrong relocation address.
427	 If I link two versions with and without this section bypassed
428	 and then do a binary comparison, the addresses which are
429	 different can be looked up in the map.  The case in which
430	 this section has been bypassed has addresses which correspond
431	 to values I can find in the map.  */
432      *addendp -= sym->n_value;
433#endif
434    }
435
436#ifndef COFF_WITH_PE
437  /* If the output symbol is common (in which case this must be a
438     relocatable link), we need to add in the final size of the
439     common symbol.  */
440  if (h != NULL && h->root.type == bfd_link_hash_common)
441    *addendp += h->root.u.c.size;
442#endif
443
444#ifdef COFF_WITH_PE
445  if (howto->pc_relative)
446    {
447      *addendp -= 4;
448
449      /* If the symbol is defined, then the generic code is going to
450         add back the symbol value in order to cancel out an
451         adjustment it made to the addend.  However, we set the addend
452         to 0 at the start of this function.  We need to adjust here,
453         to avoid the adjustment the generic code will make.  FIXME:
454         This is getting a bit hackish.  */
455      if (sym != NULL && sym->n_scnum != 0)
456	*addendp -= sym->n_value;
457    }
458
459  if (rel->r_type == MIPS_R_RVA)
460    *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
461#endif
462
463  return howto;
464}
465
466#define coff_rtype_to_howto         coff_mips_rtype_to_howto
467#define coff_bfd_reloc_type_lookup  coff_mips_reloc_type_lookup
468#define coff_bfd_reloc_name_lookup coff_mips_reloc_name_lookup
469
470/* Get the howto structure for a generic reloc type.  */
471
472static reloc_howto_type *
473coff_mips_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
474			     bfd_reloc_code_real_type code)
475{
476  int mips_type;
477
478  switch (code)
479    {
480    case BFD_RELOC_16:
481      mips_type = MIPS_R_REFHALF;
482      break;
483    case BFD_RELOC_32:
484    case BFD_RELOC_CTOR:
485      mips_type = MIPS_R_REFWORD;
486      break;
487    case BFD_RELOC_MIPS_JMP:
488      mips_type = MIPS_R_JMPADDR;
489      break;
490    case BFD_RELOC_HI16_S:
491      mips_type = MIPS_R_REFHI;
492      break;
493    case BFD_RELOC_LO16:
494      mips_type = MIPS_R_REFLO;
495      break;
496    case BFD_RELOC_GPREL16:
497      mips_type = MIPS_R_GPREL;
498      break;
499    case BFD_RELOC_MIPS_LITERAL:
500      mips_type = MIPS_R_LITERAL;
501      break;
502    case BFD_RELOC_RVA:
503      mips_type = MIPS_R_RVA;
504      break;
505    default:
506      return NULL;
507    }
508
509  return & howto_table [mips_type];
510}
511
512static reloc_howto_type *
513coff_mips_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
514			     const char *r_name)
515{
516  unsigned int i;
517
518  for (i = 0; i < NUM_HOWTOS; i++)
519    if (howto_table[i].name != NULL
520	&& strcasecmp (howto_table[i].name, r_name) == 0)
521      return &howto_table[i];
522
523  return NULL;
524}
525
526static void
527mips_swap_reloc_in (bfd * abfd, void * src, void * dst)
528{
529  static struct internal_reloc pair_prev;
530  RELOC *reloc_src = (RELOC *) src;
531  struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
532
533  reloc_dst->r_vaddr = H_GET_32 (abfd, reloc_src->r_vaddr);
534  reloc_dst->r_symndx = H_GET_S32 (abfd, reloc_src->r_symndx);
535  reloc_dst->r_type = H_GET_16 (abfd, reloc_src->r_type);
536  reloc_dst->r_size = 0;
537  reloc_dst->r_extern = 0;
538  reloc_dst->r_offset = 0;
539
540  switch (reloc_dst->r_type)
541  {
542  case MIPS_R_REFHI:
543    pair_prev = *reloc_dst;
544    break;
545  case MIPS_R_PAIR:
546    reloc_dst->r_offset = reloc_dst->r_symndx;
547    if (reloc_dst->r_offset & 0x8000)
548      reloc_dst->r_offset -= 0x10000;
549    reloc_dst->r_symndx = pair_prev.r_symndx;
550    break;
551  }
552}
553
554static unsigned int
555mips_swap_reloc_out (bfd * abfd, void * src, void * dst)
556{
557  static bfd_vma prev_addr = 0;
558  struct internal_reloc *reloc_src = (struct internal_reloc *)src;
559  struct external_reloc *reloc_dst = (struct external_reloc *)dst;
560
561  switch (reloc_src->r_type)
562    {
563    case MIPS_R_REFHI:
564      prev_addr = reloc_src->r_vaddr;
565      break;
566    case MIPS_R_REFLO:
567      if (reloc_src->r_vaddr == prev_addr)
568	{
569	  /* FIXME: only slightly hackish.  If we see a REFLO pointing to
570	     the same address as a REFHI, we assume this is the matching
571	     PAIR reloc and output it accordingly.  The symndx is really
572	     the low 16 bits of the addend */
573	  H_PUT_32 (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
574	  H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
575	  H_PUT_16 (abfd, MIPS_R_PAIR, reloc_dst->r_type);
576	  return RELSZ;
577	}
578      break;
579    }
580
581  H_PUT_32 (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
582  H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
583
584  H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type);
585  return RELSZ;
586}
587
588#define coff_swap_reloc_in   mips_swap_reloc_in
589#define coff_swap_reloc_out  mips_swap_reloc_out
590#define NO_COFF_RELOCS
591
592static bfd_boolean
593coff_pe_mips_relocate_section (bfd *output_bfd,
594			       struct bfd_link_info *info,
595			       bfd *input_bfd,
596			       asection *input_section,
597			       bfd_byte *contents,
598			       struct internal_reloc *relocs,
599			       struct internal_syment *syms,
600			       asection **sections)
601{
602  struct internal_reloc *rel;
603  struct internal_reloc *rel_end;
604  unsigned int i;
605
606  if (bfd_link_relocatable (info))
607    {
608      _bfd_error_handler
609	(_("%B: `ld -r' not supported with PE MIPS objects\n"), input_bfd);
610      bfd_set_error (bfd_error_bad_value);
611      return FALSE;
612    }
613
614  BFD_ASSERT (input_bfd->xvec->byteorder
615	      == output_bfd->xvec->byteorder);
616
617  rel = relocs;
618  rel_end = rel + input_section->reloc_count;
619
620  for (i = 0; rel < rel_end; rel++, i++)
621    {
622      long symndx;
623      struct coff_link_hash_entry *h;
624      struct internal_syment *sym;
625      bfd_vma addend = 0;
626      bfd_vma val, tmp, targ, src, low;
627      reloc_howto_type *howto;
628      unsigned char *mem = contents + rel->r_vaddr;
629
630      symndx = rel->r_symndx;
631
632      if (symndx == -1)
633	{
634	  h = NULL;
635	  sym = NULL;
636	}
637      else
638	{
639	  h = obj_coff_sym_hashes (input_bfd)[symndx];
640	  sym = syms + symndx;
641	}
642
643      /* COFF treats common symbols in one of two ways.  Either the
644         size of the symbol is included in the section contents, or it
645         is not.  We assume that the size is not included, and force
646         the rtype_to_howto function to adjust the addend as needed.  */
647
648      if (sym != NULL && sym->n_scnum != 0)
649	addend = - sym->n_value;
650      else
651	addend = 0;
652
653      howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
654				       sym, &addend);
655      if (howto == NULL)
656	return FALSE;
657
658      /* If we are doing a relocatable link, then we can just ignore
659         a PC relative reloc that is pcrel_offset.  It will already
660         have the correct value.  If this is not a relocatable link,
661         then we should ignore the symbol value.  */
662      if (howto->pc_relative && howto->pcrel_offset)
663	{
664	  if (bfd_link_relocatable (info))
665	    continue;
666	  if (sym != NULL && sym->n_scnum != 0)
667	    addend += sym->n_value;
668	}
669
670      val = 0;
671
672      if (h == NULL)
673	{
674	  asection *sec;
675
676	  if (symndx == -1)
677	    {
678	      sec = bfd_abs_section_ptr;
679	      val = 0;
680	    }
681	  else
682	    {
683	      sec = sections[symndx];
684              val = (sec->output_section->vma
685		     + sec->output_offset
686		     + sym->n_value);
687	      if (! obj_pe (input_bfd))
688		val -= sec->vma;
689	    }
690	}
691      else
692	{
693	  if (h->root.type == bfd_link_hash_defined
694	      || h->root.type == bfd_link_hash_defweak)
695	    {
696	      asection *sec;
697
698	      sec = h->root.u.def.section;
699	      val = (h->root.u.def.value
700		     + sec->output_section->vma
701		     + sec->output_offset);
702	      }
703
704	  else if (! bfd_link_relocatable (info))
705	    (*info->callbacks->undefined_symbol)
706	      (info, h->root.root.string, input_bfd, input_section,
707	       rel->r_vaddr - input_section->vma, TRUE);
708	}
709
710      src = rel->r_vaddr + input_section->output_section->vma
711	+ input_section->output_offset;
712
713      /* OK, at this point the following variables are set up:
714	   src = VMA of the memory we're fixing up
715	   mem = pointer to memory we're fixing up
716	   val = VMA of what we need to refer to.  */
717
718#define UI(x)						       \
719      /* xgettext:c-format */				       \
720	_bfd_error_handler (_("%B: unimplemented %s\n"),       \
721			    input_bfd, x);		       \
722	bfd_set_error (bfd_error_bad_value);
723
724      switch (rel->r_type)
725	{
726	case MIPS_R_ABSOLUTE:
727	  /* Ignore these.  */
728	  break;
729
730	case MIPS_R_REFHALF:
731	  UI ("refhalf");
732	  break;
733
734	case MIPS_R_REFWORD:
735	  tmp = bfd_get_32 (input_bfd, mem);
736	  /* printf ("refword: src=%08x targ=%08x+%08x\n", src, tmp, val); */
737	  tmp += val;
738	  bfd_put_32 (input_bfd, tmp, mem);
739	  break;
740
741	case MIPS_R_JMPADDR:
742	  tmp = bfd_get_32 (input_bfd, mem);
743	  targ = val + (tmp & 0x03ffffff) * 4;
744	  if ((src & 0xf0000000) != (targ & 0xf0000000))
745	    {
746	      _bfd_error_handler (_("%B: jump too far away\n"), input_bfd);
747	      bfd_set_error (bfd_error_bad_value);
748	      return FALSE;
749	    }
750	  tmp &= 0xfc000000;
751	  tmp |= (targ / 4) & 0x3ffffff;
752	  bfd_put_32 (input_bfd, tmp, mem);
753	  break;
754
755	case MIPS_R_REFHI:
756	  tmp = bfd_get_32 (input_bfd, mem);
757	  switch (rel[1].r_type)
758	    {
759	    case MIPS_R_PAIR:
760	      /* MS PE object */
761	      targ = val + rel[1].r_offset + ((tmp & 0xffff) << 16);
762	      break;
763	    case MIPS_R_REFLO:
764	      /* GNU COFF object */
765	      low = bfd_get_32 (input_bfd, contents + rel[1].r_vaddr);
766	      low &= 0xffff;
767	      if (low & 0x8000)
768		low -= 0x10000;
769	      targ = val + low + ((tmp & 0xffff) << 16);
770	      break;
771	    default:
772	      _bfd_error_handler (_("%B: bad pair/reflo after refhi\n"),
773				  input_bfd);
774	      bfd_set_error (bfd_error_bad_value);
775	      return FALSE;
776	    }
777	  tmp &= 0xffff0000;
778	  tmp |= (targ >> 16) & 0xffff;
779	  bfd_put_32 (input_bfd, tmp, mem);
780	  break;
781
782	case MIPS_R_REFLO:
783	  tmp = bfd_get_32 (input_bfd, mem);
784	  targ = val + (tmp & 0xffff);
785	  /* printf ("refword: src=%08x targ=%08x\n", src, targ); */
786	  tmp &= 0xffff0000;
787	  tmp |= targ & 0xffff;
788	  bfd_put_32 (input_bfd, tmp, mem);
789	  break;
790
791	case MIPS_R_GPREL:
792	case MIPS_R_LITERAL:
793	  UI ("gprel");
794	  break;
795
796	case MIPS_R_SECTION:
797	  UI ("section");
798	  break;
799
800	case MIPS_R_SECREL:
801	  UI ("secrel");
802	  break;
803
804	case MIPS_R_SECRELLO:
805	  UI ("secrello");
806	  break;
807
808	case MIPS_R_SECRELHI:
809	  UI ("secrelhi");
810	  break;
811
812	case MIPS_R_RVA:
813	  tmp = bfd_get_32 (input_bfd, mem);
814	  /* printf ("rva: src=%08x targ=%08x+%08x\n", src, tmp, val); */
815	  tmp += val
816	    - pe_data (input_section->output_section->owner)->pe_opthdr.ImageBase;
817	  bfd_put_32 (input_bfd, tmp, mem);
818	  break;
819
820	case MIPS_R_PAIR:
821	  /* ignore these */
822	  break;
823	}
824    }
825
826  return TRUE;
827}
828
829#define coff_relocate_section coff_pe_mips_relocate_section
830
831#ifdef TARGET_UNDERSCORE
832
833/* If mips gcc uses underscores for symbol names, then it does not use
834   a leading dot for local labels, so if TARGET_UNDERSCORE is defined
835   we treat all symbols starting with L as local.  */
836
837static bfd_boolean
838coff_mips_is_local_label_name (bfd *abfd, const char *name)
839{
840  if (name[0] == 'L')
841    return TRUE;
842
843  return _bfd_coff_is_local_label_name (abfd, name);
844}
845
846#define coff_bfd_is_local_label_name coff_mips_is_local_label_name
847
848#endif /* TARGET_UNDERSCORE */
849
850#define COFF_NO_HACK_SCNHDR_SIZE
851
852#ifndef bfd_pe_print_pdata
853#define bfd_pe_print_pdata	NULL
854#endif
855
856#include "coffcode.h"
857
858const bfd_target
859#ifdef TARGET_SYM
860  TARGET_SYM =
861#else
862  mips_pe_le_vec =
863#endif
864{
865#ifdef TARGET_NAME
866  TARGET_NAME,
867#else
868  "pe-mips",			/* Name.  */
869#endif
870  bfd_target_coff_flavour,
871  BFD_ENDIAN_LITTLE,		/* Data byte order is little.  */
872  BFD_ENDIAN_LITTLE,		/* Header byte order is little.  */
873
874  (HAS_RELOC | EXEC_P |		/* Object flags.  */
875   HAS_LINENO | HAS_DEBUG |
876   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
877
878#ifndef COFF_WITH_PE
879  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags.  */
880   | SEC_CODE | SEC_DATA),
881#else
882  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags.  */
883   | SEC_CODE | SEC_DATA
884   | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
885#endif
886
887#ifdef TARGET_UNDERSCORE
888  TARGET_UNDERSCORE,		/* Leading underscore.  */
889#else
890  0,				/* leading underscore */
891#endif
892  '/',				/* AR_pad_char.  */
893  15,				/* AR_max_namelen.  */
894  0,				/* match priority.  */
895
896  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
897     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
898     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
899  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
900     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
901     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Headers.  */
902
903  /* Note that we allow an object file to be treated as a core file as well.  */
904  {_bfd_dummy_target, coff_object_p, /* bfd_check_format.  */
905   bfd_generic_archive_p, coff_object_p},
906  {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format.  */
907   bfd_false},
908  {bfd_false, coff_write_object_contents, /* bfd_write_contents.  */
909   _bfd_write_archive_contents, bfd_false},
910
911  BFD_JUMP_TABLE_GENERIC (coff),
912  BFD_JUMP_TABLE_COPY (coff),
913  BFD_JUMP_TABLE_CORE (_bfd_nocore),
914  BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
915  BFD_JUMP_TABLE_SYMBOLS (coff),
916  BFD_JUMP_TABLE_RELOCS (coff),
917  BFD_JUMP_TABLE_WRITE (coff),
918  BFD_JUMP_TABLE_LINK (coff),
919  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
920
921  NULL,
922
923  COFF_SWAP_TABLE
924};
925