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