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