Back to index

cell-binutils  2.17cvs20070401
elfn32-mips.c
Go to the documentation of this file.
00001 /* MIPS-specific support for 32-bit ELF
00002    Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
00003    2003, 2004, 2005, 2007 Free Software Foundation, Inc.
00004 
00005    Most of the information added by Ian Lance Taylor, Cygnus Support,
00006    <ian@cygnus.com>.
00007    N32/64 ABI support added by Mark Mitchell, CodeSourcery, LLC.
00008    <mark@codesourcery.com>
00009    Traditional MIPS targets support added by Koundinya.K, Dansk Data
00010    Elektronik & Operations Research Group. <kk@ddeorg.soft.net>
00011 
00012 This file is part of BFD, the Binary File Descriptor library.
00013 
00014 This program is free software; you can redistribute it and/or modify
00015 it under the terms of the GNU General Public License as published by
00016 the Free Software Foundation; either version 2 of the License, or
00017 (at your option) any later version.
00018 
00019 This program is distributed in the hope that it will be useful,
00020 but WITHOUT ANY WARRANTY; without even the implied warranty of
00021 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022 GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License
00025 along with this program; if not, write to the Free Software
00026 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00027 
00028 /* This file handles MIPS ELF targets.  SGI Irix 5 uses a slightly
00029    different MIPS ELF from other targets.  This matters when linking.
00030    This file supports both, switching at runtime.  */
00031 
00032 #include "bfd.h"
00033 #include "sysdep.h"
00034 #include "libbfd.h"
00035 #include "bfdlink.h"
00036 #include "genlink.h"
00037 #include "elf-bfd.h"
00038 #include "elfxx-mips.h"
00039 #include "elf/mips.h"
00040 
00041 /* Get the ECOFF swapping routines.  */
00042 #include "coff/sym.h"
00043 #include "coff/symconst.h"
00044 #include "coff/internal.h"
00045 #include "coff/ecoff.h"
00046 #include "coff/mips.h"
00047 #define ECOFF_SIGNED_32
00048 #include "ecoffswap.h"
00049 
00050 static bfd_boolean mips_elf_assign_gp
00051   (bfd *, bfd_vma *);
00052 static bfd_reloc_status_type mips_elf_final_gp
00053   (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *);
00054 static bfd_reloc_status_type mips_elf_gprel16_reloc
00055   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00056 static bfd_reloc_status_type mips_elf_literal_reloc
00057   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00058 static bfd_reloc_status_type mips_elf_gprel32_reloc
00059   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00060 static bfd_reloc_status_type gprel32_with_gp
00061   (bfd *, asymbol *, arelent *, asection *, bfd_boolean, void *, bfd_vma);
00062 static bfd_reloc_status_type mips_elf_shift6_reloc
00063   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00064 static bfd_reloc_status_type mips16_gprel_reloc
00065   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00066 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
00067   (bfd *, bfd_reloc_code_real_type);
00068 static reloc_howto_type *mips_elf_n32_rtype_to_howto
00069   (unsigned int, bfd_boolean);
00070 static void mips_info_to_howto_rel
00071   (bfd *, arelent *, Elf_Internal_Rela *);
00072 static void mips_info_to_howto_rela
00073   (bfd *, arelent *, Elf_Internal_Rela *);
00074 static bfd_boolean mips_elf_sym_is_global
00075   (bfd *, asymbol *);
00076 static bfd_boolean mips_elf_n32_object_p
00077   (bfd *);
00078 static bfd_boolean elf32_mips_grok_prstatus
00079   (bfd *, Elf_Internal_Note *);
00080 static bfd_boolean elf32_mips_grok_psinfo
00081   (bfd *, Elf_Internal_Note *);
00082 static irix_compat_t elf_n32_mips_irix_compat
00083   (bfd *);
00084 
00085 extern const bfd_target bfd_elf32_nbigmips_vec;
00086 extern const bfd_target bfd_elf32_nlittlemips_vec;
00087 
00088 /* Nonzero if ABFD is using the N32 ABI.  */
00089 #define ABI_N32_P(abfd) \
00090   ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0)
00091 
00092 /* Whether we are trying to be compatible with IRIX at all.  */
00093 #define SGI_COMPAT(abfd) \
00094   (elf_n32_mips_irix_compat (abfd) != ict_none)
00095 
00096 /* The number of local .got entries we reserve.  */
00097 #define MIPS_RESERVED_GOTNO (2)
00098 
00099 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
00100    from smaller values.  Start with zero, widen, *then* decrement.  */
00101 #define MINUS_ONE    (((bfd_vma)0) - 1)
00102 
00103 /* The relocation table used for SHT_REL sections.  */
00104 
00105 static reloc_howto_type elf_mips_howto_table_rel[] =
00106 {
00107   /* No relocation.  */
00108   HOWTO (R_MIPS_NONE,              /* type */
00109         0,                  /* rightshift */
00110         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00111         0,                  /* bitsize */
00112         FALSE,                     /* pc_relative */
00113         0,                  /* bitpos */
00114         complain_overflow_dont, /* complain_on_overflow */
00115         _bfd_mips_elf_generic_reloc, /* special_function */
00116         "R_MIPS_NONE",             /* name */
00117         FALSE,                     /* partial_inplace */
00118         0,                  /* src_mask */
00119         0,                  /* dst_mask */
00120         FALSE),             /* pcrel_offset */
00121 
00122   /* 16 bit relocation.  */
00123   HOWTO (R_MIPS_16,         /* type */
00124         0,                  /* rightshift */
00125         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00126         16,                 /* bitsize */
00127         FALSE,                     /* pc_relative */
00128         0,                  /* bitpos */
00129         complain_overflow_signed, /* complain_on_overflow */
00130         _bfd_mips_elf_generic_reloc, /* special_function */
00131         "R_MIPS_16",        /* name */
00132         TRUE,               /* partial_inplace */
00133         0x0000ffff,         /* src_mask */
00134         0x0000ffff,         /* dst_mask */
00135         FALSE),             /* pcrel_offset */
00136 
00137   /* 32 bit relocation.  */
00138   HOWTO (R_MIPS_32,         /* type */
00139         0,                  /* rightshift */
00140         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00141         32,                 /* bitsize */
00142         FALSE,                     /* pc_relative */
00143         0,                  /* bitpos */
00144         complain_overflow_dont, /* complain_on_overflow */
00145         _bfd_mips_elf_generic_reloc, /* special_function */
00146         "R_MIPS_32",        /* name */
00147         TRUE,               /* partial_inplace */
00148         0xffffffff,         /* src_mask */
00149         0xffffffff,         /* dst_mask */
00150         FALSE),             /* pcrel_offset */
00151 
00152   /* 32 bit symbol relative relocation.  */
00153   HOWTO (R_MIPS_REL32,             /* type */
00154         0,                  /* rightshift */
00155         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00156         32,                 /* bitsize */
00157         FALSE,                     /* pc_relative */
00158         0,                  /* bitpos */
00159         complain_overflow_dont, /* complain_on_overflow */
00160         _bfd_mips_elf_generic_reloc, /* special_function */
00161         "R_MIPS_REL32",     /* name */
00162         TRUE,               /* partial_inplace */
00163         0xffffffff,         /* src_mask */
00164         0xffffffff,         /* dst_mask */
00165         FALSE),             /* pcrel_offset */
00166 
00167   /* 26 bit jump address.  */
00168   HOWTO (R_MIPS_26,         /* type */
00169         2,                  /* rightshift */
00170         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00171         26,                 /* bitsize */
00172         FALSE,                     /* pc_relative */
00173         0,                  /* bitpos */
00174         complain_overflow_dont, /* complain_on_overflow */
00175                             /* This needs complex overflow
00176                                detection, because the upper four
00177                                bits must match the PC + 4.  */
00178         _bfd_mips_elf_generic_reloc, /* special_function */
00179         "R_MIPS_26",        /* name */
00180         TRUE,               /* partial_inplace */
00181         0x03ffffff,         /* src_mask */
00182         0x03ffffff,         /* dst_mask */
00183         FALSE),             /* pcrel_offset */
00184 
00185   /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
00186      However, the native IRIX6 tools use them, so we try our best. */
00187 
00188   /* High 16 bits of symbol value.  */
00189   HOWTO (R_MIPS_HI16,              /* type */
00190         16,                 /* rightshift */
00191         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00192         16,                 /* bitsize */
00193         FALSE,                     /* pc_relative */
00194         0,                  /* bitpos */
00195         complain_overflow_dont, /* complain_on_overflow */
00196         _bfd_mips_elf_hi16_reloc, /* special_function */
00197         "R_MIPS_HI16",             /* name */
00198         TRUE,               /* partial_inplace */
00199         0x0000ffff,         /* src_mask */
00200         0x0000ffff,         /* dst_mask */
00201         FALSE),             /* pcrel_offset */
00202 
00203   /* Low 16 bits of symbol value.  */
00204   HOWTO (R_MIPS_LO16,              /* type */
00205         0,                  /* rightshift */
00206         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00207         16,                 /* bitsize */
00208         FALSE,                     /* pc_relative */
00209         0,                  /* bitpos */
00210         complain_overflow_dont, /* complain_on_overflow */
00211         _bfd_mips_elf_lo16_reloc, /* special_function */
00212         "R_MIPS_LO16",             /* name */
00213         TRUE,               /* partial_inplace */
00214         0x0000ffff,         /* src_mask */
00215         0x0000ffff,         /* dst_mask */
00216         FALSE),             /* pcrel_offset */
00217 
00218   /* GP relative reference.  */
00219   HOWTO (R_MIPS_GPREL16,    /* type */
00220         0,                  /* rightshift */
00221         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00222         16,                 /* bitsize */
00223         FALSE,                     /* pc_relative */
00224         0,                  /* bitpos */
00225         complain_overflow_signed, /* complain_on_overflow */
00226         mips_elf_gprel16_reloc, /* special_function */
00227         "R_MIPS_GPREL16",   /* name */
00228         TRUE,               /* partial_inplace */
00229         0x0000ffff,         /* src_mask */
00230         0x0000ffff,         /* dst_mask */
00231         FALSE),             /* pcrel_offset */
00232 
00233   /* Reference to literal section.  */
00234   HOWTO (R_MIPS_LITERAL,    /* type */
00235         0,                  /* rightshift */
00236         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00237         16,                 /* bitsize */
00238         FALSE,                     /* pc_relative */
00239         0,                  /* bitpos */
00240         complain_overflow_signed, /* complain_on_overflow */
00241         mips_elf_literal_reloc, /* special_function */
00242         "R_MIPS_LITERAL",   /* name */
00243         TRUE,               /* partial_inplace */
00244         0x0000ffff,         /* src_mask */
00245         0x0000ffff,         /* dst_mask */
00246         FALSE),             /* pcrel_offset */
00247 
00248   /* Reference to global offset table.  */
00249   HOWTO (R_MIPS_GOT16,             /* type */
00250         0,                  /* rightshift */
00251         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00252         16,                 /* bitsize */
00253         FALSE,                     /* pc_relative */
00254         0,                  /* bitpos */
00255         complain_overflow_signed, /* complain_on_overflow */
00256         _bfd_mips_elf_got16_reloc, /* special_function */
00257         "R_MIPS_GOT16",     /* name */
00258         TRUE,               /* partial_inplace */
00259         0x0000ffff,         /* src_mask */
00260         0x0000ffff,         /* dst_mask */
00261         FALSE),             /* pcrel_offset */
00262 
00263   /* 16 bit PC relative reference.  Note that the ABI document has a typo
00264      and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
00265      We do the right thing here.  */
00266   HOWTO (R_MIPS_PC16,              /* type */
00267         2,                  /* rightshift */
00268         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00269         16,                 /* bitsize */
00270         TRUE,               /* pc_relative */
00271         0,                  /* bitpos */
00272         complain_overflow_signed, /* complain_on_overflow */
00273         _bfd_mips_elf_generic_reloc, /* special_function */
00274         "R_MIPS_PC16",             /* name */
00275         TRUE,               /* partial_inplace */
00276         0x0000ffff,         /* src_mask */
00277         0x0000ffff,         /* dst_mask */
00278         TRUE),                     /* pcrel_offset */
00279 
00280   /* 16 bit call through global offset table.  */
00281   HOWTO (R_MIPS_CALL16,            /* type */
00282         0,                  /* rightshift */
00283         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00284         16,                 /* bitsize */
00285         FALSE,                     /* pc_relative */
00286         0,                  /* bitpos */
00287         complain_overflow_signed, /* complain_on_overflow */
00288         _bfd_mips_elf_generic_reloc, /* special_function */
00289         "R_MIPS_CALL16",    /* name */
00290         TRUE,               /* partial_inplace */
00291         0x0000ffff,         /* src_mask */
00292         0x0000ffff,         /* dst_mask */
00293         FALSE),             /* pcrel_offset */
00294 
00295   /* 32 bit GP relative reference.  */
00296   HOWTO (R_MIPS_GPREL32,    /* type */
00297         0,                  /* rightshift */
00298         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00299         32,                 /* bitsize */
00300         FALSE,                     /* pc_relative */
00301         0,                  /* bitpos */
00302         complain_overflow_dont, /* complain_on_overflow */
00303         mips_elf_gprel32_reloc, /* special_function */
00304         "R_MIPS_GPREL32",   /* name */
00305         TRUE,               /* partial_inplace */
00306         0xffffffff,         /* src_mask */
00307         0xffffffff,         /* dst_mask */
00308         FALSE),             /* pcrel_offset */
00309 
00310   /* The remaining relocs are defined on Irix 5, although they are
00311      not defined by the ABI.  */
00312   EMPTY_HOWTO (13),
00313   EMPTY_HOWTO (14),
00314   EMPTY_HOWTO (15),
00315 
00316   /* A 5 bit shift field.  */
00317   HOWTO (R_MIPS_SHIFT5,            /* type */
00318         0,                  /* rightshift */
00319         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00320         5,                  /* bitsize */
00321         FALSE,                     /* pc_relative */
00322         6,                  /* bitpos */
00323         complain_overflow_bitfield, /* complain_on_overflow */
00324         _bfd_mips_elf_generic_reloc, /* special_function */
00325         "R_MIPS_SHIFT5",    /* name */
00326         TRUE,               /* partial_inplace */
00327         0x000007c0,         /* src_mask */
00328         0x000007c0,         /* dst_mask */
00329         FALSE),             /* pcrel_offset */
00330 
00331   /* A 6 bit shift field.  */
00332   HOWTO (R_MIPS_SHIFT6,            /* type */
00333         0,                  /* rightshift */
00334         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00335         6,                  /* bitsize */
00336         FALSE,                     /* pc_relative */
00337         6,                  /* bitpos */
00338         complain_overflow_bitfield, /* complain_on_overflow */
00339         mips_elf_shift6_reloc,     /* special_function */
00340         "R_MIPS_SHIFT6",    /* name */
00341         TRUE,               /* partial_inplace */
00342         0x000007c4,         /* src_mask */
00343         0x000007c4,         /* dst_mask */
00344         FALSE),             /* pcrel_offset */
00345 
00346   /* A 64 bit relocation.  */
00347   HOWTO (R_MIPS_64,         /* type */
00348         0,                  /* rightshift */
00349         4,                  /* size (0 = byte, 1 = short, 2 = long) */
00350         64,                 /* bitsize */
00351         FALSE,                     /* pc_relative */
00352         0,                  /* bitpos */
00353         complain_overflow_dont, /* complain_on_overflow */
00354         _bfd_mips_elf_generic_reloc, /* special_function */
00355         "R_MIPS_64",        /* name */
00356         TRUE,               /* partial_inplace */
00357         MINUS_ONE,          /* src_mask */
00358         MINUS_ONE,          /* dst_mask */
00359         FALSE),             /* pcrel_offset */
00360 
00361   /* Displacement in the global offset table.  */
00362   HOWTO (R_MIPS_GOT_DISP,   /* type */
00363         0,                  /* rightshift */
00364         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00365         16,                 /* bitsize */
00366         FALSE,                     /* pc_relative */
00367         0,                  /* bitpos */
00368         complain_overflow_signed, /* complain_on_overflow */
00369         _bfd_mips_elf_generic_reloc, /* special_function */
00370         "R_MIPS_GOT_DISP",  /* name */
00371         TRUE,               /* partial_inplace */
00372         0x0000ffff,         /* src_mask */
00373         0x0000ffff,         /* dst_mask */
00374         FALSE),             /* pcrel_offset */
00375 
00376   /* Displacement to page pointer in the global offset table.  */
00377   HOWTO (R_MIPS_GOT_PAGE,   /* type */
00378         0,                  /* rightshift */
00379         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00380         16,                 /* bitsize */
00381         FALSE,                     /* pc_relative */
00382         0,                  /* bitpos */
00383         complain_overflow_signed, /* complain_on_overflow */
00384         _bfd_mips_elf_generic_reloc, /* special_function */
00385         "R_MIPS_GOT_PAGE",  /* name */
00386         TRUE,               /* partial_inplace */
00387         0x0000ffff,         /* src_mask */
00388         0x0000ffff,         /* dst_mask */
00389         FALSE),             /* pcrel_offset */
00390 
00391   /* Offset from page pointer in the global offset table.  */
00392   HOWTO (R_MIPS_GOT_OFST,   /* type */
00393         0,                  /* rightshift */
00394         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00395         16,                 /* bitsize */
00396         FALSE,                     /* pc_relative */
00397         0,                  /* bitpos */
00398         complain_overflow_signed, /* complain_on_overflow */
00399         _bfd_mips_elf_generic_reloc, /* special_function */
00400         "R_MIPS_GOT_OFST",  /* name */
00401         TRUE,               /* partial_inplace */
00402         0x0000ffff,         /* src_mask */
00403         0x0000ffff,         /* dst_mask */
00404         FALSE),             /* pcrel_offset */
00405 
00406   /* High 16 bits of displacement in global offset table.  */
00407   HOWTO (R_MIPS_GOT_HI16,   /* type */
00408         0,                  /* rightshift */
00409         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00410         16,                 /* bitsize */
00411         FALSE,                     /* pc_relative */
00412         0,                  /* bitpos */
00413         complain_overflow_dont, /* complain_on_overflow */
00414         _bfd_mips_elf_generic_reloc, /* special_function */
00415         "R_MIPS_GOT_HI16",  /* name */
00416         TRUE,               /* partial_inplace */
00417         0x0000ffff,         /* src_mask */
00418         0x0000ffff,         /* dst_mask */
00419         FALSE),             /* pcrel_offset */
00420 
00421   /* Low 16 bits of displacement in global offset table.  */
00422   HOWTO (R_MIPS_GOT_LO16,   /* type */
00423         0,                  /* rightshift */
00424         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00425         16,                 /* bitsize */
00426         FALSE,                     /* pc_relative */
00427         0,                  /* bitpos */
00428         complain_overflow_dont, /* complain_on_overflow */
00429         _bfd_mips_elf_generic_reloc, /* special_function */
00430         "R_MIPS_GOT_LO16",  /* name */
00431         TRUE,               /* partial_inplace */
00432         0x0000ffff,         /* src_mask */
00433         0x0000ffff,         /* dst_mask */
00434         FALSE),             /* pcrel_offset */
00435 
00436   /* 64 bit subtraction.  */
00437   HOWTO (R_MIPS_SUB,        /* type */
00438         0,                  /* rightshift */
00439         4,                  /* size (0 = byte, 1 = short, 2 = long) */
00440         64,                 /* bitsize */
00441         FALSE,                     /* pc_relative */
00442         0,                  /* bitpos */
00443         complain_overflow_dont, /* complain_on_overflow */
00444         _bfd_mips_elf_generic_reloc, /* special_function */
00445         "R_MIPS_SUB",              /* name */
00446         TRUE,               /* partial_inplace */
00447         MINUS_ONE,          /* src_mask */
00448         MINUS_ONE,          /* dst_mask */
00449         FALSE),             /* pcrel_offset */
00450 
00451   /* Insert the addend as an instruction.  */
00452   /* FIXME: Not handled correctly.  */
00453   HOWTO (R_MIPS_INSERT_A,   /* type */
00454         0,                  /* rightshift */
00455         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00456         32,                 /* bitsize */
00457         FALSE,                     /* pc_relative */
00458         0,                  /* bitpos */
00459         complain_overflow_dont, /* complain_on_overflow */
00460         _bfd_mips_elf_generic_reloc, /* special_function */
00461         "R_MIPS_INSERT_A",  /* name */
00462         TRUE,               /* partial_inplace */
00463         0xffffffff,         /* src_mask */
00464         0xffffffff,         /* dst_mask */
00465         FALSE),             /* pcrel_offset */
00466 
00467   /* Insert the addend as an instruction, and change all relocations
00468      to refer to the old instruction at the address.  */
00469   /* FIXME: Not handled correctly.  */
00470   HOWTO (R_MIPS_INSERT_B,   /* type */
00471         0,                  /* rightshift */
00472         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00473         32,                 /* bitsize */
00474         FALSE,                     /* pc_relative */
00475         0,                  /* bitpos */
00476         complain_overflow_dont, /* complain_on_overflow */
00477         _bfd_mips_elf_generic_reloc, /* special_function */
00478         "R_MIPS_INSERT_B",  /* name */
00479         TRUE,               /* partial_inplace */
00480         0xffffffff,         /* src_mask */
00481         0xffffffff,         /* dst_mask */
00482         FALSE),             /* pcrel_offset */
00483 
00484   /* Delete a 32 bit instruction.  */
00485   /* FIXME: Not handled correctly.  */
00486   HOWTO (R_MIPS_DELETE,            /* type */
00487         0,                  /* rightshift */
00488         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00489         32,                 /* bitsize */
00490         FALSE,                     /* pc_relative */
00491         0,                  /* bitpos */
00492         complain_overflow_dont, /* complain_on_overflow */
00493         _bfd_mips_elf_generic_reloc, /* special_function */
00494         "R_MIPS_DELETE",    /* name */
00495         TRUE,               /* partial_inplace */
00496         0xffffffff,         /* src_mask */
00497         0xffffffff,         /* dst_mask */
00498         FALSE),             /* pcrel_offset */
00499 
00500   /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
00501      We don't, because
00502        a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
00503          R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
00504          fallable heuristics.
00505        b) No other NewABI toolchain actually emits such relocations.  */
00506   EMPTY_HOWTO (R_MIPS_HIGHER),
00507   EMPTY_HOWTO (R_MIPS_HIGHEST),
00508 
00509   /* High 16 bits of displacement in global offset table.  */
00510   HOWTO (R_MIPS_CALL_HI16,  /* type */
00511         0,                  /* rightshift */
00512         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00513         16,                 /* bitsize */
00514         FALSE,                     /* pc_relative */
00515         0,                  /* bitpos */
00516         complain_overflow_dont, /* complain_on_overflow */
00517         _bfd_mips_elf_generic_reloc, /* special_function */
00518         "R_MIPS_CALL_HI16", /* name */
00519         TRUE,               /* partial_inplace */
00520         0x0000ffff,         /* src_mask */
00521         0x0000ffff,         /* dst_mask */
00522         FALSE),             /* pcrel_offset */
00523 
00524   /* Low 16 bits of displacement in global offset table.  */
00525   HOWTO (R_MIPS_CALL_LO16,  /* type */
00526         0,                  /* rightshift */
00527         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00528         16,                 /* bitsize */
00529         FALSE,                     /* pc_relative */
00530         0,                  /* bitpos */
00531         complain_overflow_dont, /* complain_on_overflow */
00532         _bfd_mips_elf_generic_reloc, /* special_function */
00533         "R_MIPS_CALL_LO16", /* name */
00534         TRUE,               /* partial_inplace */
00535         0x0000ffff,         /* src_mask */
00536         0x0000ffff,         /* dst_mask */
00537         FALSE),             /* pcrel_offset */
00538 
00539   /* Section displacement.  */
00540   HOWTO (R_MIPS_SCN_DISP,       /* type */
00541         0,                  /* rightshift */
00542         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00543         32,                 /* bitsize */
00544         FALSE,                     /* pc_relative */
00545         0,                  /* bitpos */
00546         complain_overflow_dont, /* complain_on_overflow */
00547         _bfd_mips_elf_generic_reloc, /* special_function */
00548         "R_MIPS_SCN_DISP",     /* name */
00549         TRUE,               /* partial_inplace */
00550         0xffffffff,         /* src_mask */
00551         0xffffffff,         /* dst_mask */
00552         FALSE),             /* pcrel_offset */
00553 
00554   HOWTO (R_MIPS_REL16,             /* type */
00555         0,                  /* rightshift */
00556         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00557         16,                 /* bitsize */
00558         FALSE,                     /* pc_relative */
00559         0,                  /* bitpos */
00560         complain_overflow_signed, /* complain_on_overflow */
00561         _bfd_mips_elf_generic_reloc, /* special_function */
00562         "R_MIPS_REL16",     /* name */
00563         TRUE,               /* partial_inplace */
00564         0xffff,             /* src_mask */
00565         0xffff,             /* dst_mask */
00566         FALSE),             /* pcrel_offset */
00567 
00568   /* These two are obsolete.  */
00569   EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
00570   EMPTY_HOWTO (R_MIPS_PJUMP),
00571 
00572   /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
00573      It must be used for multigot GOT's (and only there).  */
00574   HOWTO (R_MIPS_RELGOT,            /* type */
00575         0,                  /* rightshift */
00576         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00577         32,                 /* bitsize */
00578         FALSE,                     /* pc_relative */
00579         0,                  /* bitpos */
00580         complain_overflow_dont, /* complain_on_overflow */
00581         _bfd_mips_elf_generic_reloc, /* special_function */
00582         "R_MIPS_RELGOT",    /* name */
00583         TRUE,               /* partial_inplace */
00584         0xffffffff,         /* src_mask */
00585         0xffffffff,         /* dst_mask */
00586         FALSE),             /* pcrel_offset */
00587 
00588   /* Protected jump conversion.  This is an optimization hint.  No
00589      relocation is required for correctness.  */
00590   HOWTO (R_MIPS_JALR,               /* type */
00591         0,                  /* rightshift */
00592         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00593         32,                 /* bitsize */
00594         FALSE,                     /* pc_relative */
00595         0,                  /* bitpos */
00596         complain_overflow_dont, /* complain_on_overflow */
00597         _bfd_mips_elf_generic_reloc, /* special_function */
00598         "R_MIPS_JALR",              /* name */
00599         FALSE,                     /* partial_inplace */
00600         0x00000000,         /* src_mask */
00601         0x00000000,         /* dst_mask */
00602         FALSE),             /* pcrel_offset */
00603 
00604   /* TLS GD/LD dynamic relocations.  */
00605   HOWTO (R_MIPS_TLS_DTPMOD32,      /* type */
00606         0,                  /* rightshift */
00607         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00608         32,                 /* bitsize */
00609         FALSE,                     /* pc_relative */
00610         0,                  /* bitpos */
00611         complain_overflow_dont, /* complain_on_overflow */
00612         _bfd_mips_elf_generic_reloc, /* special_function */
00613         "R_MIPS_TLS_DTPMOD32",     /* name */
00614         TRUE,               /* partial_inplace */
00615         0xffffffff,         /* src_mask */
00616         0xffffffff,         /* dst_mask */
00617         FALSE),             /* pcrel_offset */
00618 
00619   HOWTO (R_MIPS_TLS_DTPREL32,      /* type */
00620         0,                  /* rightshift */
00621         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00622         32,                 /* bitsize */
00623         FALSE,                     /* pc_relative */
00624         0,                  /* bitpos */
00625         complain_overflow_dont, /* complain_on_overflow */
00626         _bfd_mips_elf_generic_reloc, /* special_function */
00627         "R_MIPS_TLS_DTPREL32",     /* name */
00628         TRUE,               /* partial_inplace */
00629         0xffffffff,         /* src_mask */
00630         0xffffffff,         /* dst_mask */
00631         FALSE),             /* pcrel_offset */
00632 
00633   EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64),
00634   EMPTY_HOWTO (R_MIPS_TLS_DTPREL64),
00635 
00636   /* TLS general dynamic variable reference.  */
00637   HOWTO (R_MIPS_TLS_GD,            /* type */
00638         0,                  /* rightshift */
00639         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00640         16,                 /* bitsize */
00641         FALSE,                     /* pc_relative */
00642         0,                  /* bitpos */
00643         complain_overflow_signed, /* complain_on_overflow */
00644         _bfd_mips_elf_generic_reloc, /* special_function */
00645         "R_MIPS_TLS_GD",    /* name */
00646         TRUE,               /* partial_inplace */
00647         0x0000ffff,         /* src_mask */
00648         0x0000ffff,         /* dst_mask */
00649         FALSE),             /* pcrel_offset */
00650 
00651   /* TLS local dynamic variable reference.  */
00652   HOWTO (R_MIPS_TLS_LDM,    /* type */
00653         0,                  /* rightshift */
00654         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00655         16,                 /* bitsize */
00656         FALSE,                     /* pc_relative */
00657         0,                  /* bitpos */
00658         complain_overflow_signed, /* complain_on_overflow */
00659         _bfd_mips_elf_generic_reloc, /* special_function */
00660         "R_MIPS_TLS_LDM",   /* name */
00661         TRUE,               /* partial_inplace */
00662         0x0000ffff,         /* src_mask */
00663         0x0000ffff,         /* dst_mask */
00664         FALSE),             /* pcrel_offset */
00665 
00666   /* TLS local dynamic offset.  */
00667   HOWTO (R_MIPS_TLS_DTPREL_HI16,   /* type */
00668         0,                  /* rightshift */
00669         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00670         16,                 /* bitsize */
00671         FALSE,                     /* pc_relative */
00672         0,                  /* bitpos */
00673         complain_overflow_signed, /* complain_on_overflow */
00674         _bfd_mips_elf_generic_reloc, /* special_function */
00675         "R_MIPS_TLS_DTPREL_HI16",  /* name */
00676         TRUE,               /* partial_inplace */
00677         0x0000ffff,         /* src_mask */
00678         0x0000ffff,         /* dst_mask */
00679         FALSE),             /* pcrel_offset */
00680 
00681   /* TLS local dynamic offset.  */
00682   HOWTO (R_MIPS_TLS_DTPREL_LO16,   /* type */
00683         0,                  /* rightshift */
00684         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00685         16,                 /* bitsize */
00686         FALSE,                     /* pc_relative */
00687         0,                  /* bitpos */
00688         complain_overflow_signed, /* complain_on_overflow */
00689         _bfd_mips_elf_generic_reloc, /* special_function */
00690         "R_MIPS_TLS_DTPREL_LO16",  /* name */
00691         TRUE,               /* partial_inplace */
00692         0x0000ffff,         /* src_mask */
00693         0x0000ffff,         /* dst_mask */
00694         FALSE),             /* pcrel_offset */
00695 
00696   /* TLS thread pointer offset.  */
00697   HOWTO (R_MIPS_TLS_GOTTPREL,      /* type */
00698         0,                  /* rightshift */
00699         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00700         16,                 /* bitsize */
00701         FALSE,                     /* pc_relative */
00702         0,                  /* bitpos */
00703         complain_overflow_signed, /* complain_on_overflow */
00704         _bfd_mips_elf_generic_reloc, /* special_function */
00705         "R_MIPS_TLS_GOTTPREL",     /* name */
00706         TRUE,               /* partial_inplace */
00707         0x0000ffff,         /* src_mask */
00708         0x0000ffff,         /* dst_mask */
00709         FALSE),             /* pcrel_offset */
00710 
00711   /* TLS IE dynamic relocations.  */
00712   HOWTO (R_MIPS_TLS_TPREL32,       /* type */
00713         0,                  /* rightshift */
00714         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00715         32,                 /* bitsize */
00716         FALSE,                     /* pc_relative */
00717         0,                  /* bitpos */
00718         complain_overflow_dont, /* complain_on_overflow */
00719         _bfd_mips_elf_generic_reloc, /* special_function */
00720         "R_MIPS_TLS_TPREL32",      /* name */
00721         TRUE,               /* partial_inplace */
00722         0xffffffff,         /* src_mask */
00723         0xffffffff,         /* dst_mask */
00724         FALSE),             /* pcrel_offset */
00725 
00726   EMPTY_HOWTO (R_MIPS_TLS_TPREL64),
00727 
00728   /* TLS thread pointer offset.  */
00729   HOWTO (R_MIPS_TLS_TPREL_HI16,    /* type */
00730         0,                  /* rightshift */
00731         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00732         16,                 /* bitsize */
00733         FALSE,                     /* pc_relative */
00734         0,                  /* bitpos */
00735         complain_overflow_signed, /* complain_on_overflow */
00736         _bfd_mips_elf_generic_reloc, /* special_function */
00737         "R_MIPS_TLS_TPREL_HI16", /* name */
00738         TRUE,               /* partial_inplace */
00739         0x0000ffff,         /* src_mask */
00740         0x0000ffff,         /* dst_mask */
00741         FALSE),             /* pcrel_offset */
00742 
00743   /* TLS thread pointer offset.  */
00744   HOWTO (R_MIPS_TLS_TPREL_LO16,    /* type */
00745         0,                  /* rightshift */
00746         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00747         16,                 /* bitsize */
00748         FALSE,                     /* pc_relative */
00749         0,                  /* bitpos */
00750         complain_overflow_signed, /* complain_on_overflow */
00751         _bfd_mips_elf_generic_reloc, /* special_function */
00752         "R_MIPS_TLS_TPREL_LO16", /* name */
00753         TRUE,               /* partial_inplace */
00754         0x0000ffff,         /* src_mask */
00755         0x0000ffff,         /* dst_mask */
00756         FALSE),             /* pcrel_offset */
00757 
00758   /* 32 bit relocation with no addend.  */
00759   HOWTO (R_MIPS_GLOB_DAT,   /* type */
00760         0,                  /* rightshift */
00761         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00762         32,                 /* bitsize */
00763         FALSE,                     /* pc_relative */
00764         0,                  /* bitpos */
00765         complain_overflow_dont, /* complain_on_overflow */
00766         _bfd_mips_elf_generic_reloc, /* special_function */
00767         "R_MIPS_GLOB_DAT",  /* name */
00768         FALSE,                     /* partial_inplace */
00769         0x0,                /* src_mask */
00770         0xffffffff,         /* dst_mask */
00771         FALSE),             /* pcrel_offset */
00772 };
00773 
00774 /* The relocation table used for SHT_RELA sections.  */
00775 
00776 static reloc_howto_type elf_mips_howto_table_rela[] =
00777 {
00778   /* No relocation.  */
00779   HOWTO (R_MIPS_NONE,              /* type */
00780         0,                  /* rightshift */
00781         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00782         0,                  /* bitsize */
00783         FALSE,                     /* pc_relative */
00784         0,                  /* bitpos */
00785         complain_overflow_dont, /* complain_on_overflow */
00786         _bfd_mips_elf_generic_reloc, /* special_function */
00787         "R_MIPS_NONE",             /* name */
00788         FALSE,                     /* partial_inplace */
00789         0,                  /* src_mask */
00790         0,                  /* dst_mask */
00791         FALSE),             /* pcrel_offset */
00792 
00793   /* 16 bit relocation.  */
00794   HOWTO (R_MIPS_16,         /* type */
00795         0,                  /* rightshift */
00796         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00797         16,                 /* bitsize */
00798         FALSE,                     /* pc_relative */
00799         0,                  /* bitpos */
00800         complain_overflow_signed, /* complain_on_overflow */
00801         _bfd_mips_elf_generic_reloc, /* special_function */
00802         "R_MIPS_16",        /* name */
00803         FALSE,                     /* partial_inplace */
00804         0,                  /* src_mask */
00805         0x0000,             /* dst_mask */
00806         FALSE),             /* pcrel_offset */
00807 
00808   /* 32 bit relocation.  */
00809   HOWTO (R_MIPS_32,         /* type */
00810         0,                  /* rightshift */
00811         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00812         32,                 /* bitsize */
00813         FALSE,                     /* pc_relative */
00814         0,                  /* bitpos */
00815         complain_overflow_dont, /* complain_on_overflow */
00816         _bfd_mips_elf_generic_reloc, /* special_function */
00817         "R_MIPS_32",        /* name */
00818         FALSE,                     /* partial_inplace */
00819         0,                  /* src_mask */
00820         0xffffffff,         /* dst_mask */
00821         FALSE),             /* pcrel_offset */
00822 
00823   /* 32 bit symbol relative relocation.  */
00824   HOWTO (R_MIPS_REL32,             /* type */
00825         0,                  /* rightshift */
00826         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00827         32,                 /* bitsize */
00828         FALSE,                     /* pc_relative */
00829         0,                  /* bitpos */
00830         complain_overflow_dont, /* complain_on_overflow */
00831         _bfd_mips_elf_generic_reloc, /* special_function */
00832         "R_MIPS_REL32",     /* name */
00833         FALSE,                     /* partial_inplace */
00834         0,                  /* src_mask */
00835         0xffffffff,         /* dst_mask */
00836         FALSE),             /* pcrel_offset */
00837 
00838   /* 26 bit jump address.  */
00839   HOWTO (R_MIPS_26,         /* type */
00840         2,                  /* rightshift */
00841         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00842         26,                 /* bitsize */
00843         FALSE,                     /* pc_relative */
00844         0,                  /* bitpos */
00845         complain_overflow_dont, /* complain_on_overflow */
00846                             /* This needs complex overflow
00847                                detection, because the upper 36
00848                                bits must match the PC + 4.  */
00849         _bfd_mips_elf_generic_reloc, /* special_function */
00850         "R_MIPS_26",        /* name */
00851         FALSE,                     /* partial_inplace */
00852         0,                  /* src_mask */
00853         0x03ffffff,         /* dst_mask */
00854         FALSE),             /* pcrel_offset */
00855 
00856   /* High 16 bits of symbol value.  */
00857   HOWTO (R_MIPS_HI16,              /* type */
00858         0,                  /* rightshift */
00859         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00860         16,                 /* bitsize */
00861         FALSE,                     /* pc_relative */
00862         0,                  /* bitpos */
00863         complain_overflow_dont, /* complain_on_overflow */
00864         _bfd_mips_elf_generic_reloc, /* special_function */
00865         "R_MIPS_HI16",             /* name */
00866         FALSE,                     /* partial_inplace */
00867         0,                  /* src_mask */
00868         0x0000ffff,         /* dst_mask */
00869         FALSE),             /* pcrel_offset */
00870 
00871   /* Low 16 bits of symbol value.  */
00872   HOWTO (R_MIPS_LO16,              /* type */
00873         0,                  /* rightshift */
00874         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00875         16,                 /* bitsize */
00876         FALSE,                     /* pc_relative */
00877         0,                  /* bitpos */
00878         complain_overflow_dont, /* complain_on_overflow */
00879         _bfd_mips_elf_generic_reloc, /* special_function */
00880         "R_MIPS_LO16",             /* name */
00881         FALSE,                     /* partial_inplace */
00882         0,                  /* src_mask */
00883         0x0000ffff,         /* dst_mask */
00884         FALSE),             /* pcrel_offset */
00885 
00886   /* GP relative reference.  */
00887   HOWTO (R_MIPS_GPREL16,    /* type */
00888         0,                  /* rightshift */
00889         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00890         16,                 /* bitsize */
00891         FALSE,                     /* pc_relative */
00892         0,                  /* bitpos */
00893         complain_overflow_signed, /* complain_on_overflow */
00894         mips_elf_gprel16_reloc, /* special_function */
00895         "R_MIPS_GPREL16",   /* name */
00896         FALSE,                     /* partial_inplace */
00897         0,                  /* src_mask */
00898         0x0000ffff,         /* dst_mask */
00899         FALSE),             /* pcrel_offset */
00900 
00901   /* Reference to literal section.  */
00902   HOWTO (R_MIPS_LITERAL,    /* type */
00903         0,                  /* rightshift */
00904         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00905         16,                 /* bitsize */
00906         FALSE,                     /* pc_relative */
00907         0,                  /* bitpos */
00908         complain_overflow_signed, /* complain_on_overflow */
00909         mips_elf_literal_reloc, /* special_function */
00910         "R_MIPS_LITERAL",   /* name */
00911         FALSE,                     /* partial_inplace */
00912         0,                  /* src_mask */
00913         0x0000ffff,         /* dst_mask */
00914         FALSE),             /* pcrel_offset */
00915 
00916   /* Reference to global offset table.  */
00917   HOWTO (R_MIPS_GOT16,             /* type */
00918         0,                  /* rightshift */
00919         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00920         16,                 /* bitsize */
00921         FALSE,                     /* pc_relative */
00922         0,                  /* bitpos */
00923         complain_overflow_signed, /* complain_on_overflow */
00924         _bfd_mips_elf_generic_reloc, /* special_function */
00925         "R_MIPS_GOT16",     /* name */
00926         FALSE,                     /* partial_inplace */
00927         0,                  /* src_mask */
00928         0x0000ffff,         /* dst_mask */
00929         FALSE),             /* pcrel_offset */
00930 
00931   /* 16 bit PC relative reference.  Note that the ABI document has a typo
00932      and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
00933      We do the right thing here.  */
00934   HOWTO (R_MIPS_PC16,              /* type */
00935         2,                  /* rightshift */
00936         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00937         16,                 /* bitsize */
00938         TRUE,               /* pc_relative */
00939         0,                  /* bitpos */
00940         complain_overflow_signed, /* complain_on_overflow */
00941         _bfd_mips_elf_generic_reloc, /* special_function */
00942         "R_MIPS_PC16",             /* name */
00943         FALSE,                     /* partial_inplace */
00944         0,                  /* src_mask */
00945         0x0000ffff,         /* dst_mask */
00946         TRUE),                     /* pcrel_offset */
00947 
00948   /* 16 bit call through global offset table.  */
00949   HOWTO (R_MIPS_CALL16,            /* type */
00950         0,                  /* rightshift */
00951         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00952         16,                 /* bitsize */
00953         FALSE,                     /* pc_relative */
00954         0,                  /* bitpos */
00955         complain_overflow_signed, /* complain_on_overflow */
00956         _bfd_mips_elf_generic_reloc, /* special_function */
00957         "R_MIPS_CALL16",    /* name */
00958         FALSE,                     /* partial_inplace */
00959         0,                  /* src_mask */
00960         0x0000ffff,         /* dst_mask */
00961         FALSE),             /* pcrel_offset */
00962 
00963   /* 32 bit GP relative reference.  */
00964   HOWTO (R_MIPS_GPREL32,    /* type */
00965         0,                  /* rightshift */
00966         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00967         32,                 /* bitsize */
00968         FALSE,                     /* pc_relative */
00969         0,                  /* bitpos */
00970         complain_overflow_dont, /* complain_on_overflow */
00971         mips_elf_gprel32_reloc, /* special_function */
00972         "R_MIPS_GPREL32",   /* name */
00973         FALSE,                     /* partial_inplace */
00974         0,                  /* src_mask */
00975         0xffffffff,         /* dst_mask */
00976         FALSE),             /* pcrel_offset */
00977 
00978   EMPTY_HOWTO (13),
00979   EMPTY_HOWTO (14),
00980   EMPTY_HOWTO (15),
00981 
00982   /* A 5 bit shift field.  */
00983   HOWTO (R_MIPS_SHIFT5,            /* type */
00984         0,                  /* rightshift */
00985         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00986         5,                  /* bitsize */
00987         FALSE,                     /* pc_relative */
00988         6,                  /* bitpos */
00989         complain_overflow_bitfield, /* complain_on_overflow */
00990         _bfd_mips_elf_generic_reloc, /* special_function */
00991         "R_MIPS_SHIFT5",    /* name */
00992         FALSE,                     /* partial_inplace */
00993         0,                  /* src_mask */
00994         0x000007c0,         /* dst_mask */
00995         FALSE),             /* pcrel_offset */
00996 
00997   /* A 6 bit shift field.  */
00998   HOWTO (R_MIPS_SHIFT6,            /* type */
00999         0,                  /* rightshift */
01000         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01001         6,                  /* bitsize */
01002         FALSE,                     /* pc_relative */
01003         6,                  /* bitpos */
01004         complain_overflow_bitfield, /* complain_on_overflow */
01005         mips_elf_shift6_reloc,     /* special_function */
01006         "R_MIPS_SHIFT6",    /* name */
01007         FALSE,                     /* partial_inplace */
01008         0,                  /* src_mask */
01009         0x000007c4,         /* dst_mask */
01010         FALSE),             /* pcrel_offset */
01011 
01012   /* 64 bit relocation.  */
01013   HOWTO (R_MIPS_64,         /* type */
01014         0,                  /* rightshift */
01015         4,                  /* size (0 = byte, 1 = short, 2 = long) */
01016         64,                 /* bitsize */
01017         FALSE,                     /* pc_relative */
01018         0,                  /* bitpos */
01019         complain_overflow_dont, /* complain_on_overflow */
01020         _bfd_mips_elf_generic_reloc, /* special_function */
01021         "R_MIPS_64",        /* name */
01022         FALSE,                     /* partial_inplace */
01023         0,                  /* src_mask */
01024         MINUS_ONE,          /* dst_mask */
01025         FALSE),             /* pcrel_offset */
01026 
01027   /* Displacement in the global offset table.  */
01028   HOWTO (R_MIPS_GOT_DISP,   /* type */
01029         0,                  /* rightshift */
01030         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01031         16,                 /* bitsize */
01032         FALSE,                     /* pc_relative */
01033         0,                  /* bitpos */
01034         complain_overflow_signed, /* complain_on_overflow */
01035         _bfd_mips_elf_generic_reloc, /* special_function */
01036         "R_MIPS_GOT_DISP",  /* name */
01037         FALSE,                     /* partial_inplace */
01038         0,                  /* src_mask */
01039         0x0000ffff,         /* dst_mask */
01040         FALSE),             /* pcrel_offset */
01041 
01042   /* Displacement to page pointer in the global offset table.  */
01043   HOWTO (R_MIPS_GOT_PAGE,   /* type */
01044         0,                  /* rightshift */
01045         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01046         16,                 /* bitsize */
01047         FALSE,                     /* pc_relative */
01048         0,                  /* bitpos */
01049         complain_overflow_signed, /* complain_on_overflow */
01050         _bfd_mips_elf_generic_reloc, /* special_function */
01051         "R_MIPS_GOT_PAGE",  /* name */
01052         FALSE,                     /* partial_inplace */
01053         0,                  /* src_mask */
01054         0x0000ffff,         /* dst_mask */
01055         FALSE),             /* pcrel_offset */
01056 
01057   /* Offset from page pointer in the global offset table.  */
01058   HOWTO (R_MIPS_GOT_OFST,   /* type */
01059         0,                  /* rightshift */
01060         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01061         16,                 /* bitsize */
01062         FALSE,                     /* pc_relative */
01063         0,                  /* bitpos */
01064         complain_overflow_signed, /* complain_on_overflow */
01065         _bfd_mips_elf_generic_reloc, /* special_function */
01066         "R_MIPS_GOT_OFST",  /* name */
01067         FALSE,                     /* partial_inplace */
01068         0,                  /* src_mask */
01069         0x0000ffff,         /* dst_mask */
01070         FALSE),             /* pcrel_offset */
01071 
01072   /* High 16 bits of displacement in global offset table.  */
01073   HOWTO (R_MIPS_GOT_HI16,   /* type */
01074         0,                  /* rightshift */
01075         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01076         16,                 /* bitsize */
01077         FALSE,                     /* pc_relative */
01078         0,                  /* bitpos */
01079         complain_overflow_dont, /* complain_on_overflow */
01080         _bfd_mips_elf_generic_reloc, /* special_function */
01081         "R_MIPS_GOT_HI16",  /* name */
01082         FALSE,                     /* partial_inplace */
01083         0,                  /* src_mask */
01084         0x0000ffff,         /* dst_mask */
01085         FALSE),             /* pcrel_offset */
01086 
01087   /* Low 16 bits of displacement in global offset table.  */
01088   HOWTO (R_MIPS_GOT_LO16,   /* type */
01089         0,                  /* rightshift */
01090         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01091         16,                 /* bitsize */
01092         FALSE,                     /* pc_relative */
01093         0,                  /* bitpos */
01094         complain_overflow_dont, /* complain_on_overflow */
01095         _bfd_mips_elf_generic_reloc, /* special_function */
01096         "R_MIPS_GOT_LO16",  /* name */
01097         FALSE,                     /* partial_inplace */
01098         0,                  /* src_mask */
01099         0x0000ffff,         /* dst_mask */
01100         FALSE),             /* pcrel_offset */
01101 
01102   /* 64 bit subtraction.  */
01103   HOWTO (R_MIPS_SUB,        /* type */
01104         0,                  /* rightshift */
01105         4,                  /* size (0 = byte, 1 = short, 2 = long) */
01106         64,                 /* bitsize */
01107         FALSE,                     /* pc_relative */
01108         0,                  /* bitpos */
01109         complain_overflow_dont, /* complain_on_overflow */
01110         _bfd_mips_elf_generic_reloc, /* special_function */
01111         "R_MIPS_SUB",              /* name */
01112         FALSE,                     /* partial_inplace */
01113         0,                  /* src_mask */
01114         MINUS_ONE,          /* dst_mask */
01115         FALSE),             /* pcrel_offset */
01116 
01117   /* Insert the addend as an instruction.  */
01118   /* FIXME: Not handled correctly.  */
01119   HOWTO (R_MIPS_INSERT_A,   /* type */
01120         0,                  /* rightshift */
01121         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01122         32,                 /* bitsize */
01123         FALSE,                     /* pc_relative */
01124         0,                  /* bitpos */
01125         complain_overflow_dont, /* complain_on_overflow */
01126         _bfd_mips_elf_generic_reloc, /* special_function */
01127         "R_MIPS_INSERT_A",  /* name */
01128         FALSE,                     /* partial_inplace */
01129         0,                  /* src_mask */
01130         0xffffffff,         /* dst_mask */
01131         FALSE),             /* pcrel_offset */
01132 
01133   /* Insert the addend as an instruction, and change all relocations
01134      to refer to the old instruction at the address.  */
01135   /* FIXME: Not handled correctly.  */
01136   HOWTO (R_MIPS_INSERT_B,   /* type */
01137         0,                  /* rightshift */
01138         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01139         32,                 /* bitsize */
01140         FALSE,                     /* pc_relative */
01141         0,                  /* bitpos */
01142         complain_overflow_dont, /* complain_on_overflow */
01143         _bfd_mips_elf_generic_reloc, /* special_function */
01144         "R_MIPS_INSERT_B",  /* name */
01145         FALSE,                     /* partial_inplace */
01146         0,                  /* src_mask */
01147         0xffffffff,         /* dst_mask */
01148         FALSE),             /* pcrel_offset */
01149 
01150   /* Delete a 32 bit instruction.  */
01151   /* FIXME: Not handled correctly.  */
01152   HOWTO (R_MIPS_DELETE,            /* type */
01153         0,                  /* rightshift */
01154         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01155         32,                 /* bitsize */
01156         FALSE,                     /* pc_relative */
01157         0,                  /* bitpos */
01158         complain_overflow_dont, /* complain_on_overflow */
01159         _bfd_mips_elf_generic_reloc, /* special_function */
01160         "R_MIPS_DELETE",    /* name */
01161         FALSE,                     /* partial_inplace */
01162         0,                  /* src_mask */
01163         0xffffffff,         /* dst_mask */
01164         FALSE),             /* pcrel_offset */
01165 
01166   /* Get the higher value of a 64 bit addend.  */
01167   HOWTO (R_MIPS_HIGHER,            /* type */
01168         0,                  /* rightshift */
01169         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01170         16,                 /* bitsize */
01171         FALSE,                     /* pc_relative */
01172         0,                  /* bitpos */
01173         complain_overflow_dont, /* complain_on_overflow */
01174         _bfd_mips_elf_generic_reloc, /* special_function */
01175         "R_MIPS_HIGHER",    /* name */
01176         FALSE,                     /* partial_inplace */
01177         0,                  /* src_mask */
01178         0x0000ffff,         /* dst_mask */
01179         FALSE),             /* pcrel_offset */
01180 
01181   /* Get the highest value of a 64 bit addend.  */
01182   HOWTO (R_MIPS_HIGHEST,    /* type */
01183         0,                  /* rightshift */
01184         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01185         16,                 /* bitsize */
01186         FALSE,                     /* pc_relative */
01187         0,                  /* bitpos */
01188         complain_overflow_dont, /* complain_on_overflow */
01189         _bfd_mips_elf_generic_reloc, /* special_function */
01190         "R_MIPS_HIGHEST",   /* name */
01191         FALSE,                     /* partial_inplace */
01192         0,                  /* src_mask */
01193         0x0000ffff,         /* dst_mask */
01194         FALSE),             /* pcrel_offset */
01195 
01196   /* High 16 bits of displacement in global offset table.  */
01197   HOWTO (R_MIPS_CALL_HI16,  /* type */
01198         0,                  /* rightshift */
01199         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01200         16,                 /* bitsize */
01201         FALSE,                     /* pc_relative */
01202         0,                  /* bitpos */
01203         complain_overflow_dont, /* complain_on_overflow */
01204         _bfd_mips_elf_generic_reloc, /* special_function */
01205         "R_MIPS_CALL_HI16", /* name */
01206         FALSE,                     /* partial_inplace */
01207         0,                  /* src_mask */
01208         0x0000ffff,         /* dst_mask */
01209         FALSE),             /* pcrel_offset */
01210 
01211   /* Low 16 bits of displacement in global offset table.  */
01212   HOWTO (R_MIPS_CALL_LO16,  /* type */
01213         0,                  /* rightshift */
01214         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01215         16,                 /* bitsize */
01216         FALSE,                     /* pc_relative */
01217         0,                  /* bitpos */
01218         complain_overflow_dont, /* complain_on_overflow */
01219         _bfd_mips_elf_generic_reloc, /* special_function */
01220         "R_MIPS_CALL_LO16", /* name */
01221         FALSE,                     /* partial_inplace */
01222         0,                  /* src_mask */
01223         0x0000ffff,         /* dst_mask */
01224         FALSE),             /* pcrel_offset */
01225 
01226   /* Section displacement, used by an associated event location section.  */
01227   HOWTO (R_MIPS_SCN_DISP,   /* type */
01228         0,                  /* rightshift */
01229         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01230         32,                 /* bitsize */
01231         FALSE,                     /* pc_relative */
01232         0,                  /* bitpos */
01233         complain_overflow_dont, /* complain_on_overflow */
01234         _bfd_mips_elf_generic_reloc, /* special_function */
01235         "R_MIPS_SCN_DISP",  /* name */
01236         FALSE,                     /* partial_inplace */
01237         0,                  /* src_mask */
01238         0xffffffff,         /* dst_mask */
01239         FALSE),             /* pcrel_offset */
01240 
01241   /* 16 bit relocation.  */
01242   HOWTO (R_MIPS_REL16,             /* type */
01243         0,                  /* rightshift */
01244         1,                  /* size (0 = byte, 1 = short, 2 = long) */
01245         16,                 /* bitsize */
01246         FALSE,                     /* pc_relative */
01247         0,                  /* bitpos */
01248         complain_overflow_signed, /* complain_on_overflow */
01249         _bfd_mips_elf_generic_reloc, /* special_function */
01250         "R_MIPS_REL16",     /* name */
01251         FALSE,                     /* partial_inplace */
01252         0,                  /* src_mask */
01253         0xffff,             /* dst_mask */
01254         FALSE),             /* pcrel_offset */
01255 
01256   /* These two are obsolete.  */
01257   EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
01258   EMPTY_HOWTO (R_MIPS_PJUMP),
01259 
01260   /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
01261      It must be used for multigot GOT's (and only there).  */
01262   HOWTO (R_MIPS_RELGOT,            /* 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_RELGOT",    /* name */
01271         FALSE,                     /* partial_inplace */
01272         0,                  /* src_mask */
01273         0xffffffff,         /* dst_mask */
01274         FALSE),             /* pcrel_offset */
01275 
01276   /* Protected jump conversion.  This is an optimization hint.  No
01277      relocation is required for correctness.  */
01278   HOWTO (R_MIPS_JALR,               /* type */
01279         0,                  /* rightshift */
01280         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01281         32,                 /* bitsize */
01282         FALSE,                     /* pc_relative */
01283         0,                  /* bitpos */
01284         complain_overflow_dont, /* complain_on_overflow */
01285         _bfd_mips_elf_generic_reloc, /* special_function */
01286         "R_MIPS_JALR",              /* name */
01287         FALSE,                     /* partial_inplace */
01288         0,                  /* src_mask */
01289         0,                  /* dst_mask */
01290         FALSE),             /* pcrel_offset */
01291 
01292   /* TLS GD/LD dynamic relocations.  */
01293   HOWTO (R_MIPS_TLS_DTPMOD32,      /* type */
01294         0,                  /* rightshift */
01295         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01296         32,                 /* bitsize */
01297         FALSE,                     /* pc_relative */
01298         0,                  /* bitpos */
01299         complain_overflow_dont, /* complain_on_overflow */
01300         _bfd_mips_elf_generic_reloc, /* special_function */
01301         "R_MIPS_TLS_DTPMOD32",     /* name */
01302         TRUE,               /* partial_inplace */
01303         0xffffffff,         /* src_mask */
01304         0xffffffff,         /* dst_mask */
01305         FALSE),             /* pcrel_offset */
01306 
01307   HOWTO (R_MIPS_TLS_DTPREL32,      /* type */
01308         0,                  /* rightshift */
01309         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01310         32,                 /* bitsize */
01311         FALSE,                     /* pc_relative */
01312         0,                  /* bitpos */
01313         complain_overflow_dont, /* complain_on_overflow */
01314         _bfd_mips_elf_generic_reloc, /* special_function */
01315         "R_MIPS_TLS_DTPREL32",     /* name */
01316         TRUE,               /* partial_inplace */
01317         0xffffffff,         /* src_mask */
01318         0xffffffff,         /* dst_mask */
01319         FALSE),             /* pcrel_offset */
01320 
01321   EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64),
01322   EMPTY_HOWTO (R_MIPS_TLS_DTPREL64),
01323 
01324   /* TLS general dynamic variable reference.  */
01325   HOWTO (R_MIPS_TLS_GD,            /* type */
01326         0,                  /* rightshift */
01327         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01328         16,                 /* bitsize */
01329         FALSE,                     /* pc_relative */
01330         0,                  /* bitpos */
01331         complain_overflow_signed, /* complain_on_overflow */
01332         _bfd_mips_elf_generic_reloc, /* special_function */
01333         "R_MIPS_TLS_GD",    /* name */
01334         TRUE,               /* partial_inplace */
01335         0x0000ffff,         /* src_mask */
01336         0x0000ffff,         /* dst_mask */
01337         FALSE),             /* pcrel_offset */
01338 
01339   /* TLS local dynamic variable reference.  */
01340   HOWTO (R_MIPS_TLS_LDM,    /* type */
01341         0,                  /* rightshift */
01342         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01343         16,                 /* bitsize */
01344         FALSE,                     /* pc_relative */
01345         0,                  /* bitpos */
01346         complain_overflow_signed, /* complain_on_overflow */
01347         _bfd_mips_elf_generic_reloc, /* special_function */
01348         "R_MIPS_TLS_LDM",   /* name */
01349         TRUE,               /* partial_inplace */
01350         0x0000ffff,         /* src_mask */
01351         0x0000ffff,         /* dst_mask */
01352         FALSE),             /* pcrel_offset */
01353 
01354   /* TLS local dynamic offset.  */
01355   HOWTO (R_MIPS_TLS_DTPREL_HI16,   /* type */
01356         0,                  /* rightshift */
01357         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01358         16,                 /* bitsize */
01359         FALSE,                     /* pc_relative */
01360         0,                  /* bitpos */
01361         complain_overflow_signed, /* complain_on_overflow */
01362         _bfd_mips_elf_generic_reloc, /* special_function */
01363         "R_MIPS_TLS_DTPREL_HI16",  /* name */
01364         TRUE,               /* partial_inplace */
01365         0x0000ffff,         /* src_mask */
01366         0x0000ffff,         /* dst_mask */
01367         FALSE),             /* pcrel_offset */
01368 
01369   /* TLS local dynamic offset.  */
01370   HOWTO (R_MIPS_TLS_DTPREL_LO16,   /* type */
01371         0,                  /* rightshift */
01372         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01373         16,                 /* bitsize */
01374         FALSE,                     /* pc_relative */
01375         0,                  /* bitpos */
01376         complain_overflow_signed, /* complain_on_overflow */
01377         _bfd_mips_elf_generic_reloc, /* special_function */
01378         "R_MIPS_TLS_DTPREL_LO16",  /* name */
01379         TRUE,               /* partial_inplace */
01380         0x0000ffff,         /* src_mask */
01381         0x0000ffff,         /* dst_mask */
01382         FALSE),             /* pcrel_offset */
01383 
01384   /* TLS thread pointer offset.  */
01385   HOWTO (R_MIPS_TLS_GOTTPREL,      /* type */
01386         0,                  /* rightshift */
01387         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01388         16,                 /* bitsize */
01389         FALSE,                     /* pc_relative */
01390         0,                  /* bitpos */
01391         complain_overflow_signed, /* complain_on_overflow */
01392         _bfd_mips_elf_generic_reloc, /* special_function */
01393         "R_MIPS_TLS_GOTTPREL",     /* name */
01394         TRUE,               /* partial_inplace */
01395         0x0000ffff,         /* src_mask */
01396         0x0000ffff,         /* dst_mask */
01397         FALSE),             /* pcrel_offset */
01398 
01399   /* TLS IE dynamic relocations.  */
01400   HOWTO (R_MIPS_TLS_TPREL32,       /* type */
01401         0,                  /* rightshift */
01402         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01403         32,                 /* bitsize */
01404         FALSE,                     /* pc_relative */
01405         0,                  /* bitpos */
01406         complain_overflow_dont, /* complain_on_overflow */
01407         _bfd_mips_elf_generic_reloc, /* special_function */
01408         "R_MIPS_TLS_TPREL32",      /* name */
01409         TRUE,               /* partial_inplace */
01410         0xffffffff,         /* src_mask */
01411         0xffffffff,         /* dst_mask */
01412         FALSE),             /* pcrel_offset */
01413 
01414   EMPTY_HOWTO (R_MIPS_TLS_TPREL64),
01415 
01416   /* TLS thread pointer offset.  */
01417   HOWTO (R_MIPS_TLS_TPREL_HI16,    /* type */
01418         0,                  /* rightshift */
01419         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01420         16,                 /* bitsize */
01421         FALSE,                     /* pc_relative */
01422         0,                  /* bitpos */
01423         complain_overflow_signed, /* complain_on_overflow */
01424         _bfd_mips_elf_generic_reloc, /* special_function */
01425         "R_MIPS_TLS_TPREL_HI16", /* name */
01426         TRUE,               /* partial_inplace */
01427         0x0000ffff,         /* src_mask */
01428         0x0000ffff,         /* dst_mask */
01429         FALSE),             /* pcrel_offset */
01430 
01431   /* TLS thread pointer offset.  */
01432   HOWTO (R_MIPS_TLS_TPREL_LO16,    /* type */
01433         0,                  /* rightshift */
01434         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01435         16,                 /* bitsize */
01436         FALSE,                     /* pc_relative */
01437         0,                  /* bitpos */
01438         complain_overflow_signed, /* complain_on_overflow */
01439         _bfd_mips_elf_generic_reloc, /* special_function */
01440         "R_MIPS_TLS_TPREL_LO16", /* name */
01441         TRUE,               /* partial_inplace */
01442         0x0000ffff,         /* src_mask */
01443         0x0000ffff,         /* dst_mask */
01444         FALSE),             /* pcrel_offset */
01445 
01446   /* 32 bit relocation with no addend.  */
01447   HOWTO (R_MIPS_GLOB_DAT,   /* type */
01448         0,                  /* rightshift */
01449         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01450         32,                 /* bitsize */
01451         FALSE,                     /* pc_relative */
01452         0,                  /* bitpos */
01453         complain_overflow_dont, /* complain_on_overflow */
01454         _bfd_mips_elf_generic_reloc, /* special_function */
01455         "R_MIPS_GLOB_DAT",  /* name */
01456         FALSE,                     /* partial_inplace */
01457         0x0,                /* src_mask */
01458         0xffffffff,         /* dst_mask */
01459         FALSE),             /* pcrel_offset */
01460 };
01461 
01462 static reloc_howto_type elf_mips16_howto_table_rel[] =
01463 {
01464   /* The reloc used for the mips16 jump instruction.  */
01465   HOWTO (R_MIPS16_26,              /* type */
01466         2,                  /* rightshift */
01467         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01468         26,                 /* bitsize */
01469         FALSE,                     /* pc_relative */
01470         0,                  /* bitpos */
01471         complain_overflow_dont, /* complain_on_overflow */
01472                             /* This needs complex overflow
01473                                detection, because the upper four
01474                                bits must match the PC.  */
01475         _bfd_mips_elf_generic_reloc, /* special_function */
01476         "R_MIPS16_26",             /* name */
01477         TRUE,               /* partial_inplace */
01478         0x3ffffff,          /* src_mask */
01479         0x3ffffff,          /* dst_mask */
01480         FALSE),             /* pcrel_offset */
01481 
01482   /* The reloc used for the mips16 gprel instruction.  */
01483   HOWTO (R_MIPS16_GPREL,    /* type */
01484         0,                  /* rightshift */
01485         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01486         16,                 /* bitsize */
01487         FALSE,                     /* pc_relative */
01488         0,                  /* bitpos */
01489         complain_overflow_signed, /* complain_on_overflow */
01490         mips16_gprel_reloc, /* special_function */
01491         "R_MIPS16_GPREL",   /* name */
01492         TRUE,               /* partial_inplace */
01493         0x0000ffff,         /* src_mask */
01494         0x0000ffff,          /* dst_mask */
01495         FALSE),             /* pcrel_offset */
01496 
01497   /* A placeholder for MIPS16 reference to global offset table.  */
01498   EMPTY_HOWTO (R_MIPS16_GOT16),
01499 
01500   /* A placeholder for MIPS16 16 bit call through global offset table.  */
01501   EMPTY_HOWTO (R_MIPS16_CALL16),
01502 
01503   /* MIPS16 high 16 bits of symbol value.  */
01504   HOWTO (R_MIPS16_HI16,            /* type */
01505         16,                 /* rightshift */
01506         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01507         16,                 /* bitsize */
01508         FALSE,                     /* pc_relative */
01509         0,                  /* bitpos */
01510         complain_overflow_dont, /* complain_on_overflow */
01511         _bfd_mips_elf_hi16_reloc, /* special_function */
01512         "R_MIPS16_HI16",    /* name */
01513         TRUE,               /* partial_inplace */
01514         0x0000ffff,         /* src_mask */
01515         0x0000ffff,         /* dst_mask */
01516         FALSE),             /* pcrel_offset */
01517 
01518   /* MIPS16 low 16 bits of symbol value.  */
01519   HOWTO (R_MIPS16_LO16,            /* type */
01520         0,                  /* rightshift */
01521         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01522         16,                 /* bitsize */
01523         FALSE,                     /* pc_relative */
01524         0,                  /* bitpos */
01525         complain_overflow_dont, /* complain_on_overflow */
01526         _bfd_mips_elf_lo16_reloc, /* special_function */
01527         "R_MIPS16_LO16",    /* name */
01528         TRUE,               /* partial_inplace */
01529         0x0000ffff,         /* src_mask */
01530         0x0000ffff,         /* dst_mask */
01531         FALSE),             /* pcrel_offset */
01532 };
01533 
01534 static reloc_howto_type elf_mips16_howto_table_rela[] =
01535 {
01536   /* The reloc used for the mips16 jump instruction.  */
01537   HOWTO (R_MIPS16_26,              /* type */
01538         2,                  /* rightshift */
01539         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01540         26,                 /* bitsize */
01541         FALSE,                     /* pc_relative */
01542         0,                  /* bitpos */
01543         complain_overflow_dont, /* complain_on_overflow */
01544                             /* This needs complex overflow
01545                                detection, because the upper four
01546                                bits must match the PC.  */
01547         _bfd_mips_elf_generic_reloc, /* special_function */
01548         "R_MIPS16_26",             /* name */
01549         FALSE,                     /* partial_inplace */
01550         0x3ffffff,          /* src_mask */
01551         0x3ffffff,          /* dst_mask */
01552         FALSE),             /* pcrel_offset */
01553 
01554   /* The reloc used for the mips16 gprel instruction.  */
01555   HOWTO (R_MIPS16_GPREL,    /* type */
01556         0,                  /* rightshift */
01557         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01558         16,                 /* bitsize */
01559         FALSE,                     /* pc_relative */
01560         0,                  /* bitpos */
01561         complain_overflow_signed, /* complain_on_overflow */
01562         mips16_gprel_reloc, /* special_function */
01563         "R_MIPS16_GPREL",   /* name */
01564         FALSE,                     /* partial_inplace */
01565         0x0000ffff,         /* src_mask */
01566         0x0000ffff,          /* dst_mask */
01567         FALSE),             /* pcrel_offset */
01568 
01569   /* A placeholder for MIPS16 reference to global offset table.  */
01570   EMPTY_HOWTO (R_MIPS16_GOT16),
01571 
01572   /* A placeholder for MIPS16 16 bit call through global offset table.  */
01573   EMPTY_HOWTO (R_MIPS16_CALL16),
01574 
01575   /* MIPS16 high 16 bits of symbol value.  */
01576   HOWTO (R_MIPS16_HI16,            /* type */
01577         16,                 /* rightshift */
01578         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01579         16,                 /* bitsize */
01580         FALSE,                     /* pc_relative */
01581         0,                  /* bitpos */
01582         complain_overflow_dont, /* complain_on_overflow */
01583         _bfd_mips_elf_hi16_reloc, /* special_function */
01584         "R_MIPS16_HI16",    /* name */
01585         FALSE,                     /* partial_inplace */
01586         0x0000ffff,         /* src_mask */
01587         0x0000ffff,         /* dst_mask */
01588         FALSE),             /* pcrel_offset */
01589 
01590   /* MIPS16 low 16 bits of symbol value.  */
01591   HOWTO (R_MIPS16_LO16,            /* type */
01592         0,                  /* rightshift */
01593         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01594         16,                 /* bitsize */
01595         FALSE,                     /* pc_relative */
01596         0,                  /* bitpos */
01597         complain_overflow_dont, /* complain_on_overflow */
01598         _bfd_mips_elf_lo16_reloc, /* special_function */
01599         "R_MIPS16_LO16",    /* name */
01600         FALSE,                     /* partial_inplace */
01601         0x0000ffff,         /* src_mask */
01602         0x0000ffff,         /* dst_mask */
01603         FALSE),             /* pcrel_offset */
01604 };
01605 
01606 /* GNU extension to record C++ vtable hierarchy */
01607 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
01608   HOWTO (R_MIPS_GNU_VTINHERIT,     /* type */
01609         0,                  /* rightshift */
01610         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01611         0,                  /* bitsize */
01612         FALSE,                     /* pc_relative */
01613         0,                  /* bitpos */
01614         complain_overflow_dont, /* complain_on_overflow */
01615         NULL,               /* special_function */
01616         "R_MIPS_GNU_VTINHERIT", /* name */
01617         FALSE,                     /* partial_inplace */
01618         0,                  /* src_mask */
01619         0,                  /* dst_mask */
01620         FALSE);             /* pcrel_offset */
01621 
01622 /* GNU extension to record C++ vtable member usage */
01623 static reloc_howto_type elf_mips_gnu_vtentry_howto =
01624   HOWTO (R_MIPS_GNU_VTENTRY,       /* type */
01625         0,                  /* rightshift */
01626         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01627         0,                  /* bitsize */
01628         FALSE,                     /* pc_relative */
01629         0,                  /* bitpos */
01630         complain_overflow_dont, /* complain_on_overflow */
01631         _bfd_elf_rel_vtable_reloc_fn, /* special_function */
01632         "R_MIPS_GNU_VTENTRY",      /* name */
01633         FALSE,                     /* partial_inplace */
01634         0,                  /* src_mask */
01635         0,                  /* dst_mask */
01636         FALSE);             /* pcrel_offset */
01637 
01638 /* 16 bit offset for pc-relative branches.  */
01639 static reloc_howto_type elf_mips_gnu_rel16_s2 =
01640   HOWTO (R_MIPS_GNU_REL16_S2,      /* type */
01641         2,                  /* rightshift */
01642         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01643         16,                 /* bitsize */
01644         TRUE,               /* pc_relative */
01645         0,                  /* bitpos */
01646         complain_overflow_signed, /* complain_on_overflow */
01647         _bfd_mips_elf_generic_reloc, /* special_function */
01648         "R_MIPS_GNU_REL16_S2",     /* name */
01649         TRUE,               /* partial_inplace */
01650         0x0000ffff,         /* src_mask */
01651         0x0000ffff,         /* dst_mask */
01652         TRUE);                     /* pcrel_offset */
01653 
01654 /* 16 bit offset for pc-relative branches.  */
01655 static reloc_howto_type elf_mips_gnu_rela16_s2 =
01656   HOWTO (R_MIPS_GNU_REL16_S2,      /* type */
01657         2,                  /* rightshift */
01658         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01659         16,                 /* bitsize */
01660         TRUE,               /* pc_relative */
01661         0,                  /* bitpos */
01662         complain_overflow_signed, /* complain_on_overflow */
01663         _bfd_mips_elf_generic_reloc, /* special_function */
01664         "R_MIPS_GNU_REL16_S2",     /* name */
01665         FALSE,                     /* partial_inplace */
01666         0,                  /* src_mask */
01667         0x0000ffff,         /* dst_mask */
01668         TRUE);                     /* pcrel_offset */
01669 
01670 /* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
01671    dangerous relocation.  */
01672 
01673 static bfd_boolean
01674 mips_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
01675 {
01676   unsigned int count;
01677   asymbol **sym;
01678   unsigned int i;
01679 
01680   /* If we've already figured out what GP will be, just return it.  */
01681   *pgp = _bfd_get_gp_value (output_bfd);
01682   if (*pgp)
01683     return TRUE;
01684 
01685   count = bfd_get_symcount (output_bfd);
01686   sym = bfd_get_outsymbols (output_bfd);
01687 
01688   /* The linker script will have created a symbol named `_gp' with the
01689      appropriate value.  */
01690   if (sym == NULL)
01691     i = count;
01692   else
01693     {
01694       for (i = 0; i < count; i++, sym++)
01695        {
01696          register const char *name;
01697 
01698          name = bfd_asymbol_name (*sym);
01699          if (*name == '_' && strcmp (name, "_gp") == 0)
01700            {
01701              *pgp = bfd_asymbol_value (*sym);
01702              _bfd_set_gp_value (output_bfd, *pgp);
01703              break;
01704            }
01705        }
01706     }
01707 
01708   if (i >= count)
01709     {
01710       /* Only get the error once.  */
01711       *pgp = 4;
01712       _bfd_set_gp_value (output_bfd, *pgp);
01713       return FALSE;
01714     }
01715 
01716   return TRUE;
01717 }
01718 
01719 /* We have to figure out the gp value, so that we can adjust the
01720    symbol value correctly.  We look up the symbol _gp in the output
01721    BFD.  If we can't find it, we're stuck.  We cache it in the ELF
01722    target data.  We don't need to adjust the symbol value for an
01723    external symbol if we are producing relocatable output.  */
01724 
01725 static bfd_reloc_status_type
01726 mips_elf_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
01727                  char **error_message, bfd_vma *pgp)
01728 {
01729   if (bfd_is_und_section (symbol->section)
01730       && ! relocatable)
01731     {
01732       *pgp = 0;
01733       return bfd_reloc_undefined;
01734     }
01735 
01736   *pgp = _bfd_get_gp_value (output_bfd);
01737   if (*pgp == 0
01738       && (! relocatable
01739          || (symbol->flags & BSF_SECTION_SYM) != 0))
01740     {
01741       if (relocatable)
01742        {
01743          /* Make up a value.  */
01744          *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
01745          _bfd_set_gp_value (output_bfd, *pgp);
01746        }
01747       else if (!mips_elf_assign_gp (output_bfd, pgp))
01748        {
01749          *error_message =
01750            (char *) _("GP relative relocation when _gp not defined");
01751          return bfd_reloc_dangerous;
01752        }
01753     }
01754 
01755   return bfd_reloc_ok;
01756 }
01757 
01758 /* Do a R_MIPS_GPREL16 relocation.  This is a 16 bit value which must
01759    become the offset from the gp register.  */
01760 
01761 static bfd_reloc_status_type
01762 mips_elf_gprel16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
01763                      asymbol *symbol, void *data ATTRIBUTE_UNUSED,
01764                      asection *input_section, bfd *output_bfd,
01765                      char **error_message ATTRIBUTE_UNUSED)
01766 {
01767   bfd_boolean relocatable;
01768   bfd_reloc_status_type ret;
01769   bfd_vma gp;
01770 
01771   if (output_bfd != NULL)
01772     relocatable = TRUE;
01773   else
01774     {
01775       relocatable = FALSE;
01776       output_bfd = symbol->section->output_section->owner;
01777     }
01778 
01779   ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
01780                         &gp);
01781   if (ret != bfd_reloc_ok)
01782     return ret;
01783 
01784   return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
01785                                    input_section, relocatable,
01786                                    data, gp);
01787 }
01788 
01789 /* Do a R_MIPS_LITERAL relocation.  */
01790 
01791 static bfd_reloc_status_type
01792 mips_elf_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
01793                      void *data, asection *input_section, bfd *output_bfd,
01794                      char **error_message)
01795 {
01796   bfd_boolean relocatable;
01797   bfd_reloc_status_type ret;
01798   bfd_vma gp;
01799 
01800   /* R_MIPS_LITERAL relocations are defined for local symbols only.  */
01801   if (output_bfd != NULL
01802       && (symbol->flags & BSF_SECTION_SYM) == 0
01803       && (symbol->flags & BSF_LOCAL) != 0)
01804     {
01805       *error_message = (char *)
01806        _("literal relocation occurs for an external symbol");
01807       return bfd_reloc_outofrange;
01808     }
01809 
01810   /* FIXME: The entries in the .lit8 and .lit4 sections should be merged.  */
01811   if (output_bfd != NULL)
01812     relocatable = TRUE;
01813   else
01814     {
01815       relocatable = FALSE;
01816       output_bfd = symbol->section->output_section->owner;
01817     }
01818 
01819   ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
01820                         &gp);
01821   if (ret != bfd_reloc_ok)
01822     return ret;
01823 
01824   return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
01825                                    input_section, relocatable,
01826                                    data, gp);
01827 }
01828 
01829 /* Do a R_MIPS_GPREL32 relocation.  This is a 32 bit value which must
01830    become the offset from the gp register.  */
01831 
01832 static bfd_reloc_status_type
01833 mips_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
01834                      void *data, asection *input_section, bfd *output_bfd,
01835                      char **error_message)
01836 {
01837   bfd_boolean relocatable;
01838   bfd_reloc_status_type ret;
01839   bfd_vma gp;
01840 
01841   /* R_MIPS_GPREL32 relocations are defined for local symbols only.  */
01842   if (output_bfd != NULL
01843       && (symbol->flags & BSF_SECTION_SYM) == 0
01844       && (symbol->flags & BSF_LOCAL) != 0)
01845     {
01846       *error_message = (char *)
01847        _("32bits gp relative relocation occurs for an external symbol");
01848       return bfd_reloc_outofrange;
01849     }
01850 
01851   if (output_bfd != NULL)
01852     {
01853       relocatable = TRUE;
01854       gp = _bfd_get_gp_value (output_bfd);
01855     }
01856   else
01857     {
01858       relocatable = FALSE;
01859       output_bfd = symbol->section->output_section->owner;
01860 
01861       ret = mips_elf_final_gp (output_bfd, symbol, relocatable,
01862                             error_message, &gp);
01863       if (ret != bfd_reloc_ok)
01864        return ret;
01865     }
01866 
01867   return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
01868                        relocatable, data, gp);
01869 }
01870 
01871 static bfd_reloc_status_type
01872 gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
01873                asection *input_section, bfd_boolean relocatable,
01874                void *data, bfd_vma gp)
01875 {
01876   bfd_vma relocation;
01877   unsigned long val;
01878 
01879   if (bfd_is_com_section (symbol->section))
01880     relocation = 0;
01881   else
01882     relocation = symbol->value;
01883 
01884   relocation += symbol->section->output_section->vma;
01885   relocation += symbol->section->output_offset;
01886 
01887   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
01888     return bfd_reloc_outofrange;
01889 
01890   if (reloc_entry->howto->src_mask == 0)
01891     val = 0;
01892   else
01893     val = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
01894 
01895   /* Set val to the offset into the section or symbol.  */
01896   val += reloc_entry->addend;
01897 
01898   /* Adjust val for the final section location and GP value.  If we
01899      are producing relocatable output, we don't want to do this for
01900      an external symbol.  */
01901   if (! relocatable
01902       || (symbol->flags & BSF_SECTION_SYM) != 0)
01903     val += relocation - gp;
01904 
01905   bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
01906 
01907   if (relocatable)
01908     reloc_entry->address += input_section->output_offset;
01909 
01910   return bfd_reloc_ok;
01911 }
01912 
01913 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
01914    the rest is at bits 6-10. The bitpos already got right by the howto.  */
01915 
01916 static bfd_reloc_status_type
01917 mips_elf_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
01918                      void *data, asection *input_section, bfd *output_bfd,
01919                      char **error_message)
01920 {
01921   if (reloc_entry->howto->partial_inplace)
01922     {
01923       reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
01924                           | (reloc_entry->addend & 0x00000800) >> 9);
01925     }
01926 
01927   return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
01928                                   input_section, output_bfd,
01929                                   error_message);
01930 }
01931 
01932 /* Handle a mips16 GP relative reloc.  */
01933 
01934 static bfd_reloc_status_type
01935 mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
01936                   void *data, asection *input_section, bfd *output_bfd,
01937                   char **error_message)
01938 {
01939   bfd_boolean relocatable;
01940   bfd_reloc_status_type ret;
01941   bfd_byte *location;
01942   bfd_vma gp;
01943 
01944   /* If we're relocating, and this is an external symbol, we don't want
01945      to change anything.  */
01946   if (output_bfd != NULL
01947       && (symbol->flags & BSF_SECTION_SYM) == 0
01948       && (symbol->flags & BSF_LOCAL) != 0)
01949     {
01950       reloc_entry->address += input_section->output_offset;
01951       return bfd_reloc_ok;
01952     }
01953 
01954   if (output_bfd != NULL)
01955     relocatable = TRUE;
01956   else
01957     {
01958       relocatable = FALSE;
01959       output_bfd = symbol->section->output_section->owner;
01960     }
01961 
01962   ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
01963                         &gp);
01964   if (ret != bfd_reloc_ok)
01965     return ret;
01966 
01967   location = (bfd_byte *) data + reloc_entry->address;
01968   _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
01969                                location);
01970   ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
01971                                    input_section, relocatable,
01972                                    data, gp);
01973   _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
01974                              location);
01975 
01976   return ret;
01977 }
01978 
01979 /* A mapping from BFD reloc types to MIPS ELF reloc types.  */
01980 
01981 struct elf_reloc_map {
01982   bfd_reloc_code_real_type bfd_val;
01983   enum elf_mips_reloc_type elf_val;
01984 };
01985 
01986 static const struct elf_reloc_map mips_reloc_map[] =
01987 {
01988   { BFD_RELOC_NONE, R_MIPS_NONE },
01989   { BFD_RELOC_16, R_MIPS_16 },
01990   { BFD_RELOC_32, R_MIPS_32 },
01991   /* There is no BFD reloc for R_MIPS_REL32.  */
01992   { BFD_RELOC_CTOR, R_MIPS_32 },
01993   { BFD_RELOC_64, R_MIPS_64 },
01994   { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
01995   { BFD_RELOC_HI16_S, R_MIPS_HI16 },
01996   { BFD_RELOC_LO16, R_MIPS_LO16 },
01997   { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
01998   { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
01999   { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
02000   { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
02001   { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
02002   { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
02003   { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
02004   { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
02005   { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
02006   { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
02007   { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
02008   { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
02009   { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
02010   { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
02011   { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
02012   { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
02013   { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
02014   { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
02015   { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
02016   { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
02017   { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
02018   { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
02019   { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
02020   /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated.  */
02021   { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
02022   { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
02023   { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
02024   { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
02025   { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
02026   { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
02027   { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
02028   { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
02029   { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
02030   { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
02031   { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
02032   { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
02033   { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
02034   { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
02035   { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
02036 };
02037 
02038 static const struct elf_reloc_map mips16_reloc_map[] =
02039 {
02040   { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
02041   { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
02042   { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
02043   { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
02044 };
02045 
02046 /* Given a BFD reloc type, return a howto structure.  */
02047 
02048 static reloc_howto_type *
02049 bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
02050                              bfd_reloc_code_real_type code)
02051 {
02052   unsigned int i;
02053   /* FIXME: We default to RELA here instead of choosing the right
02054      relocation variant.  */
02055   reloc_howto_type *howto_table = elf_mips_howto_table_rela;
02056   reloc_howto_type *howto16_table = elf_mips16_howto_table_rela;
02057 
02058   for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
02059        i++)
02060     {
02061       if (mips_reloc_map[i].bfd_val == code)
02062        return &howto_table[(int) mips_reloc_map[i].elf_val];
02063     }
02064 
02065   for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
02066        i++)
02067     {
02068       if (mips16_reloc_map[i].bfd_val == code)
02069        return &howto16_table[(int) mips16_reloc_map[i].elf_val];
02070     }
02071 
02072   switch (code)
02073     {
02074     case BFD_RELOC_VTABLE_INHERIT:
02075       return &elf_mips_gnu_vtinherit_howto;
02076     case BFD_RELOC_VTABLE_ENTRY:
02077       return &elf_mips_gnu_vtentry_howto;
02078     default:
02079       bfd_set_error (bfd_error_bad_value);
02080       return NULL;
02081     }
02082 }
02083 
02084 static reloc_howto_type *
02085 bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
02086                              const char *r_name)
02087 {
02088   unsigned int i;
02089 
02090   for (i = 0;
02091        i < (sizeof (elf_mips_howto_table_rela)
02092            / sizeof (elf_mips_howto_table_rela[0]));
02093        i++)
02094     if (elf_mips_howto_table_rela[i].name != NULL
02095        && strcasecmp (elf_mips_howto_table_rela[i].name, r_name) == 0)
02096       return &elf_mips_howto_table_rela[i];
02097 
02098   for (i = 0;
02099        i < (sizeof (elf_mips16_howto_table_rela)
02100            / sizeof (elf_mips16_howto_table_rela[0]));
02101        i++)
02102     if (elf_mips16_howto_table_rela[i].name != NULL
02103        && strcasecmp (elf_mips16_howto_table_rela[i].name, r_name) == 0)
02104       return &elf_mips16_howto_table_rela[i];
02105 
02106   if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
02107     return &elf_mips_gnu_vtinherit_howto;
02108   if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
02109     return &elf_mips_gnu_vtentry_howto;
02110   if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
02111     return &elf_mips_gnu_rel16_s2;
02112   if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
02113     return &elf_mips_gnu_rela16_s2;
02114 
02115   return NULL;
02116 }
02117 
02118 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
02119 
02120 static reloc_howto_type *
02121 mips_elf_n32_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
02122 {
02123   switch (r_type)
02124     {
02125     case R_MIPS_GNU_VTINHERIT:
02126       return &elf_mips_gnu_vtinherit_howto;
02127     case R_MIPS_GNU_VTENTRY:
02128       return &elf_mips_gnu_vtentry_howto;
02129     case R_MIPS_GNU_REL16_S2:
02130       if (rela_p)
02131        return &elf_mips_gnu_rela16_s2;
02132       else
02133        return &elf_mips_gnu_rel16_s2;
02134     default:
02135       if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
02136        {
02137          if (rela_p)
02138            return &elf_mips16_howto_table_rela[r_type - R_MIPS16_min];
02139          else
02140            return &elf_mips16_howto_table_rel[r_type - R_MIPS16_min];
02141        }
02142       BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
02143       if (rela_p)
02144        return &elf_mips_howto_table_rela[r_type];
02145       else
02146        return &elf_mips_howto_table_rel[r_type];
02147       break;
02148     }
02149 }
02150 
02151 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
02152 
02153 static void
02154 mips_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
02155 {
02156   unsigned int r_type;
02157 
02158   r_type = ELF32_R_TYPE (dst->r_info);
02159   cache_ptr->howto = mips_elf_n32_rtype_to_howto (r_type, FALSE);
02160 
02161   /* The addend for a GPREL16 or LITERAL relocation comes from the GP
02162      value for the object file.  We get the addend now, rather than
02163      when we do the relocation, because the symbol manipulations done
02164      by the linker may cause us to lose track of the input BFD.  */
02165   if (((*cache_ptr->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
02166       && (r_type == (unsigned int) R_MIPS_GPREL16
02167          || r_type == (unsigned int) R_MIPS_LITERAL))
02168     cache_ptr->addend = elf_gp (abfd);
02169 }
02170 
02171 /* Given a MIPS Elf_Internal_Rela, fill in an arelent structure.  */
02172 
02173 static void
02174 mips_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
02175                       arelent *cache_ptr, Elf_Internal_Rela *dst)
02176 {
02177   unsigned int r_type;
02178 
02179   r_type = ELF32_R_TYPE (dst->r_info);
02180   cache_ptr->howto = mips_elf_n32_rtype_to_howto (r_type, TRUE);
02181   cache_ptr->addend = dst->r_addend;
02182 }
02183 
02184 /* Determine whether a symbol is global for the purposes of splitting
02185    the symbol table into global symbols and local symbols.  At least
02186    on Irix 5, this split must be between section symbols and all other
02187    symbols.  On most ELF targets the split is between static symbols
02188    and externally visible symbols.  */
02189 
02190 static bfd_boolean
02191 mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
02192 {
02193   if (SGI_COMPAT (abfd))
02194     return (sym->flags & BSF_SECTION_SYM) == 0;
02195   else
02196     return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
02197            || bfd_is_und_section (bfd_get_section (sym))
02198            || bfd_is_com_section (bfd_get_section (sym)));
02199 }
02200 
02201 /* Set the right machine number for a MIPS ELF file.  */
02202 
02203 static bfd_boolean
02204 mips_elf_n32_object_p (bfd *abfd)
02205 {
02206   unsigned long mach;
02207 
02208   /* Irix 5 and 6 are broken.  Object file symbol tables are not always
02209      sorted correctly such that local symbols precede global symbols,
02210      and the sh_info field in the symbol table is not always right.  */
02211   if (SGI_COMPAT (abfd))
02212     elf_bad_symtab (abfd) = TRUE;
02213 
02214   mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
02215   bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
02216 
02217   if (! ABI_N32_P(abfd))
02218     return FALSE;
02219 
02220   return TRUE;
02221 }
02222 
02223 /* Support for core dump NOTE sections.  */
02224 static bfd_boolean
02225 elf32_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
02226 {
02227   int offset;
02228   unsigned int size;
02229 
02230   switch (note->descsz)
02231     {
02232       default:
02233        return FALSE;
02234 
02235       case 440:             /* Linux/MIPS N32 */
02236        /* pr_cursig */
02237        elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
02238 
02239        /* pr_pid */
02240        elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
02241 
02242        /* pr_reg */
02243        offset = 72;
02244        size = 360;
02245 
02246        break;
02247     }
02248 
02249   /* Make a ".reg/999" section.  */
02250   return _bfd_elfcore_make_pseudosection (abfd, ".reg", size,
02251                                      note->descpos + offset);
02252 }
02253 
02254 static bfd_boolean
02255 elf32_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
02256 {
02257   switch (note->descsz)
02258     {
02259       default:
02260        return FALSE;
02261 
02262       case 128:             /* Linux/MIPS elf_prpsinfo */
02263        elf_tdata (abfd)->core_program
02264         = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
02265        elf_tdata (abfd)->core_command
02266         = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
02267     }
02268 
02269   /* Note that for some reason, a spurious space is tacked
02270      onto the end of the args in some (at least one anyway)
02271      implementations, so strip it off if it exists.  */
02272 
02273   {
02274     char *command = elf_tdata (abfd)->core_command;
02275     int n = strlen (command);
02276 
02277     if (0 < n && command[n - 1] == ' ')
02278       command[n - 1] = '\0';
02279   }
02280 
02281   return TRUE;
02282 }
02283 
02284 /* Depending on the target vector we generate some version of Irix
02285    executables or "normal" MIPS ELF ABI executables.  */
02286 static irix_compat_t
02287 elf_n32_mips_irix_compat (bfd *abfd)
02288 {
02289   if ((abfd->xvec == &bfd_elf32_nbigmips_vec)
02290       || (abfd->xvec == &bfd_elf32_nlittlemips_vec))
02291     return ict_irix6;
02292   else
02293     return ict_none;
02294 }
02295 
02296 /* ECOFF swapping routines.  These are used when dealing with the
02297    .mdebug section, which is in the ECOFF debugging format.  */
02298 static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
02299   /* Symbol table magic number.  */
02300   magicSym,
02301   /* Alignment of debugging information.  E.g., 4.  */
02302   4,
02303   /* Sizes of external symbolic information.  */
02304   sizeof (struct hdr_ext),
02305   sizeof (struct dnr_ext),
02306   sizeof (struct pdr_ext),
02307   sizeof (struct sym_ext),
02308   sizeof (struct opt_ext),
02309   sizeof (struct fdr_ext),
02310   sizeof (struct rfd_ext),
02311   sizeof (struct ext_ext),
02312   /* Functions to swap in external symbolic data.  */
02313   ecoff_swap_hdr_in,
02314   ecoff_swap_dnr_in,
02315   ecoff_swap_pdr_in,
02316   ecoff_swap_sym_in,
02317   ecoff_swap_opt_in,
02318   ecoff_swap_fdr_in,
02319   ecoff_swap_rfd_in,
02320   ecoff_swap_ext_in,
02321   _bfd_ecoff_swap_tir_in,
02322   _bfd_ecoff_swap_rndx_in,
02323   /* Functions to swap out external symbolic data.  */
02324   ecoff_swap_hdr_out,
02325   ecoff_swap_dnr_out,
02326   ecoff_swap_pdr_out,
02327   ecoff_swap_sym_out,
02328   ecoff_swap_opt_out,
02329   ecoff_swap_fdr_out,
02330   ecoff_swap_rfd_out,
02331   ecoff_swap_ext_out,
02332   _bfd_ecoff_swap_tir_out,
02333   _bfd_ecoff_swap_rndx_out,
02334   /* Function to read in symbolic data.  */
02335   _bfd_mips_elf_read_ecoff_info
02336 };
02337 
02338 #define ELF_ARCH                   bfd_arch_mips
02339 #define ELF_MACHINE_CODE           EM_MIPS
02340 
02341 #define elf_backend_collect        TRUE
02342 #define elf_backend_type_change_ok TRUE
02343 #define elf_backend_can_gc_sections       TRUE
02344 #define elf_info_to_howto          mips_info_to_howto_rela
02345 #define elf_info_to_howto_rel             mips_info_to_howto_rel
02346 #define elf_backend_sym_is_global  mips_elf_sym_is_global
02347 #define elf_backend_object_p              mips_elf_n32_object_p
02348 #define elf_backend_symbol_processing     _bfd_mips_elf_symbol_processing
02349 #define elf_backend_section_processing    _bfd_mips_elf_section_processing
02350 #define elf_backend_section_from_shdr     _bfd_mips_elf_section_from_shdr
02351 #define elf_backend_fake_sections  _bfd_mips_elf_fake_sections
02352 #define elf_backend_section_from_bfd_section \
02353                                    _bfd_mips_elf_section_from_bfd_section
02354 #define elf_backend_add_symbol_hook       _bfd_mips_elf_add_symbol_hook
02355 #define elf_backend_link_output_symbol_hook \
02356                                    _bfd_mips_elf_link_output_symbol_hook
02357 #define elf_backend_create_dynamic_sections \
02358                                    _bfd_mips_elf_create_dynamic_sections
02359 #define elf_backend_check_relocs   _bfd_mips_elf_check_relocs
02360 #define elf_backend_merge_symbol_attribute \
02361                                    _bfd_mips_elf_merge_symbol_attribute
02362 #define elf_backend_adjust_dynamic_symbol \
02363                                    _bfd_mips_elf_adjust_dynamic_symbol
02364 #define elf_backend_always_size_sections \
02365                                    _bfd_mips_elf_always_size_sections
02366 #define elf_backend_size_dynamic_sections \
02367                                    _bfd_mips_elf_size_dynamic_sections
02368 #define elf_backend_init_index_section    _bfd_elf_init_1_index_section
02369 #define elf_backend_relocate_section      _bfd_mips_elf_relocate_section
02370 #define elf_backend_finish_dynamic_symbol \
02371                                    _bfd_mips_elf_finish_dynamic_symbol
02372 #define elf_backend_finish_dynamic_sections \
02373                                    _bfd_mips_elf_finish_dynamic_sections
02374 #define elf_backend_final_write_processing \
02375                                    _bfd_mips_elf_final_write_processing
02376 #define elf_backend_additional_program_headers \
02377                                    _bfd_mips_elf_additional_program_headers
02378 #define elf_backend_modify_segment_map    _bfd_mips_elf_modify_segment_map
02379 #define elf_backend_gc_mark_hook   _bfd_mips_elf_gc_mark_hook
02380 #define elf_backend_gc_sweep_hook  _bfd_mips_elf_gc_sweep_hook
02381 #define elf_backend_copy_indirect_symbol \
02382                                    _bfd_mips_elf_copy_indirect_symbol
02383 #define elf_backend_hide_symbol           _bfd_mips_elf_hide_symbol
02384 #define elf_backend_grok_prstatus  elf32_mips_grok_prstatus
02385 #define elf_backend_grok_psinfo           elf32_mips_grok_psinfo
02386 #define elf_backend_ecoff_debug_swap      &mips_elf32_ecoff_debug_swap
02387 
02388 #define elf_backend_got_header_size       (4 * MIPS_RESERVED_GOTNO)
02389 
02390 /* MIPS n32 ELF can use a mixture of REL and RELA, but some Relocations
02391    work better/work only in RELA, so we default to this.  */
02392 #define elf_backend_may_use_rel_p  1
02393 #define elf_backend_may_use_rela_p 1
02394 #define elf_backend_default_use_rela_p    1
02395 #define elf_backend_sign_extend_vma       TRUE
02396 
02397 #define elf_backend_discard_info   _bfd_mips_elf_discard_info
02398 #define elf_backend_ignore_discarded_relocs \
02399                                    _bfd_mips_elf_ignore_discarded_relocs
02400 #define elf_backend_write_section  _bfd_mips_elf_write_section
02401 #define elf_backend_mips_irix_compat      elf_n32_mips_irix_compat
02402 #define elf_backend_mips_rtype_to_howto   mips_elf_n32_rtype_to_howto
02403 #define bfd_elf32_find_nearest_line       _bfd_mips_elf_find_nearest_line
02404 #define bfd_elf32_find_inliner_info       _bfd_mips_elf_find_inliner_info
02405 #define bfd_elf32_new_section_hook _bfd_mips_elf_new_section_hook
02406 #define bfd_elf32_set_section_contents    _bfd_mips_elf_set_section_contents
02407 #define bfd_elf32_bfd_get_relocated_section_contents \
02408                             _bfd_elf_mips_get_relocated_section_contents
02409 #define bfd_elf32_bfd_link_hash_table_create \
02410                                    _bfd_mips_elf_link_hash_table_create
02411 #define bfd_elf32_bfd_final_link   _bfd_mips_elf_final_link
02412 #define bfd_elf32_bfd_merge_private_bfd_data \
02413                                    _bfd_mips_elf_merge_private_bfd_data
02414 #define bfd_elf32_bfd_set_private_flags   _bfd_mips_elf_set_private_flags
02415 #define bfd_elf32_bfd_print_private_bfd_data \
02416                                    _bfd_mips_elf_print_private_bfd_data
02417 #define bfd_elf32_bfd_relax_section     _bfd_mips_relax_section
02418 
02419 /* Support for SGI-ish mips targets using n32 ABI.  */
02420 
02421 #define TARGET_LITTLE_SYM               bfd_elf32_nlittlemips_vec
02422 #define TARGET_LITTLE_NAME              "elf32-nlittlemips"
02423 #define TARGET_BIG_SYM                  bfd_elf32_nbigmips_vec
02424 #define TARGET_BIG_NAME                 "elf32-nbigmips"
02425 
02426 #define ELF_MAXPAGESIZE                   0x10000
02427 #define ELF_COMMONPAGESIZE         0x1000
02428 
02429 #include "elf32-target.h"
02430 
02431 /* Support for traditional mips targets using n32 ABI.  */
02432 #undef TARGET_LITTLE_SYM
02433 #undef TARGET_LITTLE_NAME
02434 #undef TARGET_BIG_SYM
02435 #undef TARGET_BIG_NAME
02436 
02437 #undef ELF_MAXPAGESIZE
02438 #undef ELF_COMMONPAGESIZE
02439 
02440 #define TARGET_LITTLE_SYM               bfd_elf32_ntradlittlemips_vec
02441 #define TARGET_LITTLE_NAME              "elf32-ntradlittlemips"
02442 #define TARGET_BIG_SYM                  bfd_elf32_ntradbigmips_vec
02443 #define TARGET_BIG_NAME                 "elf32-ntradbigmips"
02444 
02445 #define ELF_MAXPAGESIZE                   0x10000
02446 #define ELF_COMMONPAGESIZE         0x1000
02447 #define elf32_bed                  elf32_tradbed
02448 
02449 /* Include the target file again for this target.  */
02450 #include "elf32-target.h"