Switch sources over to use the GPL version 3
[platform/upstream/binutils.git] / bfd / coff-mips.c
1 /* BFD back-end for MIPS Extended-Coff files.
2    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3    2000, 2001, 2002, 2003, 2004, 2007
4    Free Software Foundation, Inc.
5    Original version by Per Bothner.
6    Full support added by Ian Lance Taylor, ian@cygnus.com.
7
8    This file is part of BFD, the Binary File Descriptor library.
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23    MA 02110-1301, USA.  */
24
25 #include "sysdep.h"
26 #include "bfd.h"
27 #include "bfdlink.h"
28 #include "libbfd.h"
29 #include "coff/internal.h"
30 #include "coff/sym.h"
31 #include "coff/symconst.h"
32 #include "coff/ecoff.h"
33 #include "coff/mips.h"
34 #include "libcoff.h"
35 #include "libecoff.h"
36 \f
37 /* Prototypes for static functions.  */
38
39 static bfd_boolean mips_ecoff_bad_format_hook
40   PARAMS ((bfd *abfd, PTR filehdr));
41 static void mips_ecoff_swap_reloc_in
42   PARAMS ((bfd *, PTR, struct internal_reloc *));
43 static void mips_ecoff_swap_reloc_out
44   PARAMS ((bfd *, const struct internal_reloc *, PTR));
45 static void mips_adjust_reloc_in
46   PARAMS ((bfd *, const struct internal_reloc *, arelent *));
47 static void mips_adjust_reloc_out
48   PARAMS ((bfd *, const arelent *, struct internal_reloc *));
49 static bfd_reloc_status_type mips_generic_reloc
50   PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
51            asection *section, bfd *output_bfd, char **error));
52 static bfd_reloc_status_type mips_refhi_reloc
53   PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
54            asection *section, bfd *output_bfd, char **error));
55 static bfd_reloc_status_type mips_reflo_reloc
56   PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
57            asection *section, bfd *output_bfd, char **error));
58 static bfd_reloc_status_type mips_gprel_reloc
59   PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
60            asection *section, bfd *output_bfd, char **error));
61 static void mips_relocate_hi
62   PARAMS ((struct internal_reloc *refhi, struct internal_reloc *reflo,
63            bfd *input_bfd, asection *input_section, bfd_byte *contents,
64            bfd_vma relocation));
65 static bfd_boolean mips_relocate_section
66   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, PTR));
67 static reloc_howto_type *mips_bfd_reloc_type_lookup
68   PARAMS ((bfd *, bfd_reloc_code_real_type));
69 \f
70 /* ECOFF has COFF sections, but the debugging information is stored in
71    a completely different format.  ECOFF targets use some of the
72    swapping routines from coffswap.h, and some of the generic COFF
73    routines in coffgen.c, but, unlike the real COFF targets, do not
74    use coffcode.h itself.
75
76    Get the generic COFF swapping routines, except for the reloc,
77    symbol, and lineno ones.  Give them ECOFF names.  */
78 #define MIPSECOFF
79 #define NO_COFF_RELOCS
80 #define NO_COFF_SYMBOLS
81 #define NO_COFF_LINENOS
82 #define coff_swap_filehdr_in mips_ecoff_swap_filehdr_in
83 #define coff_swap_filehdr_out mips_ecoff_swap_filehdr_out
84 #define coff_swap_aouthdr_in mips_ecoff_swap_aouthdr_in
85 #define coff_swap_aouthdr_out mips_ecoff_swap_aouthdr_out
86 #define coff_swap_scnhdr_in mips_ecoff_swap_scnhdr_in
87 #define coff_swap_scnhdr_out mips_ecoff_swap_scnhdr_out
88 #include "coffswap.h"
89
90 /* Get the ECOFF swapping routines.  */
91 #define ECOFF_32
92 #include "ecoffswap.h"
93 \f
94 /* How to process the various relocs types.  */
95
96 static reloc_howto_type mips_howto_table[] =
97 {
98   /* Reloc type 0 is ignored.  The reloc reading code ensures that
99      this is a reference to the .abs section, which will cause
100      bfd_perform_relocation to do nothing.  */
101   HOWTO (MIPS_R_IGNORE, /* type */
102          0,                     /* rightshift */
103          0,                     /* size (0 = byte, 1 = short, 2 = long) */
104          8,                     /* bitsize */
105          FALSE,                 /* pc_relative */
106          0,                     /* bitpos */
107          complain_overflow_dont, /* complain_on_overflow */
108          0,                     /* special_function */
109          "IGNORE",              /* name */
110          FALSE,                 /* partial_inplace */
111          0,                     /* src_mask */
112          0,                     /* dst_mask */
113          FALSE),                /* pcrel_offset */
114
115   /* A 16 bit reference to a symbol, normally from a data section.  */
116   HOWTO (MIPS_R_REFHALF,        /* type */
117          0,                     /* rightshift */
118          1,                     /* size (0 = byte, 1 = short, 2 = long) */
119          16,                    /* bitsize */
120          FALSE,                 /* pc_relative */
121          0,                     /* bitpos */
122          complain_overflow_bitfield, /* complain_on_overflow */
123          mips_generic_reloc,    /* special_function */
124          "REFHALF",             /* name */
125          TRUE,                  /* partial_inplace */
126          0xffff,                /* src_mask */
127          0xffff,                /* dst_mask */
128          FALSE),                /* pcrel_offset */
129
130   /* A 32 bit reference to a symbol, normally from a data section.  */
131   HOWTO (MIPS_R_REFWORD,        /* type */
132          0,                     /* rightshift */
133          2,                     /* size (0 = byte, 1 = short, 2 = long) */
134          32,                    /* bitsize */
135          FALSE,                 /* pc_relative */
136          0,                     /* bitpos */
137          complain_overflow_bitfield, /* complain_on_overflow */
138          mips_generic_reloc,    /* special_function */
139          "REFWORD",             /* name */
140          TRUE,                  /* partial_inplace */
141          0xffffffff,            /* src_mask */
142          0xffffffff,            /* dst_mask */
143          FALSE),                /* pcrel_offset */
144
145   /* A 26 bit absolute jump address.  */
146   HOWTO (MIPS_R_JMPADDR,        /* type */
147          2,                     /* rightshift */
148          2,                     /* size (0 = byte, 1 = short, 2 = long) */
149          26,                    /* bitsize */
150          FALSE,                 /* pc_relative */
151          0,                     /* bitpos */
152          complain_overflow_dont, /* complain_on_overflow */
153                                 /* This needs complex overflow
154                                    detection, because the upper four
155                                    bits must match the PC.  */
156          mips_generic_reloc,    /* special_function */
157          "JMPADDR",             /* name */
158          TRUE,                  /* partial_inplace */
159          0x3ffffff,             /* src_mask */
160          0x3ffffff,             /* dst_mask */
161          FALSE),                /* pcrel_offset */
162
163   /* The high 16 bits of a symbol value.  Handled by the function
164      mips_refhi_reloc.  */
165   HOWTO (MIPS_R_REFHI,          /* type */
166          16,                    /* rightshift */
167          2,                     /* size (0 = byte, 1 = short, 2 = long) */
168          16,                    /* bitsize */
169          FALSE,                 /* pc_relative */
170          0,                     /* bitpos */
171          complain_overflow_bitfield, /* complain_on_overflow */
172          mips_refhi_reloc,      /* special_function */
173          "REFHI",               /* name */
174          TRUE,                  /* partial_inplace */
175          0xffff,                /* src_mask */
176          0xffff,                /* dst_mask */
177          FALSE),                /* pcrel_offset */
178
179   /* The low 16 bits of a symbol value.  */
180   HOWTO (MIPS_R_REFLO,          /* type */
181          0,                     /* rightshift */
182          2,                     /* size (0 = byte, 1 = short, 2 = long) */
183          16,                    /* bitsize */
184          FALSE,                 /* pc_relative */
185          0,                     /* bitpos */
186          complain_overflow_dont, /* complain_on_overflow */
187          mips_reflo_reloc,      /* special_function */
188          "REFLO",               /* name */
189          TRUE,                  /* partial_inplace */
190          0xffff,                /* src_mask */
191          0xffff,                /* dst_mask */
192          FALSE),                /* pcrel_offset */
193
194   /* A reference to an offset from the gp register.  Handled by the
195      function mips_gprel_reloc.  */
196   HOWTO (MIPS_R_GPREL,          /* type */
197          0,                     /* rightshift */
198          2,                     /* size (0 = byte, 1 = short, 2 = long) */
199          16,                    /* bitsize */
200          FALSE,                 /* pc_relative */
201          0,                     /* bitpos */
202          complain_overflow_signed, /* complain_on_overflow */
203          mips_gprel_reloc,      /* special_function */
204          "GPREL",               /* name */
205          TRUE,                  /* partial_inplace */
206          0xffff,                /* src_mask */
207          0xffff,                /* dst_mask */
208          FALSE),                /* pcrel_offset */
209
210   /* A reference to a literal using an offset from the gp register.
211      Handled by the function mips_gprel_reloc.  */
212   HOWTO (MIPS_R_LITERAL,        /* type */
213          0,                     /* rightshift */
214          2,                     /* size (0 = byte, 1 = short, 2 = long) */
215          16,                    /* bitsize */
216          FALSE,                 /* pc_relative */
217          0,                     /* bitpos */
218          complain_overflow_signed, /* complain_on_overflow */
219          mips_gprel_reloc,      /* special_function */
220          "LITERAL",             /* name */
221          TRUE,                  /* partial_inplace */
222          0xffff,                /* src_mask */
223          0xffff,                /* dst_mask */
224          FALSE),                /* pcrel_offset */
225
226   EMPTY_HOWTO (8),
227   EMPTY_HOWTO (9),
228   EMPTY_HOWTO (10),
229   EMPTY_HOWTO (11),
230
231   /* FIXME: This relocation is used (internally only) to represent branches
232      when assembling.  It should never appear in output files, and
233      be removed.  (It used to be used for embedded-PIC support.)  */
234   HOWTO (MIPS_R_PCREL16,        /* type */
235          2,                     /* rightshift */
236          2,                     /* size (0 = byte, 1 = short, 2 = long) */
237          16,                    /* bitsize */
238          TRUE,                  /* pc_relative */
239          0,                     /* bitpos */
240          complain_overflow_signed, /* complain_on_overflow */
241          mips_generic_reloc,    /* special_function */
242          "PCREL16",             /* name */
243          TRUE,                  /* partial_inplace */
244          0xffff,                /* src_mask */
245          0xffff,                /* dst_mask */
246          TRUE),                 /* pcrel_offset */
247 };
248
249 #define MIPS_HOWTO_COUNT \
250   (sizeof mips_howto_table / sizeof mips_howto_table[0])
251 \f
252 /* See whether the magic number matches.  */
253
254 static bfd_boolean
255 mips_ecoff_bad_format_hook (abfd, filehdr)
256      bfd *abfd;
257      PTR filehdr;
258 {
259   struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
260
261   switch (internal_f->f_magic)
262     {
263     case MIPS_MAGIC_1:
264       /* I don't know what endianness this implies.  */
265       return TRUE;
266
267     case MIPS_MAGIC_BIG:
268     case MIPS_MAGIC_BIG2:
269     case MIPS_MAGIC_BIG3:
270       return bfd_big_endian (abfd);
271
272     case MIPS_MAGIC_LITTLE:
273     case MIPS_MAGIC_LITTLE2:
274     case MIPS_MAGIC_LITTLE3:
275       return bfd_little_endian (abfd);
276
277     default:
278       return FALSE;
279     }
280 }
281 \f
282 /* Reloc handling.  MIPS ECOFF relocs are packed into 8 bytes in
283    external form.  They use a bit which indicates whether the symbol
284    is external.  */
285
286 /* Swap a reloc in.  */
287
288 static void
289 mips_ecoff_swap_reloc_in (abfd, ext_ptr, intern)
290      bfd *abfd;
291      PTR ext_ptr;
292      struct internal_reloc *intern;
293 {
294   const RELOC *ext = (RELOC *) ext_ptr;
295
296   intern->r_vaddr = H_GET_32 (abfd, ext->r_vaddr);
297   if (bfd_header_big_endian (abfd))
298     {
299       intern->r_symndx = (((int) ext->r_bits[0]
300                            << RELOC_BITS0_SYMNDX_SH_LEFT_BIG)
301                           | ((int) ext->r_bits[1]
302                              << RELOC_BITS1_SYMNDX_SH_LEFT_BIG)
303                           | ((int) ext->r_bits[2]
304                              << RELOC_BITS2_SYMNDX_SH_LEFT_BIG));
305       intern->r_type = ((ext->r_bits[3] & RELOC_BITS3_TYPE_BIG)
306                         >> RELOC_BITS3_TYPE_SH_BIG);
307       intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_BIG) != 0;
308     }
309   else
310     {
311       intern->r_symndx = (((int) ext->r_bits[0]
312                            << RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE)
313                           | ((int) ext->r_bits[1]
314                              << RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE)
315                           | ((int) ext->r_bits[2]
316                              << RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE));
317       intern->r_type = (((ext->r_bits[3] & RELOC_BITS3_TYPE_LITTLE)
318                          >> RELOC_BITS3_TYPE_SH_LITTLE)
319                         | ((ext->r_bits[3] & RELOC_BITS3_TYPEHI_LITTLE)
320                            << RELOC_BITS3_TYPEHI_SH_LITTLE));
321       intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) != 0;
322     }
323 }
324
325 /* Swap a reloc out.  */
326
327 static void
328 mips_ecoff_swap_reloc_out (abfd, intern, dst)
329      bfd *abfd;
330      const struct internal_reloc *intern;
331      PTR dst;
332 {
333   RELOC *ext = (RELOC *) dst;
334   long r_symndx;
335
336   BFD_ASSERT (intern->r_extern
337               || (intern->r_symndx >= 0 && intern->r_symndx <= 12));
338
339   r_symndx = intern->r_symndx;
340
341   H_PUT_32 (abfd, intern->r_vaddr, ext->r_vaddr);
342   if (bfd_header_big_endian (abfd))
343     {
344       ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_BIG;
345       ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_BIG;
346       ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_BIG;
347       ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_BIG)
348                          & RELOC_BITS3_TYPE_BIG)
349                         | (intern->r_extern ? RELOC_BITS3_EXTERN_BIG : 0));
350     }
351   else
352     {
353       ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE;
354       ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE;
355       ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE;
356       ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_LITTLE)
357                          & RELOC_BITS3_TYPE_LITTLE)
358                         | ((intern->r_type >> RELOC_BITS3_TYPEHI_SH_LITTLE
359                             & RELOC_BITS3_TYPEHI_LITTLE))
360                         | (intern->r_extern ? RELOC_BITS3_EXTERN_LITTLE : 0));
361     }
362 }
363
364 /* Finish canonicalizing a reloc.  Part of this is generic to all
365    ECOFF targets, and that part is in ecoff.c.  The rest is done in
366    this backend routine.  It must fill in the howto field.  */
367
368 static void
369 mips_adjust_reloc_in (abfd, intern, rptr)
370      bfd *abfd;
371      const struct internal_reloc *intern;
372      arelent *rptr;
373 {
374   if (intern->r_type > MIPS_R_PCREL16)
375     abort ();
376
377   if (! intern->r_extern
378       && (intern->r_type == MIPS_R_GPREL
379           || intern->r_type == MIPS_R_LITERAL))
380     rptr->addend += ecoff_data (abfd)->gp;
381
382   /* If the type is MIPS_R_IGNORE, make sure this is a reference to
383      the absolute section so that the reloc is ignored.  */
384   if (intern->r_type == MIPS_R_IGNORE)
385     rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
386
387   rptr->howto = &mips_howto_table[intern->r_type];
388 }
389
390 /* Make any adjustments needed to a reloc before writing it out.  None
391    are needed for MIPS.  */
392
393 static void
394 mips_adjust_reloc_out (abfd, rel, intern)
395      bfd *abfd ATTRIBUTE_UNUSED;
396      const arelent *rel ATTRIBUTE_UNUSED;
397      struct internal_reloc *intern ATTRIBUTE_UNUSED;
398 {
399 }
400
401 /* ECOFF relocs are either against external symbols, or against
402    sections.  If we are producing relocatable output, and the reloc
403    is against an external symbol, and nothing has given us any
404    additional addend, the resulting reloc will also be against the
405    same symbol.  In such a case, we don't want to change anything
406    about the way the reloc is handled, since it will all be done at
407    final link time.  Rather than put special case code into
408    bfd_perform_relocation, all the reloc types use this howto
409    function.  It just short circuits the reloc if producing
410    relocatable output against an external symbol.  */
411
412 static bfd_reloc_status_type
413 mips_generic_reloc (abfd,
414                     reloc_entry,
415                     symbol,
416                     data,
417                     input_section,
418                     output_bfd,
419                     error_message)
420      bfd *abfd ATTRIBUTE_UNUSED;
421      arelent *reloc_entry;
422      asymbol *symbol;
423      PTR data ATTRIBUTE_UNUSED;
424      asection *input_section;
425      bfd *output_bfd;
426      char **error_message ATTRIBUTE_UNUSED;
427 {
428   if (output_bfd != (bfd *) NULL
429       && (symbol->flags & BSF_SECTION_SYM) == 0
430       && reloc_entry->addend == 0)
431     {
432       reloc_entry->address += input_section->output_offset;
433       return bfd_reloc_ok;
434     }
435
436   return bfd_reloc_continue;
437 }
438
439 /* Do a REFHI relocation.  This has to be done in combination with a
440    REFLO reloc, because there is a carry from the REFLO to the REFHI.
441    Here we just save the information we need; we do the actual
442    relocation when we see the REFLO.  MIPS ECOFF requires that the
443    REFLO immediately follow the REFHI.  As a GNU extension, we permit
444    an arbitrary number of HI relocs to be associated with a single LO
445    reloc.  This extension permits gcc to output the HI and LO relocs
446    itself.  */
447
448 struct mips_hi
449 {
450   struct mips_hi *next;
451   bfd_byte *addr;
452   bfd_vma addend;
453 };
454
455 /* FIXME: This should not be a static variable.  */
456
457 static struct mips_hi *mips_refhi_list;
458
459 static bfd_reloc_status_type
460 mips_refhi_reloc (abfd,
461                   reloc_entry,
462                   symbol,
463                   data,
464                   input_section,
465                   output_bfd,
466                   error_message)
467      bfd *abfd ATTRIBUTE_UNUSED;
468      arelent *reloc_entry;
469      asymbol *symbol;
470      PTR data;
471      asection *input_section;
472      bfd *output_bfd;
473      char **error_message ATTRIBUTE_UNUSED;
474 {
475   bfd_reloc_status_type ret;
476   bfd_vma relocation;
477   struct mips_hi *n;
478
479   /* If we're relocating, and this an external symbol, we don't want
480      to change anything.  */
481   if (output_bfd != (bfd *) NULL
482       && (symbol->flags & BSF_SECTION_SYM) == 0
483       && reloc_entry->addend == 0)
484     {
485       reloc_entry->address += input_section->output_offset;
486       return bfd_reloc_ok;
487     }
488
489   ret = bfd_reloc_ok;
490   if (bfd_is_und_section (symbol->section)
491       && output_bfd == (bfd *) NULL)
492     ret = bfd_reloc_undefined;
493
494   if (bfd_is_com_section (symbol->section))
495     relocation = 0;
496   else
497     relocation = symbol->value;
498
499   relocation += symbol->section->output_section->vma;
500   relocation += symbol->section->output_offset;
501   relocation += reloc_entry->addend;
502
503   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
504     return bfd_reloc_outofrange;
505
506   /* Save the information, and let REFLO do the actual relocation.  */
507   n = (struct mips_hi *) bfd_malloc ((bfd_size_type) sizeof *n);
508   if (n == NULL)
509     return bfd_reloc_outofrange;
510   n->addr = (bfd_byte *) data + reloc_entry->address;
511   n->addend = relocation;
512   n->next = mips_refhi_list;
513   mips_refhi_list = n;
514
515   if (output_bfd != (bfd *) NULL)
516     reloc_entry->address += input_section->output_offset;
517
518   return ret;
519 }
520
521 /* Do a REFLO relocation.  This is a straightforward 16 bit inplace
522    relocation; this function exists in order to do the REFHI
523    relocation described above.  */
524
525 static bfd_reloc_status_type
526 mips_reflo_reloc (abfd,
527                   reloc_entry,
528                   symbol,
529                   data,
530                   input_section,
531                   output_bfd,
532                   error_message)
533      bfd *abfd;
534      arelent *reloc_entry;
535      asymbol *symbol;
536      PTR data;
537      asection *input_section;
538      bfd *output_bfd;
539      char **error_message;
540 {
541   if (mips_refhi_list != NULL)
542     {
543       struct mips_hi *l;
544
545       l = mips_refhi_list;
546       while (l != NULL)
547         {
548           unsigned long insn;
549           unsigned long val;
550           unsigned long vallo;
551           struct mips_hi *next;
552
553           /* Do the REFHI relocation.  Note that we actually don't
554              need to know anything about the REFLO itself, except
555              where to find the low 16 bits of the addend needed by the
556              REFHI.  */
557           insn = bfd_get_32 (abfd, l->addr);
558           vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
559                    & 0xffff);
560           val = ((insn & 0xffff) << 16) + vallo;
561           val += l->addend;
562
563           /* The low order 16 bits are always treated as a signed
564              value.  Therefore, a negative value in the low order bits
565              requires an adjustment in the high order bits.  We need
566              to make this adjustment in two ways: once for the bits we
567              took from the data, and once for the bits we are putting
568              back in to the data.  */
569           if ((vallo & 0x8000) != 0)
570             val -= 0x10000;
571           if ((val & 0x8000) != 0)
572             val += 0x10000;
573
574           insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
575           bfd_put_32 (abfd, (bfd_vma) insn, l->addr);
576
577           next = l->next;
578           free (l);
579           l = next;
580         }
581
582       mips_refhi_list = NULL;
583     }
584
585   /* Now do the REFLO reloc in the usual way.  */
586   return mips_generic_reloc (abfd, reloc_entry, symbol, data,
587                               input_section, output_bfd, error_message);
588 }
589
590 /* Do a GPREL relocation.  This is a 16 bit value which must become
591    the offset from the gp register.  */
592
593 static bfd_reloc_status_type
594 mips_gprel_reloc (abfd,
595                   reloc_entry,
596                   symbol,
597                   data,
598                   input_section,
599                   output_bfd,
600                   error_message)
601      bfd *abfd;
602      arelent *reloc_entry;
603      asymbol *symbol;
604      PTR data;
605      asection *input_section;
606      bfd *output_bfd;
607      char **error_message;
608 {
609   bfd_boolean relocatable;
610   bfd_vma gp;
611   bfd_vma relocation;
612   unsigned long val;
613   unsigned long insn;
614
615   /* If we're relocating, and this is an external symbol with no
616      addend, we don't want to change anything.  We will only have an
617      addend if this is a newly created reloc, not read from an ECOFF
618      file.  */
619   if (output_bfd != (bfd *) NULL
620       && (symbol->flags & BSF_SECTION_SYM) == 0
621       && reloc_entry->addend == 0)
622     {
623       reloc_entry->address += input_section->output_offset;
624       return bfd_reloc_ok;
625     }
626
627   if (output_bfd != (bfd *) NULL)
628     relocatable = TRUE;
629   else
630     {
631       relocatable = FALSE;
632       output_bfd = symbol->section->output_section->owner;
633     }
634
635   if (bfd_is_und_section (symbol->section) && ! relocatable)
636     return bfd_reloc_undefined;
637
638   /* We have to figure out the gp value, so that we can adjust the
639      symbol value correctly.  We look up the symbol _gp in the output
640      BFD.  If we can't find it, we're stuck.  We cache it in the ECOFF
641      target data.  We don't need to adjust the symbol value for an
642      external symbol if we are producing relocatable output.  */
643   gp = _bfd_get_gp_value (output_bfd);
644   if (gp == 0
645       && (! relocatable
646           || (symbol->flags & BSF_SECTION_SYM) != 0))
647     {
648       if (relocatable)
649         {
650           /* Make up a value.  */
651           gp = symbol->section->output_section->vma + 0x4000;
652           _bfd_set_gp_value (output_bfd, gp);
653         }
654       else
655         {
656           unsigned int count;
657           asymbol **sym;
658           unsigned int i;
659
660           count = bfd_get_symcount (output_bfd);
661           sym = bfd_get_outsymbols (output_bfd);
662
663           if (sym == (asymbol **) NULL)
664             i = count;
665           else
666             {
667               for (i = 0; i < count; i++, sym++)
668                 {
669                   register const char *name;
670
671                   name = bfd_asymbol_name (*sym);
672                   if (*name == '_' && strcmp (name, "_gp") == 0)
673                     {
674                       gp = bfd_asymbol_value (*sym);
675                       _bfd_set_gp_value (output_bfd, gp);
676                       break;
677                     }
678                 }
679             }
680
681           if (i >= count)
682             {
683               /* Only get the error once.  */
684               gp = 4;
685               _bfd_set_gp_value (output_bfd, gp);
686               *error_message =
687                 (char *) _("GP relative relocation when _gp not defined");
688               return bfd_reloc_dangerous;
689             }
690         }
691     }
692
693   if (bfd_is_com_section (symbol->section))
694     relocation = 0;
695   else
696     relocation = symbol->value;
697
698   relocation += symbol->section->output_section->vma;
699   relocation += symbol->section->output_offset;
700
701   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
702     return bfd_reloc_outofrange;
703
704   insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
705
706   /* Set val to the offset into the section or symbol.  */
707   val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff;
708   if (val & 0x8000)
709     val -= 0x10000;
710
711   /* Adjust val for the final section location and GP value.  If we
712      are producing relocatable output, we don't want to do this for
713      an external symbol.  */
714   if (! relocatable
715       || (symbol->flags & BSF_SECTION_SYM) != 0)
716     val += relocation - gp;
717
718   insn = (insn &~ (unsigned) 0xffff) | (val & 0xffff);
719   bfd_put_32 (abfd, (bfd_vma) insn, (bfd_byte *) data + reloc_entry->address);
720
721   if (relocatable)
722     reloc_entry->address += input_section->output_offset;
723
724   /* Make sure it fit in 16 bits.  */
725   if ((long) val >= 0x8000 || (long) val < -0x8000)
726     return bfd_reloc_overflow;
727
728   return bfd_reloc_ok;
729 }
730
731 /* Get the howto structure for a generic reloc type.  */
732
733 static reloc_howto_type *
734 mips_bfd_reloc_type_lookup (abfd, code)
735      bfd *abfd ATTRIBUTE_UNUSED;
736      bfd_reloc_code_real_type code;
737 {
738   int mips_type;
739
740   switch (code)
741     {
742     case BFD_RELOC_16:
743       mips_type = MIPS_R_REFHALF;
744       break;
745     case BFD_RELOC_32:
746     case BFD_RELOC_CTOR:
747       mips_type = MIPS_R_REFWORD;
748       break;
749     case BFD_RELOC_MIPS_JMP:
750       mips_type = MIPS_R_JMPADDR;
751       break;
752     case BFD_RELOC_HI16_S:
753       mips_type = MIPS_R_REFHI;
754       break;
755     case BFD_RELOC_LO16:
756       mips_type = MIPS_R_REFLO;
757       break;
758     case BFD_RELOC_GPREL16:
759       mips_type = MIPS_R_GPREL;
760       break;
761     case BFD_RELOC_MIPS_LITERAL:
762       mips_type = MIPS_R_LITERAL;
763       break;
764     case BFD_RELOC_16_PCREL_S2:
765       mips_type = MIPS_R_PCREL16;
766       break;
767     default:
768       return (reloc_howto_type *) NULL;
769     }
770
771   return &mips_howto_table[mips_type];
772 }
773
774 static reloc_howto_type *
775 mips_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
776                             const char *r_name)
777 {
778   unsigned int i;
779
780   for (i = 0;
781        i < sizeof (mips_howto_table) / sizeof (mips_howto_table[0]);
782        i++)
783     if (mips_howto_table[i].name != NULL
784         && strcasecmp (mips_howto_table[i].name, r_name) == 0)
785       return &mips_howto_table[i];
786
787   return NULL;
788 }
789 \f
790 /* A helper routine for mips_relocate_section which handles the REFHI
791    relocations.  The REFHI relocation must be followed by a REFLO
792    relocation, and the addend used is formed from the addends of both
793    instructions.  */
794
795 static void
796 mips_relocate_hi (refhi, reflo, input_bfd, input_section, contents,
797                   relocation)
798      struct internal_reloc *refhi;
799      struct internal_reloc *reflo;
800      bfd *input_bfd;
801      asection *input_section;
802      bfd_byte *contents;
803      bfd_vma relocation;
804 {
805   unsigned long insn;
806   unsigned long val;
807   unsigned long vallo;
808
809   if (refhi == NULL)
810     return;
811
812   insn = bfd_get_32 (input_bfd,
813                      contents + refhi->r_vaddr - input_section->vma);
814   if (reflo == NULL)
815     vallo = 0;
816   else
817     vallo = (bfd_get_32 (input_bfd,
818                          contents + reflo->r_vaddr - input_section->vma)
819              & 0xffff);
820
821   val = ((insn & 0xffff) << 16) + vallo;
822   val += relocation;
823
824   /* The low order 16 bits are always treated as a signed value.
825      Therefore, a negative value in the low order bits requires an
826      adjustment in the high order bits.  We need to make this
827      adjustment in two ways: once for the bits we took from the data,
828      and once for the bits we are putting back in to the data.  */
829   if ((vallo & 0x8000) != 0)
830     val -= 0x10000;
831
832   if ((val & 0x8000) != 0)
833     val += 0x10000;
834
835   insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
836   bfd_put_32 (input_bfd, (bfd_vma) insn,
837               contents + refhi->r_vaddr - input_section->vma);
838 }
839
840 /* Relocate a section while linking a MIPS ECOFF file.  */
841
842 static bfd_boolean
843 mips_relocate_section (output_bfd, info, input_bfd, input_section,
844                        contents, external_relocs)
845      bfd *output_bfd;
846      struct bfd_link_info *info;
847      bfd *input_bfd;
848      asection *input_section;
849      bfd_byte *contents;
850      PTR external_relocs;
851 {
852   asection **symndx_to_section;
853   struct ecoff_link_hash_entry **sym_hashes;
854   bfd_vma gp;
855   bfd_boolean gp_undefined;
856   struct external_reloc *ext_rel;
857   struct external_reloc *ext_rel_end;
858   unsigned int i;
859   bfd_boolean got_lo;
860   struct internal_reloc lo_int_rel;
861   bfd_size_type amt;
862
863   BFD_ASSERT (input_bfd->xvec->byteorder
864               == output_bfd->xvec->byteorder);
865
866   /* We keep a table mapping the symndx found in an internal reloc to
867      the appropriate section.  This is faster than looking up the
868      section by name each time.  */
869   symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
870   if (symndx_to_section == (asection **) NULL)
871     {
872       amt = NUM_RELOC_SECTIONS * sizeof (asection *);
873       symndx_to_section = (asection **) bfd_alloc (input_bfd, amt);
874       if (!symndx_to_section)
875         return FALSE;
876
877       symndx_to_section[RELOC_SECTION_NONE] = NULL;
878       symndx_to_section[RELOC_SECTION_TEXT] =
879         bfd_get_section_by_name (input_bfd, ".text");
880       symndx_to_section[RELOC_SECTION_RDATA] =
881         bfd_get_section_by_name (input_bfd, ".rdata");
882       symndx_to_section[RELOC_SECTION_DATA] =
883         bfd_get_section_by_name (input_bfd, ".data");
884       symndx_to_section[RELOC_SECTION_SDATA] =
885         bfd_get_section_by_name (input_bfd, ".sdata");
886       symndx_to_section[RELOC_SECTION_SBSS] =
887         bfd_get_section_by_name (input_bfd, ".sbss");
888       symndx_to_section[RELOC_SECTION_BSS] =
889         bfd_get_section_by_name (input_bfd, ".bss");
890       symndx_to_section[RELOC_SECTION_INIT] =
891         bfd_get_section_by_name (input_bfd, ".init");
892       symndx_to_section[RELOC_SECTION_LIT8] =
893         bfd_get_section_by_name (input_bfd, ".lit8");
894       symndx_to_section[RELOC_SECTION_LIT4] =
895         bfd_get_section_by_name (input_bfd, ".lit4");
896       symndx_to_section[RELOC_SECTION_XDATA] = NULL;
897       symndx_to_section[RELOC_SECTION_PDATA] = NULL;
898       symndx_to_section[RELOC_SECTION_FINI] =
899         bfd_get_section_by_name (input_bfd, ".fini");
900       symndx_to_section[RELOC_SECTION_LITA] = NULL;
901       symndx_to_section[RELOC_SECTION_ABS] = NULL;
902
903       ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
904     }
905
906   sym_hashes = ecoff_data (input_bfd)->sym_hashes;
907
908   gp = _bfd_get_gp_value (output_bfd);
909   if (gp == 0)
910     gp_undefined = TRUE;
911   else
912     gp_undefined = FALSE;
913
914   got_lo = FALSE;
915
916   ext_rel = (struct external_reloc *) external_relocs;
917   ext_rel_end = ext_rel + input_section->reloc_count;
918   for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++)
919     {
920       struct internal_reloc int_rel;
921       bfd_boolean use_lo = FALSE;
922       bfd_vma addend;
923       reloc_howto_type *howto;
924       struct ecoff_link_hash_entry *h = NULL;
925       asection *s = NULL;
926       bfd_vma relocation;
927       bfd_reloc_status_type r;
928
929       if (! got_lo)
930         mips_ecoff_swap_reloc_in (input_bfd, (PTR) ext_rel, &int_rel);
931       else
932         {
933           int_rel = lo_int_rel;
934           got_lo = FALSE;
935         }
936
937       BFD_ASSERT (int_rel.r_type
938                   < sizeof mips_howto_table / sizeof mips_howto_table[0]);
939
940       /* The REFHI reloc requires special handling.  It must be followed
941          by a REFLO reloc, and the addend is formed from both relocs.  */
942       if (int_rel.r_type == MIPS_R_REFHI)
943         {
944           struct external_reloc *lo_ext_rel;
945
946           /* As a GNU extension, permit an arbitrary number of REFHI
947              relocs before the REFLO reloc.  This permits gcc to emit
948              the HI and LO relocs itself.  */
949           for (lo_ext_rel = ext_rel + 1;
950                lo_ext_rel < ext_rel_end;
951                lo_ext_rel++)
952             {
953               mips_ecoff_swap_reloc_in (input_bfd, (PTR) lo_ext_rel,
954                                         &lo_int_rel);
955               if (lo_int_rel.r_type != int_rel.r_type)
956                 break;
957             }
958
959           if (lo_ext_rel < ext_rel_end
960               && lo_int_rel.r_type == MIPS_R_REFLO
961               && int_rel.r_extern == lo_int_rel.r_extern
962               && int_rel.r_symndx == lo_int_rel.r_symndx)
963             {
964               use_lo = TRUE;
965               if (lo_ext_rel == ext_rel + 1)
966                 got_lo = TRUE;
967             }
968         }
969
970       howto = &mips_howto_table[int_rel.r_type];
971
972       if (int_rel.r_extern)
973         {
974           h = sym_hashes[int_rel.r_symndx];
975           /* If h is NULL, that means that there is a reloc against an
976              external symbol which we thought was just a debugging
977              symbol.  This should not happen.  */
978           if (h == (struct ecoff_link_hash_entry *) NULL)
979             abort ();
980         }
981       else
982         {
983           if (int_rel.r_symndx < 0 || int_rel.r_symndx >= NUM_RELOC_SECTIONS)
984             s = NULL;
985           else
986             s = symndx_to_section[int_rel.r_symndx];
987
988           if (s == (asection *) NULL)
989             abort ();
990         }
991
992       /* The GPREL reloc uses an addend: the difference in the GP
993          values.  */
994       if (int_rel.r_type != MIPS_R_GPREL
995           && int_rel.r_type != MIPS_R_LITERAL)
996         addend = 0;
997       else
998         {
999           if (gp_undefined)
1000             {
1001               if (! ((*info->callbacks->reloc_dangerous)
1002                      (info, _("GP relative relocation used when GP not defined"),
1003                       input_bfd, input_section,
1004                       int_rel.r_vaddr - input_section->vma)))
1005                 return FALSE;
1006               /* Only give the error once per link.  */
1007               gp = 4;
1008               _bfd_set_gp_value (output_bfd, gp);
1009               gp_undefined = FALSE;
1010             }
1011           if (! int_rel.r_extern)
1012             {
1013               /* This is a relocation against a section.  The current
1014                  addend in the instruction is the difference between
1015                  INPUT_SECTION->vma and the GP value of INPUT_BFD.  We
1016                  must change this to be the difference between the
1017                  final definition (which will end up in RELOCATION)
1018                  and the GP value of OUTPUT_BFD (which is in GP).  */
1019               addend = ecoff_data (input_bfd)->gp - gp;
1020             }
1021           else if (! info->relocatable
1022                    || h->root.type == bfd_link_hash_defined
1023                    || h->root.type == bfd_link_hash_defweak)
1024             {
1025               /* This is a relocation against a defined symbol.  The
1026                  current addend in the instruction is simply the
1027                  desired offset into the symbol (normally zero).  We
1028                  are going to change this into a relocation against a
1029                  defined symbol, so we want the instruction to hold
1030                  the difference between the final definition of the
1031                  symbol (which will end up in RELOCATION) and the GP
1032                  value of OUTPUT_BFD (which is in GP).  */
1033               addend = - gp;
1034             }
1035           else
1036             {
1037               /* This is a relocation against an undefined or common
1038                  symbol.  The current addend in the instruction is
1039                  simply the desired offset into the symbol (normally
1040                  zero).  We are generating relocatable output, and we
1041                  aren't going to define this symbol, so we just leave
1042                  the instruction alone.  */
1043               addend = 0;
1044             }
1045         }
1046
1047       if (info->relocatable)
1048         {
1049           /* We are generating relocatable output, and must convert
1050              the existing reloc.  */
1051           if (int_rel.r_extern)
1052             {
1053               if ((h->root.type == bfd_link_hash_defined
1054                    || h->root.type == bfd_link_hash_defweak)
1055                   && ! bfd_is_abs_section (h->root.u.def.section))
1056                 {
1057                   const char *name;
1058
1059                   /* This symbol is defined in the output.  Convert
1060                      the reloc from being against the symbol to being
1061                      against the section.  */
1062
1063                   /* Clear the r_extern bit.  */
1064                   int_rel.r_extern = 0;
1065
1066                   /* Compute a new r_symndx value.  */
1067                   s = h->root.u.def.section;
1068                   name = bfd_get_section_name (output_bfd,
1069                                                s->output_section);
1070
1071                   int_rel.r_symndx = -1;
1072                   switch (name[1])
1073                     {
1074                     case 'b':
1075                       if (strcmp (name, ".bss") == 0)
1076                         int_rel.r_symndx = RELOC_SECTION_BSS;
1077                       break;
1078                     case 'd':
1079                       if (strcmp (name, ".data") == 0)
1080                         int_rel.r_symndx = RELOC_SECTION_DATA;
1081                       break;
1082                     case 'f':
1083                       if (strcmp (name, ".fini") == 0)
1084                         int_rel.r_symndx = RELOC_SECTION_FINI;
1085                       break;
1086                     case 'i':
1087                       if (strcmp (name, ".init") == 0)
1088                         int_rel.r_symndx = RELOC_SECTION_INIT;
1089                       break;
1090                     case 'l':
1091                       if (strcmp (name, ".lit8") == 0)
1092                         int_rel.r_symndx = RELOC_SECTION_LIT8;
1093                       else if (strcmp (name, ".lit4") == 0)
1094                         int_rel.r_symndx = RELOC_SECTION_LIT4;
1095                       break;
1096                     case 'r':
1097                       if (strcmp (name, ".rdata") == 0)
1098                         int_rel.r_symndx = RELOC_SECTION_RDATA;
1099                       break;
1100                     case 's':
1101                       if (strcmp (name, ".sdata") == 0)
1102                         int_rel.r_symndx = RELOC_SECTION_SDATA;
1103                       else if (strcmp (name, ".sbss") == 0)
1104                         int_rel.r_symndx = RELOC_SECTION_SBSS;
1105                       break;
1106                     case 't':
1107                       if (strcmp (name, ".text") == 0)
1108                         int_rel.r_symndx = RELOC_SECTION_TEXT;
1109                       break;
1110                     }
1111
1112                   if (int_rel.r_symndx == -1)
1113                     abort ();
1114
1115                   /* Add the section VMA and the symbol value.  */
1116                   relocation = (h->root.u.def.value
1117                                 + s->output_section->vma
1118                                 + s->output_offset);
1119
1120                   /* For a PC relative relocation, the object file
1121                      currently holds just the addend.  We must adjust
1122                      by the address to get the right value.  */
1123                   if (howto->pc_relative)
1124                     relocation -= int_rel.r_vaddr - input_section->vma;
1125
1126                   h = NULL;
1127                 }
1128               else
1129                 {
1130                   /* Change the symndx value to the right one for the
1131                      output BFD.  */
1132                   int_rel.r_symndx = h->indx;
1133                   if (int_rel.r_symndx == -1)
1134                     {
1135                       /* This symbol is not being written out.  */
1136                       if (! ((*info->callbacks->unattached_reloc)
1137                              (info, h->root.root.string, input_bfd,
1138                               input_section,
1139                               int_rel.r_vaddr - input_section->vma)))
1140                         return FALSE;
1141                       int_rel.r_symndx = 0;
1142                     }
1143                   relocation = 0;
1144                 }
1145             }
1146           else
1147             {
1148               /* This is a relocation against a section.  Adjust the
1149                  value by the amount the section moved.  */
1150               relocation = (s->output_section->vma
1151                             + s->output_offset
1152                             - s->vma);
1153             }
1154
1155           relocation += addend;
1156           addend = 0;
1157
1158           /* Adjust a PC relative relocation by removing the reference
1159              to the original address in the section and including the
1160              reference to the new address.  */
1161           if (howto->pc_relative)
1162             relocation -= (input_section->output_section->vma
1163                            + input_section->output_offset
1164                            - input_section->vma);
1165
1166           /* Adjust the contents.  */
1167           if (relocation == 0)
1168             r = bfd_reloc_ok;
1169           else
1170             {
1171               if (int_rel.r_type != MIPS_R_REFHI)
1172                 r = _bfd_relocate_contents (howto, input_bfd, relocation,
1173                                             (contents
1174                                              + int_rel.r_vaddr
1175                                              - input_section->vma));
1176               else
1177                 {
1178                   mips_relocate_hi (&int_rel,
1179                                     use_lo ? &lo_int_rel : NULL,
1180                                     input_bfd, input_section, contents,
1181                                     relocation);
1182                   r = bfd_reloc_ok;
1183                 }
1184             }
1185
1186           /* Adjust the reloc address.  */
1187           int_rel.r_vaddr += (input_section->output_section->vma
1188                               + input_section->output_offset
1189                               - input_section->vma);
1190
1191           /* Save the changed reloc information.  */
1192           mips_ecoff_swap_reloc_out (input_bfd, &int_rel, (PTR) ext_rel);
1193         }
1194       else
1195         {
1196           /* We are producing a final executable.  */
1197           if (int_rel.r_extern)
1198             {
1199               /* This is a reloc against a symbol.  */
1200               if (h->root.type == bfd_link_hash_defined
1201                   || h->root.type == bfd_link_hash_defweak)
1202                 {
1203                   asection *hsec;
1204
1205                   hsec = h->root.u.def.section;
1206                   relocation = (h->root.u.def.value
1207                                 + hsec->output_section->vma
1208                                 + hsec->output_offset);
1209                 }
1210               else
1211                 {
1212                   if (! ((*info->callbacks->undefined_symbol)
1213                          (info, h->root.root.string, input_bfd,
1214                           input_section,
1215                           int_rel.r_vaddr - input_section->vma, TRUE)))
1216                     return FALSE;
1217                   relocation = 0;
1218                 }
1219             }
1220           else
1221             {
1222               /* This is a reloc against a section.  */
1223               relocation = (s->output_section->vma
1224                             + s->output_offset
1225                             - s->vma);
1226
1227               /* A PC relative reloc is already correct in the object
1228                  file.  Make it look like a pcrel_offset relocation by
1229                  adding in the start address.  */
1230               if (howto->pc_relative)
1231                 relocation += int_rel.r_vaddr;
1232             }
1233
1234           if (int_rel.r_type != MIPS_R_REFHI)
1235             r = _bfd_final_link_relocate (howto,
1236                                           input_bfd,
1237                                           input_section,
1238                                           contents,
1239                                           (int_rel.r_vaddr
1240                                            - input_section->vma),
1241                                           relocation,
1242                                           addend);
1243           else
1244             {
1245               mips_relocate_hi (&int_rel,
1246                                 use_lo ? &lo_int_rel : NULL,
1247                                 input_bfd, input_section, contents,
1248                                 relocation);
1249               r = bfd_reloc_ok;
1250             }
1251         }
1252
1253       /* MIPS_R_JMPADDR requires peculiar overflow detection.  The
1254          instruction provides a 28 bit address (the two lower bits are
1255          implicit zeroes) which is combined with the upper four bits
1256          of the instruction address.  */
1257       if (r == bfd_reloc_ok
1258           && int_rel.r_type == MIPS_R_JMPADDR
1259           && (((relocation
1260                 + addend
1261                 + (int_rel.r_extern ? 0 : s->vma))
1262                & 0xf0000000)
1263               != ((input_section->output_section->vma
1264                    + input_section->output_offset
1265                    + (int_rel.r_vaddr - input_section->vma))
1266                   & 0xf0000000)))
1267         r = bfd_reloc_overflow;
1268
1269       if (r != bfd_reloc_ok)
1270         {
1271           switch (r)
1272             {
1273             default:
1274             case bfd_reloc_outofrange:
1275               abort ();
1276             case bfd_reloc_overflow:
1277               {
1278                 const char *name;
1279
1280                 if (int_rel.r_extern)
1281                   name = NULL;
1282                 else
1283                   name = bfd_section_name (input_bfd, s);
1284                 if (! ((*info->callbacks->reloc_overflow)
1285                        (info, (h ? &h->root : NULL), name, howto->name,
1286                         (bfd_vma) 0, input_bfd, input_section,
1287                         int_rel.r_vaddr - input_section->vma)))
1288                   return FALSE;
1289               }
1290               break;
1291             }
1292         }
1293     }
1294
1295   return TRUE;
1296 }
1297 \f
1298 /* This is the ECOFF backend structure.  The backend field of the
1299    target vector points to this.  */
1300
1301 static const struct ecoff_backend_data mips_ecoff_backend_data =
1302 {
1303   /* COFF backend structure.  */
1304   {
1305     (void (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR))) bfd_void, /* aux_in */
1306     (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
1307     (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
1308     (unsigned (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR)))bfd_void,/*aux_out*/
1309     (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
1310     (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
1311     (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */
1312     mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out,
1313     mips_ecoff_swap_scnhdr_out,
1314     FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, TRUE, FALSE, 4, FALSE, 2,
1315     mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in,
1316     mips_ecoff_swap_scnhdr_in, NULL,
1317     mips_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
1318     _bfd_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
1319     _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
1320     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1321     NULL, NULL
1322   },
1323   /* Supported architecture.  */
1324   bfd_arch_mips,
1325   /* Initial portion of armap string.  */
1326   "__________",
1327   /* The page boundary used to align sections in a demand-paged
1328      executable file.  E.g., 0x1000.  */
1329   0x1000,
1330   /* TRUE if the .rdata section is part of the text segment, as on the
1331      Alpha.  FALSE if .rdata is part of the data segment, as on the
1332      MIPS.  */
1333   FALSE,
1334   /* Bitsize of constructor entries.  */
1335   32,
1336   /* Reloc to use for constructor entries.  */
1337   &mips_howto_table[MIPS_R_REFWORD],
1338   {
1339     /* Symbol table magic number.  */
1340     magicSym,
1341     /* Alignment of debugging information.  E.g., 4.  */
1342     4,
1343     /* Sizes of external symbolic information.  */
1344     sizeof (struct hdr_ext),
1345     sizeof (struct dnr_ext),
1346     sizeof (struct pdr_ext),
1347     sizeof (struct sym_ext),
1348     sizeof (struct opt_ext),
1349     sizeof (struct fdr_ext),
1350     sizeof (struct rfd_ext),
1351     sizeof (struct ext_ext),
1352     /* Functions to swap in external symbolic data.  */
1353     ecoff_swap_hdr_in,
1354     ecoff_swap_dnr_in,
1355     ecoff_swap_pdr_in,
1356     ecoff_swap_sym_in,
1357     ecoff_swap_opt_in,
1358     ecoff_swap_fdr_in,
1359     ecoff_swap_rfd_in,
1360     ecoff_swap_ext_in,
1361     _bfd_ecoff_swap_tir_in,
1362     _bfd_ecoff_swap_rndx_in,
1363     /* Functions to swap out external symbolic data.  */
1364     ecoff_swap_hdr_out,
1365     ecoff_swap_dnr_out,
1366     ecoff_swap_pdr_out,
1367     ecoff_swap_sym_out,
1368     ecoff_swap_opt_out,
1369     ecoff_swap_fdr_out,
1370     ecoff_swap_rfd_out,
1371     ecoff_swap_ext_out,
1372     _bfd_ecoff_swap_tir_out,
1373     _bfd_ecoff_swap_rndx_out,
1374     /* Function to read in symbolic data.  */
1375     _bfd_ecoff_slurp_symbolic_info
1376   },
1377   /* External reloc size.  */
1378   RELSZ,
1379   /* Reloc swapping functions.  */
1380   mips_ecoff_swap_reloc_in,
1381   mips_ecoff_swap_reloc_out,
1382   /* Backend reloc tweaking.  */
1383   mips_adjust_reloc_in,
1384   mips_adjust_reloc_out,
1385   /* Relocate section contents while linking.  */
1386   mips_relocate_section,
1387   /* Do final adjustments to filehdr and aouthdr.  */
1388   NULL,
1389   /* Read an element from an archive at a given file position.  */
1390   _bfd_get_elt_at_filepos
1391 };
1392
1393 /* Looking up a reloc type is MIPS specific.  */
1394 #define _bfd_ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup
1395 #define _bfd_ecoff_bfd_reloc_name_lookup mips_bfd_reloc_name_lookup
1396
1397 /* Getting relocated section contents is generic.  */
1398 #define _bfd_ecoff_bfd_get_relocated_section_contents \
1399   bfd_generic_get_relocated_section_contents
1400
1401 /* Handling file windows is generic.  */
1402 #define _bfd_ecoff_get_section_contents_in_window \
1403   _bfd_generic_get_section_contents_in_window
1404
1405 /* Relaxing sections is MIPS specific.  */
1406 #define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section
1407
1408 /* GC of sections is not done.  */
1409 #define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
1410
1411 /* Merging of sections is not done.  */
1412 #define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections
1413
1414 #define _bfd_ecoff_bfd_is_group_section bfd_generic_is_group_section
1415 #define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group
1416 #define _bfd_ecoff_section_already_linked \
1417   _bfd_generic_section_already_linked
1418
1419 extern const bfd_target ecoff_big_vec;
1420
1421 const bfd_target ecoff_little_vec =
1422 {
1423   "ecoff-littlemips",           /* name */
1424   bfd_target_ecoff_flavour,
1425   BFD_ENDIAN_LITTLE,            /* data byte order is little */
1426   BFD_ENDIAN_LITTLE,            /* header byte order is little */
1427
1428   (HAS_RELOC | EXEC_P |         /* object flags */
1429    HAS_LINENO | HAS_DEBUG |
1430    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1431
1432   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
1433   0,                            /* leading underscore */
1434   ' ',                          /* ar_pad_char */
1435   15,                           /* ar_max_namelen */
1436   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1437      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1438      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
1439   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1440      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1441      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
1442
1443   {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
1444      _bfd_ecoff_archive_p, _bfd_dummy_target},
1445   {bfd_false, _bfd_ecoff_mkobject,  /* bfd_set_format */
1446      _bfd_generic_mkarchive, bfd_false},
1447   {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
1448      _bfd_write_archive_contents, bfd_false},
1449
1450      BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
1451      BFD_JUMP_TABLE_COPY (_bfd_ecoff),
1452      BFD_JUMP_TABLE_CORE (_bfd_nocore),
1453      BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
1454      BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
1455      BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
1456      BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
1457      BFD_JUMP_TABLE_LINK (_bfd_ecoff),
1458      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1459
1460   & ecoff_big_vec,
1461
1462   (PTR) &mips_ecoff_backend_data
1463 };
1464
1465 const bfd_target ecoff_big_vec =
1466 {
1467   "ecoff-bigmips",              /* name */
1468   bfd_target_ecoff_flavour,
1469   BFD_ENDIAN_BIG,               /* data byte order is big */
1470   BFD_ENDIAN_BIG,               /* header byte order is big */
1471
1472   (HAS_RELOC | EXEC_P |         /* object flags */
1473    HAS_LINENO | HAS_DEBUG |
1474    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1475
1476   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
1477   0,                            /* leading underscore */
1478   ' ',                          /* ar_pad_char */
1479   15,                           /* ar_max_namelen */
1480   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1481      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1482      bfd_getb16, bfd_getb_signed_16, bfd_putb16,
1483   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1484      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1485      bfd_getb16, bfd_getb_signed_16, bfd_putb16,
1486  {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
1487     _bfd_ecoff_archive_p, _bfd_dummy_target},
1488  {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
1489     _bfd_generic_mkarchive, bfd_false},
1490  {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
1491     _bfd_write_archive_contents, bfd_false},
1492
1493      BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
1494      BFD_JUMP_TABLE_COPY (_bfd_ecoff),
1495      BFD_JUMP_TABLE_CORE (_bfd_nocore),
1496      BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
1497      BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
1498      BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
1499      BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
1500      BFD_JUMP_TABLE_LINK (_bfd_ecoff),
1501      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1502
1503   & ecoff_little_vec,
1504
1505   (PTR) &mips_ecoff_backend_data
1506 };
1507
1508 const bfd_target ecoff_biglittle_vec =
1509 {
1510   "ecoff-biglittlemips",                /* name */
1511   bfd_target_ecoff_flavour,
1512   BFD_ENDIAN_LITTLE,            /* data byte order is little */
1513   BFD_ENDIAN_BIG,               /* header byte order is big */
1514
1515   (HAS_RELOC | EXEC_P |         /* object flags */
1516    HAS_LINENO | HAS_DEBUG |
1517    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1518
1519   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
1520   0,                            /* leading underscore */
1521   ' ',                          /* ar_pad_char */
1522   15,                           /* ar_max_namelen */
1523   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1524      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1525      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
1526   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1527      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1528      bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
1529
1530   {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
1531      _bfd_ecoff_archive_p, _bfd_dummy_target},
1532   {bfd_false, _bfd_ecoff_mkobject,  /* bfd_set_format */
1533      _bfd_generic_mkarchive, bfd_false},
1534   {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
1535      _bfd_write_archive_contents, bfd_false},
1536
1537      BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
1538      BFD_JUMP_TABLE_COPY (_bfd_ecoff),
1539      BFD_JUMP_TABLE_CORE (_bfd_nocore),
1540      BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
1541      BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
1542      BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
1543      BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
1544      BFD_JUMP_TABLE_LINK (_bfd_ecoff),
1545      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1546
1547   NULL,
1548
1549   (PTR) &mips_ecoff_backend_data
1550 };