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