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