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