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