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