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