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