Home | History | Annotate | Line # | Download | only in bfd
coff-mips.c revision 1.1.1.12
      1 /* BFD back-end for MIPS Extended-Coff files.
      2    Copyright (C) 1990-2026 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 	 1,			/* size */
     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 	 2,			/* size */
    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 	 4,			/* size */
    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 	 4,			/* size */
    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 	 4,			/* size */
    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 	 4,			/* size */
    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 	 4,			/* size */
    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 	 4,			/* size */
    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 	 4,			/* size */
    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 bool
    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     {
    360       /* xgettext:c-format */
    361       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
    362 			  abfd, intern->r_type);
    363       bfd_set_error (bfd_error_bad_value);
    364       rptr->howto  = NULL;
    365       return;
    366     }
    367 
    368   if (! intern->r_extern
    369       && (intern->r_type == MIPS_R_GPREL
    370 	  || intern->r_type == MIPS_R_LITERAL))
    371     rptr->addend += ecoff_data (abfd)->gp;
    372 
    373   /* If the type is MIPS_R_IGNORE, make sure this is a reference to
    374      the absolute section so that the reloc is ignored.  */
    375   if (intern->r_type == MIPS_R_IGNORE)
    376     rptr->sym_ptr_ptr = &bfd_abs_section_ptr->symbol;
    377 
    378   rptr->howto = &mips_howto_table[intern->r_type];
    379 }
    380 
    381 /* Make any adjustments needed to a reloc before writing it out.  None
    382    are needed for MIPS.  */
    383 
    384 static void
    385 mips_adjust_reloc_out (bfd *abfd ATTRIBUTE_UNUSED,
    386 		       const arelent *rel ATTRIBUTE_UNUSED,
    387 		       struct internal_reloc *intern ATTRIBUTE_UNUSED)
    388 {
    389 }
    390 
    391 /* ECOFF relocs are either against external symbols, or against
    392    sections.  If we are producing relocatable output, and the reloc
    393    is against an external symbol, and nothing has given us any
    394    additional addend, the resulting reloc will also be against the
    395    same symbol.  In such a case, we don't want to change anything
    396    about the way the reloc is handled, since it will all be done at
    397    final link time.  Rather than put special case code into
    398    bfd_perform_relocation, all the reloc types use this howto
    399    function.  It just short circuits the reloc if producing
    400    relocatable output against an external symbol.  */
    401 
    402 static bfd_reloc_status_type
    403 mips_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED,
    404 		    arelent *reloc_entry,
    405 		    asymbol *symbol,
    406 		    void * data ATTRIBUTE_UNUSED,
    407 		    asection *input_section,
    408 		    bfd *output_bfd,
    409 		    char **error_message ATTRIBUTE_UNUSED)
    410 {
    411   if (output_bfd != (bfd *) NULL
    412       && (symbol->flags & BSF_SECTION_SYM) == 0
    413       && reloc_entry->addend == 0)
    414     {
    415       reloc_entry->address += input_section->output_offset;
    416       return bfd_reloc_ok;
    417     }
    418 
    419   return bfd_reloc_continue;
    420 }
    421 
    422 /* Do a REFHI relocation.  This has to be done in combination with a
    423    REFLO reloc, because there is a carry from the REFLO to the REFHI.
    424    Here we just save the information we need; we do the actual
    425    relocation when we see the REFLO.  MIPS ECOFF requires that the
    426    REFLO immediately follow the REFHI.  As a GNU extension, we permit
    427    an arbitrary number of HI relocs to be associated with a single LO
    428    reloc.  This extension permits gcc to output the HI and LO relocs
    429    itself.  */
    430 
    431 static bfd_reloc_status_type
    432 mips_refhi_reloc (bfd *abfd,
    433 		  arelent *reloc_entry,
    434 		  asymbol *symbol,
    435 		  void * data,
    436 		  asection *input_section,
    437 		  bfd *output_bfd,
    438 		  char **error_message ATTRIBUTE_UNUSED)
    439 {
    440   bfd_reloc_status_type ret;
    441   bfd_vma relocation;
    442   struct mips_hi *n;
    443 
    444   /* If we're relocating, and this an external symbol, we don't want
    445      to change anything.  */
    446   if (output_bfd != (bfd *) NULL
    447       && (symbol->flags & BSF_SECTION_SYM) == 0
    448       && reloc_entry->addend == 0)
    449     {
    450       reloc_entry->address += input_section->output_offset;
    451       return bfd_reloc_ok;
    452     }
    453 
    454   ret = bfd_reloc_ok;
    455   if (bfd_is_und_section (symbol->section)
    456       && output_bfd == (bfd *) NULL)
    457     ret = bfd_reloc_undefined;
    458 
    459   if (bfd_is_com_section (symbol->section))
    460     relocation = 0;
    461   else
    462     relocation = symbol->value;
    463 
    464   relocation += symbol->section->output_section->vma;
    465   relocation += symbol->section->output_offset;
    466   relocation += reloc_entry->addend;
    467 
    468   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
    469     return bfd_reloc_outofrange;
    470 
    471   /* Save the information, and let REFLO do the actual relocation.  */
    472   n = (struct mips_hi *) bfd_malloc ((bfd_size_type) sizeof *n);
    473   if (n == NULL)
    474     return bfd_reloc_outofrange;
    475   n->addr = (bfd_byte *) data + reloc_entry->address;
    476   n->addend = relocation;
    477   n->next = ecoff_data (abfd)->mips_refhi_list;
    478   ecoff_data (abfd)->mips_refhi_list = n;
    479 
    480   if (output_bfd != (bfd *) NULL)
    481     reloc_entry->address += input_section->output_offset;
    482 
    483   return ret;
    484 }
    485 
    486 /* Do a REFLO relocation.  This is a straightforward 16 bit inplace
    487    relocation; this function exists in order to do the REFHI
    488    relocation described above.  */
    489 
    490 static bfd_reloc_status_type
    491 mips_reflo_reloc (bfd *abfd,
    492 		  arelent *reloc_entry,
    493 		  asymbol *symbol,
    494 		  void * data,
    495 		  asection *input_section,
    496 		  bfd *output_bfd,
    497 		  char **error_message)
    498 {
    499   if (ecoff_data (abfd)->mips_refhi_list != NULL)
    500     {
    501       struct mips_hi *l;
    502 
    503       l = ecoff_data (abfd)->mips_refhi_list;
    504       while (l != NULL)
    505 	{
    506 	  unsigned long insn;
    507 	  unsigned long val;
    508 	  unsigned long vallo;
    509 	  struct mips_hi *next;
    510 	  bfd_size_type octets = (reloc_entry->address
    511 				  * OCTETS_PER_BYTE (abfd, input_section));
    512 	  bfd_byte *loc = (bfd_byte *) data + octets;
    513 
    514 	  if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
    515 					  input_section, octets))
    516 	    return bfd_reloc_outofrange;
    517 
    518 	  /* Do the REFHI relocation.  Note that we actually don't
    519 	     need to know anything about the REFLO itself, except
    520 	     where to find the low 16 bits of the addend needed by the
    521 	     REFHI.  */
    522 	  insn = bfd_get_32 (abfd, l->addr);
    523 	  vallo = bfd_get_32 (abfd, loc) & 0xffff;
    524 	  val = ((insn & 0xffff) << 16) + vallo;
    525 	  val += l->addend;
    526 
    527 	  /* The low order 16 bits are always treated as a signed
    528 	     value.  Therefore, a negative value in the low order bits
    529 	     requires an adjustment in the high order bits.  We need
    530 	     to make this adjustment in two ways: once for the bits we
    531 	     took from the data, and once for the bits we are putting
    532 	     back in to the data.  */
    533 	  if ((vallo & 0x8000) != 0)
    534 	    val -= 0x10000;
    535 	  if ((val & 0x8000) != 0)
    536 	    val += 0x10000;
    537 
    538 	  insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
    539 	  bfd_put_32 (abfd, (bfd_vma) insn, l->addr);
    540 
    541 	  next = l->next;
    542 	  free (l);
    543 	  l = next;
    544 	}
    545 
    546       ecoff_data (abfd)->mips_refhi_list = NULL;
    547     }
    548 
    549   /* Now do the REFLO reloc in the usual way.  */
    550   return mips_generic_reloc (abfd, reloc_entry, symbol, data,
    551 			     input_section, output_bfd, error_message);
    552 }
    553 
    554 /* Do a GPREL relocation.  This is a 16 bit value which must become
    555    the offset from the gp register.  */
    556 
    557 static bfd_reloc_status_type
    558 mips_gprel_reloc (bfd *abfd ATTRIBUTE_UNUSED,
    559 		  arelent *reloc_entry,
    560 		  asymbol *symbol,
    561 		  void * data,
    562 		  asection *input_section,
    563 		  bfd *output_bfd,
    564 		  char **error_message ATTRIBUTE_UNUSED)
    565 {
    566   bool relocatable;
    567   bfd_vma gp;
    568   bfd_vma relocation;
    569   unsigned long val;
    570   unsigned long insn;
    571 
    572   /* If we're relocating, and this is an external symbol with no
    573      addend, we don't want to change anything.  We will only have an
    574      addend if this is a newly created reloc, not read from an ECOFF
    575      file.  */
    576   if (output_bfd != (bfd *) NULL
    577       && (symbol->flags & BSF_SECTION_SYM) == 0
    578       && reloc_entry->addend == 0)
    579     {
    580       reloc_entry->address += input_section->output_offset;
    581       return bfd_reloc_ok;
    582     }
    583 
    584   if (output_bfd != (bfd *) NULL)
    585     relocatable = true;
    586   else
    587     {
    588       relocatable = false;
    589       output_bfd = symbol->section->output_section->owner;
    590       if (output_bfd == NULL)
    591 	return bfd_reloc_undefined;
    592     }
    593 
    594   /* We have to figure out the gp value, so that we can adjust the
    595      symbol value correctly.  We look up the symbol _gp in the output
    596      BFD.  If we can't find it, we're stuck.  We cache it in the ECOFF
    597      target data.  We don't need to adjust the symbol value for an
    598      external symbol if we are producing relocatable output.  */
    599   gp = _bfd_get_gp_value (output_bfd);
    600   if (gp == 0
    601       && (! relocatable
    602 	  || (symbol->flags & BSF_SECTION_SYM) != 0))
    603     {
    604       if (relocatable)
    605 	{
    606 	  /* Make up a value.  */
    607 	  gp = symbol->section->output_section->vma + 0x4000;
    608 	  _bfd_set_gp_value (output_bfd, gp);
    609 	}
    610       else
    611 	{
    612 	  unsigned int count;
    613 	  asymbol **sym;
    614 	  unsigned int i;
    615 
    616 	  count = bfd_get_symcount (output_bfd);
    617 	  sym = bfd_get_outsymbols (output_bfd);
    618 
    619 	  if (sym == (asymbol **) NULL)
    620 	    i = count;
    621 	  else
    622 	    {
    623 	      for (i = 0; i < count; i++, sym++)
    624 		{
    625 		  register const char *name;
    626 
    627 		  name = bfd_asymbol_name (*sym);
    628 		  if (*name == '_' && strcmp (name, "_gp") == 0)
    629 		    {
    630 		      gp = bfd_asymbol_value (*sym);
    631 		      _bfd_set_gp_value (output_bfd, gp);
    632 		      break;
    633 		    }
    634 		}
    635 	    }
    636 
    637 	  if (i >= count)
    638 	    {
    639 	      /* Only get the error once.  */
    640 	      gp = 4;
    641 	      _bfd_set_gp_value (output_bfd, gp);
    642 	      *error_message =
    643 		(char *) _("GP relative relocation when _gp not defined");
    644 	      return bfd_reloc_dangerous;
    645 	    }
    646 	}
    647     }
    648 
    649   if (bfd_is_com_section (symbol->section))
    650     relocation = 0;
    651   else
    652     relocation = symbol->value;
    653 
    654   relocation += symbol->section->output_section->vma;
    655   relocation += symbol->section->output_offset;
    656 
    657   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
    658     return bfd_reloc_outofrange;
    659 
    660   insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
    661 
    662   /* Set val to the offset into the section or symbol.  */
    663   val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff;
    664   if (val & 0x8000)
    665     val -= 0x10000;
    666 
    667   /* Adjust val for the final section location and GP value.  If we
    668      are producing relocatable output, we don't want to do this for
    669      an external symbol.  */
    670   if (! relocatable
    671       || (symbol->flags & BSF_SECTION_SYM) != 0)
    672     val += relocation - gp;
    673 
    674   insn = (insn &~ (unsigned) 0xffff) | (val & 0xffff);
    675   bfd_put_32 (abfd, (bfd_vma) insn, (bfd_byte *) data + reloc_entry->address);
    676 
    677   if (relocatable)
    678     reloc_entry->address += input_section->output_offset;
    679 
    680   /* Make sure it fit in 16 bits.  */
    681   if ((long) val >= 0x8000 || (long) val < -0x8000)
    682     return bfd_reloc_overflow;
    683 
    684   return bfd_reloc_ok;
    685 }
    686 
    687 /* Get the howto structure for a generic reloc type.  */
    688 
    689 static reloc_howto_type *
    690 mips_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    691 			    bfd_reloc_code_real_type code)
    692 {
    693   int mips_type;
    694 
    695   switch (code)
    696     {
    697     case BFD_RELOC_16:
    698       mips_type = MIPS_R_REFHALF;
    699       break;
    700     case BFD_RELOC_32:
    701     case BFD_RELOC_CTOR:
    702       mips_type = MIPS_R_REFWORD;
    703       break;
    704     case BFD_RELOC_MIPS_JMP:
    705       mips_type = MIPS_R_JMPADDR;
    706       break;
    707     case BFD_RELOC_HI16_S:
    708       mips_type = MIPS_R_REFHI;
    709       break;
    710     case BFD_RELOC_LO16:
    711       mips_type = MIPS_R_REFLO;
    712       break;
    713     case BFD_RELOC_GPREL16:
    714       mips_type = MIPS_R_GPREL;
    715       break;
    716     case BFD_RELOC_MIPS_LITERAL:
    717       mips_type = MIPS_R_LITERAL;
    718       break;
    719     case BFD_RELOC_16_PCREL_S2:
    720       mips_type = MIPS_R_PCREL16;
    721       break;
    722     default:
    723       return (reloc_howto_type *) NULL;
    724     }
    725 
    726   return &mips_howto_table[mips_type];
    727 }
    728 
    729 static reloc_howto_type *
    730 mips_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    731 			    const char *r_name)
    732 {
    733   unsigned int i;
    734 
    735   for (i = 0;
    736        i < sizeof (mips_howto_table) / sizeof (mips_howto_table[0]);
    737        i++)
    738     if (mips_howto_table[i].name != NULL
    739 	&& strcasecmp (mips_howto_table[i].name, r_name) == 0)
    740       return &mips_howto_table[i];
    741 
    742   return NULL;
    743 }
    744 
    745 /* A helper routine for mips_relocate_section which handles the REFHI
    747    relocations.  The REFHI relocation must be followed by a REFLO
    748    relocation, and the addend used is formed from the addends of both
    749    instructions.  */
    750 
    751 static void
    752 mips_relocate_hi (struct internal_reloc *refhi,
    753 		  struct internal_reloc *reflo,
    754 		  bfd *input_bfd,
    755 		  asection *input_section,
    756 		  bfd_byte *contents,
    757 		  bfd_vma relocation)
    758 {
    759   unsigned long insn;
    760   unsigned long val;
    761   unsigned long vallo;
    762 
    763   if (refhi == NULL)
    764     return;
    765 
    766   insn = bfd_get_32 (input_bfd,
    767 		     contents + refhi->r_vaddr - input_section->vma);
    768   if (reflo == NULL)
    769     vallo = 0;
    770   else
    771     vallo = (bfd_get_32 (input_bfd,
    772 			 contents + reflo->r_vaddr - input_section->vma)
    773 	     & 0xffff);
    774 
    775   val = ((insn & 0xffff) << 16) + vallo;
    776   val += relocation;
    777 
    778   /* The low order 16 bits are always treated as a signed value.
    779      Therefore, a negative value in the low order bits requires an
    780      adjustment in the high order bits.  We need to make this
    781      adjustment in two ways: once for the bits we took from the data,
    782      and once for the bits we are putting back in to the data.  */
    783   if ((vallo & 0x8000) != 0)
    784     val -= 0x10000;
    785 
    786   if ((val & 0x8000) != 0)
    787     val += 0x10000;
    788 
    789   insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
    790   bfd_put_32 (input_bfd, (bfd_vma) insn,
    791 	      contents + refhi->r_vaddr - input_section->vma);
    792 }
    793 
    794 /* Relocate a section while linking a MIPS ECOFF file.  */
    795 
    796 static bool
    797 mips_relocate_section (bfd *output_bfd,
    798 		       struct bfd_link_info *info,
    799 		       bfd *input_bfd,
    800 		       asection *input_section,
    801 		       bfd_byte *contents,
    802 		       void * external_relocs)
    803 {
    804   asection **symndx_to_section;
    805   struct ecoff_link_hash_entry **sym_hashes;
    806   bfd_vma gp;
    807   bool gp_undefined;
    808   struct external_reloc *ext_rel;
    809   struct external_reloc *ext_rel_end;
    810   bool got_lo;
    811   struct internal_reloc lo_int_rel;
    812   bfd_size_type amt;
    813 
    814   BFD_ASSERT (input_bfd->xvec->byteorder
    815 	      == output_bfd->xvec->byteorder);
    816 
    817   /* We keep a table mapping the symndx found in an internal reloc to
    818      the appropriate section.  This is faster than looking up the
    819      section by name each time.  */
    820   symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
    821   if (symndx_to_section == (asection **) NULL)
    822     {
    823       amt = NUM_RELOC_SECTIONS * sizeof (asection *);
    824       symndx_to_section = (asection **) bfd_alloc (input_bfd, amt);
    825       if (!symndx_to_section)
    826 	return false;
    827 
    828       symndx_to_section[RELOC_SECTION_NONE] = NULL;
    829       symndx_to_section[RELOC_SECTION_TEXT] =
    830 	bfd_get_section_by_name (input_bfd, ".text");
    831       symndx_to_section[RELOC_SECTION_RDATA] =
    832 	bfd_get_section_by_name (input_bfd, ".rdata");
    833       symndx_to_section[RELOC_SECTION_DATA] =
    834 	bfd_get_section_by_name (input_bfd, ".data");
    835       symndx_to_section[RELOC_SECTION_SDATA] =
    836 	bfd_get_section_by_name (input_bfd, ".sdata");
    837       symndx_to_section[RELOC_SECTION_SBSS] =
    838 	bfd_get_section_by_name (input_bfd, ".sbss");
    839       symndx_to_section[RELOC_SECTION_BSS] =
    840 	bfd_get_section_by_name (input_bfd, ".bss");
    841       symndx_to_section[RELOC_SECTION_INIT] =
    842 	bfd_get_section_by_name (input_bfd, ".init");
    843       symndx_to_section[RELOC_SECTION_LIT8] =
    844 	bfd_get_section_by_name (input_bfd, ".lit8");
    845       symndx_to_section[RELOC_SECTION_LIT4] =
    846 	bfd_get_section_by_name (input_bfd, ".lit4");
    847       symndx_to_section[RELOC_SECTION_XDATA] = NULL;
    848       symndx_to_section[RELOC_SECTION_PDATA] = NULL;
    849       symndx_to_section[RELOC_SECTION_FINI] =
    850 	bfd_get_section_by_name (input_bfd, ".fini");
    851       symndx_to_section[RELOC_SECTION_LITA] = NULL;
    852       symndx_to_section[RELOC_SECTION_ABS] = NULL;
    853 
    854       ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
    855     }
    856 
    857   sym_hashes = ecoff_data (input_bfd)->sym_hashes;
    858 
    859   gp = _bfd_get_gp_value (output_bfd);
    860   if (gp == 0)
    861     gp_undefined = true;
    862   else
    863     gp_undefined = false;
    864 
    865   got_lo = false;
    866 
    867   ext_rel = (struct external_reloc *) external_relocs;
    868   ext_rel_end = ext_rel + input_section->reloc_count;
    869   for (; ext_rel < ext_rel_end; ext_rel++)
    870     {
    871       struct internal_reloc int_rel;
    872       bool use_lo = false;
    873       bfd_vma addend;
    874       reloc_howto_type *howto;
    875       struct ecoff_link_hash_entry *h = NULL;
    876       asection *s = NULL;
    877       bfd_vma relocation;
    878       bfd_reloc_status_type r;
    879 
    880       if (! got_lo)
    881 	mips_ecoff_swap_reloc_in (input_bfd, ext_rel, &int_rel);
    882       else
    883 	{
    884 	  int_rel = lo_int_rel;
    885 	  got_lo = false;
    886 	}
    887 
    888       BFD_ASSERT (int_rel.r_type
    889 		  < sizeof mips_howto_table / sizeof mips_howto_table[0]);
    890 
    891       /* The REFHI reloc requires special handling.  It must be followed
    892 	 by a REFLO reloc, and the addend is formed from both relocs.  */
    893       if (int_rel.r_type == MIPS_R_REFHI)
    894 	{
    895 	  struct external_reloc *lo_ext_rel;
    896 
    897 	  /* As a GNU extension, permit an arbitrary number of REFHI
    898 	     relocs before the REFLO reloc.  This permits gcc to emit
    899 	     the HI and LO relocs itself.  */
    900 	  for (lo_ext_rel = ext_rel + 1;
    901 	       lo_ext_rel < ext_rel_end;
    902 	       lo_ext_rel++)
    903 	    {
    904 	      mips_ecoff_swap_reloc_in (input_bfd, lo_ext_rel,
    905 					&lo_int_rel);
    906 	      if (lo_int_rel.r_type != int_rel.r_type)
    907 		break;
    908 	    }
    909 
    910 	  if (lo_ext_rel < ext_rel_end
    911 	      && lo_int_rel.r_type == MIPS_R_REFLO
    912 	      && int_rel.r_extern == lo_int_rel.r_extern
    913 	      && int_rel.r_symndx == lo_int_rel.r_symndx)
    914 	    {
    915 	      use_lo = true;
    916 	      if (lo_ext_rel == ext_rel + 1)
    917 		got_lo = true;
    918 	    }
    919 	}
    920 
    921       howto = &mips_howto_table[int_rel.r_type];
    922 
    923       if (int_rel.r_extern)
    924 	{
    925 	  h = sym_hashes[int_rel.r_symndx];
    926 	  /* If h is NULL, that means that there is a reloc against an
    927 	     external symbol which we thought was just a debugging
    928 	     symbol.  This should not happen.  */
    929 	  if (h == (struct ecoff_link_hash_entry *) NULL)
    930 	    abort ();
    931 	}
    932       else
    933 	{
    934 	  if (int_rel.r_symndx < 0 || int_rel.r_symndx >= NUM_RELOC_SECTIONS)
    935 	    s = NULL;
    936 	  else
    937 	    s = symndx_to_section[int_rel.r_symndx];
    938 
    939 	  if (s == (asection *) NULL)
    940 	    abort ();
    941 	}
    942 
    943       /* The GPREL reloc uses an addend: the difference in the GP
    944 	 values.  */
    945       if (int_rel.r_type != MIPS_R_GPREL
    946 	  && int_rel.r_type != MIPS_R_LITERAL)
    947 	addend = 0;
    948       else
    949 	{
    950 	  if (gp_undefined)
    951 	    {
    952 	      (*info->callbacks->reloc_dangerous)
    953 		(info, _("GP relative relocation used when GP not defined"),
    954 		 input_bfd, input_section,
    955 		 int_rel.r_vaddr - input_section->vma);
    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 (! bfd_link_relocatable (info)
    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 (bfd_link_relocatable (info))
    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_section_name (s->output_section);
   1019 
   1020 		  int_rel.r_symndx = -1;
   1021 		  switch (name[1])
   1022 		    {
   1023 		    case 'b':
   1024 		      if (strcmp (name, ".bss") == 0)
   1025 			int_rel.r_symndx = RELOC_SECTION_BSS;
   1026 		      break;
   1027 		    case 'd':
   1028 		      if (strcmp (name, ".data") == 0)
   1029 			int_rel.r_symndx = RELOC_SECTION_DATA;
   1030 		      break;
   1031 		    case 'f':
   1032 		      if (strcmp (name, ".fini") == 0)
   1033 			int_rel.r_symndx = RELOC_SECTION_FINI;
   1034 		      break;
   1035 		    case 'i':
   1036 		      if (strcmp (name, ".init") == 0)
   1037 			int_rel.r_symndx = RELOC_SECTION_INIT;
   1038 		      break;
   1039 		    case 'l':
   1040 		      if (strcmp (name, ".lit8") == 0)
   1041 			int_rel.r_symndx = RELOC_SECTION_LIT8;
   1042 		      else if (strcmp (name, ".lit4") == 0)
   1043 			int_rel.r_symndx = RELOC_SECTION_LIT4;
   1044 		      break;
   1045 		    case 'r':
   1046 		      if (strcmp (name, ".rdata") == 0)
   1047 			int_rel.r_symndx = RELOC_SECTION_RDATA;
   1048 		      break;
   1049 		    case 's':
   1050 		      if (strcmp (name, ".sdata") == 0)
   1051 			int_rel.r_symndx = RELOC_SECTION_SDATA;
   1052 		      else if (strcmp (name, ".sbss") == 0)
   1053 			int_rel.r_symndx = RELOC_SECTION_SBSS;
   1054 		      break;
   1055 		    case 't':
   1056 		      if (strcmp (name, ".text") == 0)
   1057 			int_rel.r_symndx = RELOC_SECTION_TEXT;
   1058 		      break;
   1059 		    }
   1060 
   1061 		  if (int_rel.r_symndx == -1)
   1062 		    abort ();
   1063 
   1064 		  /* Add the section VMA and the symbol value.  */
   1065 		  relocation = (h->root.u.def.value
   1066 				+ s->output_section->vma
   1067 				+ s->output_offset);
   1068 
   1069 		  /* For a PC relative relocation, the object file
   1070 		     currently holds just the addend.  We must adjust
   1071 		     by the address to get the right value.  */
   1072 		  if (howto->pc_relative)
   1073 		    relocation -= int_rel.r_vaddr - input_section->vma;
   1074 
   1075 		  h = NULL;
   1076 		}
   1077 	      else
   1078 		{
   1079 		  /* Change the symndx value to the right one for the
   1080 		     output BFD.  */
   1081 		  int_rel.r_symndx = h->indx;
   1082 		  if (int_rel.r_symndx == -1)
   1083 		    {
   1084 		      /* This symbol is not being written out.  */
   1085 		      (*info->callbacks->unattached_reloc)
   1086 			(info, h->root.root.string, input_bfd, input_section,
   1087 			 int_rel.r_vaddr - input_section->vma);
   1088 		      int_rel.r_symndx = 0;
   1089 		    }
   1090 		  relocation = 0;
   1091 		}
   1092 	    }
   1093 	  else
   1094 	    {
   1095 	      /* This is a relocation against a section.  Adjust the
   1096 		 value by the amount the section moved.  */
   1097 	      relocation = (s->output_section->vma
   1098 			    + s->output_offset
   1099 			    - s->vma);
   1100 	    }
   1101 
   1102 	  relocation += addend;
   1103 	  addend = 0;
   1104 
   1105 	  /* Adjust a PC relative relocation by removing the reference
   1106 	     to the original address in the section and including the
   1107 	     reference to the new address.  */
   1108 	  if (howto->pc_relative)
   1109 	    relocation -= (input_section->output_section->vma
   1110 			   + input_section->output_offset
   1111 			   - input_section->vma);
   1112 
   1113 	  /* Adjust the contents.  */
   1114 	  if (relocation == 0)
   1115 	    r = bfd_reloc_ok;
   1116 	  else
   1117 	    {
   1118 	      if (int_rel.r_type != MIPS_R_REFHI)
   1119 		r = _bfd_relocate_contents (howto, input_bfd, relocation,
   1120 					    (contents
   1121 					     + int_rel.r_vaddr
   1122 					     - input_section->vma));
   1123 	      else
   1124 		{
   1125 		  mips_relocate_hi (&int_rel,
   1126 				    use_lo ? &lo_int_rel : NULL,
   1127 				    input_bfd, input_section, contents,
   1128 				    relocation);
   1129 		  r = bfd_reloc_ok;
   1130 		}
   1131 	    }
   1132 
   1133 	  /* Adjust the reloc address.  */
   1134 	  int_rel.r_vaddr += (input_section->output_section->vma
   1135 			      + input_section->output_offset
   1136 			      - input_section->vma);
   1137 
   1138 	  /* Save the changed reloc information.  */
   1139 	  mips_ecoff_swap_reloc_out (input_bfd, &int_rel, ext_rel);
   1140 	}
   1141       else
   1142 	{
   1143 	  /* We are producing a final executable.  */
   1144 	  if (int_rel.r_extern)
   1145 	    {
   1146 	      /* This is a reloc against a symbol.  */
   1147 	      if (h->root.type == bfd_link_hash_defined
   1148 		  || h->root.type == bfd_link_hash_defweak)
   1149 		{
   1150 		  asection *hsec;
   1151 
   1152 		  hsec = h->root.u.def.section;
   1153 		  relocation = (h->root.u.def.value
   1154 				+ hsec->output_section->vma
   1155 				+ hsec->output_offset);
   1156 		}
   1157 	      else
   1158 		{
   1159 		  (*info->callbacks->undefined_symbol)
   1160 		    (info, h->root.root.string, input_bfd, input_section,
   1161 		     int_rel.r_vaddr - input_section->vma, true);
   1162 		  relocation = 0;
   1163 		}
   1164 	    }
   1165 	  else
   1166 	    {
   1167 	      /* This is a reloc against a section.  */
   1168 	      relocation = (s->output_section->vma
   1169 			    + s->output_offset
   1170 			    - s->vma);
   1171 
   1172 	      /* A PC relative reloc is already correct in the object
   1173 		 file.  Make it look like a pcrel_offset relocation by
   1174 		 adding in the start address.  */
   1175 	      if (howto->pc_relative)
   1176 		relocation += int_rel.r_vaddr;
   1177 	    }
   1178 
   1179 	  if (int_rel.r_type != MIPS_R_REFHI)
   1180 	    r = _bfd_final_link_relocate (howto,
   1181 					  input_bfd,
   1182 					  input_section,
   1183 					  contents,
   1184 					  (int_rel.r_vaddr
   1185 					   - input_section->vma),
   1186 					  relocation,
   1187 					  addend);
   1188 	  else
   1189 	    {
   1190 	      mips_relocate_hi (&int_rel,
   1191 				use_lo ? &lo_int_rel : NULL,
   1192 				input_bfd, input_section, contents,
   1193 				relocation);
   1194 	      r = bfd_reloc_ok;
   1195 	    }
   1196 	}
   1197 
   1198       /* MIPS_R_JMPADDR requires peculiar overflow detection.  The
   1199 	 instruction provides a 28 bit address (the two lower bits are
   1200 	 implicit zeroes) which is combined with the upper four bits
   1201 	 of the instruction address.  */
   1202       if (r == bfd_reloc_ok
   1203 	  && int_rel.r_type == MIPS_R_JMPADDR
   1204 	  && (((relocation
   1205 		+ addend
   1206 		+ (int_rel.r_extern ? 0 : s->vma))
   1207 	       & 0xf0000000)
   1208 	      != ((input_section->output_section->vma
   1209 		   + input_section->output_offset
   1210 		   + (int_rel.r_vaddr - input_section->vma))
   1211 		  & 0xf0000000)))
   1212 	r = bfd_reloc_overflow;
   1213 
   1214       if (r != bfd_reloc_ok)
   1215 	{
   1216 	  switch (r)
   1217 	    {
   1218 	    default:
   1219 	    case bfd_reloc_outofrange:
   1220 	      abort ();
   1221 	    case bfd_reloc_overflow:
   1222 	      {
   1223 		const char *name;
   1224 
   1225 		if (int_rel.r_extern)
   1226 		  name = NULL;
   1227 		else
   1228 		  name = bfd_section_name (s);
   1229 		(*info->callbacks->reloc_overflow)
   1230 		  (info, (h ? &h->root : NULL), name, howto->name,
   1231 		   (bfd_vma) 0, input_bfd, input_section,
   1232 		   int_rel.r_vaddr - input_section->vma);
   1233 	      }
   1234 	      break;
   1235 	    }
   1236 	}
   1237     }
   1238 
   1239   return true;
   1240 }
   1241 
   1242 static void
   1243 mips_ecoff_swap_coff_aux_in (bfd *abfd ATTRIBUTE_UNUSED,
   1244 			     void *ext1 ATTRIBUTE_UNUSED,
   1245 			     int type ATTRIBUTE_UNUSED,
   1246 			     int in_class ATTRIBUTE_UNUSED,
   1247 			     int indx ATTRIBUTE_UNUSED,
   1248 			     int numaux ATTRIBUTE_UNUSED,
   1249 			     void *in1 ATTRIBUTE_UNUSED)
   1250 {
   1251 }
   1252 
   1253 static void
   1254 mips_ecoff_swap_coff_sym_in (bfd *abfd ATTRIBUTE_UNUSED,
   1255 			     void *ext1 ATTRIBUTE_UNUSED,
   1256 			     void *in1 ATTRIBUTE_UNUSED)
   1257 {
   1258 }
   1259 
   1260 static void
   1261 mips_ecoff_swap_coff_lineno_in (bfd *abfd ATTRIBUTE_UNUSED,
   1262 				void *ext1 ATTRIBUTE_UNUSED,
   1263 				void *in1 ATTRIBUTE_UNUSED)
   1264 {
   1265 }
   1266 
   1267 static unsigned int
   1268 mips_ecoff_swap_coff_aux_out (bfd *abfd ATTRIBUTE_UNUSED,
   1269 			      void *inp ATTRIBUTE_UNUSED,
   1270 			      int type ATTRIBUTE_UNUSED,
   1271 			      int in_class ATTRIBUTE_UNUSED,
   1272 			      int indx ATTRIBUTE_UNUSED,
   1273 			      int numaux ATTRIBUTE_UNUSED,
   1274 			      void *extp ATTRIBUTE_UNUSED)
   1275 {
   1276   return 0;
   1277 }
   1278 
   1279 static unsigned int
   1280 mips_ecoff_swap_coff_sym_out (bfd *abfd ATTRIBUTE_UNUSED,
   1281 			      void *inp ATTRIBUTE_UNUSED,
   1282 			      void *extp ATTRIBUTE_UNUSED)
   1283 {
   1284   return 0;
   1285 }
   1286 
   1287 static unsigned int
   1288 mips_ecoff_swap_coff_lineno_out (bfd *abfd ATTRIBUTE_UNUSED,
   1289 				 void *inp ATTRIBUTE_UNUSED,
   1290 				 void *extp ATTRIBUTE_UNUSED)
   1291 {
   1292   return 0;
   1293 }
   1294 
   1295 static unsigned int
   1296 mips_ecoff_swap_coff_reloc_out (bfd *abfd ATTRIBUTE_UNUSED,
   1297 				void *inp ATTRIBUTE_UNUSED,
   1298 				void *extp ATTRIBUTE_UNUSED)
   1299 {
   1300   return 0;
   1301 }
   1302 
   1303 /* This is the ECOFF backend structure.  The backend field of the
   1305    target vector points to this.  */
   1306 
   1307 static const struct ecoff_backend_data mips_ecoff_backend_data =
   1308 {
   1309   /* COFF backend structure.  */
   1310   {
   1311     mips_ecoff_swap_coff_aux_in, mips_ecoff_swap_coff_sym_in,
   1312     mips_ecoff_swap_coff_lineno_in, mips_ecoff_swap_coff_aux_out,
   1313     mips_ecoff_swap_coff_sym_out, mips_ecoff_swap_coff_lineno_out,
   1314     mips_ecoff_swap_coff_reloc_out,
   1315     mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out,
   1316     mips_ecoff_swap_scnhdr_out,
   1317     FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, true,
   1318     ECOFF_NO_LONG_SECTION_NAMES, 4, false, 2, 32768,
   1319     mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in,
   1320     mips_ecoff_swap_scnhdr_in, NULL,
   1321     mips_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
   1322     _bfd_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
   1323     _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
   1324     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
   1325     NULL, NULL,
   1326   },
   1327   /* Supported architecture.  */
   1328   bfd_arch_mips,
   1329   /* Initial portion of armap string.  */
   1330   "__________",
   1331   /* The page boundary used to align sections in a demand-paged
   1332      executable file.  E.g., 0x1000.  */
   1333   0x1000,
   1334   /* TRUE if the .rdata section is part of the text segment, as on the
   1335      Alpha.  FALSE if .rdata is part of the data segment, as on the
   1336      MIPS.  */
   1337   false,
   1338   /* Bitsize of constructor entries.  */
   1339   32,
   1340   /* Reloc to use for constructor entries.  */
   1341   &mips_howto_table[MIPS_R_REFWORD],
   1342   {
   1343     /* Symbol table magic number.  */
   1344     magicSym,
   1345     /* Alignment of debugging information.  E.g., 4.  */
   1346     4,
   1347     /* Sizes of external symbolic information.  */
   1348     sizeof (struct hdr_ext),
   1349     sizeof (struct dnr_ext),
   1350     sizeof (struct pdr_ext),
   1351     sizeof (struct sym_ext),
   1352     sizeof (struct opt_ext),
   1353     sizeof (struct fdr_ext),
   1354     sizeof (struct rfd_ext),
   1355     sizeof (struct ext_ext),
   1356     /* Functions to swap in external symbolic data.  */
   1357     ecoff_swap_hdr_in,
   1358     ecoff_swap_dnr_in,
   1359     ecoff_swap_pdr_in,
   1360     ecoff_swap_sym_in,
   1361     ecoff_swap_opt_in,
   1362     ecoff_swap_fdr_in,
   1363     ecoff_swap_rfd_in,
   1364     ecoff_swap_ext_in,
   1365     _bfd_ecoff_swap_tir_in,
   1366     _bfd_ecoff_swap_rndx_in,
   1367     /* Functions to swap out external symbolic data.  */
   1368     ecoff_swap_hdr_out,
   1369     ecoff_swap_dnr_out,
   1370     ecoff_swap_pdr_out,
   1371     ecoff_swap_sym_out,
   1372     ecoff_swap_opt_out,
   1373     ecoff_swap_fdr_out,
   1374     ecoff_swap_rfd_out,
   1375     ecoff_swap_ext_out,
   1376     _bfd_ecoff_swap_tir_out,
   1377     _bfd_ecoff_swap_rndx_out,
   1378     /* Function to read in symbolic data.  */
   1379     _bfd_ecoff_slurp_symbolic_info
   1380   },
   1381   /* External reloc size.  */
   1382   RELSZ,
   1383   /* Reloc swapping functions.  */
   1384   mips_ecoff_swap_reloc_in,
   1385   mips_ecoff_swap_reloc_out,
   1386   /* Backend reloc tweaking.  */
   1387   mips_adjust_reloc_in,
   1388   mips_adjust_reloc_out,
   1389   /* Relocate section contents while linking.  */
   1390   mips_relocate_section,
   1391   /* Do final adjustments to filehdr and aouthdr.  */
   1392   NULL,
   1393   /* Read an element from an archive at a given file position.  */
   1394   _bfd_get_elt_at_filepos
   1395 };
   1396 
   1397 /* Looking up a reloc type is MIPS specific.  */
   1398 #define _bfd_ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup
   1399 #define _bfd_ecoff_bfd_reloc_name_lookup mips_bfd_reloc_name_lookup
   1400 
   1401 /* Getting relocated section contents is generic.  */
   1402 #define _bfd_ecoff_bfd_get_relocated_section_contents \
   1403   bfd_generic_get_relocated_section_contents
   1404 
   1405 /* Relaxing sections is MIPS specific.  */
   1406 #define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section
   1407 
   1408 /* GC of sections is not done.  */
   1409 #define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
   1410 
   1411 /* Input section flags is not implemented.  */
   1412 #define _bfd_ecoff_bfd_lookup_section_flags bfd_generic_lookup_section_flags
   1413 
   1414 #define _bfd_ecoff_bfd_is_group_section bfd_generic_is_group_section
   1415 #define _bfd_ecoff_bfd_group_name bfd_generic_group_name
   1416 #define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group
   1417 #define _bfd_ecoff_section_already_linked \
   1418   _bfd_coff_section_already_linked
   1419 #define _bfd_ecoff_bfd_define_common_symbol bfd_generic_define_common_symbol
   1420 #define _bfd_ecoff_bfd_link_hide_symbol _bfd_generic_link_hide_symbol
   1421 #define _bfd_ecoff_bfd_define_start_stop bfd_generic_define_start_stop
   1422 #define _bfd_ecoff_finalize_section_relocs _bfd_generic_finalize_section_relocs
   1423 
   1424 extern const bfd_target mips_ecoff_be_vec;
   1425 
   1426 const bfd_target mips_ecoff_le_vec =
   1427 {
   1428   "ecoff-littlemips",		/* name */
   1429   bfd_target_ecoff_flavour,
   1430   BFD_ENDIAN_LITTLE,		/* data byte order is little */
   1431   BFD_ENDIAN_LITTLE,		/* header byte order is little */
   1432 
   1433   (HAS_RELOC | EXEC_P		/* object flags */
   1434    | HAS_LINENO | HAS_DEBUG
   1435    | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
   1436 
   1437   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE
   1438    | SEC_DATA | SEC_SMALL_DATA),
   1439   0,				/* leading underscore */
   1440   ' ',				/* ar_pad_char */
   1441   15,				/* ar_max_namelen */
   1442   0,				/* match priority.  */
   1443   TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
   1444   TARGET_MERGE_SECTIONS,
   1445   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
   1446      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
   1447      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
   1448   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
   1449      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
   1450      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
   1451 
   1452   {				/* bfd_check_format */
   1453     _bfd_dummy_target,
   1454     coff_object_p,
   1455     bfd_generic_archive_p,
   1456     _bfd_dummy_target
   1457   },
   1458   {				/* bfd_set_format */
   1459     _bfd_bool_bfd_false_error,
   1460     _bfd_ecoff_mkobject,
   1461     _bfd_generic_mkarchive,
   1462     _bfd_bool_bfd_false_error
   1463   },
   1464   {				/* bfd_write_contents */
   1465     _bfd_bool_bfd_false_error,
   1466     _bfd_ecoff_write_object_contents,
   1467     _bfd_write_archive_contents,
   1468     _bfd_bool_bfd_false_error
   1469   },
   1470 
   1471   BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
   1472   BFD_JUMP_TABLE_COPY (_bfd_ecoff),
   1473   BFD_JUMP_TABLE_CORE (_bfd_nocore),
   1474   BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
   1475   BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
   1476   BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
   1477   BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
   1478   BFD_JUMP_TABLE_LINK (_bfd_ecoff),
   1479   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
   1480 
   1481   &mips_ecoff_be_vec,
   1482 
   1483   &mips_ecoff_backend_data
   1484 };
   1485 
   1486 const bfd_target mips_ecoff_be_vec =
   1487 {
   1488   "ecoff-bigmips",		/* name */
   1489   bfd_target_ecoff_flavour,
   1490   BFD_ENDIAN_BIG,		/* data byte order is big */
   1491   BFD_ENDIAN_BIG,		/* header byte order is big */
   1492 
   1493   (HAS_RELOC | EXEC_P		/* object flags */
   1494    | HAS_LINENO | HAS_DEBUG
   1495    | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
   1496 
   1497   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE
   1498    | SEC_DATA | SEC_SMALL_DATA),
   1499   0,				/* leading underscore */
   1500   ' ',				/* ar_pad_char */
   1501   15,				/* ar_max_namelen */
   1502   0,				/* match priority.  */
   1503   TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
   1504   TARGET_MERGE_SECTIONS,
   1505   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
   1506      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
   1507      bfd_getb16, bfd_getb_signed_16, bfd_putb16,
   1508   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
   1509      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
   1510      bfd_getb16, bfd_getb_signed_16, bfd_putb16,
   1511 
   1512   {				/* bfd_check_format */
   1513     _bfd_dummy_target,
   1514     coff_object_p,
   1515     bfd_generic_archive_p,
   1516     _bfd_dummy_target
   1517   },
   1518   {				/* bfd_set_format */
   1519     _bfd_bool_bfd_false_error,
   1520     _bfd_ecoff_mkobject,
   1521     _bfd_generic_mkarchive,
   1522     _bfd_bool_bfd_false_error
   1523   },
   1524   {				/* bfd_write_contents */
   1525     _bfd_bool_bfd_false_error,
   1526     _bfd_ecoff_write_object_contents,
   1527     _bfd_write_archive_contents,
   1528     _bfd_bool_bfd_false_error
   1529   },
   1530 
   1531   BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
   1532   BFD_JUMP_TABLE_COPY (_bfd_ecoff),
   1533   BFD_JUMP_TABLE_CORE (_bfd_nocore),
   1534   BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
   1535   BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
   1536   BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
   1537   BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
   1538   BFD_JUMP_TABLE_LINK (_bfd_ecoff),
   1539   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
   1540 
   1541   &mips_ecoff_le_vec,
   1542 
   1543   &mips_ecoff_backend_data
   1544 };
   1545 
   1546 const bfd_target mips_ecoff_bele_vec =
   1547 {
   1548   "ecoff-biglittlemips",		/* name */
   1549   bfd_target_ecoff_flavour,
   1550   BFD_ENDIAN_LITTLE,		/* data byte order is little */
   1551   BFD_ENDIAN_BIG,		/* header byte order is big */
   1552 
   1553   (HAS_RELOC | EXEC_P		/* object flags */
   1554    | HAS_LINENO | HAS_DEBUG
   1555    | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
   1556 
   1557   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE
   1558    | SEC_DATA | SEC_SMALL_DATA),
   1559   0,				/* leading underscore */
   1560   ' ',				/* ar_pad_char */
   1561   15,				/* ar_max_namelen */
   1562   0,				/* match priority.  */
   1563   TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
   1564   TARGET_MERGE_SECTIONS,
   1565   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
   1566      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
   1567      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
   1568   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
   1569      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
   1570      bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
   1571 
   1572   {				/* bfd_check_format */
   1573     _bfd_dummy_target,
   1574     coff_object_p,
   1575     bfd_generic_archive_p,
   1576     _bfd_dummy_target
   1577   },
   1578   {				/* bfd_set_format */
   1579     _bfd_bool_bfd_false_error,
   1580     _bfd_ecoff_mkobject,
   1581     _bfd_generic_mkarchive,
   1582     _bfd_bool_bfd_false_error
   1583   },
   1584   {				/* bfd_write_contents */
   1585     _bfd_bool_bfd_false_error,
   1586     _bfd_ecoff_write_object_contents,
   1587     _bfd_write_archive_contents,
   1588     _bfd_bool_bfd_false_error
   1589   },
   1590 
   1591   BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
   1592   BFD_JUMP_TABLE_COPY (_bfd_ecoff),
   1593   BFD_JUMP_TABLE_CORE (_bfd_nocore),
   1594   BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
   1595   BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
   1596   BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
   1597   BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
   1598   BFD_JUMP_TABLE_LINK (_bfd_ecoff),
   1599   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
   1600 
   1601   NULL,
   1602 
   1603   &mips_ecoff_backend_data
   1604 };
   1605