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