Back to index

cell-binutils  2.17cvs20070401
elf32-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 #include "elf-vxworks.h"
00041 
00042 /* Get the ECOFF swapping routines.  */
00043 #include "coff/sym.h"
00044 #include "coff/symconst.h"
00045 #include "coff/internal.h"
00046 #include "coff/ecoff.h"
00047 #include "coff/mips.h"
00048 #define ECOFF_SIGNED_32
00049 #include "ecoffswap.h"
00050 
00051 static bfd_reloc_status_type gprel32_with_gp
00052   (bfd *, asymbol *, arelent *, asection *, bfd_boolean, void *, bfd_vma);
00053 static bfd_reloc_status_type mips_elf_gprel32_reloc
00054   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00055 static bfd_reloc_status_type mips32_64bit_reloc
00056   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00057 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
00058   (bfd *, bfd_reloc_code_real_type);
00059 static reloc_howto_type *mips_elf32_rtype_to_howto
00060   (unsigned int, bfd_boolean);
00061 static void mips_info_to_howto_rel
00062   (bfd *, arelent *, Elf_Internal_Rela *);
00063 static void mips_info_to_howto_rela
00064   (bfd *, arelent *, Elf_Internal_Rela *);
00065 static bfd_boolean mips_elf_sym_is_global
00066   (bfd *, asymbol *);
00067 static bfd_boolean mips_elf32_object_p
00068   (bfd *);
00069 static bfd_boolean mips_elf_is_local_label_name
00070   (bfd *, const char *);
00071 static bfd_reloc_status_type mips16_gprel_reloc
00072   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00073 static bfd_reloc_status_type mips_elf_final_gp
00074   (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *);
00075 static bfd_boolean mips_elf_assign_gp
00076   (bfd *, bfd_vma *);
00077 static bfd_boolean elf32_mips_grok_prstatus
00078   (bfd *, Elf_Internal_Note *);
00079 static bfd_boolean elf32_mips_grok_psinfo
00080   (bfd *, Elf_Internal_Note *);
00081 static irix_compat_t elf32_mips_irix_compat
00082   (bfd *);
00083 
00084 extern const bfd_target bfd_elf32_bigmips_vec;
00085 extern const bfd_target bfd_elf32_littlemips_vec;
00086 
00087 /* Nonzero if ABFD is using the N32 ABI.  */
00088 #define ABI_N32_P(abfd) \
00089   ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0)
00090 
00091 /* Whether we are trying to be compatible with IRIX at all.  */
00092 #define SGI_COMPAT(abfd) \
00093   (elf32_mips_irix_compat (abfd) != ict_none)
00094 
00095 /* The number of local .got entries we reserve.  */
00096 #define MIPS_RESERVED_GOTNO (2)
00097 
00098 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
00099    from smaller values.  Start with zero, widen, *then* decrement.  */
00100 #define MINUS_ONE    (((bfd_vma)0) - 1)
00101 
00102 /* The relocation table used for SHT_REL sections.  */
00103 
00104 static reloc_howto_type elf_mips_howto_table_rel[] =
00105 {
00106   /* No relocation.  */
00107   HOWTO (R_MIPS_NONE,              /* type */
00108         0,                  /* rightshift */
00109         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00110         0,                  /* bitsize */
00111         FALSE,                     /* pc_relative */
00112         0,                  /* bitpos */
00113         complain_overflow_dont, /* complain_on_overflow */
00114         _bfd_mips_elf_generic_reloc, /* special_function */
00115         "R_MIPS_NONE",             /* name */
00116         FALSE,                     /* partial_inplace */
00117         0,                  /* src_mask */
00118         0,                  /* dst_mask */
00119         FALSE),             /* pcrel_offset */
00120 
00121   /* 16 bit relocation.  */
00122   HOWTO (R_MIPS_16,         /* type */
00123         0,                  /* rightshift */
00124         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00125         16,                 /* bitsize */
00126         FALSE,                     /* pc_relative */
00127         0,                  /* bitpos */
00128         complain_overflow_signed, /* complain_on_overflow */
00129         _bfd_mips_elf_generic_reloc, /* special_function */
00130         "R_MIPS_16",        /* name */
00131         TRUE,               /* partial_inplace */
00132         0x0000ffff,         /* src_mask */
00133         0x0000ffff,         /* dst_mask */
00134         FALSE),             /* pcrel_offset */
00135 
00136   /* 32 bit relocation.  */
00137   HOWTO (R_MIPS_32,         /* type */
00138         0,                  /* rightshift */
00139         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00140         32,                 /* bitsize */
00141         FALSE,                     /* pc_relative */
00142         0,                  /* bitpos */
00143         complain_overflow_dont, /* complain_on_overflow */
00144         _bfd_mips_elf_generic_reloc, /* special_function */
00145         "R_MIPS_32",        /* name */
00146         TRUE,               /* partial_inplace */
00147         0xffffffff,         /* src_mask */
00148         0xffffffff,         /* dst_mask */
00149         FALSE),             /* pcrel_offset */
00150 
00151   /* 32 bit symbol relative relocation.  */
00152   HOWTO (R_MIPS_REL32,             /* type */
00153         0,                  /* rightshift */
00154         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00155         32,                 /* bitsize */
00156         FALSE,                     /* pc_relative */
00157         0,                  /* bitpos */
00158         complain_overflow_dont, /* complain_on_overflow */
00159         _bfd_mips_elf_generic_reloc, /* special_function */
00160         "R_MIPS_REL32",     /* name */
00161         TRUE,               /* partial_inplace */
00162         0xffffffff,         /* src_mask */
00163         0xffffffff,         /* dst_mask */
00164         FALSE),             /* pcrel_offset */
00165 
00166   /* 26 bit jump address.  */
00167   HOWTO (R_MIPS_26,         /* type */
00168         2,                  /* rightshift */
00169         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00170         26,                 /* bitsize */
00171         FALSE,                     /* pc_relative */
00172         0,                  /* bitpos */
00173         complain_overflow_dont, /* complain_on_overflow */
00174                             /* This needs complex overflow
00175                                detection, because the upper four
00176                                bits must match the PC + 4.  */
00177         _bfd_mips_elf_generic_reloc, /* special_function */
00178         "R_MIPS_26",        /* name */
00179         TRUE,               /* partial_inplace */
00180         0x03ffffff,         /* src_mask */
00181         0x03ffffff,         /* dst_mask */
00182         FALSE),             /* pcrel_offset */
00183 
00184   /* High 16 bits of symbol value.  */
00185   HOWTO (R_MIPS_HI16,              /* type */
00186         16,                 /* rightshift */
00187         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00188         16,                 /* bitsize */
00189         FALSE,                     /* pc_relative */
00190         0,                  /* bitpos */
00191         complain_overflow_dont, /* complain_on_overflow */
00192         _bfd_mips_elf_hi16_reloc, /* special_function */
00193         "R_MIPS_HI16",             /* name */
00194         TRUE,               /* partial_inplace */
00195         0x0000ffff,         /* src_mask */
00196         0x0000ffff,         /* dst_mask */
00197         FALSE),             /* pcrel_offset */
00198 
00199   /* Low 16 bits of symbol value.  */
00200   HOWTO (R_MIPS_LO16,              /* type */
00201         0,                  /* rightshift */
00202         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00203         16,                 /* bitsize */
00204         FALSE,                     /* pc_relative */
00205         0,                  /* bitpos */
00206         complain_overflow_dont, /* complain_on_overflow */
00207         _bfd_mips_elf_lo16_reloc, /* special_function */
00208         "R_MIPS_LO16",             /* name */
00209         TRUE,               /* partial_inplace */
00210         0x0000ffff,         /* src_mask */
00211         0x0000ffff,         /* dst_mask */
00212         FALSE),             /* pcrel_offset */
00213 
00214   /* GP relative reference.  */
00215   HOWTO (R_MIPS_GPREL16,    /* type */
00216         0,                  /* rightshift */
00217         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00218         16,                 /* bitsize */
00219         FALSE,                     /* pc_relative */
00220         0,                  /* bitpos */
00221         complain_overflow_signed, /* complain_on_overflow */
00222         _bfd_mips_elf32_gprel16_reloc, /* special_function */
00223         "R_MIPS_GPREL16",   /* name */
00224         TRUE,               /* partial_inplace */
00225         0x0000ffff,         /* src_mask */
00226         0x0000ffff,         /* dst_mask */
00227         FALSE),             /* pcrel_offset */
00228 
00229   /* Reference to literal section.  */
00230   HOWTO (R_MIPS_LITERAL,    /* type */
00231         0,                  /* rightshift */
00232         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00233         16,                 /* bitsize */
00234         FALSE,                     /* pc_relative */
00235         0,                  /* bitpos */
00236         complain_overflow_signed, /* complain_on_overflow */
00237         _bfd_mips_elf32_gprel16_reloc, /* special_function */
00238         "R_MIPS_LITERAL",   /* name */
00239         TRUE,               /* partial_inplace */
00240         0x0000ffff,         /* src_mask */
00241         0x0000ffff,         /* dst_mask */
00242         FALSE),             /* pcrel_offset */
00243 
00244   /* Reference to global offset table.  */
00245   HOWTO (R_MIPS_GOT16,             /* type */
00246         0,                  /* rightshift */
00247         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00248         16,                 /* bitsize */
00249         FALSE,                     /* pc_relative */
00250         0,                  /* bitpos */
00251         complain_overflow_signed, /* complain_on_overflow */
00252         _bfd_mips_elf_got16_reloc, /* special_function */
00253         "R_MIPS_GOT16",     /* name */
00254         TRUE,               /* partial_inplace */
00255         0x0000ffff,         /* src_mask */
00256         0x0000ffff,         /* dst_mask */
00257         FALSE),             /* pcrel_offset */
00258 
00259   /* 16 bit PC relative reference.  Note that the ABI document has a typo
00260      and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
00261      We do the right thing here.  */
00262   HOWTO (R_MIPS_PC16,              /* type */
00263         2,                  /* rightshift */
00264         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00265         16,                 /* bitsize */
00266         TRUE,               /* pc_relative */
00267         0,                  /* bitpos */
00268         complain_overflow_signed, /* complain_on_overflow */
00269         _bfd_mips_elf_generic_reloc, /* special_function */
00270         "R_MIPS_PC16",             /* name */
00271         TRUE,               /* partial_inplace */
00272         0x0000ffff,         /* src_mask */
00273         0x0000ffff,         /* dst_mask */
00274         TRUE),                     /* pcrel_offset */
00275 
00276   /* 16 bit call through global offset table.  */
00277   HOWTO (R_MIPS_CALL16,            /* type */
00278         0,                  /* rightshift */
00279         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00280         16,                 /* bitsize */
00281         FALSE,                     /* pc_relative */
00282         0,                  /* bitpos */
00283         complain_overflow_signed, /* complain_on_overflow */
00284         _bfd_mips_elf_generic_reloc, /* special_function */
00285         "R_MIPS_CALL16",    /* name */
00286         TRUE,               /* partial_inplace */
00287         0x0000ffff,         /* src_mask */
00288         0x0000ffff,         /* dst_mask */
00289         FALSE),             /* pcrel_offset */
00290 
00291   /* 32 bit GP relative reference.  */
00292   HOWTO (R_MIPS_GPREL32,    /* type */
00293         0,                  /* rightshift */
00294         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00295         32,                 /* bitsize */
00296         FALSE,                     /* pc_relative */
00297         0,                  /* bitpos */
00298         complain_overflow_dont, /* complain_on_overflow */
00299         mips_elf_gprel32_reloc, /* special_function */
00300         "R_MIPS_GPREL32",   /* name */
00301         TRUE,               /* partial_inplace */
00302         0xffffffff,         /* src_mask */
00303         0xffffffff,         /* dst_mask */
00304         FALSE),             /* pcrel_offset */
00305 
00306   /* The remaining relocs are defined on Irix 5, although they are
00307      not defined by the ABI.  */
00308   EMPTY_HOWTO (13),
00309   EMPTY_HOWTO (14),
00310   EMPTY_HOWTO (15),
00311 
00312   /* A 5 bit shift field.  */
00313   HOWTO (R_MIPS_SHIFT5,            /* type */
00314         0,                  /* rightshift */
00315         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00316         5,                  /* bitsize */
00317         FALSE,                     /* pc_relative */
00318         6,                  /* bitpos */
00319         complain_overflow_bitfield, /* complain_on_overflow */
00320         _bfd_mips_elf_generic_reloc, /* special_function */
00321         "R_MIPS_SHIFT5",    /* name */
00322         TRUE,               /* partial_inplace */
00323         0x000007c0,         /* src_mask */
00324         0x000007c0,         /* dst_mask */
00325         FALSE),             /* pcrel_offset */
00326 
00327   /* A 6 bit shift field.  */
00328   /* FIXME: This is not handled correctly; a special function is
00329      needed to put the most significant bit in the right place.  */
00330   HOWTO (R_MIPS_SHIFT6,            /* type */
00331         0,                  /* rightshift */
00332         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00333         6,                  /* bitsize */
00334         FALSE,                     /* pc_relative */
00335         6,                  /* bitpos */
00336         complain_overflow_bitfield, /* complain_on_overflow */
00337         _bfd_mips_elf_generic_reloc, /* special_function */
00338         "R_MIPS_SHIFT6",    /* name */
00339         TRUE,               /* partial_inplace */
00340         0x000007c4,         /* src_mask */
00341         0x000007c4,         /* dst_mask */
00342         FALSE),             /* pcrel_offset */
00343 
00344   /* A 64 bit relocation.  */
00345   HOWTO (R_MIPS_64,         /* type */
00346         0,                  /* rightshift */
00347         4,                  /* size (0 = byte, 1 = short, 2 = long) */
00348         64,                 /* bitsize */
00349         FALSE,                     /* pc_relative */
00350         0,                  /* bitpos */
00351         complain_overflow_dont, /* complain_on_overflow */
00352         mips32_64bit_reloc, /* special_function */
00353         "R_MIPS_64",        /* name */
00354         TRUE,               /* partial_inplace */
00355         MINUS_ONE,          /* src_mask */
00356         MINUS_ONE,          /* dst_mask */
00357         FALSE),             /* pcrel_offset */
00358 
00359   /* Displacement in the global offset table.  */
00360   HOWTO (R_MIPS_GOT_DISP,   /* type */
00361         0,                  /* rightshift */
00362         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00363         16,                 /* bitsize */
00364         FALSE,                     /* pc_relative */
00365         0,                  /* bitpos */
00366         complain_overflow_signed, /* complain_on_overflow */
00367         _bfd_mips_elf_generic_reloc, /* special_function */
00368         "R_MIPS_GOT_DISP",  /* name */
00369         TRUE,               /* partial_inplace */
00370         0x0000ffff,         /* src_mask */
00371         0x0000ffff,         /* dst_mask */
00372         FALSE),             /* pcrel_offset */
00373 
00374   /* Displacement to page pointer in the global offset table.  */
00375   HOWTO (R_MIPS_GOT_PAGE,   /* type */
00376         0,                  /* rightshift */
00377         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00378         16,                 /* bitsize */
00379         FALSE,                     /* pc_relative */
00380         0,                  /* bitpos */
00381         complain_overflow_signed, /* complain_on_overflow */
00382         _bfd_mips_elf_generic_reloc, /* special_function */
00383         "R_MIPS_GOT_PAGE",  /* name */
00384         TRUE,               /* partial_inplace */
00385         0x0000ffff,         /* src_mask */
00386         0x0000ffff,         /* dst_mask */
00387         FALSE),             /* pcrel_offset */
00388 
00389   /* Offset from page pointer in the global offset table.  */
00390   HOWTO (R_MIPS_GOT_OFST,   /* type */
00391         0,                  /* rightshift */
00392         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00393         16,                 /* bitsize */
00394         FALSE,                     /* pc_relative */
00395         0,                  /* bitpos */
00396         complain_overflow_signed, /* complain_on_overflow */
00397         _bfd_mips_elf_generic_reloc, /* special_function */
00398         "R_MIPS_GOT_OFST",  /* name */
00399         TRUE,               /* partial_inplace */
00400         0x0000ffff,         /* src_mask */
00401         0x0000ffff,         /* dst_mask */
00402         FALSE),             /* pcrel_offset */
00403 
00404   /* High 16 bits of displacement in global offset table.  */
00405   HOWTO (R_MIPS_GOT_HI16,   /* type */
00406         0,                  /* rightshift */
00407         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00408         16,                 /* bitsize */
00409         FALSE,                     /* pc_relative */
00410         0,                  /* bitpos */
00411         complain_overflow_dont, /* complain_on_overflow */
00412         _bfd_mips_elf_generic_reloc, /* special_function */
00413         "R_MIPS_GOT_HI16",  /* name */
00414         TRUE,               /* partial_inplace */
00415         0x0000ffff,         /* src_mask */
00416         0x0000ffff,         /* dst_mask */
00417         FALSE),             /* pcrel_offset */
00418 
00419   /* Low 16 bits of displacement in global offset table.  */
00420   HOWTO (R_MIPS_GOT_LO16,   /* type */
00421         0,                  /* rightshift */
00422         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00423         16,                 /* bitsize */
00424         FALSE,                     /* pc_relative */
00425         0,                  /* bitpos */
00426         complain_overflow_dont, /* complain_on_overflow */
00427         _bfd_mips_elf_generic_reloc, /* special_function */
00428         "R_MIPS_GOT_LO16",  /* name */
00429         TRUE,               /* partial_inplace */
00430         0x0000ffff,         /* src_mask */
00431         0x0000ffff,         /* dst_mask */
00432         FALSE),             /* pcrel_offset */
00433 
00434   /* 64 bit subtraction.  Used in the N32 ABI.  */
00435   HOWTO (R_MIPS_SUB,        /* type */
00436         0,                  /* rightshift */
00437         4,                  /* size (0 = byte, 1 = short, 2 = long) */
00438         64,                 /* bitsize */
00439         FALSE,                     /* pc_relative */
00440         0,                  /* bitpos */
00441         complain_overflow_dont, /* complain_on_overflow */
00442         _bfd_mips_elf_generic_reloc, /* special_function */
00443         "R_MIPS_SUB",              /* name */
00444         TRUE,               /* partial_inplace */
00445         MINUS_ONE,          /* src_mask */
00446         MINUS_ONE,          /* dst_mask */
00447         FALSE),             /* pcrel_offset */
00448 
00449   /* Used to cause the linker to insert and delete instructions?  */
00450   EMPTY_HOWTO (R_MIPS_INSERT_A),
00451   EMPTY_HOWTO (R_MIPS_INSERT_B),
00452   EMPTY_HOWTO (R_MIPS_DELETE),
00453 
00454   /* Get the higher value of a 64 bit addend.  */
00455   HOWTO (R_MIPS_HIGHER,            /* type */
00456         0,                  /* rightshift */
00457         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00458         16,                 /* bitsize */
00459         FALSE,                     /* pc_relative */
00460         0,                  /* bitpos */
00461         complain_overflow_dont, /* complain_on_overflow */
00462         _bfd_mips_elf_generic_reloc, /* special_function */
00463         "R_MIPS_HIGHER",    /* name */
00464         TRUE,               /* partial_inplace */
00465         0x0000ffff,         /* src_mask */
00466         0x0000ffff,         /* dst_mask */
00467         FALSE),             /* pcrel_offset */
00468 
00469   /* Get the highest value of a 64 bit addend.  */
00470   HOWTO (R_MIPS_HIGHEST,    /* type */
00471         0,                  /* rightshift */
00472         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00473         16,                 /* 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_HIGHEST",   /* name */
00479         TRUE,               /* partial_inplace */
00480         0x0000ffff,         /* src_mask */
00481         0x0000ffff,         /* dst_mask */
00482         FALSE),             /* pcrel_offset */
00483 
00484   /* High 16 bits of displacement in global offset table.  */
00485   HOWTO (R_MIPS_CALL_HI16,  /* type */
00486         0,                  /* rightshift */
00487         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00488         16,                 /* bitsize */
00489         FALSE,                     /* pc_relative */
00490         0,                  /* bitpos */
00491         complain_overflow_dont, /* complain_on_overflow */
00492         _bfd_mips_elf_generic_reloc, /* special_function */
00493         "R_MIPS_CALL_HI16", /* name */
00494         TRUE,               /* partial_inplace */
00495         0x0000ffff,         /* src_mask */
00496         0x0000ffff,         /* dst_mask */
00497         FALSE),             /* pcrel_offset */
00498 
00499   /* Low 16 bits of displacement in global offset table.  */
00500   HOWTO (R_MIPS_CALL_LO16,  /* type */
00501         0,                  /* rightshift */
00502         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00503         16,                 /* bitsize */
00504         FALSE,                     /* pc_relative */
00505         0,                  /* bitpos */
00506         complain_overflow_dont, /* complain_on_overflow */
00507         _bfd_mips_elf_generic_reloc, /* special_function */
00508         "R_MIPS_CALL_LO16", /* name */
00509         TRUE,               /* partial_inplace */
00510         0x0000ffff,         /* src_mask */
00511         0x0000ffff,         /* dst_mask */
00512         FALSE),             /* pcrel_offset */
00513 
00514   /* Section displacement.  */
00515   HOWTO (R_MIPS_SCN_DISP,       /* type */
00516         0,                  /* rightshift */
00517         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00518         32,                 /* bitsize */
00519         FALSE,                     /* pc_relative */
00520         0,                  /* bitpos */
00521         complain_overflow_dont, /* complain_on_overflow */
00522         _bfd_mips_elf_generic_reloc, /* special_function */
00523         "R_MIPS_SCN_DISP",     /* name */
00524         TRUE,               /* partial_inplace */
00525         0xffffffff,         /* src_mask */
00526         0xffffffff,         /* dst_mask */
00527         FALSE),             /* pcrel_offset */
00528 
00529   EMPTY_HOWTO (R_MIPS_REL16),
00530   EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
00531   EMPTY_HOWTO (R_MIPS_PJUMP),
00532   EMPTY_HOWTO (R_MIPS_RELGOT),
00533 
00534   /* Protected jump conversion.  This is an optimization hint.  No
00535      relocation is required for correctness.  */
00536   HOWTO (R_MIPS_JALR,               /* type */
00537         0,                  /* rightshift */
00538         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00539         32,                 /* bitsize */
00540         FALSE,                     /* pc_relative */
00541         0,                  /* bitpos */
00542         complain_overflow_dont, /* complain_on_overflow */
00543         _bfd_mips_elf_generic_reloc, /* special_function */
00544         "R_MIPS_JALR",              /* name */
00545         FALSE,                     /* partial_inplace */
00546         0x00000000,         /* src_mask */
00547         0x00000000,         /* dst_mask */
00548         FALSE),             /* pcrel_offset */
00549 
00550   /* TLS GD/LD dynamic relocations.  */
00551   HOWTO (R_MIPS_TLS_DTPMOD32,      /* type */
00552         0,                  /* rightshift */
00553         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00554         32,                 /* bitsize */
00555         FALSE,                     /* pc_relative */
00556         0,                  /* bitpos */
00557         complain_overflow_dont, /* complain_on_overflow */
00558         _bfd_mips_elf_generic_reloc, /* special_function */
00559         "R_MIPS_TLS_DTPMOD32",     /* name */
00560         TRUE,               /* partial_inplace */
00561         0xffffffff,         /* src_mask */
00562         0xffffffff,         /* dst_mask */
00563         FALSE),             /* pcrel_offset */
00564 
00565   HOWTO (R_MIPS_TLS_DTPREL32,      /* type */
00566         0,                  /* rightshift */
00567         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00568         32,                 /* bitsize */
00569         FALSE,                     /* pc_relative */
00570         0,                  /* bitpos */
00571         complain_overflow_dont, /* complain_on_overflow */
00572         _bfd_mips_elf_generic_reloc, /* special_function */
00573         "R_MIPS_TLS_DTPREL32",     /* name */
00574         TRUE,               /* partial_inplace */
00575         0xffffffff,         /* src_mask */
00576         0xffffffff,         /* dst_mask */
00577         FALSE),             /* pcrel_offset */
00578 
00579   EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64),
00580   EMPTY_HOWTO (R_MIPS_TLS_DTPREL64),
00581 
00582   /* TLS general dynamic variable reference.  */
00583   HOWTO (R_MIPS_TLS_GD,            /* type */
00584         0,                  /* rightshift */
00585         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00586         16,                 /* bitsize */
00587         FALSE,                     /* pc_relative */
00588         0,                  /* bitpos */
00589         complain_overflow_signed, /* complain_on_overflow */
00590         _bfd_mips_elf_generic_reloc, /* special_function */
00591         "R_MIPS_TLS_GD",    /* name */
00592         TRUE,               /* partial_inplace */
00593         0x0000ffff,         /* src_mask */
00594         0x0000ffff,         /* dst_mask */
00595         FALSE),             /* pcrel_offset */
00596 
00597   /* TLS local dynamic variable reference.  */
00598   HOWTO (R_MIPS_TLS_LDM,    /* type */
00599         0,                  /* rightshift */
00600         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00601         16,                 /* bitsize */
00602         FALSE,                     /* pc_relative */
00603         0,                  /* bitpos */
00604         complain_overflow_signed, /* complain_on_overflow */
00605         _bfd_mips_elf_generic_reloc, /* special_function */
00606         "R_MIPS_TLS_LDM",   /* name */
00607         TRUE,               /* partial_inplace */
00608         0x0000ffff,         /* src_mask */
00609         0x0000ffff,         /* dst_mask */
00610         FALSE),             /* pcrel_offset */
00611 
00612   /* TLS local dynamic offset.  */
00613   HOWTO (R_MIPS_TLS_DTPREL_HI16,   /* type */
00614         0,                  /* rightshift */
00615         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00616         16,                 /* bitsize */
00617         FALSE,                     /* pc_relative */
00618         0,                  /* bitpos */
00619         complain_overflow_signed, /* complain_on_overflow */
00620         _bfd_mips_elf_generic_reloc, /* special_function */
00621         "R_MIPS_TLS_DTPREL_HI16",  /* name */
00622         TRUE,               /* partial_inplace */
00623         0x0000ffff,         /* src_mask */
00624         0x0000ffff,         /* dst_mask */
00625         FALSE),             /* pcrel_offset */
00626 
00627   /* TLS local dynamic offset.  */
00628   HOWTO (R_MIPS_TLS_DTPREL_LO16,   /* type */
00629         0,                  /* rightshift */
00630         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00631         16,                 /* bitsize */
00632         FALSE,                     /* pc_relative */
00633         0,                  /* bitpos */
00634         complain_overflow_signed, /* complain_on_overflow */
00635         _bfd_mips_elf_generic_reloc, /* special_function */
00636         "R_MIPS_TLS_DTPREL_LO16",  /* name */
00637         TRUE,               /* partial_inplace */
00638         0x0000ffff,         /* src_mask */
00639         0x0000ffff,         /* dst_mask */
00640         FALSE),             /* pcrel_offset */
00641 
00642   /* TLS thread pointer offset.  */
00643   HOWTO (R_MIPS_TLS_GOTTPREL,      /* type */
00644         0,                  /* rightshift */
00645         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00646         16,                 /* bitsize */
00647         FALSE,                     /* pc_relative */
00648         0,                  /* bitpos */
00649         complain_overflow_signed, /* complain_on_overflow */
00650         _bfd_mips_elf_generic_reloc, /* special_function */
00651         "R_MIPS_TLS_GOTTPREL",     /* name */
00652         TRUE,               /* partial_inplace */
00653         0x0000ffff,         /* src_mask */
00654         0x0000ffff,         /* dst_mask */
00655         FALSE),             /* pcrel_offset */
00656 
00657   /* TLS IE dynamic relocations.  */
00658   HOWTO (R_MIPS_TLS_TPREL32,       /* type */
00659         0,                  /* rightshift */
00660         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00661         32,                 /* bitsize */
00662         FALSE,                     /* pc_relative */
00663         0,                  /* bitpos */
00664         complain_overflow_dont, /* complain_on_overflow */
00665         _bfd_mips_elf_generic_reloc, /* special_function */
00666         "R_MIPS_TLS_TPREL32",      /* name */
00667         TRUE,               /* partial_inplace */
00668         0xffffffff,         /* src_mask */
00669         0xffffffff,         /* dst_mask */
00670         FALSE),             /* pcrel_offset */
00671 
00672   EMPTY_HOWTO (R_MIPS_TLS_TPREL64),
00673 
00674   /* TLS thread pointer offset.  */
00675   HOWTO (R_MIPS_TLS_TPREL_HI16,    /* type */
00676         0,                  /* rightshift */
00677         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00678         16,                 /* bitsize */
00679         FALSE,                     /* pc_relative */
00680         0,                  /* bitpos */
00681         complain_overflow_signed, /* complain_on_overflow */
00682         _bfd_mips_elf_generic_reloc, /* special_function */
00683         "R_MIPS_TLS_TPREL_HI16", /* name */
00684         TRUE,               /* partial_inplace */
00685         0x0000ffff,         /* src_mask */
00686         0x0000ffff,         /* dst_mask */
00687         FALSE),             /* pcrel_offset */
00688 
00689   /* TLS thread pointer offset.  */
00690   HOWTO (R_MIPS_TLS_TPREL_LO16,    /* type */
00691         0,                  /* rightshift */
00692         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00693         16,                 /* bitsize */
00694         FALSE,                     /* pc_relative */
00695         0,                  /* bitpos */
00696         complain_overflow_signed, /* complain_on_overflow */
00697         _bfd_mips_elf_generic_reloc, /* special_function */
00698         "R_MIPS_TLS_TPREL_LO16", /* name */
00699         TRUE,               /* partial_inplace */
00700         0x0000ffff,         /* src_mask */
00701         0x0000ffff,         /* dst_mask */
00702         FALSE),             /* pcrel_offset */
00703 
00704   /* 32 bit relocation with no addend.  */
00705   HOWTO (R_MIPS_GLOB_DAT,   /* type */
00706         0,                  /* rightshift */
00707         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00708         32,                 /* bitsize */
00709         FALSE,                     /* pc_relative */
00710         0,                  /* bitpos */
00711         complain_overflow_dont, /* complain_on_overflow */
00712         _bfd_mips_elf_generic_reloc, /* special_function */
00713         "R_MIPS_GLOB_DAT",  /* name */
00714         FALSE,                     /* partial_inplace */
00715         0x0,                /* src_mask */
00716         0xffffffff,         /* dst_mask */
00717         FALSE),             /* pcrel_offset */
00718 };
00719 
00720 /* The reloc used for BFD_RELOC_CTOR when doing a 64 bit link.  This
00721    is a hack to make the linker think that we need 64 bit values.  */
00722 static reloc_howto_type elf_mips_ctor64_howto =
00723   HOWTO (R_MIPS_64,         /* type */
00724         0,                  /* rightshift */
00725         4,                  /* size (0 = byte, 1 = short, 2 = long) */
00726         32,                 /* bitsize */
00727         FALSE,                     /* pc_relative */
00728         0,                  /* bitpos */
00729         complain_overflow_signed, /* complain_on_overflow */
00730         mips32_64bit_reloc, /* special_function */
00731         "R_MIPS_64",        /* name */
00732         TRUE,               /* partial_inplace */
00733         0xffffffff,         /* src_mask */
00734         0xffffffff,         /* dst_mask */
00735         FALSE);             /* pcrel_offset */
00736 
00737 static reloc_howto_type elf_mips16_howto_table_rel[] =
00738 {
00739   /* The reloc used for the mips16 jump instruction.  */
00740   HOWTO (R_MIPS16_26,              /* type */
00741         2,                  /* rightshift */
00742         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00743         26,                 /* bitsize */
00744         FALSE,                     /* pc_relative */
00745         0,                  /* bitpos */
00746         complain_overflow_dont, /* complain_on_overflow */
00747                             /* This needs complex overflow
00748                                detection, because the upper four
00749                                bits must match the PC.  */
00750         _bfd_mips_elf_generic_reloc, /* special_function */
00751         "R_MIPS16_26",             /* name */
00752         TRUE,               /* partial_inplace */
00753         0x3ffffff,          /* src_mask */
00754         0x3ffffff,          /* dst_mask */
00755         FALSE),             /* pcrel_offset */
00756 
00757   /* The reloc used for the mips16 gprel instruction.  */
00758   HOWTO (R_MIPS16_GPREL,    /* type */
00759         0,                  /* rightshift */
00760         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00761         16,                 /* bitsize */
00762         FALSE,                     /* pc_relative */
00763         0,                  /* bitpos */
00764         complain_overflow_signed, /* complain_on_overflow */
00765         mips16_gprel_reloc, /* special_function */
00766         "R_MIPS16_GPREL",   /* name */
00767         TRUE,               /* partial_inplace */
00768         0x0000ffff,         /* src_mask */
00769         0x0000ffff,          /* dst_mask */
00770         FALSE),             /* pcrel_offset */
00771 
00772   /* A placeholder for MIPS16 reference to global offset table.  */
00773   EMPTY_HOWTO (R_MIPS16_GOT16),
00774 
00775   /* A placeholder for MIPS16 16 bit call through global offset table.  */
00776   EMPTY_HOWTO (R_MIPS16_CALL16),
00777 
00778   /* MIPS16 high 16 bits of symbol value.  */
00779   HOWTO (R_MIPS16_HI16,            /* type */
00780         16,                 /* rightshift */
00781         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00782         16,                 /* bitsize */
00783         FALSE,                     /* pc_relative */
00784         0,                  /* bitpos */
00785         complain_overflow_dont, /* complain_on_overflow */
00786         _bfd_mips_elf_hi16_reloc, /* special_function */
00787         "R_MIPS16_HI16",    /* name */
00788         TRUE,               /* partial_inplace */
00789         0x0000ffff,         /* src_mask */
00790         0x0000ffff,          /* dst_mask */
00791         FALSE),             /* pcrel_offset */
00792 
00793   /* MIPS16 low 16 bits of symbol value.  */
00794   HOWTO (R_MIPS16_LO16,            /* 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_dont, /* complain_on_overflow */
00801         _bfd_mips_elf_lo16_reloc, /* special_function */
00802         "R_MIPS16_LO16",    /* name */
00803         TRUE,               /* partial_inplace */
00804         0x0000ffff,         /* src_mask */
00805         0x0000ffff,          /* dst_mask */
00806         FALSE),             /* pcrel_offset */
00807 };
00808 
00809 /* 16 bit offset for pc-relative branches.  */
00810 static reloc_howto_type elf_mips_gnu_rel16_s2 =
00811   HOWTO (R_MIPS_GNU_REL16_S2,      /* type */
00812         2,                  /* rightshift */
00813         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00814         16,                 /* bitsize */
00815         TRUE,               /* pc_relative */
00816         0,                  /* bitpos */
00817         complain_overflow_signed, /* complain_on_overflow */
00818         _bfd_mips_elf_generic_reloc, /* special_function */
00819         "R_MIPS_GNU_REL16_S2",     /* name */
00820         TRUE,               /* partial_inplace */
00821         0xffff,             /* src_mask */
00822         0xffff,             /* dst_mask */
00823         TRUE);                     /* pcrel_offset */
00824 
00825 /* 32 bit pc-relative.  This was a GNU extension used by embedded-PIC.
00826    It was co-opted by mips-linux for exception-handling data.  It is no
00827    longer used, but should continue to be supported by the linker for
00828    backward compatibility.  (GCC stopped using it in May, 2004.)  */
00829 static reloc_howto_type elf_mips_gnu_pcrel32 =
00830   HOWTO (R_MIPS_PC32,              /* type */
00831         0,                  /* rightshift */
00832         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00833         32,                 /* bitsize */
00834         TRUE,               /* pc_relative */
00835         0,                  /* bitpos */
00836         complain_overflow_signed, /* complain_on_overflow */
00837         _bfd_mips_elf_generic_reloc, /* special_function */
00838         "R_MIPS_PC32",             /* name */
00839         TRUE,               /* partial_inplace */
00840         0xffffffff,         /* src_mask */
00841         0xffffffff,         /* dst_mask */
00842         TRUE);                     /* pcrel_offset */
00843 
00844 /* GNU extension to record C++ vtable hierarchy */
00845 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
00846   HOWTO (R_MIPS_GNU_VTINHERIT,     /* type */
00847         0,                  /* rightshift */
00848         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00849         0,                  /* bitsize */
00850         FALSE,                     /* pc_relative */
00851         0,                  /* bitpos */
00852         complain_overflow_dont, /* complain_on_overflow */
00853         NULL,               /* special_function */
00854         "R_MIPS_GNU_VTINHERIT", /* name */
00855         FALSE,                     /* partial_inplace */
00856         0,                  /* src_mask */
00857         0,                  /* dst_mask */
00858         FALSE);             /* pcrel_offset */
00859 
00860 /* GNU extension to record C++ vtable member usage */
00861 static reloc_howto_type elf_mips_gnu_vtentry_howto =
00862   HOWTO (R_MIPS_GNU_VTENTRY,       /* type */
00863         0,                  /* rightshift */
00864         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00865         0,                  /* bitsize */
00866         FALSE,                     /* pc_relative */
00867         0,                  /* bitpos */
00868         complain_overflow_dont, /* complain_on_overflow */
00869         _bfd_elf_rel_vtable_reloc_fn, /* special_function */
00870         "R_MIPS_GNU_VTENTRY",      /* name */
00871         FALSE,                     /* partial_inplace */
00872         0,                  /* src_mask */
00873         0,                  /* dst_mask */
00874         FALSE);             /* pcrel_offset */
00875 
00876 /* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
00877    dangerous relocation.  */
00878 
00879 static bfd_boolean
00880 mips_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
00881 {
00882   unsigned int count;
00883   asymbol **sym;
00884   unsigned int i;
00885 
00886   /* If we've already figured out what GP will be, just return it.  */
00887   *pgp = _bfd_get_gp_value (output_bfd);
00888   if (*pgp)
00889     return TRUE;
00890 
00891   count = bfd_get_symcount (output_bfd);
00892   sym = bfd_get_outsymbols (output_bfd);
00893 
00894   /* The linker script will have created a symbol named `_gp' with the
00895      appropriate value.  */
00896   if (sym == NULL)
00897     i = count;
00898   else
00899     {
00900       for (i = 0; i < count; i++, sym++)
00901        {
00902          register const char *name;
00903 
00904          name = bfd_asymbol_name (*sym);
00905          if (*name == '_' && strcmp (name, "_gp") == 0)
00906            {
00907              *pgp = bfd_asymbol_value (*sym);
00908              _bfd_set_gp_value (output_bfd, *pgp);
00909              break;
00910            }
00911        }
00912     }
00913 
00914   if (i >= count)
00915     {
00916       /* Only get the error once.  */
00917       *pgp = 4;
00918       _bfd_set_gp_value (output_bfd, *pgp);
00919       return FALSE;
00920     }
00921 
00922   return TRUE;
00923 }
00924 
00925 /* We have to figure out the gp value, so that we can adjust the
00926    symbol value correctly.  We look up the symbol _gp in the output
00927    BFD.  If we can't find it, we're stuck.  We cache it in the ELF
00928    target data.  We don't need to adjust the symbol value for an
00929    external symbol if we are producing relocatable output.  */
00930 
00931 static bfd_reloc_status_type
00932 mips_elf_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
00933                  char **error_message, bfd_vma *pgp)
00934 {
00935   if (bfd_is_und_section (symbol->section)
00936       && ! relocatable)
00937     {
00938       *pgp = 0;
00939       return bfd_reloc_undefined;
00940     }
00941 
00942   *pgp = _bfd_get_gp_value (output_bfd);
00943   if (*pgp == 0
00944       && (! relocatable
00945          || (symbol->flags & BSF_SECTION_SYM) != 0))
00946     {
00947       if (relocatable)
00948        {
00949          /* Make up a value.  */
00950          *pgp = symbol->section->output_section->vma + 0x4000;
00951          _bfd_set_gp_value (output_bfd, *pgp);
00952        }
00953       else if (!mips_elf_assign_gp (output_bfd, pgp))
00954        {
00955          *error_message =
00956            (char *) _("GP relative relocation when _gp not defined");
00957          return bfd_reloc_dangerous;
00958        }
00959     }
00960 
00961   return bfd_reloc_ok;
00962 }
00963 
00964 /* Do a R_MIPS_GPREL16 relocation.  This is a 16 bit value which must
00965    become the offset from the gp register.  This function also handles
00966    R_MIPS_LITERAL relocations, although those can be handled more
00967    cleverly because the entries in the .lit8 and .lit4 sections can be
00968    merged.  */
00969 
00970 bfd_reloc_status_type
00971 _bfd_mips_elf32_gprel16_reloc (bfd *abfd, arelent *reloc_entry,
00972                             asymbol *symbol, void *data,
00973                             asection *input_section, bfd *output_bfd,
00974                             char **error_message)
00975 {
00976   bfd_boolean relocatable;
00977   bfd_reloc_status_type ret;
00978   bfd_vma gp;
00979 
00980   /* R_MIPS_LITERAL relocations are defined for local symbols only.  */
00981   if (reloc_entry->howto->type == R_MIPS_LITERAL
00982       && output_bfd != NULL
00983       && (symbol->flags & BSF_SECTION_SYM) == 0
00984       && (symbol->flags & BSF_LOCAL) != 0)
00985     {
00986       *error_message = (char *)
00987        _("literal relocation occurs for an external symbol");
00988       return bfd_reloc_outofrange;
00989     }
00990 
00991   if (output_bfd != NULL)
00992     relocatable = TRUE;
00993   else
00994     {
00995       relocatable = FALSE;
00996       output_bfd = symbol->section->output_section->owner;
00997     }
00998 
00999   ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
01000                         &gp);
01001   if (ret != bfd_reloc_ok)
01002     return ret;
01003 
01004   return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
01005                                    input_section, relocatable,
01006                                    data, gp);
01007 }
01008 
01009 /* Do a R_MIPS_GPREL32 relocation.  This is a 32 bit value which must
01010    become the offset from the gp register.  */
01011 
01012 static bfd_reloc_status_type
01013 mips_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
01014                      void *data, asection *input_section, bfd *output_bfd,
01015                      char **error_message)
01016 {
01017   bfd_boolean relocatable;
01018   bfd_reloc_status_type ret;
01019   bfd_vma gp;
01020 
01021   /* R_MIPS_GPREL32 relocations are defined for local symbols only.  */
01022   if (output_bfd != NULL
01023       && (symbol->flags & BSF_SECTION_SYM) == 0
01024       && (symbol->flags & BSF_LOCAL) != 0)
01025     {
01026       *error_message = (char *)
01027        _("32bits gp relative relocation occurs for an external symbol");
01028       return bfd_reloc_outofrange;
01029     }
01030 
01031   if (output_bfd != NULL)
01032     relocatable = TRUE;
01033   else
01034     {
01035       relocatable = FALSE;
01036       output_bfd = symbol->section->output_section->owner;
01037     }
01038 
01039   ret = mips_elf_final_gp (output_bfd, symbol, relocatable,
01040                         error_message, &gp);
01041   if (ret != bfd_reloc_ok)
01042     return ret;
01043 
01044   return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
01045                        relocatable, data, gp);
01046 }
01047 
01048 static bfd_reloc_status_type
01049 gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
01050                asection *input_section, bfd_boolean relocatable,
01051                void *data, bfd_vma gp)
01052 {
01053   bfd_vma relocation;
01054   bfd_vma val;
01055 
01056   if (bfd_is_com_section (symbol->section))
01057     relocation = 0;
01058   else
01059     relocation = symbol->value;
01060 
01061   relocation += symbol->section->output_section->vma;
01062   relocation += symbol->section->output_offset;
01063 
01064   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
01065     return bfd_reloc_outofrange;
01066 
01067   /* Set val to the offset into the section or symbol.  */
01068   val = reloc_entry->addend;
01069 
01070   if (reloc_entry->howto->partial_inplace)
01071     val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
01072 
01073   /* Adjust val for the final section location and GP value.  If we
01074      are producing relocatable output, we don't want to do this for
01075      an external symbol.  */
01076   if (! relocatable
01077       || (symbol->flags & BSF_SECTION_SYM) != 0)
01078     val += relocation - gp;
01079 
01080   if (reloc_entry->howto->partial_inplace)
01081     bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
01082   else
01083     reloc_entry->addend = val;
01084 
01085   if (relocatable)
01086     reloc_entry->address += input_section->output_offset;
01087 
01088   return bfd_reloc_ok;
01089 }
01090 
01091 /* Handle a 64 bit reloc in a 32 bit MIPS ELF file.  These are
01092    generated when addresses are 64 bits.  The upper 32 bits are a simple
01093    sign extension.  */
01094 
01095 static bfd_reloc_status_type
01096 mips32_64bit_reloc (bfd *abfd, arelent *reloc_entry,
01097                   asymbol *symbol ATTRIBUTE_UNUSED,
01098                   void *data, asection *input_section,
01099                   bfd *output_bfd, char **error_message)
01100 {
01101   bfd_reloc_status_type r;
01102   arelent reloc32;
01103   unsigned long val;
01104   bfd_size_type addr;
01105 
01106   /* Do a normal 32 bit relocation on the lower 32 bits.  */
01107   reloc32 = *reloc_entry;
01108   if (bfd_big_endian (abfd))
01109     reloc32.address += 4;
01110   reloc32.howto = &elf_mips_howto_table_rel[R_MIPS_32];
01111   r = bfd_perform_relocation (abfd, &reloc32, data, input_section,
01112                            output_bfd, error_message);
01113 
01114   /* Sign extend into the upper 32 bits.  */
01115   val = bfd_get_32 (abfd, (bfd_byte *) data + reloc32.address);
01116   if ((val & 0x80000000) != 0)
01117     val = 0xffffffff;
01118   else
01119     val = 0;
01120   addr = reloc_entry->address;
01121   if (bfd_little_endian (abfd))
01122     addr += 4;
01123   bfd_put_32 (abfd, val, (bfd_byte *) data + addr);
01124 
01125   return r;
01126 }
01127 
01128 /* Handle a mips16 GP relative reloc.  */
01129 
01130 static bfd_reloc_status_type
01131 mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
01132                   void *data, asection *input_section, bfd *output_bfd,
01133                   char **error_message)
01134 {
01135   bfd_boolean relocatable;
01136   bfd_reloc_status_type ret;
01137   bfd_byte *location;
01138   bfd_vma gp;
01139 
01140   /* If we're relocating, and this is an external symbol, we don't want
01141      to change anything.  */
01142   if (output_bfd != NULL
01143       && (symbol->flags & BSF_SECTION_SYM) == 0
01144       && (symbol->flags & BSF_LOCAL) != 0)
01145     {
01146       reloc_entry->address += input_section->output_offset;
01147       return bfd_reloc_ok;
01148     }
01149 
01150   if (output_bfd != NULL)
01151     relocatable = TRUE;
01152   else
01153     {
01154       relocatable = FALSE;
01155       output_bfd = symbol->section->output_section->owner;
01156     }
01157 
01158   ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
01159                         &gp);
01160   if (ret != bfd_reloc_ok)
01161     return ret;
01162 
01163   location = (bfd_byte *) data + reloc_entry->address;
01164   _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
01165                                location);
01166   ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
01167                                    input_section, relocatable,
01168                                    data, gp);
01169   _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
01170                              location);
01171 
01172   return ret;
01173 }
01174 
01175 /* A mapping from BFD reloc types to MIPS ELF reloc types.  */
01176 
01177 struct elf_reloc_map {
01178   bfd_reloc_code_real_type bfd_val;
01179   enum elf_mips_reloc_type elf_val;
01180 };
01181 
01182 static const struct elf_reloc_map mips_reloc_map[] =
01183 {
01184   { BFD_RELOC_NONE, R_MIPS_NONE },
01185   { BFD_RELOC_16, R_MIPS_16 },
01186   { BFD_RELOC_32, R_MIPS_32 },
01187   /* There is no BFD reloc for R_MIPS_REL32.  */
01188   { BFD_RELOC_64, R_MIPS_64 },
01189   { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
01190   { BFD_RELOC_HI16_S, R_MIPS_HI16 },
01191   { BFD_RELOC_LO16, R_MIPS_LO16 },
01192   { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
01193   { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
01194   { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
01195   { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
01196   { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
01197   { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
01198   { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
01199   { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
01200   { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
01201   { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
01202   { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
01203   { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
01204   { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
01205   { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
01206   { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
01207   { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
01208   { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
01209   { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
01210   { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
01211   { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
01212   { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
01213   { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
01214   { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
01215   { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
01216   { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
01217   { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
01218   { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
01219 };
01220 
01221 static const struct elf_reloc_map mips16_reloc_map[] =
01222 {
01223   { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
01224   { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
01225   { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
01226   { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
01227 };
01228 
01229 /* Given a BFD reloc type, return a howto structure.  */
01230 
01231 static reloc_howto_type *
01232 bfd_elf32_bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
01233 {
01234   unsigned int i;
01235   reloc_howto_type *howto_table = elf_mips_howto_table_rel;
01236   reloc_howto_type *howto16_table = elf_mips16_howto_table_rel;
01237 
01238   for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
01239        i++)
01240     {
01241       if (mips_reloc_map[i].bfd_val == code)
01242        return &howto_table[(int) mips_reloc_map[i].elf_val];
01243     }
01244 
01245   for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
01246        i++)
01247     {
01248       if (mips16_reloc_map[i].bfd_val == code)
01249        return &howto16_table[(int) mips16_reloc_map[i].elf_val];
01250     }
01251 
01252   switch (code)
01253     {
01254     default:
01255       bfd_set_error (bfd_error_bad_value);
01256       return NULL;
01257 
01258     case BFD_RELOC_CTOR:
01259       /* We need to handle BFD_RELOC_CTOR specially.
01260         Select the right relocation (R_MIPS_32 or R_MIPS_64) based on the
01261         size of addresses of the ABI.  */
01262       if ((elf_elfheader (abfd)->e_flags & (E_MIPS_ABI_O64
01263                                        | E_MIPS_ABI_EABI64)) != 0)
01264        return &elf_mips_ctor64_howto;
01265       else
01266        return &howto_table[(int) R_MIPS_32];
01267 
01268     case BFD_RELOC_VTABLE_INHERIT:
01269       return &elf_mips_gnu_vtinherit_howto;
01270     case BFD_RELOC_VTABLE_ENTRY:
01271       return &elf_mips_gnu_vtentry_howto;
01272     case BFD_RELOC_32_PCREL:
01273       return &elf_mips_gnu_pcrel32;
01274     }
01275 }
01276 
01277 static reloc_howto_type *
01278 bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
01279                              const char *r_name)
01280 {
01281   unsigned int i;
01282 
01283   for (i = 0;
01284        i < (sizeof (elf_mips_howto_table_rel)
01285            / sizeof (elf_mips_howto_table_rel[0]));
01286        i++)
01287     if (elf_mips_howto_table_rel[i].name != NULL
01288        && strcasecmp (elf_mips_howto_table_rel[i].name, r_name) == 0)
01289       return &elf_mips_howto_table_rel[i];
01290 
01291   for (i = 0;
01292        i < (sizeof (elf_mips16_howto_table_rel)
01293            / sizeof (elf_mips16_howto_table_rel[0]));
01294        i++)
01295     if (elf_mips16_howto_table_rel[i].name != NULL
01296        && strcasecmp (elf_mips16_howto_table_rel[i].name, r_name) == 0)
01297       return &elf_mips16_howto_table_rel[i];
01298 
01299   if (strcasecmp (elf_mips_gnu_pcrel32.name, r_name) == 0)
01300     return &elf_mips_gnu_pcrel32;
01301   if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
01302     return &elf_mips_gnu_rel16_s2;
01303   if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
01304     return &elf_mips_gnu_vtinherit_howto;
01305   if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
01306     return &elf_mips_gnu_vtentry_howto;
01307 
01308   return NULL;
01309 }
01310 
01311 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
01312 
01313 static reloc_howto_type *
01314 mips_elf32_rtype_to_howto (unsigned int r_type,
01315                         bfd_boolean rela_p ATTRIBUTE_UNUSED)
01316 {
01317   switch (r_type)
01318     {
01319     case R_MIPS_GNU_VTINHERIT:
01320       return &elf_mips_gnu_vtinherit_howto;
01321     case R_MIPS_GNU_VTENTRY:
01322       return &elf_mips_gnu_vtentry_howto;
01323     case R_MIPS_GNU_REL16_S2:
01324       return &elf_mips_gnu_rel16_s2;
01325     case R_MIPS_PC32:
01326       return &elf_mips_gnu_pcrel32;
01327     default:
01328       if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
01329         return &elf_mips16_howto_table_rel[r_type - R_MIPS16_min];
01330       BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
01331       return &elf_mips_howto_table_rel[r_type];
01332     }
01333 }
01334 
01335 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
01336 
01337 static void
01338 mips_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
01339 {
01340   const struct elf_backend_data *bed;
01341   unsigned int r_type;
01342 
01343   r_type = ELF32_R_TYPE (dst->r_info);
01344   bed = get_elf_backend_data (abfd);
01345   cache_ptr->howto = bed->elf_backend_mips_rtype_to_howto (r_type, FALSE);
01346 
01347   /* The addend for a GPREL16 or LITERAL relocation comes from the GP
01348      value for the object file.  We get the addend now, rather than
01349      when we do the relocation, because the symbol manipulations done
01350      by the linker may cause us to lose track of the input BFD.  */
01351   if (((*cache_ptr->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
01352       && (r_type == (unsigned int) R_MIPS_GPREL16
01353          || r_type == (unsigned int) R_MIPS_LITERAL))
01354     cache_ptr->addend = elf_gp (abfd);
01355 }
01356 
01357 /* Given a MIPS Elf_Internal_Rela, fill in an arelent structure.  */
01358 
01359 static void
01360 mips_info_to_howto_rela (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
01361 {
01362   mips_info_to_howto_rel (abfd, cache_ptr, dst);
01363 
01364   /* If we ever need to do any extra processing with dst->r_addend
01365      (the field omitted in an Elf_Internal_Rel) we can do it here.  */
01366 }
01367 
01368 /* Determine whether a symbol is global for the purposes of splitting
01369    the symbol table into global symbols and local symbols.  At least
01370    on Irix 5, this split must be between section symbols and all other
01371    symbols.  On most ELF targets the split is between static symbols
01372    and externally visible symbols.  */
01373 
01374 static bfd_boolean
01375 mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
01376 {
01377   if (SGI_COMPAT (abfd))
01378     return (sym->flags & BSF_SECTION_SYM) == 0;
01379   else
01380     return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
01381            || bfd_is_und_section (bfd_get_section (sym))
01382            || bfd_is_com_section (bfd_get_section (sym)));
01383 }
01384 
01385 /* Set the right machine number for a MIPS ELF file.  */
01386 
01387 static bfd_boolean
01388 mips_elf32_object_p (bfd *abfd)
01389 {
01390   unsigned long mach;
01391 
01392   /* Irix 5 and 6 are broken.  Object file symbol tables are not always
01393      sorted correctly such that local symbols precede global symbols,
01394      and the sh_info field in the symbol table is not always right.  */
01395   if (SGI_COMPAT (abfd))
01396     elf_bad_symtab (abfd) = TRUE;
01397 
01398   if (ABI_N32_P (abfd))
01399     return FALSE;
01400 
01401   mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
01402   bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
01403 
01404   return TRUE;
01405 }
01406 
01407 /* MIPS ELF local labels start with '$', not 'L'.  */
01408 
01409 static bfd_boolean
01410 mips_elf_is_local_label_name (bfd *abfd, const char *name)
01411 {
01412   if (name[0] == '$')
01413     return TRUE;
01414 
01415   /* On Irix 6, the labels go back to starting with '.', so we accept
01416      the generic ELF local label syntax as well.  */
01417   return _bfd_elf_is_local_label_name (abfd, name);
01418 }
01419 
01420 /* Support for core dump NOTE sections.  */
01421 static bfd_boolean
01422 elf32_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
01423 {
01424   int offset;
01425   unsigned int size;
01426 
01427   switch (note->descsz)
01428     {
01429       default:
01430        return FALSE;
01431 
01432       case 256:             /* Linux/MIPS */
01433        /* pr_cursig */
01434        elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
01435 
01436        /* pr_pid */
01437        elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
01438 
01439        /* pr_reg */
01440        offset = 72;
01441        size = 180;
01442 
01443        break;
01444     }
01445 
01446   /* Make a ".reg/999" section.  */
01447   return _bfd_elfcore_make_pseudosection (abfd, ".reg",
01448                                      size, note->descpos + offset);
01449 }
01450 
01451 static bfd_boolean
01452 elf32_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
01453 {
01454   switch (note->descsz)
01455     {
01456       default:
01457        return FALSE;
01458 
01459       case 128:             /* Linux/MIPS elf_prpsinfo */
01460        elf_tdata (abfd)->core_program
01461         = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
01462        elf_tdata (abfd)->core_command
01463         = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
01464     }
01465 
01466   /* Note that for some reason, a spurious space is tacked
01467      onto the end of the args in some (at least one anyway)
01468      implementations, so strip it off if it exists.  */
01469 
01470   {
01471     char *command = elf_tdata (abfd)->core_command;
01472     int n = strlen (command);
01473 
01474     if (0 < n && command[n - 1] == ' ')
01475       command[n - 1] = '\0';
01476   }
01477 
01478   return TRUE;
01479 }
01480 
01481 /* Depending on the target vector we generate some version of Irix
01482    executables or "normal" MIPS ELF ABI executables.  */
01483 static irix_compat_t
01484 elf32_mips_irix_compat (bfd *abfd)
01485 {
01486   if ((abfd->xvec == &bfd_elf32_bigmips_vec)
01487       || (abfd->xvec == &bfd_elf32_littlemips_vec))
01488     return ict_irix5;
01489   else
01490     return ict_none;
01491 }
01492 
01493 /* ECOFF swapping routines.  These are used when dealing with the
01494    .mdebug section, which is in the ECOFF debugging format.  */
01495 static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
01496   /* Symbol table magic number.  */
01497   magicSym,
01498   /* Alignment of debugging information.  E.g., 4.  */
01499   4,
01500   /* Sizes of external symbolic information.  */
01501   sizeof (struct hdr_ext),
01502   sizeof (struct dnr_ext),
01503   sizeof (struct pdr_ext),
01504   sizeof (struct sym_ext),
01505   sizeof (struct opt_ext),
01506   sizeof (struct fdr_ext),
01507   sizeof (struct rfd_ext),
01508   sizeof (struct ext_ext),
01509   /* Functions to swap in external symbolic data.  */
01510   ecoff_swap_hdr_in,
01511   ecoff_swap_dnr_in,
01512   ecoff_swap_pdr_in,
01513   ecoff_swap_sym_in,
01514   ecoff_swap_opt_in,
01515   ecoff_swap_fdr_in,
01516   ecoff_swap_rfd_in,
01517   ecoff_swap_ext_in,
01518   _bfd_ecoff_swap_tir_in,
01519   _bfd_ecoff_swap_rndx_in,
01520   /* Functions to swap out external symbolic data.  */
01521   ecoff_swap_hdr_out,
01522   ecoff_swap_dnr_out,
01523   ecoff_swap_pdr_out,
01524   ecoff_swap_sym_out,
01525   ecoff_swap_opt_out,
01526   ecoff_swap_fdr_out,
01527   ecoff_swap_rfd_out,
01528   ecoff_swap_ext_out,
01529   _bfd_ecoff_swap_tir_out,
01530   _bfd_ecoff_swap_rndx_out,
01531   /* Function to read in symbolic data.  */
01532   _bfd_mips_elf_read_ecoff_info
01533 };
01534 
01535 #define ELF_ARCH                   bfd_arch_mips
01536 #define ELF_MACHINE_CODE           EM_MIPS
01537 
01538 #define elf_backend_collect        TRUE
01539 #define elf_backend_type_change_ok TRUE
01540 #define elf_backend_can_gc_sections       TRUE
01541 #define elf_info_to_howto          mips_info_to_howto_rela
01542 #define elf_info_to_howto_rel             mips_info_to_howto_rel
01543 #define elf_backend_sym_is_global  mips_elf_sym_is_global
01544 #define elf_backend_object_p              mips_elf32_object_p
01545 #define elf_backend_symbol_processing     _bfd_mips_elf_symbol_processing
01546 #define elf_backend_section_processing    _bfd_mips_elf_section_processing
01547 #define elf_backend_section_from_shdr     _bfd_mips_elf_section_from_shdr
01548 #define elf_backend_fake_sections  _bfd_mips_elf_fake_sections
01549 #define elf_backend_section_from_bfd_section \
01550                                    _bfd_mips_elf_section_from_bfd_section
01551 #define elf_backend_add_symbol_hook       _bfd_mips_elf_add_symbol_hook
01552 #define elf_backend_link_output_symbol_hook \
01553                                    _bfd_mips_elf_link_output_symbol_hook
01554 #define elf_backend_create_dynamic_sections \
01555                                    _bfd_mips_elf_create_dynamic_sections
01556 #define elf_backend_check_relocs   _bfd_mips_elf_check_relocs
01557 #define elf_backend_merge_symbol_attribute \
01558                                    _bfd_mips_elf_merge_symbol_attribute
01559 #define elf_backend_adjust_dynamic_symbol \
01560                                    _bfd_mips_elf_adjust_dynamic_symbol
01561 #define elf_backend_always_size_sections \
01562                                    _bfd_mips_elf_always_size_sections
01563 #define elf_backend_size_dynamic_sections \
01564                                    _bfd_mips_elf_size_dynamic_sections
01565 #define elf_backend_init_index_section    _bfd_elf_init_1_index_section
01566 #define elf_backend_relocate_section      _bfd_mips_elf_relocate_section
01567 #define elf_backend_finish_dynamic_symbol \
01568                                    _bfd_mips_elf_finish_dynamic_symbol
01569 #define elf_backend_finish_dynamic_sections \
01570                                    _bfd_mips_elf_finish_dynamic_sections
01571 #define elf_backend_final_write_processing \
01572                                    _bfd_mips_elf_final_write_processing
01573 #define elf_backend_additional_program_headers \
01574                                    _bfd_mips_elf_additional_program_headers
01575 #define elf_backend_modify_segment_map    _bfd_mips_elf_modify_segment_map
01576 #define elf_backend_gc_mark_hook   _bfd_mips_elf_gc_mark_hook
01577 #define elf_backend_gc_sweep_hook  _bfd_mips_elf_gc_sweep_hook
01578 #define elf_backend_copy_indirect_symbol \
01579                                    _bfd_mips_elf_copy_indirect_symbol
01580 #define elf_backend_hide_symbol           _bfd_mips_elf_hide_symbol
01581 #define elf_backend_grok_prstatus  elf32_mips_grok_prstatus
01582 #define elf_backend_grok_psinfo           elf32_mips_grok_psinfo
01583 #define elf_backend_ecoff_debug_swap      &mips_elf32_ecoff_debug_swap
01584 
01585 #define elf_backend_got_header_size       (4 * MIPS_RESERVED_GOTNO)
01586 #define elf_backend_may_use_rel_p  1
01587 #define elf_backend_may_use_rela_p 0
01588 #define elf_backend_default_use_rela_p    0
01589 #define elf_backend_sign_extend_vma       TRUE
01590 
01591 #define elf_backend_discard_info   _bfd_mips_elf_discard_info
01592 #define elf_backend_ignore_discarded_relocs \
01593                                    _bfd_mips_elf_ignore_discarded_relocs
01594 #define elf_backend_mips_irix_compat      elf32_mips_irix_compat
01595 #define elf_backend_mips_rtype_to_howto   mips_elf32_rtype_to_howto
01596 #define bfd_elf32_bfd_is_local_label_name \
01597                                    mips_elf_is_local_label_name
01598 #define bfd_elf32_find_nearest_line       _bfd_mips_elf_find_nearest_line
01599 #define bfd_elf32_find_inliner_info       _bfd_mips_elf_find_inliner_info
01600 #define bfd_elf32_new_section_hook _bfd_mips_elf_new_section_hook
01601 #define bfd_elf32_set_section_contents    _bfd_mips_elf_set_section_contents
01602 #define bfd_elf32_bfd_get_relocated_section_contents \
01603                             _bfd_elf_mips_get_relocated_section_contents
01604 #define bfd_elf32_bfd_link_hash_table_create \
01605                                    _bfd_mips_elf_link_hash_table_create
01606 #define bfd_elf32_bfd_final_link   _bfd_mips_elf_final_link
01607 #define bfd_elf32_bfd_merge_private_bfd_data \
01608                                    _bfd_mips_elf_merge_private_bfd_data
01609 #define bfd_elf32_bfd_set_private_flags   _bfd_mips_elf_set_private_flags
01610 #define bfd_elf32_bfd_print_private_bfd_data \
01611                                    _bfd_mips_elf_print_private_bfd_data
01612 
01613 /* Support for SGI-ish mips targets.  */
01614 #define TARGET_LITTLE_SYM          bfd_elf32_littlemips_vec
01615 #define TARGET_LITTLE_NAME         "elf32-littlemips"
01616 #define TARGET_BIG_SYM                    bfd_elf32_bigmips_vec
01617 #define TARGET_BIG_NAME                   "elf32-bigmips"
01618 
01619 /* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
01620    a value of 0x1000, and we are compatible.  */
01621 #define ELF_MAXPAGESIZE                   0x1000
01622 #define ELF_COMMONPAGESIZE         0x1000
01623 
01624 #include "elf32-target.h"
01625 
01626 /* Support for traditional mips targets.  */
01627 #undef TARGET_LITTLE_SYM
01628 #undef TARGET_LITTLE_NAME
01629 #undef TARGET_BIG_SYM
01630 #undef TARGET_BIG_NAME
01631 
01632 #undef ELF_MAXPAGESIZE
01633 #undef ELF_COMMONPAGESIZE
01634 
01635 #define TARGET_LITTLE_SYM               bfd_elf32_tradlittlemips_vec
01636 #define TARGET_LITTLE_NAME              "elf32-tradlittlemips"
01637 #define TARGET_BIG_SYM                  bfd_elf32_tradbigmips_vec
01638 #define TARGET_BIG_NAME                 "elf32-tradbigmips"
01639 
01640 /* The MIPS ABI says at Page 5-1:
01641    Virtual addresses and file offsets for MIPS segments are congruent
01642    modulo 64 KByte (0x10000) or larger powers of 2.  Because 64 KBytes
01643    is the maximum page size, the files are suitable for paging
01644    regardless of physical page size.  */
01645 #define ELF_MAXPAGESIZE                   0x10000
01646 #define ELF_COMMONPAGESIZE         0x1000
01647 #define elf32_bed                  elf32_tradbed
01648 
01649 /* Include the target file again for this target.  */
01650 #include "elf32-target.h"
01651 
01652 
01653 /* Specific to VxWorks.  */
01654 static reloc_howto_type mips_vxworks_copy_howto_rela =
01655   HOWTO (R_MIPS_COPY,              /* type */
01656         0,                  /* rightshift */
01657         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01658         32,                 /* bitsize */
01659         FALSE,                     /* pc_relative */
01660         0,                  /* bitpos */
01661         complain_overflow_bitfield, /* complain_on_overflow */
01662         bfd_elf_generic_reloc,     /* special_function */
01663         "R_MIPS_COPY",             /* name */
01664         FALSE,                     /* partial_inplace */
01665         0x0,                       /* src_mask */
01666         0x0,                 /* dst_mask */
01667         FALSE);             /* pcrel_offset */
01668 
01669 /* Specific to VxWorks.  */
01670 static reloc_howto_type mips_vxworks_jump_slot_howto_rela =
01671   HOWTO (R_MIPS_JUMP_SLOT,  /* type */
01672         0,                  /* rightshift */
01673         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01674         32,                 /* bitsize */
01675         FALSE,                     /* pc_relative */
01676         0,                  /* bitpos */
01677         complain_overflow_bitfield, /* complain_on_overflow */
01678         bfd_elf_generic_reloc,     /* special_function */
01679         "R_MIPS_JUMP_SLOT", /* name */
01680         FALSE,                     /* partial_inplace */
01681         0x0,                       /* src_mask */
01682         0x0,                 /* dst_mask */
01683         FALSE);             /* pcrel_offset */
01684 
01685 /* Implement elf_backend_bfd_reloc_type_lookup for VxWorks.  */
01686 
01687 static reloc_howto_type *
01688 mips_vxworks_bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
01689 {
01690   switch (code)
01691     {
01692     case BFD_RELOC_MIPS_COPY:
01693       return &mips_vxworks_copy_howto_rela;
01694     case BFD_RELOC_MIPS_JUMP_SLOT:
01695       return &mips_vxworks_jump_slot_howto_rela;
01696     default:
01697       return bfd_elf32_bfd_reloc_type_lookup (abfd, code);
01698     }
01699 }
01700 
01701 static reloc_howto_type *
01702 mips_vxworks_bfd_reloc_name_lookup (bfd *abfd, const char *r_name)
01703 {
01704   if (strcasecmp (mips_vxworks_copy_howto_rela.name, r_name) == 0)
01705     return &mips_vxworks_copy_howto_rela;
01706   if (strcasecmp (mips_vxworks_jump_slot_howto_rela.name, r_name) == 0)
01707     return &mips_vxworks_jump_slot_howto_rela;
01708 
01709   return bfd_elf32_bfd_reloc_name_lookup (abfd, r_name);
01710 }
01711 
01712 /* Implement elf_backend_mips_rtype_to_lookup for VxWorks.  */
01713 
01714 static reloc_howto_type *
01715 mips_vxworks_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
01716 {
01717   switch (r_type)
01718     {
01719     case R_MIPS_COPY:
01720       return &mips_vxworks_copy_howto_rela;
01721     case R_MIPS_JUMP_SLOT:
01722       return &mips_vxworks_jump_slot_howto_rela;
01723     default:
01724       return mips_elf32_rtype_to_howto (r_type, rela_p);
01725     }
01726 }
01727 
01728 /* Implement elf_backend_final_write_processing for VxWorks.  */
01729 
01730 static void
01731 mips_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
01732 {
01733   _bfd_mips_elf_final_write_processing (abfd, linker);
01734   elf_vxworks_final_write_processing (abfd, linker);
01735 }
01736 
01737 #undef TARGET_LITTLE_SYM
01738 #undef TARGET_LITTLE_NAME
01739 #undef TARGET_BIG_SYM
01740 #undef TARGET_BIG_NAME
01741 
01742 #undef ELF_MAXPAGESIZE
01743 #undef ELF_COMMONPAGESIZE
01744 
01745 #define TARGET_LITTLE_SYM               bfd_elf32_littlemips_vxworks_vec
01746 #define TARGET_LITTLE_NAME              "elf32-littlemips-vxworks"
01747 #define TARGET_BIG_SYM                  bfd_elf32_bigmips_vxworks_vec
01748 #define TARGET_BIG_NAME                 "elf32-bigmips-vxworks"
01749 
01750 #undef elf32_bed
01751 #define elf32_bed                  elf32_mips_vxworks_bed
01752 
01753 #define ELF_MAXPAGESIZE                   0x1000
01754 #define ELF_COMMONPAGESIZE         0x1000
01755 
01756 #undef elf_backend_want_got_plt
01757 #define elf_backend_want_got_plt          1
01758 #undef elf_backend_want_plt_sym
01759 #define elf_backend_want_plt_sym          1
01760 #undef elf_backend_got_symbol_offset
01761 #define elf_backend_got_symbol_offset            0
01762 #undef elf_backend_want_dynbss
01763 #define elf_backend_want_dynbss                  1
01764 #undef elf_backend_may_use_rel_p
01765 #define elf_backend_may_use_rel_p         0
01766 #undef elf_backend_may_use_rela_p
01767 #define elf_backend_may_use_rela_p        1
01768 #undef elf_backend_default_use_rela_p
01769 #define elf_backend_default_use_rela_p           1
01770 #undef elf_backend_got_header_size
01771 #define elf_backend_got_header_size              (4 * 3)
01772 #undef elf_backend_plt_readonly
01773 #define elf_backend_plt_readonly          1
01774 
01775 #undef bfd_elf32_bfd_reloc_type_lookup
01776 #define bfd_elf32_bfd_reloc_type_lookup \
01777   mips_vxworks_bfd_reloc_type_lookup
01778 #undef bfd_elf32_bfd_reloc_name_lookup
01779 #define bfd_elf32_bfd_reloc_name_lookup \
01780   mips_vxworks_bfd_reloc_name_lookup
01781 #undef elf_backend_mips_rtype_to_howto
01782 #define elf_backend_mips_rtype_to_howto   \
01783   mips_vxworks_rtype_to_howto
01784 #undef elf_backend_adjust_dynamic_symbol
01785 #define elf_backend_adjust_dynamic_symbol \
01786   _bfd_mips_vxworks_adjust_dynamic_symbol
01787 #undef elf_backend_finish_dynamic_symbol
01788 #define elf_backend_finish_dynamic_symbol \
01789   _bfd_mips_vxworks_finish_dynamic_symbol
01790 #undef bfd_elf32_bfd_link_hash_table_create
01791 #define bfd_elf32_bfd_link_hash_table_create \
01792   _bfd_mips_vxworks_link_hash_table_create
01793 #undef elf_backend_add_symbol_hook
01794 #define elf_backend_add_symbol_hook \
01795   elf_vxworks_add_symbol_hook
01796 #undef elf_backend_link_output_symbol_hook
01797 #define elf_backend_link_output_symbol_hook \
01798   elf_vxworks_link_output_symbol_hook
01799 #undef elf_backend_emit_relocs
01800 #define elf_backend_emit_relocs \
01801   elf_vxworks_emit_relocs
01802 #undef elf_backend_final_write_processing
01803 #define elf_backend_final_write_processing \
01804   mips_vxworks_final_write_processing
01805 
01806 #undef elf_backend_additional_program_headers
01807 #undef elf_backend_modify_segment_map
01808 #undef elf_backend_symbol_processing
01809 /* NOTE: elf_backend_rela_normal is not defined for MIPS.  */
01810 
01811 #include "elf32-target.h"