Back to index

cell-binutils  2.17cvs20070401
elf64-mips.c
Go to the documentation of this file.
00001 /* MIPS-specific support for 64-bit ELF
00002    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
00003    2007 Free Software Foundation, Inc.
00004    Ian Lance Taylor, Cygnus Support
00005    Linker support added by Mark Mitchell, CodeSourcery, LLC.
00006    <mark@codesourcery.com>
00007 
00008 This file is part of BFD, the Binary File Descriptor library.
00009 
00010 This program is free software; you can redistribute it and/or modify
00011 it under the terms of the GNU General Public License as published by
00012 the Free Software Foundation; either version 2 of the License, or
00013 (at your option) any later version.
00014 
00015 This program is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00023 
00024 /* This file supports the 64-bit MIPS ELF ABI.
00025 
00026    The MIPS 64-bit ELF ABI uses an unusual reloc format.  This file
00027    overrides the usual ELF reloc handling, and handles reading and
00028    writing the relocations here.  */
00029 
00030 /* TODO: Many things are unsupported, even if there is some code for it
00031  .       (which was mostly stolen from elf32-mips.c and slightly adapted).
00032  .
00033  .   - Relocation handling for REL relocs is wrong in many cases and
00034  .     generally untested.
00035  .   - Relocation handling for RELA relocs related to GOT support are
00036  .     also likely to be wrong.
00037  .   - Support for MIPS16 is untested.
00038  .   - Combined relocs with RSS_* entries are unsupported.
00039  .   - The whole GOT handling for NewABI is missing, some parts of
00040  .     the OldABI version is still lying around and should be removed.
00041  */
00042 
00043 #include "bfd.h"
00044 #include "sysdep.h"
00045 #include "libbfd.h"
00046 #include "aout/ar.h"
00047 #include "bfdlink.h"
00048 #include "genlink.h"
00049 #include "elf-bfd.h"
00050 #include "elfxx-mips.h"
00051 #include "elf/mips.h"
00052 
00053 /* Get the ECOFF swapping routines.  The 64-bit ABI is not supposed to
00054    use ECOFF.  However, we support it anyhow for an easier changeover.  */
00055 #include "coff/sym.h"
00056 #include "coff/symconst.h"
00057 #include "coff/internal.h"
00058 #include "coff/ecoff.h"
00059 /* The 64 bit versions of the mdebug data structures are in alpha.h.  */
00060 #include "coff/alpha.h"
00061 #define ECOFF_SIGNED_64
00062 #include "ecoffswap.h"
00063 
00064 static void mips_elf64_swap_reloc_in
00065   (bfd *, const Elf64_Mips_External_Rel *, Elf64_Mips_Internal_Rela *);
00066 static void mips_elf64_swap_reloca_in
00067   (bfd *, const Elf64_Mips_External_Rela *, Elf64_Mips_Internal_Rela *);
00068 static void mips_elf64_swap_reloc_out
00069   (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rel *);
00070 static void mips_elf64_swap_reloca_out
00071   (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rela *);
00072 static void mips_elf64_be_swap_reloc_in
00073   (bfd *, const bfd_byte *, Elf_Internal_Rela *);
00074 static void mips_elf64_be_swap_reloc_out
00075   (bfd *, const Elf_Internal_Rela *, bfd_byte *);
00076 static void mips_elf64_be_swap_reloca_in
00077   (bfd *, const bfd_byte *, Elf_Internal_Rela *);
00078 static void mips_elf64_be_swap_reloca_out
00079   (bfd *, const Elf_Internal_Rela *, bfd_byte *);
00080 static reloc_howto_type *bfd_elf64_bfd_reloc_type_lookup
00081   (bfd *, bfd_reloc_code_real_type);
00082 static reloc_howto_type *mips_elf64_rtype_to_howto
00083   (unsigned int, bfd_boolean);
00084 static void mips_elf64_info_to_howto_rel
00085   (bfd *, arelent *, Elf_Internal_Rela *);
00086 static void mips_elf64_info_to_howto_rela
00087   (bfd *, arelent *, Elf_Internal_Rela *);
00088 static long mips_elf64_get_reloc_upper_bound
00089   (bfd *, asection *);
00090 static long mips_elf64_canonicalize_reloc
00091   (bfd *, asection *, arelent **, asymbol **);
00092 static long mips_elf64_get_dynamic_reloc_upper_bound
00093   (bfd *);
00094 static long mips_elf64_canonicalize_dynamic_reloc
00095   (bfd *, arelent **, asymbol **);
00096 static bfd_boolean mips_elf64_slurp_one_reloc_table
00097   (bfd *, asection *, Elf_Internal_Shdr *, bfd_size_type, arelent *,
00098    asymbol **, bfd_boolean);
00099 static bfd_boolean mips_elf64_slurp_reloc_table
00100   (bfd *, asection *, asymbol **, bfd_boolean);
00101 static void mips_elf64_write_relocs
00102   (bfd *, asection *, void *);
00103 static void mips_elf64_write_rel
00104   (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
00105 static void mips_elf64_write_rela
00106   (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
00107 static bfd_reloc_status_type mips_elf64_gprel16_reloc
00108   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00109 static bfd_reloc_status_type mips_elf64_literal_reloc
00110   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00111 static bfd_reloc_status_type mips_elf64_gprel32_reloc
00112   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00113 static bfd_reloc_status_type mips_elf64_shift6_reloc
00114   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00115 static bfd_reloc_status_type mips16_gprel_reloc
00116   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00117 static bfd_boolean mips_elf64_assign_gp
00118   (bfd *, bfd_vma *);
00119 static bfd_reloc_status_type mips_elf64_final_gp
00120   (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *);
00121 static bfd_boolean mips_elf64_object_p
00122   (bfd *);
00123 static irix_compat_t elf64_mips_irix_compat
00124   (bfd *);
00125 static bfd_boolean elf64_mips_grok_prstatus
00126   (bfd *, Elf_Internal_Note *);
00127 static bfd_boolean elf64_mips_grok_psinfo
00128   (bfd *, Elf_Internal_Note *);
00129 
00130 extern const bfd_target bfd_elf64_bigmips_vec;
00131 extern const bfd_target bfd_elf64_littlemips_vec;
00132 
00133 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
00134    from smaller values.  Start with zero, widen, *then* decrement.  */
00135 #define MINUS_ONE    (((bfd_vma)0) - 1)
00136 
00137 /* The number of local .got entries we reserve.  */
00138 #define MIPS_RESERVED_GOTNO (2)
00139 
00140 /* The relocation table used for SHT_REL sections.  */
00141 
00142 static reloc_howto_type mips_elf64_howto_table_rel[] =
00143 {
00144   /* No relocation.  */
00145   HOWTO (R_MIPS_NONE,              /* type */
00146         0,                  /* rightshift */
00147         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00148         0,                  /* bitsize */
00149         FALSE,                     /* pc_relative */
00150         0,                  /* bitpos */
00151         complain_overflow_dont, /* complain_on_overflow */
00152         _bfd_mips_elf_generic_reloc,      /* special_function */
00153         "R_MIPS_NONE",             /* name */
00154         FALSE,                     /* partial_inplace */
00155         0,                  /* src_mask */
00156         0,                  /* dst_mask */
00157         FALSE),             /* pcrel_offset */
00158 
00159   /* 16 bit relocation.  */
00160   HOWTO (R_MIPS_16,         /* type */
00161         0,                  /* rightshift */
00162         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00163         16,                 /* bitsize */
00164         FALSE,                     /* pc_relative */
00165         0,                  /* bitpos */
00166         complain_overflow_signed, /* complain_on_overflow */
00167         _bfd_mips_elf_generic_reloc,      /* special_function */
00168         "R_MIPS_16",        /* name */
00169         TRUE,               /* partial_inplace */
00170         0x0000ffff,         /* src_mask */
00171         0x0000ffff,         /* dst_mask */
00172         FALSE),             /* pcrel_offset */
00173 
00174   /* 32 bit relocation.  */
00175   HOWTO (R_MIPS_32,         /* type */
00176         0,                  /* rightshift */
00177         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00178         32,                 /* bitsize */
00179         FALSE,                     /* pc_relative */
00180         0,                  /* bitpos */
00181         complain_overflow_dont, /* complain_on_overflow */
00182         _bfd_mips_elf_generic_reloc,      /* special_function */
00183         "R_MIPS_32",        /* name */
00184         TRUE,               /* partial_inplace */
00185         0xffffffff,         /* src_mask */
00186         0xffffffff,         /* dst_mask */
00187         FALSE),             /* pcrel_offset */
00188 
00189   /* 32 bit symbol relative relocation.  */
00190   HOWTO (R_MIPS_REL32,             /* type */
00191         0,                  /* rightshift */
00192         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00193         32,                 /* bitsize */
00194         FALSE,                     /* pc_relative */
00195         0,                  /* bitpos */
00196         complain_overflow_dont, /* complain_on_overflow */
00197         _bfd_mips_elf_generic_reloc,      /* special_function */
00198         "R_MIPS_REL32",     /* name */
00199         TRUE,               /* partial_inplace */
00200         0xffffffff,         /* src_mask */
00201         0xffffffff,         /* dst_mask */
00202         FALSE),             /* pcrel_offset */
00203 
00204   /* 26 bit jump address.  */
00205   HOWTO (R_MIPS_26,         /* type */
00206         2,                  /* rightshift */
00207         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00208         26,                 /* bitsize */
00209         FALSE,                     /* pc_relative */
00210         0,                  /* bitpos */
00211         complain_overflow_dont, /* complain_on_overflow */
00212                             /* This needs complex overflow
00213                                detection, because the upper 36
00214                                bits must match the PC + 4.  */
00215         _bfd_mips_elf_generic_reloc,      /* special_function */
00216         "R_MIPS_26",        /* name */
00217         TRUE,               /* partial_inplace */
00218         0x03ffffff,         /* src_mask */
00219         0x03ffffff,         /* dst_mask */
00220         FALSE),             /* pcrel_offset */
00221 
00222   /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
00223      However, the native IRIX6 tools use them, so we try our best. */
00224 
00225   /* High 16 bits of symbol value.  */
00226   HOWTO (R_MIPS_HI16,              /* type */
00227         16,                 /* rightshift */
00228         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00229         16,                 /* bitsize */
00230         FALSE,                     /* pc_relative */
00231         0,                  /* bitpos */
00232         complain_overflow_dont, /* complain_on_overflow */
00233         _bfd_mips_elf_hi16_reloc, /* special_function */
00234         "R_MIPS_HI16",             /* name */
00235         TRUE,               /* partial_inplace */
00236         0x0000ffff,         /* src_mask */
00237         0x0000ffff,         /* dst_mask */
00238         FALSE),             /* pcrel_offset */
00239 
00240   /* Low 16 bits of symbol value.  */
00241   HOWTO (R_MIPS_LO16,              /* type */
00242         0,                  /* rightshift */
00243         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00244         16,                 /* bitsize */
00245         FALSE,                     /* pc_relative */
00246         0,                  /* bitpos */
00247         complain_overflow_dont, /* complain_on_overflow */
00248         _bfd_mips_elf_lo16_reloc, /* special_function */
00249         "R_MIPS_LO16",             /* name */
00250         TRUE,               /* partial_inplace */
00251         0x0000ffff,         /* src_mask */
00252         0x0000ffff,         /* dst_mask */
00253         FALSE),             /* pcrel_offset */
00254 
00255   /* GP relative reference.  */
00256   HOWTO (R_MIPS_GPREL16,    /* type */
00257         0,                  /* rightshift */
00258         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00259         16,                 /* bitsize */
00260         FALSE,                     /* pc_relative */
00261         0,                  /* bitpos */
00262         complain_overflow_signed, /* complain_on_overflow */
00263         mips_elf64_gprel16_reloc, /* special_function */
00264         "R_MIPS_GPREL16",   /* name */
00265         TRUE,               /* partial_inplace */
00266         0x0000ffff,         /* src_mask */
00267         0x0000ffff,         /* dst_mask */
00268         FALSE),             /* pcrel_offset */
00269 
00270   /* Reference to literal section.  */
00271   HOWTO (R_MIPS_LITERAL,    /* type */
00272         0,                  /* rightshift */
00273         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00274         16,                 /* bitsize */
00275         FALSE,                     /* pc_relative */
00276         0,                  /* bitpos */
00277         complain_overflow_signed, /* complain_on_overflow */
00278         mips_elf64_literal_reloc, /* special_function */
00279         "R_MIPS_LITERAL",   /* name */
00280         TRUE,               /* partial_inplace */
00281         0x0000ffff,         /* src_mask */
00282         0x0000ffff,         /* dst_mask */
00283         FALSE),             /* pcrel_offset */
00284 
00285   /* Reference to global offset table.  */
00286   HOWTO (R_MIPS_GOT16,             /* type */
00287         0,                  /* rightshift */
00288         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00289         16,                 /* bitsize */
00290         FALSE,                     /* pc_relative */
00291         0,                  /* bitpos */
00292         complain_overflow_signed, /* complain_on_overflow */
00293         _bfd_mips_elf_got16_reloc, /* special_function */
00294         "R_MIPS_GOT16",     /* name */
00295         TRUE,               /* partial_inplace */
00296         0x0000ffff,         /* src_mask */
00297         0x0000ffff,         /* dst_mask */
00298         FALSE),             /* pcrel_offset */
00299 
00300   /* 16 bit PC relative reference.  Note that the ABI document has a typo
00301      and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
00302      We do the right thing here.  */
00303   HOWTO (R_MIPS_PC16,              /* type */
00304         2,                  /* rightshift */
00305         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00306         16,                 /* bitsize */
00307         TRUE,               /* pc_relative */
00308         0,                  /* bitpos */
00309         complain_overflow_signed, /* complain_on_overflow */
00310         _bfd_mips_elf_generic_reloc,      /* special_function */
00311         "R_MIPS_PC16",             /* name */
00312         TRUE,               /* partial_inplace */
00313         0x0000ffff,         /* src_mask */
00314         0x0000ffff,         /* dst_mask */
00315         TRUE),                     /* pcrel_offset */
00316 
00317   /* 16 bit call through global offset table.  */
00318   HOWTO (R_MIPS_CALL16,            /* type */
00319         0,                  /* rightshift */
00320         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00321         16,                 /* bitsize */
00322         FALSE,                     /* pc_relative */
00323         0,                  /* bitpos */
00324         complain_overflow_signed, /* complain_on_overflow */
00325         _bfd_mips_elf_generic_reloc,      /* special_function */
00326         "R_MIPS_CALL16",    /* name */
00327         TRUE,               /* partial_inplace */
00328         0x0000ffff,         /* src_mask */
00329         0x0000ffff,         /* dst_mask */
00330         FALSE),             /* pcrel_offset */
00331 
00332   /* 32 bit GP relative reference.  */
00333   HOWTO (R_MIPS_GPREL32,    /* type */
00334         0,                  /* rightshift */
00335         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00336         32,                 /* bitsize */
00337         FALSE,                     /* pc_relative */
00338         0,                  /* bitpos */
00339         complain_overflow_dont, /* complain_on_overflow */
00340         mips_elf64_gprel32_reloc, /* special_function */
00341         "R_MIPS_GPREL32",   /* name */
00342         TRUE,               /* partial_inplace */
00343         0xffffffff,         /* src_mask */
00344         0xffffffff,         /* dst_mask */
00345         FALSE),             /* pcrel_offset */
00346 
00347   EMPTY_HOWTO (13),
00348   EMPTY_HOWTO (14),
00349   EMPTY_HOWTO (15),
00350 
00351   /* A 5 bit shift field.  */
00352   HOWTO (R_MIPS_SHIFT5,            /* type */
00353         0,                  /* rightshift */
00354         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00355         5,                  /* bitsize */
00356         FALSE,                     /* pc_relative */
00357         6,                  /* bitpos */
00358         complain_overflow_bitfield, /* complain_on_overflow */
00359         _bfd_mips_elf_generic_reloc,      /* special_function */
00360         "R_MIPS_SHIFT5",    /* name */
00361         TRUE,               /* partial_inplace */
00362         0x000007c0,         /* src_mask */
00363         0x000007c0,         /* dst_mask */
00364         FALSE),             /* pcrel_offset */
00365 
00366   /* A 6 bit shift field.  */
00367   HOWTO (R_MIPS_SHIFT6,            /* type */
00368         0,                  /* rightshift */
00369         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00370         6,                  /* bitsize */
00371         FALSE,                     /* pc_relative */
00372         6,                  /* bitpos */
00373         complain_overflow_bitfield, /* complain_on_overflow */
00374         mips_elf64_shift6_reloc, /* special_function */
00375         "R_MIPS_SHIFT6",    /* name */
00376         TRUE,               /* partial_inplace */
00377         0x000007c4,         /* src_mask */
00378         0x000007c4,         /* dst_mask */
00379         FALSE),             /* pcrel_offset */
00380 
00381   /* 64 bit relocation.  */
00382   HOWTO (R_MIPS_64,         /* type */
00383         0,                  /* rightshift */
00384         4,                  /* size (0 = byte, 1 = short, 2 = long) */
00385         64,                 /* bitsize */
00386         FALSE,                     /* pc_relative */
00387         0,                  /* bitpos */
00388         complain_overflow_dont, /* complain_on_overflow */
00389         _bfd_mips_elf_generic_reloc,      /* special_function */
00390         "R_MIPS_64",        /* name */
00391         TRUE,               /* partial_inplace */
00392         MINUS_ONE,          /* src_mask */
00393         MINUS_ONE,          /* dst_mask */
00394         FALSE),             /* pcrel_offset */
00395 
00396   /* Displacement in the global offset table.  */
00397   HOWTO (R_MIPS_GOT_DISP,   /* type */
00398         0,                  /* rightshift */
00399         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00400         16,                 /* bitsize */
00401         FALSE,                     /* pc_relative */
00402         0,                  /* bitpos */
00403         complain_overflow_signed, /* complain_on_overflow */
00404         _bfd_mips_elf_generic_reloc,      /* special_function */
00405         "R_MIPS_GOT_DISP",  /* name */
00406         TRUE,               /* partial_inplace */
00407         0x0000ffff,         /* src_mask */
00408         0x0000ffff,         /* dst_mask */
00409         FALSE),             /* pcrel_offset */
00410 
00411   /* Displacement to page pointer in the global offset table.  */
00412   HOWTO (R_MIPS_GOT_PAGE,   /* type */
00413         0,                  /* rightshift */
00414         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00415         16,                 /* bitsize */
00416         FALSE,                     /* pc_relative */
00417         0,                  /* bitpos */
00418         complain_overflow_signed, /* complain_on_overflow */
00419         _bfd_mips_elf_generic_reloc,      /* special_function */
00420         "R_MIPS_GOT_PAGE",  /* name */
00421         TRUE,               /* partial_inplace */
00422         0x0000ffff,         /* src_mask */
00423         0x0000ffff,         /* dst_mask */
00424         FALSE),             /* pcrel_offset */
00425 
00426   /* Offset from page pointer in the global offset table.  */
00427   HOWTO (R_MIPS_GOT_OFST,   /* type */
00428         0,                  /* rightshift */
00429         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00430         16,                 /* bitsize */
00431         FALSE,                     /* pc_relative */
00432         0,                  /* bitpos */
00433         complain_overflow_signed, /* complain_on_overflow */
00434         _bfd_mips_elf_generic_reloc,      /* special_function */
00435         "R_MIPS_GOT_OFST",  /* name */
00436         TRUE,               /* partial_inplace */
00437         0x0000ffff,         /* src_mask */
00438         0x0000ffff,         /* dst_mask */
00439         FALSE),             /* pcrel_offset */
00440 
00441   /* High 16 bits of displacement in global offset table.  */
00442   HOWTO (R_MIPS_GOT_HI16,   /* type */
00443         0,                  /* rightshift */
00444         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00445         16,                 /* bitsize */
00446         FALSE,                     /* pc_relative */
00447         0,                  /* bitpos */
00448         complain_overflow_dont, /* complain_on_overflow */
00449         _bfd_mips_elf_generic_reloc,      /* special_function */
00450         "R_MIPS_GOT_HI16",  /* name */
00451         TRUE,               /* partial_inplace */
00452         0x0000ffff,         /* src_mask */
00453         0x0000ffff,         /* dst_mask */
00454         FALSE),             /* pcrel_offset */
00455 
00456   /* Low 16 bits of displacement in global offset table.  */
00457   HOWTO (R_MIPS_GOT_LO16,   /* type */
00458         0,                  /* rightshift */
00459         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00460         16,                 /* bitsize */
00461         FALSE,                     /* pc_relative */
00462         0,                  /* bitpos */
00463         complain_overflow_dont, /* complain_on_overflow */
00464         _bfd_mips_elf_generic_reloc,      /* special_function */
00465         "R_MIPS_GOT_LO16",  /* name */
00466         TRUE,               /* partial_inplace */
00467         0x0000ffff,         /* src_mask */
00468         0x0000ffff,         /* dst_mask */
00469         FALSE),             /* pcrel_offset */
00470 
00471   /* 64 bit subtraction.  */
00472   HOWTO (R_MIPS_SUB,        /* type */
00473         0,                  /* rightshift */
00474         4,                  /* size (0 = byte, 1 = short, 2 = long) */
00475         64,                 /* bitsize */
00476         FALSE,                     /* pc_relative */
00477         0,                  /* bitpos */
00478         complain_overflow_dont, /* complain_on_overflow */
00479         _bfd_mips_elf_generic_reloc,      /* special_function */
00480         "R_MIPS_SUB",              /* name */
00481         TRUE,               /* partial_inplace */
00482         MINUS_ONE,          /* src_mask */
00483         MINUS_ONE,          /* dst_mask */
00484         FALSE),             /* pcrel_offset */
00485 
00486   /* Insert the addend as an instruction.  */
00487   /* FIXME: Not handled correctly.  */
00488   HOWTO (R_MIPS_INSERT_A,   /* type */
00489         0,                  /* rightshift */
00490         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00491         32,                 /* bitsize */
00492         FALSE,                     /* pc_relative */
00493         0,                  /* bitpos */
00494         complain_overflow_dont, /* complain_on_overflow */
00495         _bfd_mips_elf_generic_reloc,      /* special_function */
00496         "R_MIPS_INSERT_A",  /* name */
00497         TRUE,               /* partial_inplace */
00498         0xffffffff,         /* src_mask */
00499         0xffffffff,         /* dst_mask */
00500         FALSE),             /* pcrel_offset */
00501 
00502   /* Insert the addend as an instruction, and change all relocations
00503      to refer to the old instruction at the address.  */
00504   /* FIXME: Not handled correctly.  */
00505   HOWTO (R_MIPS_INSERT_B,   /* type */
00506         0,                  /* rightshift */
00507         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00508         32,                 /* bitsize */
00509         FALSE,                     /* pc_relative */
00510         0,                  /* bitpos */
00511         complain_overflow_dont, /* complain_on_overflow */
00512         _bfd_mips_elf_generic_reloc,      /* special_function */
00513         "R_MIPS_INSERT_B",  /* name */
00514         TRUE,               /* partial_inplace */
00515         0xffffffff,         /* src_mask */
00516         0xffffffff,         /* dst_mask */
00517         FALSE),             /* pcrel_offset */
00518 
00519   /* Delete a 32 bit instruction.  */
00520   /* FIXME: Not handled correctly.  */
00521   HOWTO (R_MIPS_DELETE,            /* type */
00522         0,                  /* rightshift */
00523         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00524         32,                 /* bitsize */
00525         FALSE,                     /* pc_relative */
00526         0,                  /* bitpos */
00527         complain_overflow_dont, /* complain_on_overflow */
00528         _bfd_mips_elf_generic_reloc,      /* special_function */
00529         "R_MIPS_DELETE",    /* name */
00530         TRUE,               /* partial_inplace */
00531         0xffffffff,         /* src_mask */
00532         0xffffffff,         /* dst_mask */
00533         FALSE),             /* pcrel_offset */
00534 
00535   /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
00536      We don't, because
00537        a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
00538          R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
00539          fallable heuristics.
00540        b) No other NewABI toolchain actually emits such relocations.  */
00541   EMPTY_HOWTO (R_MIPS_HIGHER),
00542   EMPTY_HOWTO (R_MIPS_HIGHEST),
00543 
00544   /* High 16 bits of displacement in global offset table.  */
00545   HOWTO (R_MIPS_CALL_HI16,  /* type */
00546         0,                  /* rightshift */
00547         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00548         16,                 /* bitsize */
00549         FALSE,                     /* pc_relative */
00550         0,                  /* bitpos */
00551         complain_overflow_dont, /* complain_on_overflow */
00552         _bfd_mips_elf_generic_reloc,      /* special_function */
00553         "R_MIPS_CALL_HI16", /* name */
00554         TRUE,               /* partial_inplace */
00555         0x0000ffff,         /* src_mask */
00556         0x0000ffff,         /* dst_mask */
00557         FALSE),             /* pcrel_offset */
00558 
00559   /* Low 16 bits of displacement in global offset table.  */
00560   HOWTO (R_MIPS_CALL_LO16,  /* type */
00561         0,                  /* rightshift */
00562         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00563         16,                 /* bitsize */
00564         FALSE,                     /* pc_relative */
00565         0,                  /* bitpos */
00566         complain_overflow_dont, /* complain_on_overflow */
00567         _bfd_mips_elf_generic_reloc,      /* special_function */
00568         "R_MIPS_CALL_LO16", /* name */
00569         TRUE,               /* partial_inplace */
00570         0x0000ffff,         /* src_mask */
00571         0x0000ffff,         /* dst_mask */
00572         FALSE),             /* pcrel_offset */
00573 
00574   /* Section displacement, used by an associated event location section.  */
00575   HOWTO (R_MIPS_SCN_DISP,   /* type */
00576         0,                  /* rightshift */
00577         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00578         32,                 /* bitsize */
00579         FALSE,                     /* pc_relative */
00580         0,                  /* bitpos */
00581         complain_overflow_dont, /* complain_on_overflow */
00582         _bfd_mips_elf_generic_reloc,      /* special_function */
00583         "R_MIPS_SCN_DISP",  /* name */
00584         TRUE,               /* partial_inplace */
00585         0xffffffff,         /* src_mask */
00586         0xffffffff,         /* dst_mask */
00587         FALSE),             /* pcrel_offset */
00588 
00589   HOWTO (R_MIPS_REL16,             /* type */
00590         0,                  /* rightshift */
00591         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00592         16,                 /* bitsize */
00593         FALSE,                     /* pc_relative */
00594         0,                  /* bitpos */
00595         complain_overflow_signed, /* complain_on_overflow */
00596         _bfd_mips_elf_generic_reloc,      /* special_function */
00597         "R_MIPS_REL16",     /* name */
00598         TRUE,               /* partial_inplace */
00599         0xffff,             /* src_mask */
00600         0xffff,             /* dst_mask */
00601         FALSE),             /* pcrel_offset */
00602 
00603   /* These two are obsolete.  */
00604   EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
00605   EMPTY_HOWTO (R_MIPS_PJUMP),
00606 
00607   /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
00608      It must be used for multigot GOT's (and only there).  */
00609   HOWTO (R_MIPS_RELGOT,            /* type */
00610         0,                  /* rightshift */
00611         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00612         32,                 /* bitsize */
00613         FALSE,                     /* pc_relative */
00614         0,                  /* bitpos */
00615         complain_overflow_dont, /* complain_on_overflow */
00616         _bfd_mips_elf_generic_reloc,      /* special_function */
00617         "R_MIPS_RELGOT",    /* name */
00618         TRUE,               /* partial_inplace */
00619         0xffffffff,         /* src_mask */
00620         0xffffffff,         /* dst_mask */
00621         FALSE),             /* pcrel_offset */
00622 
00623   /* Protected jump conversion.  This is an optimization hint.  No
00624      relocation is required for correctness.  */
00625   HOWTO (R_MIPS_JALR,              /* type */
00626         0,                  /* rightshift */
00627         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00628         32,                 /* bitsize */
00629         FALSE,                     /* pc_relative */
00630         0,                  /* bitpos */
00631         complain_overflow_dont, /* complain_on_overflow */
00632         _bfd_mips_elf_generic_reloc,      /* special_function */
00633         "R_MIPS_JALR",             /* name */
00634         FALSE,                     /* partial_inplace */
00635         0,                  /* src_mask */
00636         0x00000000,         /* dst_mask */
00637         FALSE),             /* pcrel_offset */
00638 
00639   /* TLS relocations.  */
00640   EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
00641   EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
00642 
00643   HOWTO (R_MIPS_TLS_DTPMOD64,      /* type */
00644         0,                  /* rightshift */
00645         4,                  /* size (0 = byte, 1 = short, 2 = long) */
00646         64,                 /* bitsize */
00647         FALSE,                     /* pc_relative */
00648         0,                  /* bitpos */
00649         complain_overflow_dont, /* complain_on_overflow */
00650         _bfd_mips_elf_generic_reloc, /* special_function */
00651         "R_MIPS_TLS_DTPMOD64",     /* name */
00652         TRUE,               /* partial_inplace */
00653         MINUS_ONE,          /* src_mask */
00654         MINUS_ONE,          /* dst_mask */
00655         FALSE),             /* pcrel_offset */
00656 
00657   HOWTO (R_MIPS_TLS_DTPREL64,      /* type */
00658         0,                  /* rightshift */
00659         4,                  /* size (0 = byte, 1 = short, 2 = long) */
00660         64,                 /* bitsize */
00661         FALSE,                     /* pc_relative */
00662         0,                  /* bitpos */
00663         complain_overflow_dont, /* complain_on_overflow */
00664         _bfd_mips_elf_generic_reloc, /* special_function */
00665         "R_MIPS_TLS_DTPREL64",     /* name */
00666         TRUE,               /* partial_inplace */
00667         MINUS_ONE,          /* src_mask */
00668         MINUS_ONE,          /* dst_mask */
00669         FALSE),             /* pcrel_offset */
00670 
00671   /* TLS general dynamic variable reference.  */
00672   HOWTO (R_MIPS_TLS_GD,            /* type */
00673         0,                  /* rightshift */
00674         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00675         16,                 /* bitsize */
00676         FALSE,                     /* pc_relative */
00677         0,                  /* bitpos */
00678         complain_overflow_signed, /* complain_on_overflow */
00679         _bfd_mips_elf_generic_reloc, /* special_function */
00680         "R_MIPS_TLS_GD",    /* name */
00681         TRUE,               /* partial_inplace */
00682         0x0000ffff,         /* src_mask */
00683         0x0000ffff,         /* dst_mask */
00684         FALSE),             /* pcrel_offset */
00685 
00686   /* TLS local dynamic variable reference.  */
00687   HOWTO (R_MIPS_TLS_LDM,    /* type */
00688         0,                  /* rightshift */
00689         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00690         16,                 /* bitsize */
00691         FALSE,                     /* pc_relative */
00692         0,                  /* bitpos */
00693         complain_overflow_signed, /* complain_on_overflow */
00694         _bfd_mips_elf_generic_reloc, /* special_function */
00695         "R_MIPS_TLS_LDM",   /* name */
00696         TRUE,               /* partial_inplace */
00697         0x0000ffff,         /* src_mask */
00698         0x0000ffff,         /* dst_mask */
00699         FALSE),             /* pcrel_offset */
00700 
00701   /* TLS local dynamic offset.  */
00702   HOWTO (R_MIPS_TLS_DTPREL_HI16,   /* type */
00703         0,                  /* rightshift */
00704         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00705         16,                 /* bitsize */
00706         FALSE,                     /* pc_relative */
00707         0,                  /* bitpos */
00708         complain_overflow_signed, /* complain_on_overflow */
00709         _bfd_mips_elf_generic_reloc, /* special_function */
00710         "R_MIPS_TLS_DTPREL_HI16",  /* name */
00711         TRUE,               /* partial_inplace */
00712         0x0000ffff,         /* src_mask */
00713         0x0000ffff,         /* dst_mask */
00714         FALSE),             /* pcrel_offset */
00715 
00716   /* TLS local dynamic offset.  */
00717   HOWTO (R_MIPS_TLS_DTPREL_LO16,   /* type */
00718         0,                  /* rightshift */
00719         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00720         16,                 /* bitsize */
00721         FALSE,                     /* pc_relative */
00722         0,                  /* bitpos */
00723         complain_overflow_signed, /* complain_on_overflow */
00724         _bfd_mips_elf_generic_reloc, /* special_function */
00725         "R_MIPS_TLS_DTPREL_LO16",  /* name */
00726         TRUE,               /* partial_inplace */
00727         0x0000ffff,         /* src_mask */
00728         0x0000ffff,         /* dst_mask */
00729         FALSE),             /* pcrel_offset */
00730 
00731   /* TLS thread pointer offset.  */
00732   HOWTO (R_MIPS_TLS_GOTTPREL,      /* type */
00733         0,                  /* rightshift */
00734         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00735         16,                 /* bitsize */
00736         FALSE,                     /* pc_relative */
00737         0,                  /* bitpos */
00738         complain_overflow_signed, /* complain_on_overflow */
00739         _bfd_mips_elf_generic_reloc, /* special_function */
00740         "R_MIPS_TLS_GOTTPREL",     /* name */
00741         TRUE,               /* partial_inplace */
00742         0x0000ffff,         /* src_mask */
00743         0x0000ffff,         /* dst_mask */
00744         FALSE),             /* pcrel_offset */
00745 
00746   /* TLS IE dynamic relocations.  */
00747   EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
00748 
00749   HOWTO (R_MIPS_TLS_TPREL64,       /* type */
00750         0,                  /* rightshift */
00751         4,                  /* size (0 = byte, 1 = short, 2 = long) */
00752         64,                 /* bitsize */
00753         FALSE,                     /* pc_relative */
00754         0,                  /* bitpos */
00755         complain_overflow_dont, /* complain_on_overflow */
00756         _bfd_mips_elf_generic_reloc, /* special_function */
00757         "R_MIPS_TLS_TPREL64",      /* name */
00758         TRUE,               /* partial_inplace */
00759         MINUS_ONE,          /* src_mask */
00760         MINUS_ONE,          /* dst_mask */
00761         FALSE),             /* pcrel_offset */
00762 
00763   /* TLS thread pointer offset.  */
00764   HOWTO (R_MIPS_TLS_TPREL_HI16,    /* type */
00765         0,                  /* rightshift */
00766         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00767         16,                 /* bitsize */
00768         FALSE,                     /* pc_relative */
00769         0,                  /* bitpos */
00770         complain_overflow_signed, /* complain_on_overflow */
00771         _bfd_mips_elf_generic_reloc, /* special_function */
00772         "R_MIPS_TLS_TPREL_HI16", /* name */
00773         TRUE,               /* partial_inplace */
00774         0x0000ffff,         /* src_mask */
00775         0x0000ffff,         /* dst_mask */
00776         FALSE),             /* pcrel_offset */
00777 
00778   /* TLS thread pointer offset.  */
00779   HOWTO (R_MIPS_TLS_TPREL_LO16,    /* type */
00780         0,                  /* rightshift */
00781         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00782         16,                 /* bitsize */
00783         FALSE,                     /* pc_relative */
00784         0,                  /* bitpos */
00785         complain_overflow_signed, /* complain_on_overflow */
00786         _bfd_mips_elf_generic_reloc, /* special_function */
00787         "R_MIPS_TLS_TPREL_LO16", /* name */
00788         TRUE,               /* partial_inplace */
00789         0x0000ffff,         /* src_mask */
00790         0x0000ffff,         /* dst_mask */
00791         FALSE),             /* pcrel_offset */
00792 
00793   /* 32 bit relocation with no addend.  */
00794   HOWTO (R_MIPS_GLOB_DAT,   /* type */
00795         0,                  /* rightshift */
00796         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00797         32,                 /* bitsize */
00798         FALSE,                     /* pc_relative */
00799         0,                  /* bitpos */
00800         complain_overflow_dont, /* complain_on_overflow */
00801         _bfd_mips_elf_generic_reloc, /* special_function */
00802         "R_MIPS_GLOB_DAT",  /* name */
00803         FALSE,                     /* partial_inplace */
00804         0x0,                /* src_mask */
00805         0xffffffff,         /* dst_mask */
00806         FALSE),             /* pcrel_offset */
00807 };
00808 
00809 /* The relocation table used for SHT_RELA sections.  */
00810 
00811 static reloc_howto_type mips_elf64_howto_table_rela[] =
00812 {
00813   /* No relocation.  */
00814   HOWTO (R_MIPS_NONE,              /* type */
00815         0,                  /* rightshift */
00816         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00817         0,                  /* bitsize */
00818         FALSE,                     /* pc_relative */
00819         0,                  /* bitpos */
00820         complain_overflow_dont, /* complain_on_overflow */
00821         _bfd_mips_elf_generic_reloc,      /* special_function */
00822         "R_MIPS_NONE",             /* name */
00823         FALSE,                     /* partial_inplace */
00824         0,                  /* src_mask */
00825         0,                  /* dst_mask */
00826         FALSE),             /* pcrel_offset */
00827 
00828   /* 16 bit relocation.  */
00829   HOWTO (R_MIPS_16,         /* type */
00830         0,                  /* rightshift */
00831         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00832         16,                 /* bitsize */
00833         FALSE,                     /* pc_relative */
00834         0,                  /* bitpos */
00835         complain_overflow_signed, /* complain_on_overflow */
00836         _bfd_mips_elf_generic_reloc,      /* special_function */
00837         "R_MIPS_16",        /* name */
00838         FALSE,                     /* partial_inplace */
00839         0,                  /* src_mask */
00840         0x0000ffff,         /* dst_mask */
00841         FALSE),             /* pcrel_offset */
00842 
00843   /* 32 bit relocation.  */
00844   HOWTO (R_MIPS_32,         /* type */
00845         0,                  /* rightshift */
00846         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00847         32,                 /* bitsize */
00848         FALSE,                     /* pc_relative */
00849         0,                  /* bitpos */
00850         complain_overflow_dont, /* complain_on_overflow */
00851         _bfd_mips_elf_generic_reloc,      /* special_function */
00852         "R_MIPS_32",        /* name */
00853         FALSE,                     /* partial_inplace */
00854         0,                  /* src_mask */
00855         0xffffffff,         /* dst_mask */
00856         FALSE),             /* pcrel_offset */
00857 
00858   /* 32 bit symbol relative relocation.  */
00859   HOWTO (R_MIPS_REL32,             /* type */
00860         0,                  /* rightshift */
00861         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00862         32,                 /* bitsize */
00863         FALSE,                     /* pc_relative */
00864         0,                  /* bitpos */
00865         complain_overflow_dont, /* complain_on_overflow */
00866         _bfd_mips_elf_generic_reloc,      /* special_function */
00867         "R_MIPS_REL32",     /* name */
00868         FALSE,                     /* partial_inplace */
00869         0,                  /* src_mask */
00870         0xffffffff,         /* dst_mask */
00871         FALSE),             /* pcrel_offset */
00872 
00873   /* 26 bit jump address.  */
00874   HOWTO (R_MIPS_26,         /* type */
00875         2,                  /* rightshift */
00876         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00877         26,                 /* bitsize */
00878         FALSE,                     /* pc_relative */
00879         0,                  /* bitpos */
00880         complain_overflow_dont, /* complain_on_overflow */
00881                             /* This needs complex overflow
00882                                detection, because the upper 36
00883                                bits must match the PC + 4.  */
00884         _bfd_mips_elf_generic_reloc,      /* special_function */
00885         "R_MIPS_26",        /* name */
00886         FALSE,                     /* partial_inplace */
00887         0,                  /* src_mask */
00888         0x03ffffff,         /* dst_mask */
00889         FALSE),             /* pcrel_offset */
00890 
00891   /* High 16 bits of symbol value.  */
00892   HOWTO (R_MIPS_HI16,              /* type */
00893         0,                  /* rightshift */
00894         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00895         16,                 /* bitsize */
00896         FALSE,                     /* pc_relative */
00897         0,                  /* bitpos */
00898         complain_overflow_dont, /* complain_on_overflow */
00899         _bfd_mips_elf_generic_reloc,      /* special_function */
00900         "R_MIPS_HI16",             /* name */
00901         FALSE,                     /* partial_inplace */
00902         0,                  /* src_mask */
00903         0x0000ffff,         /* dst_mask */
00904         FALSE),             /* pcrel_offset */
00905 
00906   /* Low 16 bits of symbol value.  */
00907   HOWTO (R_MIPS_LO16,              /* type */
00908         0,                  /* rightshift */
00909         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00910         16,                 /* bitsize */
00911         FALSE,                     /* pc_relative */
00912         0,                  /* bitpos */
00913         complain_overflow_dont, /* complain_on_overflow */
00914         _bfd_mips_elf_generic_reloc,      /* special_function */
00915         "R_MIPS_LO16",             /* name */
00916         FALSE,                     /* partial_inplace */
00917         0,                  /* src_mask */
00918         0x0000ffff,         /* dst_mask */
00919         FALSE),             /* pcrel_offset */
00920 
00921   /* GP relative reference.  */
00922   HOWTO (R_MIPS_GPREL16,    /* type */
00923         0,                  /* rightshift */
00924         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00925         16,                 /* bitsize */
00926         FALSE,                     /* pc_relative */
00927         0,                  /* bitpos */
00928         complain_overflow_signed, /* complain_on_overflow */
00929         mips_elf64_gprel16_reloc, /* special_function */
00930         "R_MIPS_GPREL16",   /* name */
00931         FALSE,                     /* partial_inplace */
00932         0,                  /* src_mask */
00933         0x0000ffff,         /* dst_mask */
00934         FALSE),             /* pcrel_offset */
00935 
00936   /* Reference to literal section.  */
00937   HOWTO (R_MIPS_LITERAL,    /* type */
00938         0,                  /* rightshift */
00939         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00940         16,                 /* bitsize */
00941         FALSE,                     /* pc_relative */
00942         0,                  /* bitpos */
00943         complain_overflow_signed, /* complain_on_overflow */
00944         mips_elf64_literal_reloc, /* special_function */
00945         "R_MIPS_LITERAL",   /* name */
00946         FALSE,                     /* partial_inplace */
00947         0,                  /* src_mask */
00948         0x0000ffff,         /* dst_mask */
00949         FALSE),             /* pcrel_offset */
00950 
00951   /* Reference to global offset table.  */
00952   HOWTO (R_MIPS_GOT16,             /* type */
00953         0,                  /* rightshift */
00954         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00955         16,                 /* bitsize */
00956         FALSE,                     /* pc_relative */
00957         0,                  /* bitpos */
00958         complain_overflow_signed, /* complain_on_overflow */
00959         _bfd_mips_elf_generic_reloc, /* special_function */
00960         "R_MIPS_GOT16",     /* name */
00961         FALSE,                     /* partial_inplace */
00962         0,                  /* src_mask */
00963         0x0000ffff,         /* dst_mask */
00964         FALSE),             /* pcrel_offset */
00965 
00966   /* 16 bit PC relative reference.  Note that the ABI document has a typo
00967      and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
00968      We do the right thing here.  */
00969   HOWTO (R_MIPS_PC16,              /* type */
00970         2,                  /* rightshift */
00971         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00972         16,                 /* bitsize */
00973         TRUE,               /* pc_relative */
00974         0,                  /* bitpos */
00975         complain_overflow_signed, /* complain_on_overflow */
00976         _bfd_mips_elf_generic_reloc,      /* special_function */
00977         "R_MIPS_PC16",             /* name */
00978         FALSE,                     /* partial_inplace */
00979         0,                  /* src_mask */
00980         0x0000ffff,         /* dst_mask */
00981         TRUE),                     /* pcrel_offset */
00982 
00983   /* 16 bit call through global offset table.  */
00984   HOWTO (R_MIPS_CALL16,            /* type */
00985         0,                  /* rightshift */
00986         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00987         16,                 /* bitsize */
00988         FALSE,                     /* pc_relative */
00989         0,                  /* bitpos */
00990         complain_overflow_signed, /* complain_on_overflow */
00991         _bfd_mips_elf_generic_reloc,      /* special_function */
00992         "R_MIPS_CALL16",    /* name */
00993         FALSE,                     /* partial_inplace */
00994         0,                  /* src_mask */
00995         0x0000ffff,         /* dst_mask */
00996         FALSE),             /* pcrel_offset */
00997 
00998   /* 32 bit GP relative reference.  */
00999   HOWTO (R_MIPS_GPREL32,    /* type */
01000         0,                  /* rightshift */
01001         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01002         32,                 /* bitsize */
01003         FALSE,                     /* pc_relative */
01004         0,                  /* bitpos */
01005         complain_overflow_dont, /* complain_on_overflow */
01006         mips_elf64_gprel32_reloc, /* special_function */
01007         "R_MIPS_GPREL32",   /* name */
01008         FALSE,                     /* partial_inplace */
01009         0,                  /* src_mask */
01010         0xffffffff,         /* dst_mask */
01011         FALSE),             /* pcrel_offset */
01012 
01013   EMPTY_HOWTO (13),
01014   EMPTY_HOWTO (14),
01015   EMPTY_HOWTO (15),
01016 
01017   /* A 5 bit shift field.  */
01018   HOWTO (R_MIPS_SHIFT5,            /* type */
01019         0,                  /* rightshift */
01020         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01021         5,                  /* bitsize */
01022         FALSE,                     /* pc_relative */
01023         6,                  /* bitpos */
01024         complain_overflow_bitfield, /* complain_on_overflow */
01025         _bfd_mips_elf_generic_reloc,      /* special_function */
01026         "R_MIPS_SHIFT5",    /* name */
01027         FALSE,                     /* partial_inplace */
01028         0,                  /* src_mask */
01029         0x000007c0,         /* dst_mask */
01030         FALSE),             /* pcrel_offset */
01031 
01032   /* A 6 bit shift field.  */
01033   HOWTO (R_MIPS_SHIFT6,            /* type */
01034         0,                  /* rightshift */
01035         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01036         6,                  /* bitsize */
01037         FALSE,                     /* pc_relative */
01038         6,                  /* bitpos */
01039         complain_overflow_bitfield, /* complain_on_overflow */
01040         mips_elf64_shift6_reloc, /* special_function */
01041         "R_MIPS_SHIFT6",    /* name */
01042         FALSE,                     /* partial_inplace */
01043         0,                  /* src_mask */
01044         0x000007c4,         /* dst_mask */
01045         FALSE),             /* pcrel_offset */
01046 
01047   /* 64 bit relocation.  */
01048   HOWTO (R_MIPS_64,         /* type */
01049         0,                  /* rightshift */
01050         4,                  /* size (0 = byte, 1 = short, 2 = long) */
01051         64,                 /* bitsize */
01052         FALSE,                     /* pc_relative */
01053         0,                  /* bitpos */
01054         complain_overflow_dont, /* complain_on_overflow */
01055         _bfd_mips_elf_generic_reloc,      /* special_function */
01056         "R_MIPS_64",        /* name */
01057         FALSE,                     /* partial_inplace */
01058         0,                  /* src_mask */
01059         MINUS_ONE,          /* dst_mask */
01060         FALSE),             /* pcrel_offset */
01061 
01062   /* Displacement in the global offset table.  */
01063   HOWTO (R_MIPS_GOT_DISP,   /* type */
01064         0,                  /* rightshift */
01065         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01066         16,                 /* bitsize */
01067         FALSE,                     /* pc_relative */
01068         0,                  /* bitpos */
01069         complain_overflow_signed, /* complain_on_overflow */
01070         _bfd_mips_elf_generic_reloc,      /* special_function */
01071         "R_MIPS_GOT_DISP",  /* name */
01072         FALSE,                     /* partial_inplace */
01073         0,                  /* src_mask */
01074         0x0000ffff,         /* dst_mask */
01075         FALSE),             /* pcrel_offset */
01076 
01077   /* Displacement to page pointer in the global offset table.  */
01078   HOWTO (R_MIPS_GOT_PAGE,   /* type */
01079         0,                  /* rightshift */
01080         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01081         16,                 /* bitsize */
01082         FALSE,                     /* pc_relative */
01083         0,                  /* bitpos */
01084         complain_overflow_signed, /* complain_on_overflow */
01085         _bfd_mips_elf_generic_reloc,      /* special_function */
01086         "R_MIPS_GOT_PAGE",  /* name */
01087         FALSE,                     /* partial_inplace */
01088         0,                  /* src_mask */
01089         0x0000ffff,         /* dst_mask */
01090         FALSE),             /* pcrel_offset */
01091 
01092   /* Offset from page pointer in the global offset table.  */
01093   HOWTO (R_MIPS_GOT_OFST,   /* type */
01094         0,                  /* rightshift */
01095         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01096         16,                 /* bitsize */
01097         FALSE,                     /* pc_relative */
01098         0,                  /* bitpos */
01099         complain_overflow_signed, /* complain_on_overflow */
01100         _bfd_mips_elf_generic_reloc,      /* special_function */
01101         "R_MIPS_GOT_OFST",  /* name */
01102         FALSE,                     /* partial_inplace */
01103         0,                  /* src_mask */
01104         0x0000ffff,         /* dst_mask */
01105         FALSE),             /* pcrel_offset */
01106 
01107   /* High 16 bits of displacement in global offset table.  */
01108   HOWTO (R_MIPS_GOT_HI16,   /* type */
01109         0,                  /* rightshift */
01110         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01111         16,                 /* bitsize */
01112         FALSE,                     /* pc_relative */
01113         0,                  /* bitpos */
01114         complain_overflow_dont, /* complain_on_overflow */
01115         _bfd_mips_elf_generic_reloc,      /* special_function */
01116         "R_MIPS_GOT_HI16",  /* name */
01117         FALSE,                     /* partial_inplace */
01118         0,                  /* src_mask */
01119         0x0000ffff,         /* dst_mask */
01120         FALSE),             /* pcrel_offset */
01121 
01122   /* Low 16 bits of displacement in global offset table.  */
01123   HOWTO (R_MIPS_GOT_LO16,   /* type */
01124         0,                  /* rightshift */
01125         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01126         16,                 /* bitsize */
01127         FALSE,                     /* pc_relative */
01128         0,                  /* bitpos */
01129         complain_overflow_dont, /* complain_on_overflow */
01130         _bfd_mips_elf_generic_reloc,      /* special_function */
01131         "R_MIPS_GOT_LO16",  /* name */
01132         FALSE,                     /* partial_inplace */
01133         0,                  /* src_mask */
01134         0x0000ffff,         /* dst_mask */
01135         FALSE),             /* pcrel_offset */
01136 
01137   /* 64 bit subtraction.  */
01138   HOWTO (R_MIPS_SUB,        /* type */
01139         0,                  /* rightshift */
01140         4,                  /* size (0 = byte, 1 = short, 2 = long) */
01141         64,                 /* bitsize */
01142         FALSE,                     /* pc_relative */
01143         0,                  /* bitpos */
01144         complain_overflow_dont, /* complain_on_overflow */
01145         _bfd_mips_elf_generic_reloc,      /* special_function */
01146         "R_MIPS_SUB",              /* name */
01147         FALSE,                     /* partial_inplace */
01148         0,                  /* src_mask */
01149         MINUS_ONE,          /* dst_mask */
01150         FALSE),             /* pcrel_offset */
01151 
01152   /* Insert the addend as an instruction.  */
01153   /* FIXME: Not handled correctly.  */
01154   HOWTO (R_MIPS_INSERT_A,   /* type */
01155         0,                  /* rightshift */
01156         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01157         32,                 /* bitsize */
01158         FALSE,                     /* pc_relative */
01159         0,                  /* bitpos */
01160         complain_overflow_dont, /* complain_on_overflow */
01161         _bfd_mips_elf_generic_reloc,      /* special_function */
01162         "R_MIPS_INSERT_A",  /* name */
01163         FALSE,                     /* partial_inplace */
01164         0,                  /* src_mask */
01165         0xffffffff,         /* dst_mask */
01166         FALSE),             /* pcrel_offset */
01167 
01168   /* Insert the addend as an instruction, and change all relocations
01169      to refer to the old instruction at the address.  */
01170   /* FIXME: Not handled correctly.  */
01171   HOWTO (R_MIPS_INSERT_B,   /* type */
01172         0,                  /* rightshift */
01173         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01174         32,                 /* bitsize */
01175         FALSE,                     /* pc_relative */
01176         0,                  /* bitpos */
01177         complain_overflow_dont, /* complain_on_overflow */
01178         _bfd_mips_elf_generic_reloc,      /* special_function */
01179         "R_MIPS_INSERT_B",  /* name */
01180         FALSE,                     /* partial_inplace */
01181         0,                  /* src_mask */
01182         0xffffffff,         /* dst_mask */
01183         FALSE),             /* pcrel_offset */
01184 
01185   /* Delete a 32 bit instruction.  */
01186   /* FIXME: Not handled correctly.  */
01187   HOWTO (R_MIPS_DELETE,            /* type */
01188         0,                  /* rightshift */
01189         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01190         32,                 /* bitsize */
01191         FALSE,                     /* pc_relative */
01192         0,                  /* bitpos */
01193         complain_overflow_dont, /* complain_on_overflow */
01194         _bfd_mips_elf_generic_reloc,      /* special_function */
01195         "R_MIPS_DELETE",    /* name */
01196         FALSE,                     /* partial_inplace */
01197         0,                  /* src_mask */
01198         0xffffffff,         /* dst_mask */
01199         FALSE),             /* pcrel_offset */
01200 
01201   /* Get the higher value of a 64 bit addend.  */
01202   HOWTO (R_MIPS_HIGHER,            /* type */
01203         0,                  /* rightshift */
01204         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01205         16,                 /* bitsize */
01206         FALSE,                     /* pc_relative */
01207         0,                  /* bitpos */
01208         complain_overflow_dont, /* complain_on_overflow */
01209         _bfd_mips_elf_generic_reloc, /* special_function */
01210         "R_MIPS_HIGHER",    /* name */
01211         FALSE,                     /* partial_inplace */
01212         0,                  /* src_mask */
01213         0x0000ffff,         /* dst_mask */
01214         FALSE),             /* pcrel_offset */
01215 
01216   /* Get the highest value of a 64 bit addend.  */
01217   HOWTO (R_MIPS_HIGHEST,    /* type */
01218         0,                  /* rightshift */
01219         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01220         16,                 /* bitsize */
01221         FALSE,                     /* pc_relative */
01222         0,                  /* bitpos */
01223         complain_overflow_dont, /* complain_on_overflow */
01224         _bfd_mips_elf_generic_reloc, /* special_function */
01225         "R_MIPS_HIGHEST",   /* name */
01226         FALSE,                     /* partial_inplace */
01227         0,                  /* src_mask */
01228         0x0000ffff,         /* dst_mask */
01229         FALSE),             /* pcrel_offset */
01230 
01231   /* High 16 bits of displacement in global offset table.  */
01232   HOWTO (R_MIPS_CALL_HI16,  /* type */
01233         0,                  /* rightshift */
01234         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01235         16,                 /* bitsize */
01236         FALSE,                     /* pc_relative */
01237         0,                  /* bitpos */
01238         complain_overflow_dont, /* complain_on_overflow */
01239         _bfd_mips_elf_generic_reloc,      /* special_function */
01240         "R_MIPS_CALL_HI16", /* name */
01241         FALSE,                     /* partial_inplace */
01242         0,                  /* src_mask */
01243         0x0000ffff,         /* dst_mask */
01244         FALSE),             /* pcrel_offset */
01245 
01246   /* Low 16 bits of displacement in global offset table.  */
01247   HOWTO (R_MIPS_CALL_LO16,  /* type */
01248         0,                  /* rightshift */
01249         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01250         16,                 /* bitsize */
01251         FALSE,                     /* pc_relative */
01252         0,                  /* bitpos */
01253         complain_overflow_dont, /* complain_on_overflow */
01254         _bfd_mips_elf_generic_reloc,      /* special_function */
01255         "R_MIPS_CALL_LO16", /* name */
01256         FALSE,                     /* partial_inplace */
01257         0,                  /* src_mask */
01258         0x0000ffff,         /* dst_mask */
01259         FALSE),             /* pcrel_offset */
01260 
01261   /* Section displacement, used by an associated event location section.  */
01262   HOWTO (R_MIPS_SCN_DISP,   /* type */
01263         0,                  /* rightshift */
01264         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01265         32,                 /* bitsize */
01266         FALSE,                     /* pc_relative */
01267         0,                  /* bitpos */
01268         complain_overflow_dont, /* complain_on_overflow */
01269         _bfd_mips_elf_generic_reloc,      /* special_function */
01270         "R_MIPS_SCN_DISP",  /* name */
01271         FALSE,                     /* partial_inplace */
01272         0,                  /* src_mask */
01273         0xffffffff,         /* dst_mask */
01274         FALSE),             /* pcrel_offset */
01275 
01276   HOWTO (R_MIPS_REL16,             /* type */
01277         0,                  /* rightshift */
01278         1,                  /* size (0 = byte, 1 = short, 2 = long) */
01279         16,                 /* bitsize */
01280         FALSE,                     /* pc_relative */
01281         0,                  /* bitpos */
01282         complain_overflow_signed, /* complain_on_overflow */
01283         _bfd_mips_elf_generic_reloc,      /* special_function */
01284         "R_MIPS_REL16",     /* name */
01285         FALSE,                     /* partial_inplace */
01286         0,                  /* src_mask */
01287         0xffff,             /* dst_mask */
01288         FALSE),             /* pcrel_offset */
01289 
01290   /* These two are obsolete.  */
01291   EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
01292   EMPTY_HOWTO (R_MIPS_PJUMP),
01293 
01294   /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
01295      It must be used for multigot GOT's (and only there).  */
01296   HOWTO (R_MIPS_RELGOT,            /* type */
01297         0,                  /* rightshift */
01298         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01299         32,                 /* bitsize */
01300         FALSE,                     /* pc_relative */
01301         0,                  /* bitpos */
01302         complain_overflow_dont, /* complain_on_overflow */
01303         _bfd_mips_elf_generic_reloc,      /* special_function */
01304         "R_MIPS_RELGOT",    /* name */
01305         FALSE,                     /* partial_inplace */
01306         0,                  /* src_mask */
01307         0xffffffff,         /* dst_mask */
01308         FALSE),             /* pcrel_offset */
01309 
01310   /* Protected jump conversion.  This is an optimization hint.  No
01311      relocation is required for correctness.  */
01312   HOWTO (R_MIPS_JALR,              /* type */
01313         0,                  /* rightshift */
01314         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01315         32,                 /* bitsize */
01316         FALSE,                     /* pc_relative */
01317         0,                  /* bitpos */
01318         complain_overflow_dont, /* complain_on_overflow */
01319         _bfd_mips_elf_generic_reloc,      /* special_function */
01320         "R_MIPS_JALR",             /* name */
01321         FALSE,                     /* partial_inplace */
01322         0,                  /* src_mask */
01323         0x00000000,         /* dst_mask */
01324         FALSE),             /* pcrel_offset */
01325 
01326   /* TLS relocations.  */
01327   EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
01328   EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
01329   EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64),
01330   EMPTY_HOWTO (R_MIPS_TLS_DTPREL64),
01331 
01332   /* TLS general dynamic variable reference.  */
01333   HOWTO (R_MIPS_TLS_GD,            /* type */
01334         0,                  /* rightshift */
01335         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01336         16,                 /* bitsize */
01337         FALSE,                     /* pc_relative */
01338         0,                  /* bitpos */
01339         complain_overflow_signed, /* complain_on_overflow */
01340         _bfd_mips_elf_generic_reloc, /* special_function */
01341         "R_MIPS_TLS_GD",    /* name */
01342         TRUE,               /* partial_inplace */
01343         0x0000ffff,         /* src_mask */
01344         0x0000ffff,         /* dst_mask */
01345         FALSE),             /* pcrel_offset */
01346 
01347   /* TLS local dynamic variable reference.  */
01348   HOWTO (R_MIPS_TLS_LDM,    /* type */
01349         0,                  /* rightshift */
01350         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01351         16,                 /* bitsize */
01352         FALSE,                     /* pc_relative */
01353         0,                  /* bitpos */
01354         complain_overflow_signed, /* complain_on_overflow */
01355         _bfd_mips_elf_generic_reloc, /* special_function */
01356         "R_MIPS_TLS_LDM",   /* name */
01357         TRUE,               /* partial_inplace */
01358         0x0000ffff,         /* src_mask */
01359         0x0000ffff,         /* dst_mask */
01360         FALSE),             /* pcrel_offset */
01361 
01362   /* TLS local dynamic offset.  */
01363   HOWTO (R_MIPS_TLS_DTPREL_HI16,   /* type */
01364         0,                  /* rightshift */
01365         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01366         16,                 /* bitsize */
01367         FALSE,                     /* pc_relative */
01368         0,                  /* bitpos */
01369         complain_overflow_signed, /* complain_on_overflow */
01370         _bfd_mips_elf_generic_reloc, /* special_function */
01371         "R_MIPS_TLS_DTPREL_HI16",  /* name */
01372         TRUE,               /* partial_inplace */
01373         0x0000ffff,         /* src_mask */
01374         0x0000ffff,         /* dst_mask */
01375         FALSE),             /* pcrel_offset */
01376 
01377   /* TLS local dynamic offset.  */
01378   HOWTO (R_MIPS_TLS_DTPREL_LO16,   /* type */
01379         0,                  /* rightshift */
01380         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01381         16,                 /* bitsize */
01382         FALSE,                     /* pc_relative */
01383         0,                  /* bitpos */
01384         complain_overflow_signed, /* complain_on_overflow */
01385         _bfd_mips_elf_generic_reloc, /* special_function */
01386         "R_MIPS_TLS_DTPREL_LO16",  /* name */
01387         TRUE,               /* partial_inplace */
01388         0x0000ffff,         /* src_mask */
01389         0x0000ffff,         /* dst_mask */
01390         FALSE),             /* pcrel_offset */
01391 
01392   /* TLS thread pointer offset.  */
01393   HOWTO (R_MIPS_TLS_GOTTPREL,      /* type */
01394         0,                  /* rightshift */
01395         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01396         16,                 /* bitsize */
01397         FALSE,                     /* pc_relative */
01398         0,                  /* bitpos */
01399         complain_overflow_signed, /* complain_on_overflow */
01400         _bfd_mips_elf_generic_reloc, /* special_function */
01401         "R_MIPS_TLS_GOTTPREL",     /* name */
01402         TRUE,               /* partial_inplace */
01403         0x0000ffff,         /* src_mask */
01404         0x0000ffff,         /* dst_mask */
01405         FALSE),             /* pcrel_offset */
01406 
01407   EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
01408   EMPTY_HOWTO (R_MIPS_TLS_TPREL64),
01409 
01410   /* TLS thread pointer offset.  */
01411   HOWTO (R_MIPS_TLS_TPREL_HI16,    /* type */
01412         0,                  /* rightshift */
01413         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01414         16,                 /* bitsize */
01415         FALSE,                     /* pc_relative */
01416         0,                  /* bitpos */
01417         complain_overflow_signed, /* complain_on_overflow */
01418         _bfd_mips_elf_generic_reloc, /* special_function */
01419         "R_MIPS_TLS_TPREL_HI16", /* name */
01420         TRUE,               /* partial_inplace */
01421         0x0000ffff,         /* src_mask */
01422         0x0000ffff,         /* dst_mask */
01423         FALSE),             /* pcrel_offset */
01424 
01425   /* TLS thread pointer offset.  */
01426   HOWTO (R_MIPS_TLS_TPREL_LO16,    /* type */
01427         0,                  /* rightshift */
01428         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01429         16,                 /* bitsize */
01430         FALSE,                     /* pc_relative */
01431         0,                  /* bitpos */
01432         complain_overflow_signed, /* complain_on_overflow */
01433         _bfd_mips_elf_generic_reloc, /* special_function */
01434         "R_MIPS_TLS_TPREL_LO16", /* name */
01435         TRUE,               /* partial_inplace */
01436         0x0000ffff,         /* src_mask */
01437         0x0000ffff,         /* dst_mask */
01438         FALSE),             /* pcrel_offset */
01439 
01440   /* 32 bit relocation with no addend.  */
01441   HOWTO (R_MIPS_GLOB_DAT,   /* type */
01442         0,                  /* rightshift */
01443         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01444         32,                 /* bitsize */
01445         FALSE,                     /* pc_relative */
01446         0,                  /* bitpos */
01447         complain_overflow_dont, /* complain_on_overflow */
01448         _bfd_mips_elf_generic_reloc, /* special_function */
01449         "R_MIPS_GLOB_DAT",  /* name */
01450         FALSE,                     /* partial_inplace */
01451         0x0,                /* src_mask */
01452         0xffffffff,         /* dst_mask */
01453         FALSE),             /* pcrel_offset */
01454 };
01455 
01456 static reloc_howto_type mips16_elf64_howto_table_rel[] =
01457 {
01458   /* The reloc used for the mips16 jump instruction.  */
01459   HOWTO (R_MIPS16_26,              /* type */
01460         2,                  /* rightshift */
01461         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01462         26,                 /* bitsize */
01463         FALSE,                     /* pc_relative */
01464         0,                  /* bitpos */
01465         complain_overflow_dont, /* complain_on_overflow */
01466                             /* This needs complex overflow
01467                                detection, because the upper four
01468                                bits must match the PC.  */
01469         _bfd_mips_elf_generic_reloc, /* special_function */
01470         "R_MIPS16_26",             /* name */
01471         TRUE,               /* partial_inplace */
01472         0x3ffffff,          /* src_mask */
01473         0x3ffffff,          /* dst_mask */
01474         FALSE),             /* pcrel_offset */
01475 
01476   /* The reloc used for the mips16 gprel instruction.  */
01477   HOWTO (R_MIPS16_GPREL,    /* type */
01478         0,                  /* rightshift */
01479         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01480         16,                 /* bitsize */
01481         FALSE,                     /* pc_relative */
01482         0,                  /* bitpos */
01483         complain_overflow_signed, /* complain_on_overflow */
01484         mips16_gprel_reloc, /* special_function */
01485         "R_MIPS16_GPREL",   /* name */
01486         TRUE,               /* partial_inplace */
01487         0x0000ffff,         /* src_mask */
01488         0x0000ffff,          /* dst_mask */
01489         FALSE),             /* pcrel_offset */
01490 
01491   /* A placeholder for MIPS16 reference to global offset table.  */
01492   EMPTY_HOWTO (R_MIPS16_GOT16),
01493 
01494   /* A placeholder for MIPS16 16 bit call through global offset table.  */
01495   EMPTY_HOWTO (R_MIPS16_CALL16),
01496 
01497   /* MIPS16 high 16 bits of symbol value.  */
01498   HOWTO (R_MIPS16_HI16,            /* type */
01499         16,                 /* rightshift */
01500         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01501         16,                 /* bitsize */
01502         FALSE,                     /* pc_relative */
01503         0,                  /* bitpos */
01504         complain_overflow_dont, /* complain_on_overflow */
01505         _bfd_mips_elf_hi16_reloc, /* special_function */
01506         "R_MIPS16_HI16",    /* name */
01507         TRUE,               /* partial_inplace */
01508         0x0000ffff,         /* src_mask */
01509         0x0000ffff,         /* dst_mask */
01510         FALSE),             /* pcrel_offset */
01511 
01512   /* MIPS16 low 16 bits of symbol value.  */
01513   HOWTO (R_MIPS16_LO16,            /* type */
01514         0,                  /* rightshift */
01515         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01516         16,                 /* bitsize */
01517         FALSE,                     /* pc_relative */
01518         0,                  /* bitpos */
01519         complain_overflow_dont, /* complain_on_overflow */
01520         _bfd_mips_elf_lo16_reloc, /* special_function */
01521         "R_MIPS16_LO16",    /* name */
01522         TRUE,               /* partial_inplace */
01523         0x0000ffff,         /* src_mask */
01524         0x0000ffff,         /* dst_mask */
01525         FALSE),             /* pcrel_offset */
01526 };
01527 
01528 static reloc_howto_type mips16_elf64_howto_table_rela[] =
01529 {
01530   /* The reloc used for the mips16 jump instruction.  */
01531   HOWTO (R_MIPS16_26,              /* type */
01532         2,                  /* rightshift */
01533         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01534         26,                 /* bitsize */
01535         FALSE,                     /* pc_relative */
01536         0,                  /* bitpos */
01537         complain_overflow_dont, /* complain_on_overflow */
01538                             /* This needs complex overflow
01539                                detection, because the upper four
01540                                bits must match the PC.  */
01541         _bfd_mips_elf_generic_reloc, /* special_function */
01542         "R_MIPS16_26",             /* name */
01543         FALSE,                     /* partial_inplace */
01544         0x3ffffff,          /* src_mask */
01545         0x3ffffff,          /* dst_mask */
01546         FALSE),             /* pcrel_offset */
01547 
01548   /* The reloc used for the mips16 gprel instruction.  */
01549   HOWTO (R_MIPS16_GPREL,    /* type */
01550         0,                  /* rightshift */
01551         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01552         16,                 /* bitsize */
01553         FALSE,                     /* pc_relative */
01554         0,                  /* bitpos */
01555         complain_overflow_signed, /* complain_on_overflow */
01556         mips16_gprel_reloc, /* special_function */
01557         "R_MIPS16_GPREL",   /* name */
01558         FALSE,                     /* partial_inplace */
01559         0x0000ffff,         /* src_mask */
01560         0x0000ffff,          /* dst_mask */
01561         FALSE),             /* pcrel_offset */
01562 
01563   /* A placeholder for MIPS16 reference to global offset table.  */
01564   EMPTY_HOWTO (R_MIPS16_GOT16),
01565 
01566   /* A placeholder for MIPS16 16 bit call through global offset table.  */
01567   EMPTY_HOWTO (R_MIPS16_CALL16),
01568 
01569   /* MIPS16 high 16 bits of symbol value.  */
01570   HOWTO (R_MIPS16_HI16,            /* type */
01571         16,                 /* rightshift */
01572         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01573         16,                 /* bitsize */
01574         FALSE,                     /* pc_relative */
01575         0,                  /* bitpos */
01576         complain_overflow_dont, /* complain_on_overflow */
01577         _bfd_mips_elf_hi16_reloc, /* special_function */
01578         "R_MIPS16_HI16",    /* name */
01579         FALSE,                     /* partial_inplace */
01580         0x0000ffff,         /* src_mask */
01581         0x0000ffff,         /* dst_mask */
01582         FALSE),             /* pcrel_offset */
01583 
01584   /* MIPS16 low 16 bits of symbol value.  */
01585   HOWTO (R_MIPS16_LO16,            /* type */
01586         0,                  /* rightshift */
01587         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01588         16,                 /* bitsize */
01589         FALSE,                     /* pc_relative */
01590         0,                  /* bitpos */
01591         complain_overflow_dont, /* complain_on_overflow */
01592         _bfd_mips_elf_lo16_reloc, /* special_function */
01593         "R_MIPS16_LO16",    /* name */
01594         FALSE,                     /* partial_inplace */
01595         0x0000ffff,         /* src_mask */
01596         0x0000ffff,         /* dst_mask */
01597         FALSE),             /* pcrel_offset */
01598 };
01599 
01600 /* GNU extension to record C++ vtable hierarchy */
01601 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
01602   HOWTO (R_MIPS_GNU_VTINHERIT,     /* type */
01603         0,                  /* rightshift */
01604         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01605         0,                  /* bitsize */
01606         FALSE,                     /* pc_relative */
01607         0,                  /* bitpos */
01608         complain_overflow_dont, /* complain_on_overflow */
01609         NULL,               /* special_function */
01610         "R_MIPS_GNU_VTINHERIT", /* name */
01611         FALSE,                     /* partial_inplace */
01612         0,                  /* src_mask */
01613         0,                  /* dst_mask */
01614         FALSE);             /* pcrel_offset */
01615 
01616 /* GNU extension to record C++ vtable member usage */
01617 static reloc_howto_type elf_mips_gnu_vtentry_howto =
01618   HOWTO (R_MIPS_GNU_VTENTRY,       /* type */
01619         0,                  /* rightshift */
01620         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01621         0,                  /* bitsize */
01622         FALSE,                     /* pc_relative */
01623         0,                  /* bitpos */
01624         complain_overflow_dont, /* complain_on_overflow */
01625         _bfd_elf_rel_vtable_reloc_fn, /* special_function */
01626         "R_MIPS_GNU_VTENTRY",      /* name */
01627         FALSE,                     /* partial_inplace */
01628         0,                  /* src_mask */
01629         0,                  /* dst_mask */
01630         FALSE);             /* pcrel_offset */
01631 
01632 /* 16 bit offset for pc-relative branches.  */
01633 static reloc_howto_type elf_mips_gnu_rel16_s2 =
01634   HOWTO (R_MIPS_GNU_REL16_S2,      /* type */
01635         2,                  /* rightshift */
01636         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01637         16,                 /* bitsize */
01638         TRUE,               /* pc_relative */
01639         0,                  /* bitpos */
01640         complain_overflow_signed, /* complain_on_overflow */
01641         _bfd_mips_elf_generic_reloc,      /* special_function */
01642         "R_MIPS_GNU_REL16_S2",     /* name */
01643         TRUE,               /* partial_inplace */
01644         0x0000ffff,         /* src_mask */
01645         0x0000ffff,         /* dst_mask */
01646         TRUE);                     /* pcrel_offset */
01647 
01648 /* 16 bit offset for pc-relative branches.  */
01649 static reloc_howto_type elf_mips_gnu_rela16_s2 =
01650   HOWTO (R_MIPS_GNU_REL16_S2,      /* type */
01651         2,                  /* rightshift */
01652         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01653         16,                 /* bitsize */
01654         TRUE,               /* pc_relative */
01655         0,                  /* bitpos */
01656         complain_overflow_signed, /* complain_on_overflow */
01657         _bfd_mips_elf_generic_reloc,      /* special_function */
01658         "R_MIPS_GNU_REL16_S2",     /* name */
01659         FALSE,                     /* partial_inplace */
01660         0,                  /* src_mask */
01661         0x0000ffff,         /* dst_mask */
01662         TRUE);                     /* pcrel_offset */
01663 
01664 /* Swap in a MIPS 64-bit Rel reloc.  */
01665 
01666 static void
01667 mips_elf64_swap_reloc_in (bfd *abfd, const Elf64_Mips_External_Rel *src,
01668                        Elf64_Mips_Internal_Rela *dst)
01669 {
01670   dst->r_offset = H_GET_64 (abfd, src->r_offset);
01671   dst->r_sym = H_GET_32 (abfd, src->r_sym);
01672   dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
01673   dst->r_type3 = H_GET_8 (abfd, src->r_type3);
01674   dst->r_type2 = H_GET_8 (abfd, src->r_type2);
01675   dst->r_type = H_GET_8 (abfd, src->r_type);
01676   dst->r_addend = 0;
01677 }
01678 
01679 /* Swap in a MIPS 64-bit Rela reloc.  */
01680 
01681 static void
01682 mips_elf64_swap_reloca_in (bfd *abfd, const Elf64_Mips_External_Rela *src,
01683                         Elf64_Mips_Internal_Rela *dst)
01684 {
01685   dst->r_offset = H_GET_64 (abfd, src->r_offset);
01686   dst->r_sym = H_GET_32 (abfd, src->r_sym);
01687   dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
01688   dst->r_type3 = H_GET_8 (abfd, src->r_type3);
01689   dst->r_type2 = H_GET_8 (abfd, src->r_type2);
01690   dst->r_type = H_GET_8 (abfd, src->r_type);
01691   dst->r_addend = H_GET_S64 (abfd, src->r_addend);
01692 }
01693 
01694 /* Swap out a MIPS 64-bit Rel reloc.  */
01695 
01696 static void
01697 mips_elf64_swap_reloc_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
01698                         Elf64_Mips_External_Rel *dst)
01699 {
01700   H_PUT_64 (abfd, src->r_offset, dst->r_offset);
01701   H_PUT_32 (abfd, src->r_sym, dst->r_sym);
01702   H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
01703   H_PUT_8 (abfd, src->r_type3, dst->r_type3);
01704   H_PUT_8 (abfd, src->r_type2, dst->r_type2);
01705   H_PUT_8 (abfd, src->r_type, dst->r_type);
01706 }
01707 
01708 /* Swap out a MIPS 64-bit Rela reloc.  */
01709 
01710 static void
01711 mips_elf64_swap_reloca_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
01712                          Elf64_Mips_External_Rela *dst)
01713 {
01714   H_PUT_64 (abfd, src->r_offset, dst->r_offset);
01715   H_PUT_32 (abfd, src->r_sym, dst->r_sym);
01716   H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
01717   H_PUT_8 (abfd, src->r_type3, dst->r_type3);
01718   H_PUT_8 (abfd, src->r_type2, dst->r_type2);
01719   H_PUT_8 (abfd, src->r_type, dst->r_type);
01720   H_PUT_S64 (abfd, src->r_addend, dst->r_addend);
01721 }
01722 
01723 /* Swap in a MIPS 64-bit Rel reloc.  */
01724 
01725 static void
01726 mips_elf64_be_swap_reloc_in (bfd *abfd, const bfd_byte *src,
01727                           Elf_Internal_Rela *dst)
01728 {
01729   Elf64_Mips_Internal_Rela mirel;
01730 
01731   mips_elf64_swap_reloc_in (abfd,
01732                          (const Elf64_Mips_External_Rel *) src,
01733                          &mirel);
01734 
01735   dst[0].r_offset = mirel.r_offset;
01736   dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type);
01737   dst[0].r_addend = 0;
01738   dst[1].r_offset = mirel.r_offset;
01739   dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2);
01740   dst[1].r_addend = 0;
01741   dst[2].r_offset = mirel.r_offset;
01742   dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3);
01743   dst[2].r_addend = 0;
01744 }
01745 
01746 /* Swap in a MIPS 64-bit Rela reloc.  */
01747 
01748 static void
01749 mips_elf64_be_swap_reloca_in (bfd *abfd, const bfd_byte *src,
01750                            Elf_Internal_Rela *dst)
01751 {
01752   Elf64_Mips_Internal_Rela mirela;
01753 
01754   mips_elf64_swap_reloca_in (abfd,
01755                           (const Elf64_Mips_External_Rela *) src,
01756                           &mirela);
01757 
01758   dst[0].r_offset = mirela.r_offset;
01759   dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type);
01760   dst[0].r_addend = mirela.r_addend;
01761   dst[1].r_offset = mirela.r_offset;
01762   dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2);
01763   dst[1].r_addend = 0;
01764   dst[2].r_offset = mirela.r_offset;
01765   dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3);
01766   dst[2].r_addend = 0;
01767 }
01768 
01769 /* Swap out a MIPS 64-bit Rel reloc.  */
01770 
01771 static void
01772 mips_elf64_be_swap_reloc_out (bfd *abfd, const Elf_Internal_Rela *src,
01773                            bfd_byte *dst)
01774 {
01775   Elf64_Mips_Internal_Rela mirel;
01776 
01777   mirel.r_offset = src[0].r_offset;
01778   BFD_ASSERT(src[0].r_offset == src[1].r_offset);
01779 
01780   mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
01781   mirel.r_sym = ELF64_R_SYM (src[0].r_info);
01782   mirel.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
01783   mirel.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
01784   mirel.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
01785 
01786   mips_elf64_swap_reloc_out (abfd, &mirel,
01787                           (Elf64_Mips_External_Rel *) dst);
01788 }
01789 
01790 /* Swap out a MIPS 64-bit Rela reloc.  */
01791 
01792 static void
01793 mips_elf64_be_swap_reloca_out (bfd *abfd, const Elf_Internal_Rela *src,
01794                             bfd_byte *dst)
01795 {
01796   Elf64_Mips_Internal_Rela mirela;
01797 
01798   mirela.r_offset = src[0].r_offset;
01799   BFD_ASSERT(src[0].r_offset == src[1].r_offset);
01800   BFD_ASSERT(src[0].r_offset == src[2].r_offset);
01801 
01802   mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
01803   mirela.r_sym = ELF64_R_SYM (src[0].r_info);
01804   mirela.r_addend = src[0].r_addend;
01805   BFD_ASSERT(src[1].r_addend == 0);
01806   BFD_ASSERT(src[2].r_addend == 0);
01807 
01808   mirela.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
01809   mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
01810   mirela.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
01811 
01812   mips_elf64_swap_reloca_out (abfd, &mirela,
01813                            (Elf64_Mips_External_Rela *) dst);
01814 }
01815 
01816 /* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
01817    dangerous relocation.  */
01818 
01819 static bfd_boolean
01820 mips_elf64_assign_gp (bfd *output_bfd, bfd_vma *pgp)
01821 {
01822   unsigned int count;
01823   asymbol **sym;
01824   unsigned int i;
01825 
01826   /* If we've already figured out what GP will be, just return it.  */
01827   *pgp = _bfd_get_gp_value (output_bfd);
01828   if (*pgp)
01829     return TRUE;
01830 
01831   count = bfd_get_symcount (output_bfd);
01832   sym = bfd_get_outsymbols (output_bfd);
01833 
01834   /* The linker script will have created a symbol named `_gp' with the
01835      appropriate value.  */
01836   if (sym == NULL)
01837     i = count;
01838   else
01839     {
01840       for (i = 0; i < count; i++, sym++)
01841        {
01842          register const char *name;
01843 
01844          name = bfd_asymbol_name (*sym);
01845          if (*name == '_' && strcmp (name, "_gp") == 0)
01846            {
01847              *pgp = bfd_asymbol_value (*sym);
01848              _bfd_set_gp_value (output_bfd, *pgp);
01849              break;
01850            }
01851        }
01852     }
01853 
01854   if (i >= count)
01855     {
01856       /* Only get the error once.  */
01857       *pgp = 4;
01858       _bfd_set_gp_value (output_bfd, *pgp);
01859       return FALSE;
01860     }
01861 
01862   return TRUE;
01863 }
01864 
01865 /* We have to figure out the gp value, so that we can adjust the
01866    symbol value correctly.  We look up the symbol _gp in the output
01867    BFD.  If we can't find it, we're stuck.  We cache it in the ELF
01868    target data.  We don't need to adjust the symbol value for an
01869    external symbol if we are producing relocatable output.  */
01870 
01871 static bfd_reloc_status_type
01872 mips_elf64_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
01873                    char **error_message, bfd_vma *pgp)
01874 {
01875   if (bfd_is_und_section (symbol->section)
01876       && ! relocatable)
01877     {
01878       *pgp = 0;
01879       return bfd_reloc_undefined;
01880     }
01881 
01882   *pgp = _bfd_get_gp_value (output_bfd);
01883   if (*pgp == 0
01884       && (! relocatable
01885          || (symbol->flags & BSF_SECTION_SYM) != 0))
01886     {
01887       if (relocatable)
01888        {
01889          /* Make up a value.  */
01890          *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
01891          _bfd_set_gp_value (output_bfd, *pgp);
01892        }
01893       else if (!mips_elf64_assign_gp (output_bfd, pgp))
01894        {
01895          *error_message =
01896            (char *) _("GP relative relocation when _gp not defined");
01897          return bfd_reloc_dangerous;
01898        }
01899     }
01900 
01901   return bfd_reloc_ok;
01902 }
01903 
01904 /* Do a R_MIPS_GPREL16 relocation.  This is a 16 bit value which must
01905    become the offset from the gp register.  */
01906 
01907 static bfd_reloc_status_type
01908 mips_elf64_gprel16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
01909                        void *data, asection *input_section, bfd *output_bfd,
01910                        char **error_message)
01911 {
01912   bfd_boolean relocatable;
01913   bfd_reloc_status_type ret;
01914   bfd_vma gp;
01915 
01916   /* If we're relocating, and this is an external symbol, we don't want
01917      to change anything.  */
01918   if (output_bfd != NULL
01919       && (symbol->flags & BSF_SECTION_SYM) == 0
01920       && (symbol->flags & BSF_LOCAL) != 0)
01921     {
01922       reloc_entry->address += input_section->output_offset;
01923       return bfd_reloc_ok;
01924     }
01925 
01926   if (output_bfd != NULL)
01927     relocatable = TRUE;
01928   else
01929     {
01930       relocatable = FALSE;
01931       output_bfd = symbol->section->output_section->owner;
01932     }
01933 
01934   ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
01935                           &gp);
01936   if (ret != bfd_reloc_ok)
01937     return ret;
01938 
01939   return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
01940                                    input_section, relocatable,
01941                                    data, gp);
01942 }
01943 
01944 /* Do a R_MIPS_LITERAL relocation.  */
01945 
01946 static bfd_reloc_status_type
01947 mips_elf64_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
01948                        void *data, asection *input_section, bfd *output_bfd,
01949                        char **error_message)
01950 {
01951   bfd_boolean relocatable;
01952   bfd_reloc_status_type ret;
01953   bfd_vma gp;
01954 
01955   /* R_MIPS_LITERAL relocations are defined for local symbols only.  */
01956   if (output_bfd != NULL
01957       && (symbol->flags & BSF_SECTION_SYM) == 0
01958       && (symbol->flags & BSF_LOCAL) != 0)
01959     {
01960       *error_message = (char *)
01961        _("literal relocation occurs for an external symbol");
01962       return bfd_reloc_outofrange;
01963     }
01964 
01965   /* FIXME: The entries in the .lit8 and .lit4 sections should be merged.  */
01966   if (output_bfd != NULL)
01967     relocatable = TRUE;
01968   else
01969     {
01970       relocatable = FALSE;
01971       output_bfd = symbol->section->output_section->owner;
01972     }
01973 
01974   ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
01975                           &gp);
01976   if (ret != bfd_reloc_ok)
01977     return ret;
01978 
01979   return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
01980                                    input_section, relocatable,
01981                                    data, gp);
01982 }
01983 
01984 /* Do a R_MIPS_GPREL32 relocation.  This is a 32 bit value which must
01985    become the offset from the gp register.  */
01986 
01987 static bfd_reloc_status_type
01988 mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
01989                        void *data, asection *input_section, bfd *output_bfd,
01990                        char **error_message)
01991 {
01992   bfd_boolean relocatable;
01993   bfd_reloc_status_type ret;
01994   bfd_vma gp;
01995   bfd_vma relocation;
01996   bfd_vma val;
01997 
01998   /* R_MIPS_GPREL32 relocations are defined for local symbols only.  */
01999   if (output_bfd != NULL
02000       && (symbol->flags & BSF_SECTION_SYM) == 0
02001       && (symbol->flags & BSF_LOCAL) != 0)
02002     {
02003       *error_message = (char *)
02004        _("32bits gp relative relocation occurs for an external symbol");
02005       return bfd_reloc_outofrange;
02006     }
02007 
02008   if (output_bfd != NULL)
02009     relocatable = TRUE;
02010   else
02011     {
02012       relocatable = FALSE;
02013       output_bfd = symbol->section->output_section->owner;
02014     }
02015 
02016   ret = mips_elf64_final_gp (output_bfd, symbol, relocatable,
02017                           error_message, &gp);
02018   if (ret != bfd_reloc_ok)
02019     return ret;
02020 
02021   if (bfd_is_com_section (symbol->section))
02022     relocation = 0;
02023   else
02024     relocation = symbol->value;
02025 
02026   relocation += symbol->section->output_section->vma;
02027   relocation += symbol->section->output_offset;
02028 
02029   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
02030     return bfd_reloc_outofrange;
02031 
02032   /* Set val to the offset into the section or symbol.  */
02033   val = reloc_entry->addend;
02034 
02035   if (reloc_entry->howto->partial_inplace)
02036     val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
02037 
02038   /* Adjust val for the final section location and GP value.  If we
02039      are producing relocatable output, we don't want to do this for
02040      an external symbol.  */
02041   if (! relocatable
02042       || (symbol->flags & BSF_SECTION_SYM) != 0)
02043     val += relocation - gp;
02044 
02045   if (reloc_entry->howto->partial_inplace)
02046     bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
02047   else
02048     reloc_entry->addend = val;
02049 
02050   if (relocatable)
02051     reloc_entry->address += input_section->output_offset;
02052 
02053   return bfd_reloc_ok;
02054 }
02055 
02056 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
02057    the rest is at bits 6-10. The bitpos already got right by the howto.  */
02058 
02059 static bfd_reloc_status_type
02060 mips_elf64_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
02061                       void *data, asection *input_section, bfd *output_bfd,
02062                       char **error_message)
02063 {
02064   if (reloc_entry->howto->partial_inplace)
02065     {
02066       reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
02067                           | (reloc_entry->addend & 0x00000800) >> 9);
02068     }
02069 
02070   return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
02071                                   input_section, output_bfd,
02072                                   error_message);
02073 }
02074 
02075 /* Handle a mips16 GP relative reloc.  */
02076 
02077 static bfd_reloc_status_type
02078 mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
02079                   void *data, asection *input_section, bfd *output_bfd,
02080                   char **error_message)
02081 {
02082   bfd_boolean relocatable;
02083   bfd_reloc_status_type ret;
02084   bfd_byte *location;
02085   bfd_vma gp;
02086 
02087   /* If we're relocating, and this is an external symbol, we don't want
02088      to change anything.  */
02089   if (output_bfd != NULL
02090       && (symbol->flags & BSF_SECTION_SYM) == 0
02091       && (symbol->flags & BSF_LOCAL) != 0)
02092     {
02093       reloc_entry->address += input_section->output_offset;
02094       return bfd_reloc_ok;
02095     }
02096 
02097   if (output_bfd != NULL)
02098     relocatable = TRUE;
02099   else
02100     {
02101       relocatable = FALSE;
02102       output_bfd = symbol->section->output_section->owner;
02103     }
02104 
02105   ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
02106                           &gp);
02107   if (ret != bfd_reloc_ok)
02108     return ret;
02109 
02110   location = (bfd_byte *) data + reloc_entry->address;
02111   _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
02112                                location);
02113   ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
02114                                    input_section, relocatable,
02115                                    data, gp);
02116   _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
02117                              location);
02118 
02119   return ret;
02120 }
02121 
02122 /* A mapping from BFD reloc types to MIPS ELF reloc types.  */
02123 
02124 struct elf_reloc_map {
02125   bfd_reloc_code_real_type bfd_val;
02126   enum elf_mips_reloc_type elf_val;
02127 };
02128 
02129 static const struct elf_reloc_map mips_reloc_map[] =
02130 {
02131   { BFD_RELOC_NONE, R_MIPS_NONE },
02132   { BFD_RELOC_16, R_MIPS_16 },
02133   { BFD_RELOC_32, R_MIPS_32 },
02134   /* There is no BFD reloc for R_MIPS_REL32.  */
02135   { BFD_RELOC_64, R_MIPS_64 },
02136   { BFD_RELOC_CTOR, R_MIPS_64 },
02137   { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
02138   { BFD_RELOC_HI16_S, R_MIPS_HI16 },
02139   { BFD_RELOC_LO16, R_MIPS_LO16 },
02140   { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
02141   { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
02142   { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
02143   { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
02144   { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
02145   { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
02146   { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
02147   { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
02148   { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
02149   { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
02150   { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
02151   { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
02152   { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
02153   { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
02154   { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
02155   { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
02156   { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
02157   { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
02158   { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
02159   { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
02160   { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
02161   { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
02162   { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
02163   /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated.  */
02164   { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
02165   { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
02166   { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
02167   { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
02168   { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
02169   { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
02170   { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
02171   { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
02172   { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
02173   { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
02174   { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
02175   { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
02176   { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
02177   { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
02178   { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
02179 };
02180 
02181 static const struct elf_reloc_map mips16_reloc_map[] =
02182 {
02183   { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
02184   { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
02185   { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
02186   { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
02187 };
02188 
02189 /* Given a BFD reloc type, return a howto structure.  */
02190 
02191 static reloc_howto_type *
02192 bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
02193                              bfd_reloc_code_real_type code)
02194 {
02195   unsigned int i;
02196   /* FIXME: We default to RELA here instead of choosing the right
02197      relocation variant.  */
02198   reloc_howto_type *howto_table = mips_elf64_howto_table_rela;
02199   reloc_howto_type *howto16_table = mips16_elf64_howto_table_rela;
02200 
02201   for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
02202        i++)
02203     {
02204       if (mips_reloc_map[i].bfd_val == code)
02205        return &howto_table[(int) mips_reloc_map[i].elf_val];
02206     }
02207 
02208   for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
02209        i++)
02210     {
02211       if (mips16_reloc_map[i].bfd_val == code)
02212        return &howto16_table[(int) mips16_reloc_map[i].elf_val];
02213     }
02214 
02215   switch (code)
02216     {
02217     case BFD_RELOC_VTABLE_INHERIT:
02218       return &elf_mips_gnu_vtinherit_howto;
02219     case BFD_RELOC_VTABLE_ENTRY:
02220       return &elf_mips_gnu_vtentry_howto;
02221     default:
02222       bfd_set_error (bfd_error_bad_value);
02223       return NULL;
02224     }
02225 }
02226 
02227 static reloc_howto_type *
02228 bfd_elf64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
02229                              const char *r_name)
02230 {
02231   unsigned int i;
02232 
02233   for (i = 0;
02234        i < (sizeof (mips_elf64_howto_table_rela)
02235            / sizeof (mips_elf64_howto_table_rela[0])); i++)
02236     if (mips_elf64_howto_table_rela[i].name != NULL
02237        && strcasecmp (mips_elf64_howto_table_rela[i].name, r_name) == 0)
02238       return &mips_elf64_howto_table_rela[i];
02239 
02240   for (i = 0;
02241        i < (sizeof (mips16_elf64_howto_table_rela)
02242            / sizeof (mips16_elf64_howto_table_rela[0]));
02243        i++)
02244     if (mips16_elf64_howto_table_rela[i].name != NULL
02245        && strcasecmp (mips16_elf64_howto_table_rela[i].name, r_name) == 0)
02246       return &mips16_elf64_howto_table_rela[i];
02247 
02248   if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
02249     return &elf_mips_gnu_vtinherit_howto;
02250   if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
02251     return &elf_mips_gnu_vtentry_howto;
02252   if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
02253     return &elf_mips_gnu_rel16_s2;
02254   if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
02255     return &elf_mips_gnu_rela16_s2;
02256 
02257   return NULL;
02258 }
02259 
02260 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
02261 
02262 static reloc_howto_type *
02263 mips_elf64_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
02264 {
02265   switch (r_type)
02266     {
02267     case R_MIPS_GNU_VTINHERIT:
02268       return &elf_mips_gnu_vtinherit_howto;
02269     case R_MIPS_GNU_VTENTRY:
02270       return &elf_mips_gnu_vtentry_howto;
02271     case R_MIPS_GNU_REL16_S2:
02272       if (rela_p)
02273        return &elf_mips_gnu_rela16_s2;
02274       else
02275        return &elf_mips_gnu_rel16_s2;
02276     default:
02277       if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
02278        {
02279          if (rela_p)
02280            return &mips16_elf64_howto_table_rela[r_type - R_MIPS16_min];
02281          else
02282            return &mips16_elf64_howto_table_rel[r_type - R_MIPS16_min];
02283        }
02284       BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
02285       if (rela_p)
02286        return &mips_elf64_howto_table_rela[r_type];
02287       else
02288        return &mips_elf64_howto_table_rel[r_type];
02289       break;
02290     }
02291 }
02292 
02293 /* Prevent relocation handling by bfd for MIPS ELF64.  */
02294 
02295 static void
02296 mips_elf64_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
02297                            arelent *cache_ptr ATTRIBUTE_UNUSED,
02298                            Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
02299 {
02300   BFD_ASSERT (0);
02301 }
02302 
02303 static void
02304 mips_elf64_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
02305                             arelent *cache_ptr ATTRIBUTE_UNUSED,
02306                             Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
02307 {
02308   BFD_ASSERT (0);
02309 }
02310 
02311 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
02312    to three relocs, we must tell the user to allocate more space.  */
02313 
02314 static long
02315 mips_elf64_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
02316 {
02317   return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
02318 }
02319 
02320 static long
02321 mips_elf64_get_dynamic_reloc_upper_bound (bfd *abfd)
02322 {
02323   return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 3;
02324 }
02325 
02326 /* We must also copy more relocations than the corresponding functions
02327    in elf.c would, so the two following functions are slightly
02328    modified from elf.c, that multiply the external relocation count by
02329    3 to obtain the internal relocation count.  */
02330 
02331 static long
02332 mips_elf64_canonicalize_reloc (bfd *abfd, sec_ptr section,
02333                             arelent **relptr, asymbol **symbols)
02334 {
02335   arelent *tblptr;
02336   unsigned int i;
02337   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
02338 
02339   if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
02340     return -1;
02341 
02342   tblptr = section->relocation;
02343   for (i = 0; i < section->reloc_count * 3; i++)
02344     *relptr++ = tblptr++;
02345 
02346   *relptr = NULL;
02347 
02348   return section->reloc_count * 3;
02349 }
02350 
02351 static long
02352 mips_elf64_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
02353                                    asymbol **syms)
02354 {
02355   bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
02356   asection *s;
02357   long ret;
02358 
02359   if (elf_dynsymtab (abfd) == 0)
02360     {
02361       bfd_set_error (bfd_error_invalid_operation);
02362       return -1;
02363     }
02364 
02365   slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
02366   ret = 0;
02367   for (s = abfd->sections; s != NULL; s = s->next)
02368     {
02369       if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
02370          && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
02371              || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
02372        {
02373          arelent *p;
02374          long count, i;
02375 
02376          if (! (*slurp_relocs) (abfd, s, syms, TRUE))
02377            return -1;
02378          count = s->size / elf_section_data (s)->this_hdr.sh_entsize * 3;
02379          p = s->relocation;
02380          for (i = 0; i < count; i++)
02381            *storage++ = p++;
02382          ret += count;
02383        }
02384     }
02385 
02386   *storage = NULL;
02387 
02388   return ret;
02389 }
02390 
02391 /* Read the relocations from one reloc section.  This is mostly copied
02392    from elfcode.h, except for the changes to expand one external
02393    relocation to 3 internal ones.  We must unfortunately set
02394    reloc_count to the number of external relocations, because a lot of
02395    generic code seems to depend on this.  */
02396 
02397 static bfd_boolean
02398 mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect,
02399                               Elf_Internal_Shdr *rel_hdr,
02400                               bfd_size_type reloc_count,
02401                               arelent *relents, asymbol **symbols,
02402                               bfd_boolean dynamic)
02403 {
02404   void *allocated;
02405   bfd_byte *native_relocs;
02406   arelent *relent;
02407   bfd_vma i;
02408   int entsize;
02409   bfd_boolean rela_p;
02410 
02411   allocated = bfd_malloc (rel_hdr->sh_size);
02412   if (allocated == NULL)
02413     return FALSE;
02414 
02415   if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
02416       || (bfd_bread (allocated, rel_hdr->sh_size, abfd)
02417          != rel_hdr->sh_size))
02418     goto error_return;
02419 
02420   native_relocs = allocated;
02421 
02422   entsize = rel_hdr->sh_entsize;
02423   BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
02424              || entsize == sizeof (Elf64_Mips_External_Rela));
02425 
02426   if (entsize == sizeof (Elf64_Mips_External_Rel))
02427     rela_p = FALSE;
02428   else
02429     rela_p = TRUE;
02430 
02431   for (i = 0, relent = relents;
02432        i < reloc_count;
02433        i++, native_relocs += entsize)
02434     {
02435       Elf64_Mips_Internal_Rela rela;
02436       bfd_boolean used_sym, used_ssym;
02437       int ir;
02438 
02439       if (entsize == sizeof (Elf64_Mips_External_Rela))
02440        mips_elf64_swap_reloca_in (abfd,
02441                                (Elf64_Mips_External_Rela *) native_relocs,
02442                                &rela);
02443       else
02444        mips_elf64_swap_reloc_in (abfd,
02445                               (Elf64_Mips_External_Rel *) native_relocs,
02446                               &rela);
02447 
02448       /* Each entry represents exactly three actual relocations.  */
02449 
02450       used_sym = FALSE;
02451       used_ssym = FALSE;
02452       for (ir = 0; ir < 3; ir++)
02453        {
02454          enum elf_mips_reloc_type type;
02455 
02456          switch (ir)
02457            {
02458            default:
02459              abort ();
02460            case 0:
02461              type = (enum elf_mips_reloc_type) rela.r_type;
02462              break;
02463            case 1:
02464              type = (enum elf_mips_reloc_type) rela.r_type2;
02465              break;
02466            case 2:
02467              type = (enum elf_mips_reloc_type) rela.r_type3;
02468              break;
02469            }
02470 
02471          /* Some types require symbols, whereas some do not.  */
02472          switch (type)
02473            {
02474            case R_MIPS_NONE:
02475            case R_MIPS_LITERAL:
02476            case R_MIPS_INSERT_A:
02477            case R_MIPS_INSERT_B:
02478            case R_MIPS_DELETE:
02479              relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
02480              break;
02481 
02482            default:
02483              if (! used_sym)
02484               {
02485                 if (rela.r_sym == 0)
02486                   relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
02487                 else
02488                   {
02489                     asymbol **ps, *s;
02490 
02491                     ps = symbols + rela.r_sym - 1;
02492                     s = *ps;
02493                     if ((s->flags & BSF_SECTION_SYM) == 0)
02494                      relent->sym_ptr_ptr = ps;
02495                     else
02496                      relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
02497                   }
02498 
02499                 used_sym = TRUE;
02500               }
02501              else if (! used_ssym)
02502               {
02503                 switch (rela.r_ssym)
02504                   {
02505                   case RSS_UNDEF:
02506                     relent->sym_ptr_ptr =
02507                      bfd_abs_section_ptr->symbol_ptr_ptr;
02508                     break;
02509 
02510                   case RSS_GP:
02511                   case RSS_GP0:
02512                   case RSS_LOC:
02513                     /* FIXME: I think these need to be handled using
02514                       special howto structures.  */
02515                     BFD_ASSERT (0);
02516                     break;
02517 
02518                   default:
02519                     BFD_ASSERT (0);
02520                     break;
02521                   }
02522 
02523                 used_ssym = TRUE;
02524               }
02525              else
02526               relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
02527 
02528              break;
02529            }
02530 
02531          /* The address of an ELF reloc is section relative for an
02532             object file, and absolute for an executable file or
02533             shared library.  The address of a BFD reloc is always
02534             section relative.  */
02535          if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
02536            relent->address = rela.r_offset;
02537          else
02538            relent->address = rela.r_offset - asect->vma;
02539 
02540          relent->addend = rela.r_addend;
02541 
02542          relent->howto = mips_elf64_rtype_to_howto (type, rela_p);
02543 
02544          ++relent;
02545        }
02546     }
02547 
02548   asect->reloc_count += (relent - relents) / 3;
02549 
02550   if (allocated != NULL)
02551     free (allocated);
02552 
02553   return TRUE;
02554 
02555  error_return:
02556   if (allocated != NULL)
02557     free (allocated);
02558   return FALSE;
02559 }
02560 
02561 /* Read the relocations.  On Irix 6, there can be two reloc sections
02562    associated with a single data section.  This is copied from
02563    elfcode.h as well, with changes as small as accounting for 3
02564    internal relocs per external reloc and resetting reloc_count to
02565    zero before processing the relocs of a section.  */
02566 
02567 static bfd_boolean
02568 mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
02569                            asymbol **symbols, bfd_boolean dynamic)
02570 {
02571   struct bfd_elf_section_data * const d = elf_section_data (asect);
02572   Elf_Internal_Shdr *rel_hdr;
02573   Elf_Internal_Shdr *rel_hdr2;
02574   bfd_size_type reloc_count;
02575   bfd_size_type reloc_count2;
02576   arelent *relents;
02577   bfd_size_type amt;
02578 
02579   if (asect->relocation != NULL)
02580     return TRUE;
02581 
02582   if (! dynamic)
02583     {
02584       if ((asect->flags & SEC_RELOC) == 0
02585          || asect->reloc_count == 0)
02586        return TRUE;
02587 
02588       rel_hdr = &d->rel_hdr;
02589       reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
02590       rel_hdr2 = d->rel_hdr2;
02591       reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
02592 
02593       BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
02594       BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
02595                 || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
02596 
02597     }
02598   else
02599     {
02600       /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
02601         case because relocations against this section may use the
02602         dynamic symbol table, and in that case bfd_section_from_shdr
02603         in elf.c does not update the RELOC_COUNT.  */
02604       if (asect->size == 0)
02605        return TRUE;
02606 
02607       rel_hdr = &d->this_hdr;
02608       reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
02609       rel_hdr2 = NULL;
02610       reloc_count2 = 0;
02611     }
02612 
02613   /* Allocate space for 3 arelent structures for each Rel structure.  */
02614   amt = (reloc_count + reloc_count2) * 3 * sizeof (arelent);
02615   relents = bfd_alloc (abfd, amt);
02616   if (relents == NULL)
02617     return FALSE;
02618 
02619   /* The slurp_one_reloc_table routine increments reloc_count.  */
02620   asect->reloc_count = 0;
02621 
02622   if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
02623                                      rel_hdr, reloc_count,
02624                                      relents,
02625                                      symbols, dynamic))
02626     return FALSE;
02627   if (d->rel_hdr2 != NULL)
02628     {
02629       if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
02630                                          rel_hdr2, reloc_count2,
02631                                          relents + reloc_count * 3,
02632                                          symbols, dynamic))
02633        return FALSE;
02634     }
02635 
02636   asect->relocation = relents;
02637   return TRUE;
02638 }
02639 
02640 /* Write out the relocations.  */
02641 
02642 static void
02643 mips_elf64_write_relocs (bfd *abfd, asection *sec, void *data)
02644 {
02645   bfd_boolean *failedp = data;
02646   int count;
02647   Elf_Internal_Shdr *rel_hdr;
02648   unsigned int idx;
02649 
02650   /* If we have already failed, don't do anything.  */
02651   if (*failedp)
02652     return;
02653 
02654   if ((sec->flags & SEC_RELOC) == 0)
02655     return;
02656 
02657   /* The linker backend writes the relocs out itself, and sets the
02658      reloc_count field to zero to inhibit writing them here.  Also,
02659      sometimes the SEC_RELOC flag gets set even when there aren't any
02660      relocs.  */
02661   if (sec->reloc_count == 0)
02662     return;
02663 
02664   /* We can combine up to three relocs that refer to the same address
02665      if the latter relocs have no associated symbol.  */
02666   count = 0;
02667   for (idx = 0; idx < sec->reloc_count; idx++)
02668     {
02669       bfd_vma addr;
02670       unsigned int i;
02671 
02672       ++count;
02673 
02674       addr = sec->orelocation[idx]->address;
02675       for (i = 0; i < 2; i++)
02676        {
02677          arelent *r;
02678 
02679          if (idx + 1 >= sec->reloc_count)
02680            break;
02681          r = sec->orelocation[idx + 1];
02682          if (r->address != addr
02683              || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
02684              || (*r->sym_ptr_ptr)->value != 0)
02685            break;
02686 
02687          /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */
02688 
02689          ++idx;
02690        }
02691     }
02692 
02693   rel_hdr = &elf_section_data (sec)->rel_hdr;
02694 
02695   /* Do the actual relocation.  */
02696 
02697   if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel))
02698     mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data);
02699   else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela))
02700     mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data);
02701   else
02702     BFD_ASSERT (0);
02703 }
02704 
02705 static void
02706 mips_elf64_write_rel (bfd *abfd, asection *sec,
02707                     Elf_Internal_Shdr *rel_hdr,
02708                     int *count, void *data)
02709 {
02710   bfd_boolean *failedp = data;
02711   Elf64_Mips_External_Rel *ext_rel;
02712   unsigned int idx;
02713   asymbol *last_sym = 0;
02714   int last_sym_idx = 0;
02715 
02716   rel_hdr->sh_size = rel_hdr->sh_entsize * *count;
02717   rel_hdr->contents = bfd_alloc (abfd, rel_hdr->sh_size);
02718   if (rel_hdr->contents == NULL)
02719     {
02720       *failedp = TRUE;
02721       return;
02722     }
02723 
02724   ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents;
02725   for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++)
02726     {
02727       arelent *ptr;
02728       Elf64_Mips_Internal_Rela int_rel;
02729       asymbol *sym;
02730       int n;
02731       unsigned int i;
02732 
02733       ptr = sec->orelocation[idx];
02734 
02735       /* The address of an ELF reloc is section relative for an object
02736         file, and absolute for an executable file or shared library.
02737         The address of a BFD reloc is always section relative.  */
02738       if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
02739        int_rel.r_offset = ptr->address;
02740       else
02741        int_rel.r_offset = ptr->address + sec->vma;
02742 
02743       sym = *ptr->sym_ptr_ptr;
02744       if (sym == last_sym)
02745        n = last_sym_idx;
02746       else if (bfd_is_abs_section (sym->section) && sym->value == 0)
02747        n = STN_UNDEF;
02748       else
02749        {
02750          last_sym = sym;
02751          n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
02752          if (n < 0)
02753            {
02754              *failedp = TRUE;
02755              return;
02756            }
02757          last_sym_idx = n;
02758        }
02759 
02760       int_rel.r_sym = n;
02761       int_rel.r_ssym = RSS_UNDEF;
02762 
02763       if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
02764          && ! _bfd_elf_validate_reloc (abfd, ptr))
02765        {
02766          *failedp = TRUE;
02767          return;
02768        }
02769 
02770       int_rel.r_type = ptr->howto->type;
02771       int_rel.r_type2 = (int) R_MIPS_NONE;
02772       int_rel.r_type3 = (int) R_MIPS_NONE;
02773 
02774       for (i = 0; i < 2; i++)
02775        {
02776          arelent *r;
02777 
02778          if (idx + 1 >= sec->reloc_count)
02779            break;
02780          r = sec->orelocation[idx + 1];
02781          if (r->address != ptr->address
02782              || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
02783              || (*r->sym_ptr_ptr)->value != 0)
02784            break;
02785 
02786          /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */
02787 
02788          if (i == 0)
02789            int_rel.r_type2 = r->howto->type;
02790          else
02791            int_rel.r_type3 = r->howto->type;
02792 
02793          ++idx;
02794        }
02795 
02796       mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel);
02797     }
02798 
02799   BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents
02800              == *count);
02801 }
02802 
02803 static void
02804 mips_elf64_write_rela (bfd *abfd, asection *sec,
02805                      Elf_Internal_Shdr *rela_hdr,
02806                      int *count, void *data)
02807 {
02808   bfd_boolean *failedp = data;
02809   Elf64_Mips_External_Rela *ext_rela;
02810   unsigned int idx;
02811   asymbol *last_sym = 0;
02812   int last_sym_idx = 0;
02813 
02814   rela_hdr->sh_size = rela_hdr->sh_entsize * *count;
02815   rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size);
02816   if (rela_hdr->contents == NULL)
02817     {
02818       *failedp = TRUE;
02819       return;
02820     }
02821 
02822   ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
02823   for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
02824     {
02825       arelent *ptr;
02826       Elf64_Mips_Internal_Rela int_rela;
02827       asymbol *sym;
02828       int n;
02829       unsigned int i;
02830 
02831       ptr = sec->orelocation[idx];
02832 
02833       /* The address of an ELF reloc is section relative for an object
02834         file, and absolute for an executable file or shared library.
02835         The address of a BFD reloc is always section relative.  */
02836       if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
02837        int_rela.r_offset = ptr->address;
02838       else
02839        int_rela.r_offset = ptr->address + sec->vma;
02840 
02841       sym = *ptr->sym_ptr_ptr;
02842       if (sym == last_sym)
02843        n = last_sym_idx;
02844       else if (bfd_is_abs_section (sym->section) && sym->value == 0)
02845        n = STN_UNDEF;
02846       else
02847        {
02848          last_sym = sym;
02849          n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
02850          if (n < 0)
02851            {
02852              *failedp = TRUE;
02853              return;
02854            }
02855          last_sym_idx = n;
02856        }
02857 
02858       int_rela.r_sym = n;
02859       int_rela.r_addend = ptr->addend;
02860       int_rela.r_ssym = RSS_UNDEF;
02861 
02862       if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
02863          && ! _bfd_elf_validate_reloc (abfd, ptr))
02864        {
02865          *failedp = TRUE;
02866          return;
02867        }
02868 
02869       int_rela.r_type = ptr->howto->type;
02870       int_rela.r_type2 = (int) R_MIPS_NONE;
02871       int_rela.r_type3 = (int) R_MIPS_NONE;
02872 
02873       for (i = 0; i < 2; i++)
02874        {
02875          arelent *r;
02876 
02877          if (idx + 1 >= sec->reloc_count)
02878            break;
02879          r = sec->orelocation[idx + 1];
02880          if (r->address != ptr->address
02881              || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
02882              || (*r->sym_ptr_ptr)->value != 0)
02883            break;
02884 
02885          /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */
02886 
02887          if (i == 0)
02888            int_rela.r_type2 = r->howto->type;
02889          else
02890            int_rela.r_type3 = r->howto->type;
02891 
02892          ++idx;
02893        }
02894 
02895       mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
02896     }
02897 
02898   BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
02899              == *count);
02900 }
02901 
02902 /* Set the right machine number for a MIPS ELF file.  */
02903 
02904 static bfd_boolean
02905 mips_elf64_object_p (bfd *abfd)
02906 {
02907   unsigned long mach;
02908 
02909   /* Irix 6 is broken.  Object file symbol tables are not always
02910      sorted correctly such that local symbols precede global symbols,
02911      and the sh_info field in the symbol table is not always right.  */
02912   if (elf64_mips_irix_compat (abfd) != ict_none)
02913     elf_bad_symtab (abfd) = TRUE;
02914 
02915   mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
02916   bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
02917   return TRUE;
02918 }
02919 
02920 /* Depending on the target vector we generate some version of Irix
02921    executables or "normal" MIPS ELF ABI executables.  */
02922 static irix_compat_t
02923 elf64_mips_irix_compat (bfd *abfd)
02924 {
02925   if ((abfd->xvec == &bfd_elf64_bigmips_vec)
02926       || (abfd->xvec == &bfd_elf64_littlemips_vec))
02927     return ict_irix6;
02928   else
02929     return ict_none;
02930 }
02931 
02932 /* Support for core dump NOTE sections.  */
02933 static bfd_boolean
02934 elf64_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
02935 {
02936   int offset;
02937   unsigned int size;
02938 
02939   switch (note->descsz)
02940     {
02941       default:
02942        return FALSE;
02943 
02944       case 480:             /* Linux/MIPS - N64 kernel */
02945        /* pr_cursig */
02946        elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
02947 
02948        /* pr_pid */
02949        elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 32);
02950 
02951        /* pr_reg */
02952        offset = 112;
02953        size = 360;
02954 
02955        break;
02956     }
02957 
02958   /* Make a ".reg/999" section.  */
02959   return _bfd_elfcore_make_pseudosection (abfd, ".reg",
02960                                      size, note->descpos + offset);
02961 }
02962 
02963 static bfd_boolean
02964 elf64_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
02965 {
02966   switch (note->descsz)
02967     {
02968       default:
02969        return FALSE;
02970 
02971       case 136:             /* Linux/MIPS - N64 kernel elf_prpsinfo */
02972        elf_tdata (abfd)->core_program
02973         = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
02974        elf_tdata (abfd)->core_command
02975         = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
02976     }
02977 
02978   /* Note that for some reason, a spurious space is tacked
02979      onto the end of the args in some (at least one anyway)
02980      implementations, so strip it off if it exists.  */
02981 
02982   {
02983     char *command = elf_tdata (abfd)->core_command;
02984     int n = strlen (command);
02985 
02986     if (0 < n && command[n - 1] == ' ')
02987       command[n - 1] = '\0';
02988   }
02989 
02990   return TRUE;
02991 }
02992 
02993 /* ECOFF swapping routines.  These are used when dealing with the
02994    .mdebug section, which is in the ECOFF debugging format.  */
02995 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
02996 {
02997   /* Symbol table magic number.  */
02998   magicSym2,
02999   /* Alignment of debugging information.  E.g., 4.  */
03000   8,
03001   /* Sizes of external symbolic information.  */
03002   sizeof (struct hdr_ext),
03003   sizeof (struct dnr_ext),
03004   sizeof (struct pdr_ext),
03005   sizeof (struct sym_ext),
03006   sizeof (struct opt_ext),
03007   sizeof (struct fdr_ext),
03008   sizeof (struct rfd_ext),
03009   sizeof (struct ext_ext),
03010   /* Functions to swap in external symbolic data.  */
03011   ecoff_swap_hdr_in,
03012   ecoff_swap_dnr_in,
03013   ecoff_swap_pdr_in,
03014   ecoff_swap_sym_in,
03015   ecoff_swap_opt_in,
03016   ecoff_swap_fdr_in,
03017   ecoff_swap_rfd_in,
03018   ecoff_swap_ext_in,
03019   _bfd_ecoff_swap_tir_in,
03020   _bfd_ecoff_swap_rndx_in,
03021   /* Functions to swap out external symbolic data.  */
03022   ecoff_swap_hdr_out,
03023   ecoff_swap_dnr_out,
03024   ecoff_swap_pdr_out,
03025   ecoff_swap_sym_out,
03026   ecoff_swap_opt_out,
03027   ecoff_swap_fdr_out,
03028   ecoff_swap_rfd_out,
03029   ecoff_swap_ext_out,
03030   _bfd_ecoff_swap_tir_out,
03031   _bfd_ecoff_swap_rndx_out,
03032   /* Function to read in symbolic data.  */
03033   _bfd_mips_elf_read_ecoff_info
03034 };
03035 
03036 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
03037    standard ELF.  This structure is used to redirect the relocation
03038    handling routines.  */
03039 
03040 const struct elf_size_info mips_elf64_size_info =
03041 {
03042   sizeof (Elf64_External_Ehdr),
03043   sizeof (Elf64_External_Phdr),
03044   sizeof (Elf64_External_Shdr),
03045   sizeof (Elf64_Mips_External_Rel),
03046   sizeof (Elf64_Mips_External_Rela),
03047   sizeof (Elf64_External_Sym),
03048   sizeof (Elf64_External_Dyn),
03049   sizeof (Elf_External_Note),
03050   4,          /* hash-table entry size */
03051   3,          /* internal relocations per external relocations */
03052   64,         /* arch_size */
03053   3,          /* log_file_align */
03054   ELFCLASS64,
03055   EV_CURRENT,
03056   bfd_elf64_write_out_phdrs,
03057   bfd_elf64_write_shdrs_and_ehdr,
03058   mips_elf64_write_relocs,
03059   bfd_elf64_swap_symbol_in,
03060   bfd_elf64_swap_symbol_out,
03061   mips_elf64_slurp_reloc_table,
03062   bfd_elf64_slurp_symbol_table,
03063   bfd_elf64_swap_dyn_in,
03064   bfd_elf64_swap_dyn_out,
03065   mips_elf64_be_swap_reloc_in,
03066   mips_elf64_be_swap_reloc_out,
03067   mips_elf64_be_swap_reloca_in,
03068   mips_elf64_be_swap_reloca_out
03069 };
03070 
03071 #define ELF_ARCH                   bfd_arch_mips
03072 #define ELF_MACHINE_CODE           EM_MIPS
03073 
03074 #define elf_backend_collect        TRUE
03075 #define elf_backend_type_change_ok TRUE
03076 #define elf_backend_can_gc_sections       TRUE
03077 #define elf_info_to_howto          mips_elf64_info_to_howto_rela
03078 #define elf_info_to_howto_rel             mips_elf64_info_to_howto_rel
03079 #define elf_backend_object_p              mips_elf64_object_p
03080 #define elf_backend_symbol_processing     _bfd_mips_elf_symbol_processing
03081 #define elf_backend_section_processing    _bfd_mips_elf_section_processing
03082 #define elf_backend_section_from_shdr     _bfd_mips_elf_section_from_shdr
03083 #define elf_backend_fake_sections  _bfd_mips_elf_fake_sections
03084 #define elf_backend_section_from_bfd_section \
03085                             _bfd_mips_elf_section_from_bfd_section
03086 #define elf_backend_add_symbol_hook       _bfd_mips_elf_add_symbol_hook
03087 #define elf_backend_link_output_symbol_hook \
03088                             _bfd_mips_elf_link_output_symbol_hook
03089 #define elf_backend_create_dynamic_sections \
03090                             _bfd_mips_elf_create_dynamic_sections
03091 #define elf_backend_check_relocs   _bfd_mips_elf_check_relocs
03092 #define elf_backend_merge_symbol_attribute \
03093                             _bfd_mips_elf_merge_symbol_attribute
03094 #define elf_backend_adjust_dynamic_symbol \
03095                             _bfd_mips_elf_adjust_dynamic_symbol
03096 #define elf_backend_always_size_sections \
03097                             _bfd_mips_elf_always_size_sections
03098 #define elf_backend_size_dynamic_sections \
03099                             _bfd_mips_elf_size_dynamic_sections
03100 #define elf_backend_init_index_section    _bfd_elf_init_1_index_section
03101 #define elf_backend_relocate_section    _bfd_mips_elf_relocate_section
03102 #define elf_backend_finish_dynamic_symbol \
03103                             _bfd_mips_elf_finish_dynamic_symbol
03104 #define elf_backend_finish_dynamic_sections \
03105                             _bfd_mips_elf_finish_dynamic_sections
03106 #define elf_backend_final_write_processing \
03107                             _bfd_mips_elf_final_write_processing
03108 #define elf_backend_additional_program_headers \
03109                             _bfd_mips_elf_additional_program_headers
03110 #define elf_backend_modify_segment_map    _bfd_mips_elf_modify_segment_map
03111 #define elf_backend_gc_mark_hook   _bfd_mips_elf_gc_mark_hook
03112 #define elf_backend_gc_sweep_hook  _bfd_mips_elf_gc_sweep_hook
03113 #define elf_backend_copy_indirect_symbol \
03114                                    _bfd_mips_elf_copy_indirect_symbol
03115 #define elf_backend_hide_symbol           _bfd_mips_elf_hide_symbol
03116 #define elf_backend_ignore_discarded_relocs \
03117                                    _bfd_mips_elf_ignore_discarded_relocs
03118 #define elf_backend_mips_irix_compat      elf64_mips_irix_compat
03119 #define elf_backend_mips_rtype_to_howto   mips_elf64_rtype_to_howto
03120 #define elf_backend_ecoff_debug_swap      &mips_elf64_ecoff_debug_swap
03121 #define elf_backend_size_info             mips_elf64_size_info
03122 
03123 #define elf_backend_grok_prstatus  elf64_mips_grok_prstatus
03124 #define elf_backend_grok_psinfo           elf64_mips_grok_psinfo
03125 
03126 #define elf_backend_got_header_size       (4 * MIPS_RESERVED_GOTNO)
03127 
03128 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
03129    work better/work only in RELA, so we default to this.  */
03130 #define elf_backend_may_use_rel_p  1
03131 #define elf_backend_may_use_rela_p 1
03132 #define elf_backend_default_use_rela_p    1
03133 
03134 #define elf_backend_write_section  _bfd_mips_elf_write_section
03135 
03136 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
03137    MIPS-specific function only applies to IRIX5, which had no 64-bit
03138    ABI.  */
03139 #define bfd_elf64_find_nearest_line       _bfd_mips_elf_find_nearest_line
03140 #define bfd_elf64_find_inliner_info       _bfd_mips_elf_find_inliner_info
03141 #define bfd_elf64_new_section_hook _bfd_mips_elf_new_section_hook
03142 #define bfd_elf64_set_section_contents    _bfd_mips_elf_set_section_contents
03143 #define bfd_elf64_bfd_get_relocated_section_contents \
03144                             _bfd_elf_mips_get_relocated_section_contents
03145 #define bfd_elf64_bfd_link_hash_table_create \
03146                             _bfd_mips_elf_link_hash_table_create
03147 #define bfd_elf64_bfd_final_link   _bfd_mips_elf_final_link
03148 #define bfd_elf64_bfd_merge_private_bfd_data \
03149                             _bfd_mips_elf_merge_private_bfd_data
03150 #define bfd_elf64_bfd_set_private_flags   _bfd_mips_elf_set_private_flags
03151 #define bfd_elf64_bfd_print_private_bfd_data \
03152                             _bfd_mips_elf_print_private_bfd_data
03153 
03154 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
03155 #define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc
03156 #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
03157 #define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc
03158 #define bfd_elf64_bfd_relax_section     _bfd_mips_relax_section
03159 
03160 /* MIPS ELF64 archive functions.  */
03161 #define bfd_elf64_archive_functions
03162 extern bfd_boolean bfd_elf64_archive_slurp_armap
03163   (bfd *);
03164 extern bfd_boolean bfd_elf64_archive_write_armap
03165   (bfd *, unsigned int, struct orl *, unsigned int, int);
03166 #define bfd_elf64_archive_slurp_extended_name_table \
03167                      _bfd_archive_coff_slurp_extended_name_table
03168 #define bfd_elf64_archive_construct_extended_name_table \
03169                      _bfd_archive_coff_construct_extended_name_table
03170 #define bfd_elf64_archive_truncate_arname \
03171                      _bfd_archive_coff_truncate_arname
03172 #define bfd_elf64_archive_read_ar_hdr     _bfd_archive_coff_read_ar_hdr
03173 #define bfd_elf64_archive_openr_next_archived_file \
03174                      _bfd_archive_coff_openr_next_archived_file
03175 #define bfd_elf64_archive_get_elt_at_index \
03176                      _bfd_archive_coff_get_elt_at_index
03177 #define bfd_elf64_archive_generic_stat_arch_elt \
03178                      _bfd_archive_coff_generic_stat_arch_elt
03179 #define bfd_elf64_archive_update_armap_timestamp \
03180                      _bfd_archive_coff_update_armap_timestamp
03181 
03182 /* The SGI style (n)64 NewABI.  */
03183 #define TARGET_LITTLE_SYM          bfd_elf64_littlemips_vec
03184 #define TARGET_LITTLE_NAME         "elf64-littlemips"
03185 #define TARGET_BIG_SYM                    bfd_elf64_bigmips_vec
03186 #define TARGET_BIG_NAME                   "elf64-bigmips"
03187 
03188 #define ELF_MAXPAGESIZE                   0x10000
03189 #define ELF_COMMONPAGESIZE         0x1000
03190 
03191 #include "elf64-target.h"
03192 
03193 /* The SYSV-style 'traditional' (n)64 NewABI.  */
03194 #undef TARGET_LITTLE_SYM
03195 #undef TARGET_LITTLE_NAME
03196 #undef TARGET_BIG_SYM
03197 #undef TARGET_BIG_NAME
03198 
03199 #undef ELF_MAXPAGESIZE
03200 #undef ELF_COMMONPAGESIZE
03201 
03202 #define TARGET_LITTLE_SYM          bfd_elf64_tradlittlemips_vec
03203 #define TARGET_LITTLE_NAME         "elf64-tradlittlemips"
03204 #define TARGET_BIG_SYM                    bfd_elf64_tradbigmips_vec
03205 #define TARGET_BIG_NAME                   "elf64-tradbigmips"
03206 
03207 #define ELF_MAXPAGESIZE                   0x10000
03208 #define ELF_COMMONPAGESIZE         0x1000
03209 #define elf64_bed                  elf64_tradbed
03210 
03211 /* Include the target file again for this target.  */
03212 #include "elf64-target.h"