X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Felf64-mips.c;h=34b02e47473a097614950ad87648817cee6c78b2;hb=bce613b9bfac3b56f4f9742776db11aeec875300;hp=46d9a92cb5b7cb5897a4b2320de27f98d8f41335;hpb=0b25d3e680e7631033d5cce5dd4d797dbc0b039c;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c index 46d9a92cb5..34b02e4747 100644 --- a/bfd/elf64-mips.c +++ b/bfd/elf64-mips.c @@ -1,5 +1,5 @@ /* MIPS-specific support for 64-bit ELF - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Ian Lance Taylor, Cygnus Support Linker support added by Mark Mitchell, CodeSourcery, LLC. @@ -19,7 +19,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ /* This file supports the 64-bit MIPS ELF ABI. @@ -62,79 +62,70 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "ecoffswap.h" static void mips_elf64_swap_reloc_in - PARAMS ((bfd *, const Elf64_Mips_External_Rel *, - Elf64_Mips_Internal_Rela *)); + (bfd *, const Elf64_Mips_External_Rel *, Elf64_Mips_Internal_Rela *); static void mips_elf64_swap_reloca_in - PARAMS ((bfd *, const Elf64_Mips_External_Rela *, - Elf64_Mips_Internal_Rela *)); + (bfd *, const Elf64_Mips_External_Rela *, Elf64_Mips_Internal_Rela *); static void mips_elf64_swap_reloc_out - PARAMS ((bfd *, const Elf64_Mips_Internal_Rela *, - Elf64_Mips_External_Rel *)); + (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rel *); static void mips_elf64_swap_reloca_out - PARAMS ((bfd *, const Elf64_Mips_Internal_Rela *, - Elf64_Mips_External_Rela *)); + (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rela *); static void mips_elf64_be_swap_reloc_in - PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rela *)); + (bfd *, const bfd_byte *, Elf_Internal_Rela *); static void mips_elf64_be_swap_reloc_out - PARAMS ((bfd *, const Elf_Internal_Rela *, bfd_byte *)); + (bfd *, const Elf_Internal_Rela *, bfd_byte *); static void mips_elf64_be_swap_reloca_in - PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rela *)); + (bfd *, const bfd_byte *, Elf_Internal_Rela *); static void mips_elf64_be_swap_reloca_out - PARAMS ((bfd *, const Elf_Internal_Rela *, bfd_byte *)); + (bfd *, const Elf_Internal_Rela *, bfd_byte *); static reloc_howto_type *bfd_elf64_bfd_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); + (bfd *, bfd_reloc_code_real_type); static reloc_howto_type *mips_elf64_rtype_to_howto - PARAMS ((unsigned int, bfd_boolean)); + (unsigned int, bfd_boolean); static void mips_elf64_info_to_howto_rel - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); + (bfd *, arelent *, Elf_Internal_Rela *); static void mips_elf64_info_to_howto_rela - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); + (bfd *, arelent *, Elf_Internal_Rela *); static long mips_elf64_get_reloc_upper_bound - PARAMS ((bfd *, asection *)); + (bfd *, asection *); static long mips_elf64_canonicalize_reloc - PARAMS ((bfd *, asection *, arelent **, asymbol **)); -static long mips_elf64_get_dynamic_reloc_upper_bound PARAMS ((bfd *)); + (bfd *, asection *, arelent **, asymbol **); +static long mips_elf64_get_dynamic_reloc_upper_bound + (bfd *); static long mips_elf64_canonicalize_dynamic_reloc - PARAMS ((bfd *, arelent **, asymbol **)); + (bfd *, arelent **, asymbol **); static bfd_boolean mips_elf64_slurp_one_reloc_table - PARAMS ((bfd *, asection *, Elf_Internal_Shdr *, bfd_size_type, - arelent *, asymbol **, bfd_boolean)); + (bfd *, asection *, Elf_Internal_Shdr *, bfd_size_type, arelent *, + asymbol **, bfd_boolean); static bfd_boolean mips_elf64_slurp_reloc_table - PARAMS ((bfd *, asection *, asymbol **, bfd_boolean)); + (bfd *, asection *, asymbol **, bfd_boolean); static void mips_elf64_write_relocs - PARAMS ((bfd *, asection *, PTR)); + (bfd *, asection *, void *); static void mips_elf64_write_rel - PARAMS((bfd *, asection *, Elf_Internal_Shdr *, int *, PTR)); + (bfd *, asection *, Elf_Internal_Shdr *, int *, void *); static void mips_elf64_write_rela - PARAMS((bfd *, asection *, Elf_Internal_Shdr *, int *, PTR)); -static bfd_reloc_status_type mips_elf64_hi16_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); + (bfd *, asection *, Elf_Internal_Shdr *, int *, void *); static bfd_reloc_status_type mips_elf64_gprel16_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); static bfd_reloc_status_type mips_elf64_literal_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); static bfd_reloc_status_type mips_elf64_gprel32_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); static bfd_reloc_status_type mips_elf64_shift6_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static bfd_reloc_status_type mips_elf64_got16_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static bfd_reloc_status_type mips16_jump_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); static bfd_reloc_status_type mips16_gprel_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); static bfd_boolean mips_elf64_assign_gp - PARAMS ((bfd *, bfd_vma *)); + (bfd *, bfd_vma *); static bfd_reloc_status_type mips_elf64_final_gp - PARAMS ((bfd *, asymbol *, bfd_boolean, char **, bfd_vma *)); + (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *); static bfd_boolean mips_elf64_object_p - PARAMS ((bfd *)); + (bfd *); static irix_compat_t elf64_mips_irix_compat - PARAMS ((bfd *)); + (bfd *); static bfd_boolean elf64_mips_grok_prstatus - PARAMS ((bfd *, Elf_Internal_Note *)); + (bfd *, Elf_Internal_Note *); static bfd_boolean elf64_mips_grok_psinfo - PARAMS ((bfd *, Elf_Internal_Note *)); + (bfd *, Elf_Internal_Note *); extern const bfd_target bfd_elf64_bigmips_vec; extern const bfd_target bfd_elf64_littlemips_vec; @@ -158,7 +149,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_NONE", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -173,7 +164,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -188,7 +179,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_32", /* name */ TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ @@ -203,7 +194,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_REL32", /* name */ TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ @@ -221,7 +212,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = /* This needs complex overflow detection, because the upper 36 bits must match the PC + 4. */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_26", /* name */ TRUE, /* partial_inplace */ 0x03ffffff, /* src_mask */ @@ -233,13 +224,13 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = /* High 16 bits of symbol value. */ HOWTO (R_MIPS_HI16, /* type */ - 0, /* rightshift */ + 16, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf64_hi16_reloc, /* special_function */ + _bfd_mips_elf_hi16_reloc, /* special_function */ "R_MIPS_HI16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -254,7 +245,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_lo16_reloc, /* special_function */ "R_MIPS_LO16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -299,22 +290,24 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf64_got16_reloc, /* special_function */ + _bfd_mips_elf_got16_reloc, /* special_function */ "R_MIPS_GOT16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* 16 bit PC relative reference. */ + /* 16 bit PC relative reference. Note that the ABI document has a typo + and claims R_MIPS_PC16 to be not rightshifted, rendering it useless. + We do the right thing here. */ HOWTO (R_MIPS_PC16, /* type */ - 0, /* rightshift */ + 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_PC16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -329,7 +322,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_CALL16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -363,7 +356,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 6, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_SHIFT5", /* name */ TRUE, /* partial_inplace */ 0x000007c0, /* src_mask */ @@ -393,7 +386,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_64", /* name */ TRUE, /* partial_inplace */ MINUS_ONE, /* src_mask */ @@ -408,7 +401,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_DISP", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -423,7 +416,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_PAGE", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -438,7 +431,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_OFST", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -453,7 +446,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_HI16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -468,14 +461,14 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_LO16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* 64 bit substraction. */ + /* 64 bit subtraction. */ HOWTO (R_MIPS_SUB, /* type */ 0, /* rightshift */ 4, /* size (0 = byte, 1 = short, 2 = long) */ @@ -483,7 +476,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_SUB", /* name */ TRUE, /* partial_inplace */ MINUS_ONE, /* src_mask */ @@ -499,7 +492,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_INSERT_A", /* name */ TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ @@ -516,7 +509,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_INSERT_B", /* name */ TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ @@ -532,7 +525,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_DELETE", /* name */ TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ @@ -556,7 +549,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_CALL_HI16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -571,7 +564,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_CALL_LO16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -586,7 +579,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_SCN_DISP", /* name */ TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ @@ -600,7 +593,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_REL16", /* name */ TRUE, /* partial_inplace */ 0xffff, /* src_mask */ @@ -620,7 +613,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_RELGOT", /* name */ TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ @@ -629,19 +622,188 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = /* Protected jump conversion. This is an optimization hint. No relocation is required for correctness. */ - HOWTO (R_MIPS_JALR, /* type */ + HOWTO (R_MIPS_JALR, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_JALR", /* name */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_JALR", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x00000000, /* dst_mask */ FALSE), /* pcrel_offset */ + + /* TLS relocations. */ + EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32), + EMPTY_HOWTO (R_MIPS_TLS_DTPREL32), + + HOWTO (R_MIPS_TLS_DTPMOD64, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_DTPMOD64", /* name */ + TRUE, /* partial_inplace */ + MINUS_ONE, /* src_mask */ + MINUS_ONE, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_MIPS_TLS_DTPREL64, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_DTPREL64", /* name */ + TRUE, /* partial_inplace */ + MINUS_ONE, /* src_mask */ + MINUS_ONE, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* TLS general dynamic variable reference. */ + HOWTO (R_MIPS_TLS_GD, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_GD", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* TLS local dynamic variable reference. */ + HOWTO (R_MIPS_TLS_LDM, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_LDM", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* TLS local dynamic offset. */ + HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_DTPREL_HI16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* TLS local dynamic offset. */ + HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_DTPREL_LO16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* TLS thread pointer offset. */ + HOWTO (R_MIPS_TLS_GOTTPREL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_GOTTPREL", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* TLS IE dynamic relocations. */ + EMPTY_HOWTO (R_MIPS_TLS_TPREL32), + + HOWTO (R_MIPS_TLS_TPREL64, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_TPREL64", /* name */ + TRUE, /* partial_inplace */ + MINUS_ONE, /* src_mask */ + MINUS_ONE, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* TLS thread pointer offset. */ + HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_TPREL_HI16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* TLS thread pointer offset. */ + HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_TPREL_LO16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* 32 bit relocation with no addend. */ + HOWTO (R_MIPS_GLOB_DAT, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_GLOB_DAT", /* name */ + FALSE, /* partial_inplace */ + 0x0, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ }; /* The relocation table used for SHT_RELA sections. */ @@ -656,7 +818,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_NONE", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -671,7 +833,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -686,7 +848,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_32", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -701,7 +863,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_REL32", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -719,7 +881,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = /* This needs complex overflow detection, because the upper 36 bits must match the PC + 4. */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_26", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -734,7 +896,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_HI16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -749,7 +911,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_LO16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -794,22 +956,24 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf64_got16_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* 16 bit PC relative reference. */ + /* 16 bit PC relative reference. Note that the ABI document has a typo + and claims R_MIPS_PC16 to be not rightshifted, rendering it useless. + We do the right thing here. */ HOWTO (R_MIPS_PC16, /* type */ - 0, /* rightshift */ + 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_PC16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -824,7 +988,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_CALL16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -858,7 +1022,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 6, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_SHIFT5", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -888,7 +1052,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_64", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -903,7 +1067,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_DISP", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -918,7 +1082,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_PAGE", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -933,7 +1097,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_OFST", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -948,7 +1112,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_HI16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -963,14 +1127,14 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_LO16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* 64 bit substraction. */ + /* 64 bit subtraction. */ HOWTO (R_MIPS_SUB, /* type */ 0, /* rightshift */ 4, /* size (0 = byte, 1 = short, 2 = long) */ @@ -978,7 +1142,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_SUB", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -994,7 +1158,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_INSERT_A", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1011,7 +1175,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_INSERT_B", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1027,7 +1191,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_DELETE", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1042,7 +1206,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_HIGHER", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1057,7 +1221,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_HIGHEST", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1072,7 +1236,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_CALL_HI16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1087,7 +1251,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_CALL_LO16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1102,7 +1266,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_SCN_DISP", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1116,7 +1280,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_REL16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1136,7 +1300,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_RELGOT", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1145,23 +1309,153 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = /* Protected jump conversion. This is an optimization hint. No relocation is required for correctness. */ - HOWTO (R_MIPS_JALR, /* type */ + HOWTO (R_MIPS_JALR, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_JALR", /* name */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_JALR", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ 0x00000000, /* dst_mask */ FALSE), /* pcrel_offset */ + + /* TLS relocations. */ + EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32), + EMPTY_HOWTO (R_MIPS_TLS_DTPREL32), + EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64), + EMPTY_HOWTO (R_MIPS_TLS_DTPREL64), + + /* TLS general dynamic variable reference. */ + HOWTO (R_MIPS_TLS_GD, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_GD", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* TLS local dynamic variable reference. */ + HOWTO (R_MIPS_TLS_LDM, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_LDM", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* TLS local dynamic offset. */ + HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_DTPREL_HI16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* TLS local dynamic offset. */ + HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_DTPREL_LO16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* TLS thread pointer offset. */ + HOWTO (R_MIPS_TLS_GOTTPREL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_GOTTPREL", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + EMPTY_HOWTO (R_MIPS_TLS_TPREL32), + EMPTY_HOWTO (R_MIPS_TLS_TPREL64), + + /* TLS thread pointer offset. */ + HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_TPREL_HI16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* TLS thread pointer offset. */ + HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_TPREL_LO16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* 32 bit relocation with no addend. */ + HOWTO (R_MIPS_GLOB_DAT, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_GLOB_DAT", /* name */ + FALSE, /* partial_inplace */ + 0x0, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ }; -/* The reloc used for the mips16 jump instruction. */ -static reloc_howto_type elf_mips16_jump_howto = +static reloc_howto_type mips16_elf64_howto_table_rel[] = +{ + /* The reloc used for the mips16 jump instruction. */ HOWTO (R_MIPS16_26, /* type */ 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ @@ -1172,15 +1466,14 @@ static reloc_howto_type elf_mips16_jump_howto = /* This needs complex overflow detection, because the upper four bits must match the PC. */ - mips16_jump_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS16_26", /* name */ TRUE, /* partial_inplace */ 0x3ffffff, /* src_mask */ 0x3ffffff, /* dst_mask */ - FALSE); /* pcrel_offset */ + FALSE), /* pcrel_offset */ -/* The reloc used for the mips16 gprel instruction. */ -static reloc_howto_type elf_mips16_gprel_howto = + /* The reloc used for the mips16 gprel instruction. */ HOWTO (R_MIPS16_GPREL, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ @@ -1191,9 +1484,118 @@ static reloc_howto_type elf_mips16_gprel_howto = mips16_gprel_reloc, /* special_function */ "R_MIPS16_GPREL", /* name */ TRUE, /* partial_inplace */ - 0x07ff001f, /* src_mask */ - 0x07ff001f, /* dst_mask */ - FALSE); /* pcrel_offset */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* A placeholder for MIPS16 reference to global offset table. */ + EMPTY_HOWTO (R_MIPS16_GOT16), + + /* A placeholder for MIPS16 16 bit call through global offset table. */ + EMPTY_HOWTO (R_MIPS16_CALL16), + + /* MIPS16 high 16 bits of symbol value. */ + HOWTO (R_MIPS16_HI16, /* type */ + 16, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_hi16_reloc, /* special_function */ + "R_MIPS16_HI16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 low 16 bits of symbol value. */ + HOWTO (R_MIPS16_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_lo16_reloc, /* special_function */ + "R_MIPS16_LO16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ +}; + +static reloc_howto_type mips16_elf64_howto_table_rela[] = +{ + /* The reloc used for the mips16 jump instruction. */ + HOWTO (R_MIPS16_26, /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 26, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + /* This needs complex overflow + detection, because the upper four + bits must match the PC. */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_26", /* name */ + FALSE, /* partial_inplace */ + 0x3ffffff, /* src_mask */ + 0x3ffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* The reloc used for the mips16 gprel instruction. */ + HOWTO (R_MIPS16_GPREL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + mips16_gprel_reloc, /* special_function */ + "R_MIPS16_GPREL", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* A placeholder for MIPS16 reference to global offset table. */ + EMPTY_HOWTO (R_MIPS16_GOT16), + + /* A placeholder for MIPS16 16 bit call through global offset table. */ + EMPTY_HOWTO (R_MIPS16_CALL16), + + /* MIPS16 high 16 bits of symbol value. */ + HOWTO (R_MIPS16_HI16, /* type */ + 16, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_hi16_reloc, /* special_function */ + "R_MIPS16_HI16", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 low 16 bits of symbol value. */ + HOWTO (R_MIPS16_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_lo16_reloc, /* special_function */ + "R_MIPS16_LO16", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ +}; /* GNU extension to record C++ vtable hierarchy */ static reloc_howto_type elf_mips_gnu_vtinherit_howto = @@ -1227,13 +1629,43 @@ static reloc_howto_type elf_mips_gnu_vtentry_howto = 0, /* dst_mask */ FALSE); /* pcrel_offset */ +/* 16 bit offset for pc-relative branches. */ +static reloc_howto_type elf_mips_gnu_rel16_s2 = + HOWTO (R_MIPS_GNU_REL16_S2, /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_GNU_REL16_S2", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + TRUE); /* pcrel_offset */ + +/* 16 bit offset for pc-relative branches. */ +static reloc_howto_type elf_mips_gnu_rela16_s2 = + HOWTO (R_MIPS_GNU_REL16_S2, /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_GNU_REL16_S2", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + TRUE); /* pcrel_offset */ + /* Swap in a MIPS 64-bit Rel reloc. */ static void -mips_elf64_swap_reloc_in (abfd, src, dst) - bfd *abfd; - const Elf64_Mips_External_Rel *src; - Elf64_Mips_Internal_Rela *dst; +mips_elf64_swap_reloc_in (bfd *abfd, const Elf64_Mips_External_Rel *src, + Elf64_Mips_Internal_Rela *dst) { dst->r_offset = H_GET_64 (abfd, src->r_offset); dst->r_sym = H_GET_32 (abfd, src->r_sym); @@ -1247,10 +1679,8 @@ mips_elf64_swap_reloc_in (abfd, src, dst) /* Swap in a MIPS 64-bit Rela reloc. */ static void -mips_elf64_swap_reloca_in (abfd, src, dst) - bfd *abfd; - const Elf64_Mips_External_Rela *src; - Elf64_Mips_Internal_Rela *dst; +mips_elf64_swap_reloca_in (bfd *abfd, const Elf64_Mips_External_Rela *src, + Elf64_Mips_Internal_Rela *dst) { dst->r_offset = H_GET_64 (abfd, src->r_offset); dst->r_sym = H_GET_32 (abfd, src->r_sym); @@ -1264,10 +1694,8 @@ mips_elf64_swap_reloca_in (abfd, src, dst) /* Swap out a MIPS 64-bit Rel reloc. */ static void -mips_elf64_swap_reloc_out (abfd, src, dst) - bfd *abfd; - const Elf64_Mips_Internal_Rela *src; - Elf64_Mips_External_Rel *dst; +mips_elf64_swap_reloc_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src, + Elf64_Mips_External_Rel *dst) { H_PUT_64 (abfd, src->r_offset, dst->r_offset); H_PUT_32 (abfd, src->r_sym, dst->r_sym); @@ -1280,10 +1708,8 @@ mips_elf64_swap_reloc_out (abfd, src, dst) /* Swap out a MIPS 64-bit Rela reloc. */ static void -mips_elf64_swap_reloca_out (abfd, src, dst) - bfd *abfd; - const Elf64_Mips_Internal_Rela *src; - Elf64_Mips_External_Rela *dst; +mips_elf64_swap_reloca_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src, + Elf64_Mips_External_Rela *dst) { H_PUT_64 (abfd, src->r_offset, dst->r_offset); H_PUT_32 (abfd, src->r_sym, dst->r_sym); @@ -1297,10 +1723,8 @@ mips_elf64_swap_reloca_out (abfd, src, dst) /* Swap in a MIPS 64-bit Rel reloc. */ static void -mips_elf64_be_swap_reloc_in (abfd, src, dst) - bfd *abfd; - const bfd_byte *src; - Elf_Internal_Rela *dst; +mips_elf64_be_swap_reloc_in (bfd *abfd, const bfd_byte *src, + Elf_Internal_Rela *dst) { Elf64_Mips_Internal_Rela mirel; @@ -1322,10 +1746,8 @@ mips_elf64_be_swap_reloc_in (abfd, src, dst) /* Swap in a MIPS 64-bit Rela reloc. */ static void -mips_elf64_be_swap_reloca_in (abfd, src, dst) - bfd *abfd; - const bfd_byte *src; - Elf_Internal_Rela *dst; +mips_elf64_be_swap_reloca_in (bfd *abfd, const bfd_byte *src, + Elf_Internal_Rela *dst) { Elf64_Mips_Internal_Rela mirela; @@ -1347,18 +1769,13 @@ mips_elf64_be_swap_reloca_in (abfd, src, dst) /* Swap out a MIPS 64-bit Rel reloc. */ static void -mips_elf64_be_swap_reloc_out (abfd, src, dst) - bfd *abfd; - const Elf_Internal_Rela *src; - bfd_byte *dst; +mips_elf64_be_swap_reloc_out (bfd *abfd, const Elf_Internal_Rela *src, + bfd_byte *dst) { Elf64_Mips_Internal_Rela mirel; mirel.r_offset = src[0].r_offset; BFD_ASSERT(src[0].r_offset == src[1].r_offset); -#if 0 - BFD_ASSERT(src[0].r_offset == src[2].r_offset); -#endif mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info); mirel.r_sym = ELF64_R_SYM (src[0].r_info); @@ -1373,10 +1790,8 @@ mips_elf64_be_swap_reloc_out (abfd, src, dst) /* Swap out a MIPS 64-bit Rela reloc. */ static void -mips_elf64_be_swap_reloca_out (abfd, src, dst) - bfd *abfd; - const Elf_Internal_Rela *src; - bfd_byte *dst; +mips_elf64_be_swap_reloca_out (bfd *abfd, const Elf_Internal_Rela *src, + bfd_byte *dst) { Elf64_Mips_Internal_Rela mirela; @@ -1398,81 +1813,11 @@ mips_elf64_be_swap_reloca_out (abfd, src, dst) (Elf64_Mips_External_Rela *) dst); } -/* Do a R_MIPS_HI16 relocation. */ - -static bfd_reloc_status_type -mips_elf64_hi16_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *reloc_entry; - asymbol *symbol; - PTR data ATTRIBUTE_UNUSED; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; -{ - /* If we're relocating, and this is an external symbol, we don't - want to change anything. */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && (! reloc_entry->howto->partial_inplace - || reloc_entry->addend == 0)) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - if (((reloc_entry->addend & 0xffff) + 0x8000) & ~0xffff) - reloc_entry->addend += 0x8000; - - return bfd_reloc_continue; -} - -/* Do a R_MIPS_GOT16 reloc. This is a reloc against the global offset - table used for PIC code. If the symbol is an external symbol, the - instruction is modified to contain the offset of the appropriate - entry in the global offset table. If the symbol is a section - symbol, the next reloc is a R_MIPS_LO16 reloc. The two 16 bit - addends are combined to form the real addend against the section - symbol; the GOT16 is modified to contain the offset of an entry in - the global offset table, and the LO16 is modified to offset it - appropriately. Thus an offset larger than 16 bits requires a - modified value in the global offset table. - - This implementation suffices for the assembler, but the linker does - not yet know how to create global offset tables. */ - -static bfd_reloc_status_type -mips_elf64_got16_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - /* If we're relocating, and this is a local symbol, we can handle it - just like an R_MIPS_HI16. */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) != 0) - return mips_elf64_hi16_reloc (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message); - - - /* Otherwise we try to handle it as R_MIPS_GOT_DISP. */ - return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message); -} - /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a dangerous relocation. */ static bfd_boolean -mips_elf64_assign_gp (output_bfd, pgp) - bfd *output_bfd; - bfd_vma *pgp; +mips_elf64_assign_gp (bfd *output_bfd, bfd_vma *pgp) { unsigned int count; asymbol **sym; @@ -1488,7 +1833,7 @@ mips_elf64_assign_gp (output_bfd, pgp) /* The linker script will have created a symbol named `_gp' with the appropriate value. */ - if (sym == (asymbol **) NULL) + if (sym == NULL) i = count; else { @@ -1521,18 +1866,14 @@ mips_elf64_assign_gp (output_bfd, pgp) symbol value correctly. We look up the symbol _gp in the output BFD. If we can't find it, we're stuck. We cache it in the ELF target data. We don't need to adjust the symbol value for an - external symbol if we are producing relocateable output. */ + external symbol if we are producing relocatable output. */ static bfd_reloc_status_type -mips_elf64_final_gp (output_bfd, symbol, relocateable, error_message, pgp) - bfd *output_bfd; - asymbol *symbol; - bfd_boolean relocateable; - char **error_message; - bfd_vma *pgp; +mips_elf64_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable, + char **error_message, bfd_vma *pgp) { if (bfd_is_und_section (symbol->section) - && ! relocateable) + && ! relocatable) { *pgp = 0; return bfd_reloc_undefined; @@ -1540,10 +1881,10 @@ mips_elf64_final_gp (output_bfd, symbol, relocateable, error_message, pgp) *pgp = _bfd_get_gp_value (output_bfd); if (*pgp == 0 - && (! relocateable + && (! relocatable || (symbol->flags & BSF_SECTION_SYM) != 0)) { - if (relocateable) + if (relocatable) { /* Make up a value. */ *pgp = symbol->section->output_section->vma /*+ 0x4000*/; @@ -1564,95 +1905,79 @@ mips_elf64_final_gp (output_bfd, symbol, relocateable, error_message, pgp) become the offset from the gp register. */ static bfd_reloc_status_type -mips_elf64_gprel16_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; +mips_elf64_gprel16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, + void *data, asection *input_section, bfd *output_bfd, + char **error_message) { - bfd_boolean relocateable; + bfd_boolean relocatable; bfd_reloc_status_type ret; bfd_vma gp; - /* If we're relocating, and this is an external symbol with no - addend, we don't want to change anything. We will only have an - addend if this is a newly created reloc, not read from an ELF - file. */ - if (output_bfd != (bfd *) NULL + /* If we're relocating, and this is an external symbol, we don't want + to change anything. */ + if (output_bfd != NULL && (symbol->flags & BSF_SECTION_SYM) == 0 - && (! reloc_entry->howto->partial_inplace - || reloc_entry->addend == 0)) + && (symbol->flags & BSF_LOCAL) != 0) { reloc_entry->address += input_section->output_offset; return bfd_reloc_ok; } - if (output_bfd != (bfd *) NULL) - relocateable = TRUE; + if (output_bfd != NULL) + relocatable = TRUE; else { - relocateable = FALSE; + relocatable = FALSE; output_bfd = symbol->section->output_section->owner; } - ret = mips_elf64_final_gp (output_bfd, symbol, relocateable, error_message, + ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message, &gp); if (ret != bfd_reloc_ok) return ret; return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry, - input_section, relocateable, + input_section, relocatable, data, gp); } /* Do a R_MIPS_LITERAL relocation. */ static bfd_reloc_status_type -mips_elf64_literal_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; +mips_elf64_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, + void *data, asection *input_section, bfd *output_bfd, + char **error_message) { - bfd_boolean relocateable; + bfd_boolean relocatable; bfd_reloc_status_type ret; bfd_vma gp; - /* If we're relocating, and this is an external symbol, we don't - want to change anything. */ - if (output_bfd != (bfd *) NULL + /* R_MIPS_LITERAL relocations are defined for local symbols only. */ + if (output_bfd != NULL && (symbol->flags & BSF_SECTION_SYM) == 0 - && (! reloc_entry->howto->partial_inplace - || reloc_entry->addend == 0)) + && (symbol->flags & BSF_LOCAL) != 0) { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; + *error_message = (char *) + _("literal relocation occurs for an external symbol"); + return bfd_reloc_outofrange; } /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */ - if (output_bfd != (bfd *) NULL) - relocateable = TRUE; + if (output_bfd != NULL) + relocatable = TRUE; else { - relocateable = FALSE; + relocatable = FALSE; output_bfd = symbol->section->output_section->owner; } - ret = mips_elf64_final_gp (output_bfd, symbol, relocateable, error_message, + ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message, &gp); if (ret != bfd_reloc_ok) return ret; return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry, - input_section, relocateable, + input_section, relocatable, data, gp); } @@ -1660,51 +1985,39 @@ mips_elf64_literal_reloc (abfd, reloc_entry, symbol, data, input_section, become the offset from the gp register. */ static bfd_reloc_status_type -mips_elf64_gprel32_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; +mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, + void *data, asection *input_section, bfd *output_bfd, + char **error_message) { - bfd_boolean relocateable; + bfd_boolean relocatable; bfd_reloc_status_type ret; bfd_vma gp; bfd_vma relocation; - unsigned long val; + bfd_vma val; - /* If we're relocating, and this is an external symbol with no - addend, we don't want to change anything. We will only have an - addend if this is a newly created reloc, not read from an ELF - file. */ - if (output_bfd != (bfd *) NULL + /* R_MIPS_GPREL32 relocations are defined for local symbols only. */ + if (output_bfd != NULL && (symbol->flags & BSF_SECTION_SYM) == 0 - && reloc_entry->addend == 0) + && (symbol->flags & BSF_LOCAL) != 0) { *error_message = (char *) _("32bits gp relative relocation occurs for an external symbol"); return bfd_reloc_outofrange; } - if (output_bfd != (bfd *) NULL) - { - relocateable = TRUE; - gp = _bfd_get_gp_value (output_bfd); - } + if (output_bfd != NULL) + relocatable = TRUE; else { - relocateable = FALSE; + relocatable = FALSE; output_bfd = symbol->section->output_section->owner; - - ret = mips_elf64_final_gp (output_bfd, symbol, relocateable, - error_message, &gp); - if (ret != bfd_reloc_ok) - return ret; } + ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, + error_message, &gp); + if (ret != bfd_reloc_ok) + return ret; + if (bfd_is_com_section (symbol->section)) relocation = 0; else @@ -1713,30 +2026,28 @@ mips_elf64_gprel32_reloc (abfd, reloc_entry, symbol, data, input_section, relocation += symbol->section->output_section->vma; relocation += symbol->section->output_offset; - if (reloc_entry->address > input_section->_cooked_size) + if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) return bfd_reloc_outofrange; - if (reloc_entry->howto->src_mask == 0) - { - /* This case arises with the 64-bit MIPS ELF ABI. */ - val = 0; - } - else - val = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); - /* Set val to the offset into the section or symbol. */ - val += reloc_entry->addend; + val = reloc_entry->addend; + + if (reloc_entry->howto->partial_inplace) + val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); /* Adjust val for the final section location and GP value. If we - are producing relocateable output, we don't want to do this for + are producing relocatable output, we don't want to do this for an external symbol. */ - if (! relocateable + if (! relocatable || (symbol->flags & BSF_SECTION_SYM) != 0) val += relocation - gp; - bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address); + if (reloc_entry->howto->partial_inplace) + bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address); + else + reloc_entry->addend = val; - if (relocateable) + if (relocatable) reloc_entry->address += input_section->output_offset; return bfd_reloc_ok; @@ -1746,141 +2057,64 @@ mips_elf64_gprel32_reloc (abfd, reloc_entry, symbol, data, input_section, the rest is at bits 6-10. The bitpos already got right by the howto. */ static bfd_reloc_status_type -mips_elf64_shift6_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *reloc_entry; - asymbol *symbol; - PTR data ATTRIBUTE_UNUSED; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; +mips_elf64_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, + void *data, asection *input_section, bfd *output_bfd, + char **error_message) { - /* If we're relocating, and this is an external symbol, we don't - want to change anything. */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && (! reloc_entry->howto->partial_inplace - || reloc_entry->addend == 0)) + if (reloc_entry->howto->partial_inplace) { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - reloc_entry->addend = (reloc_entry->addend & 0x00007c0) - | (reloc_entry->addend & 0x00000800) >> 9; - - return bfd_reloc_continue; -} - -/* Handle a mips16 jump. */ - -static bfd_reloc_status_type -mips16_jump_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *reloc_entry; - asymbol *symbol; - PTR data ATTRIBUTE_UNUSED; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; -{ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && (! reloc_entry->howto->partial_inplace - || reloc_entry->addend == 0)) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; + reloc_entry->addend = ((reloc_entry->addend & 0x00007c0) + | (reloc_entry->addend & 0x00000800) >> 9); } - /* FIXME. */ - { - static bfd_boolean warned; - - if (! warned) - (*_bfd_error_handler) - (_("Linking mips16 objects into %s format is not supported"), - bfd_get_target (input_section->output_section->owner)); - warned = TRUE; - } - - return bfd_reloc_undefined; + return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, + error_message); } /* Handle a mips16 GP relative reloc. */ static bfd_reloc_status_type -mips16_gprel_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; +mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, + void *data, asection *input_section, bfd *output_bfd, + char **error_message) { - bfd_boolean relocateable; + bfd_boolean relocatable; bfd_reloc_status_type ret; + bfd_byte *location; bfd_vma gp; - unsigned short extend, insn; - unsigned long final; - /* If we're relocating, and this is an external symbol with no - addend, we don't want to change anything. We will only have an - addend if this is a newly created reloc, not read from an ELF - file. */ + /* If we're relocating, and this is an external symbol, we don't want + to change anything. */ if (output_bfd != NULL && (symbol->flags & BSF_SECTION_SYM) == 0 - && reloc_entry->addend == 0) + && (symbol->flags & BSF_LOCAL) != 0) { reloc_entry->address += input_section->output_offset; return bfd_reloc_ok; } if (output_bfd != NULL) - relocateable = TRUE; + relocatable = TRUE; else { - relocateable = FALSE; + relocatable = FALSE; output_bfd = symbol->section->output_section->owner; } - ret = mips_elf64_final_gp (output_bfd, symbol, relocateable, error_message, + ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message, &gp); if (ret != bfd_reloc_ok) return ret; - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - /* Pick up the mips16 extend instruction and the real instruction. */ - extend = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address); - insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address + 2); - - /* Stuff the current addend back as a 32 bit value, do the usual - relocation, and then clean up. */ - bfd_put_32 (abfd, - (bfd_vma) (((extend & 0x1f) << 11) - | (extend & 0x7e0) - | (insn & 0x1f)), - (bfd_byte *) data + reloc_entry->address); - + location = (bfd_byte *) data + reloc_entry->address; + _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE, + location); ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry, - input_section, relocateable, data, gp); - - final = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); - bfd_put_16 (abfd, - (bfd_vma) ((extend & 0xf800) - | ((final >> 11) & 0x1f) - | (final & 0x7e0)), - (bfd_byte *) data + reloc_entry->address); - bfd_put_16 (abfd, - (bfd_vma) ((insn & 0xffe0) - | (final & 0x1f)), - (bfd_byte *) data + reloc_entry->address + 2); + input_section, relocatable, + data, gp); + _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable, + location); return ret; } @@ -1900,7 +2134,7 @@ static const struct elf_reloc_map mips_reloc_map[] = /* There is no BFD reloc for R_MIPS_REL32. */ { BFD_RELOC_64, R_MIPS_64 }, { BFD_RELOC_CTOR, R_MIPS_64 }, - { BFD_RELOC_16_PCREL, R_MIPS_PC16 }, + { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 }, { BFD_RELOC_HI16_S, R_MIPS_HI16 }, { BFD_RELOC_LO16, R_MIPS_LO16 }, { BFD_RELOC_GPREL16, R_MIPS_GPREL16 }, @@ -1928,20 +2162,41 @@ static const struct elf_reloc_map mips_reloc_map[] = { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 }, /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */ { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT }, - { BFD_RELOC_MIPS_JALR, R_MIPS_JALR } + { BFD_RELOC_MIPS_JALR, R_MIPS_JALR }, + { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 }, + { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 }, + { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 }, + { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 }, + { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD }, + { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM }, + { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 }, + { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 }, + { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL }, + { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 }, + { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 }, + { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 }, + { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 } +}; + +static const struct elf_reloc_map mips16_reloc_map[] = +{ + { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min }, + { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min }, + { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min }, + { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min }, }; /* Given a BFD reloc type, return a howto structure. */ static reloc_howto_type * -bfd_elf64_bfd_reloc_type_lookup (abfd, code) - bfd *abfd ATTRIBUTE_UNUSED; - bfd_reloc_code_real_type code; +bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) { unsigned int i; /* FIXME: We default to RELA here instead of choosing the right relocation variant. */ reloc_howto_type *howto_table = mips_elf64_howto_table_rela; + reloc_howto_type *howto16_table = mips16_elf64_howto_table_rela; for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map); i++) @@ -1950,12 +2205,15 @@ bfd_elf64_bfd_reloc_type_lookup (abfd, code) return &howto_table[(int) mips_reloc_map[i].elf_val]; } + for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map); + i++) + { + if (mips16_reloc_map[i].bfd_val == code) + return &howto16_table[(int) mips16_reloc_map[i].elf_val]; + } + switch (code) { - case BFD_RELOC_MIPS16_JMP: - return &elf_mips16_jump_howto; - case BFD_RELOC_MIPS16_GPREL: - return &elf_mips16_gprel_howto; case BFD_RELOC_VTABLE_INHERIT: return &elf_mips_gnu_vtinherit_howto; case BFD_RELOC_VTABLE_ENTRY: @@ -1969,21 +2227,27 @@ bfd_elf64_bfd_reloc_type_lookup (abfd, code) /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */ static reloc_howto_type * -mips_elf64_rtype_to_howto (r_type, rela_p) - unsigned int r_type; - bfd_boolean rela_p; +mips_elf64_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p) { switch (r_type) { - case R_MIPS16_26: - return &elf_mips16_jump_howto; - case R_MIPS16_GPREL: - return &elf_mips16_gprel_howto; case R_MIPS_GNU_VTINHERIT: return &elf_mips_gnu_vtinherit_howto; case R_MIPS_GNU_VTENTRY: return &elf_mips_gnu_vtentry_howto; + case R_MIPS_GNU_REL16_S2: + if (rela_p) + return &elf_mips_gnu_rela16_s2; + else + return &elf_mips_gnu_rel16_s2; default: + if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max) + { + if (rela_p) + return &mips16_elf64_howto_table_rela[r_type - R_MIPS16_min]; + else + return &mips16_elf64_howto_table_rel[r_type - R_MIPS16_min]; + } BFD_ASSERT (r_type < (unsigned int) R_MIPS_max); if (rela_p) return &mips_elf64_howto_table_rela[r_type]; @@ -1996,19 +2260,17 @@ mips_elf64_rtype_to_howto (r_type, rela_p) /* Prevent relocation handling by bfd for MIPS ELF64. */ static void -mips_elf64_info_to_howto_rel (abfd, cache_ptr, dst) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *cache_ptr ATTRIBUTE_UNUSED; - Elf_Internal_Rela *dst ATTRIBUTE_UNUSED; +mips_elf64_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, + arelent *cache_ptr ATTRIBUTE_UNUSED, + Elf_Internal_Rela *dst ATTRIBUTE_UNUSED) { BFD_ASSERT (0); } static void -mips_elf64_info_to_howto_rela (abfd, cache_ptr, dst) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *cache_ptr ATTRIBUTE_UNUSED; - Elf_Internal_Rela *dst ATTRIBUTE_UNUSED; +mips_elf64_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED, + arelent *cache_ptr ATTRIBUTE_UNUSED, + Elf_Internal_Rela *dst ATTRIBUTE_UNUSED) { BFD_ASSERT (0); } @@ -2017,16 +2279,13 @@ mips_elf64_info_to_howto_rela (abfd, cache_ptr, dst) to three relocs, we must tell the user to allocate more space. */ static long -mips_elf64_get_reloc_upper_bound (abfd, sec) - bfd *abfd ATTRIBUTE_UNUSED; - asection *sec; +mips_elf64_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec) { return (sec->reloc_count * 3 + 1) * sizeof (arelent *); } static long -mips_elf64_get_dynamic_reloc_upper_bound (abfd) - bfd *abfd; +mips_elf64_get_dynamic_reloc_upper_bound (bfd *abfd) { return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 3; } @@ -2037,15 +2296,12 @@ mips_elf64_get_dynamic_reloc_upper_bound (abfd) 3 to obtain the internal relocation count. */ static long -mips_elf64_canonicalize_reloc (abfd, section, relptr, symbols) - bfd *abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; +mips_elf64_canonicalize_reloc (bfd *abfd, sec_ptr section, + arelent **relptr, asymbol **symbols) { arelent *tblptr; unsigned int i; - struct elf_backend_data *bed = get_elf_backend_data (abfd); + const struct elf_backend_data *bed = get_elf_backend_data (abfd); if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE)) return -1; @@ -2060,13 +2316,10 @@ mips_elf64_canonicalize_reloc (abfd, section, relptr, symbols) } static long -mips_elf64_canonicalize_dynamic_reloc (abfd, storage, syms) - bfd *abfd; - arelent **storage; - asymbol **syms; +mips_elf64_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage, + asymbol **syms) { - bfd_boolean (*slurp_relocs) - PARAMS ((bfd *, asection *, asymbol **, bfd_boolean)); + bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean); asection *s; long ret; @@ -2089,7 +2342,7 @@ mips_elf64_canonicalize_dynamic_reloc (abfd, storage, syms) if (! (*slurp_relocs) (abfd, s, syms, TRUE)) return -1; - count = s->_raw_size / elf_section_data (s)->this_hdr.sh_entsize * 3; + count = s->size / elf_section_data (s)->this_hdr.sh_entsize * 3; p = s->relocation; for (i = 0; i < count; i++) *storage++ = p++; @@ -2109,24 +2362,20 @@ mips_elf64_canonicalize_dynamic_reloc (abfd, storage, syms) generic code seems to depend on this. */ static bfd_boolean -mips_elf64_slurp_one_reloc_table (abfd, asect, rel_hdr, reloc_count, - relents, symbols, dynamic) - bfd *abfd; - asection *asect; - Elf_Internal_Shdr *rel_hdr; - bfd_size_type reloc_count; - arelent *relents; - asymbol **symbols; - bfd_boolean dynamic; +mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect, + Elf_Internal_Shdr *rel_hdr, + bfd_size_type reloc_count, + arelent *relents, asymbol **symbols, + bfd_boolean dynamic) { - PTR allocated = NULL; + void *allocated; bfd_byte *native_relocs; arelent *relent; bfd_vma i; int entsize; - reloc_howto_type *howto_table; + bfd_boolean rela_p; - allocated = (PTR) bfd_malloc (rel_hdr->sh_size); + allocated = bfd_malloc (rel_hdr->sh_size); if (allocated == NULL) return FALSE; @@ -2135,16 +2384,16 @@ mips_elf64_slurp_one_reloc_table (abfd, asect, rel_hdr, reloc_count, != rel_hdr->sh_size)) goto error_return; - native_relocs = (bfd_byte *) allocated; + native_relocs = allocated; entsize = rel_hdr->sh_entsize; BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel) || entsize == sizeof (Elf64_Mips_External_Rela)); if (entsize == sizeof (Elf64_Mips_External_Rel)) - howto_table = mips_elf64_howto_table_rel; + rela_p = FALSE; else - howto_table = mips_elf64_howto_table_rela; + rela_p = TRUE; for (i = 0, relent = relents; i < reloc_count; @@ -2229,7 +2478,7 @@ mips_elf64_slurp_one_reloc_table (abfd, asect, rel_hdr, reloc_count, case RSS_GP0: case RSS_LOC: /* FIXME: I think these need to be handled using - special howto structures. */ + special howto structures. */ BFD_ASSERT (0); break; @@ -2257,7 +2506,7 @@ mips_elf64_slurp_one_reloc_table (abfd, asect, rel_hdr, reloc_count, relent->addend = rela.r_addend; - relent->howto = &howto_table[(int) type]; + relent->howto = mips_elf64_rtype_to_howto (type, rela_p); ++relent; } @@ -2283,11 +2532,8 @@ mips_elf64_slurp_one_reloc_table (abfd, asect, rel_hdr, reloc_count, zero before processing the relocs of a section. */ static bfd_boolean -mips_elf64_slurp_reloc_table (abfd, asect, symbols, dynamic) - bfd *abfd; - asection *asect; - asymbol **symbols; - bfd_boolean dynamic; +mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect, + asymbol **symbols, bfd_boolean dynamic) { struct bfd_elf_section_data * const d = elf_section_data (asect); Elf_Internal_Shdr *rel_hdr; @@ -2322,7 +2568,7 @@ mips_elf64_slurp_reloc_table (abfd, asect, symbols, dynamic) case because relocations against this section may use the dynamic symbol table, and in that case bfd_section_from_shdr in elf.c does not update the RELOC_COUNT. */ - if (asect->_raw_size == 0) + if (asect->size == 0) return TRUE; rel_hdr = &d->this_hdr; @@ -2333,7 +2579,7 @@ mips_elf64_slurp_reloc_table (abfd, asect, symbols, dynamic) /* Allocate space for 3 arelent structures for each Rel structure. */ amt = (reloc_count + reloc_count2) * 3 * sizeof (arelent); - relents = (arelent *) bfd_alloc (abfd, amt); + relents = bfd_alloc (abfd, amt); if (relents == NULL) return FALSE; @@ -2361,12 +2607,9 @@ mips_elf64_slurp_reloc_table (abfd, asect, symbols, dynamic) /* Write out the relocations. */ static void -mips_elf64_write_relocs (abfd, sec, data) - bfd *abfd; - asection *sec; - PTR data; +mips_elf64_write_relocs (bfd *abfd, asection *sec, void *data) { - bfd_boolean *failedp = (bfd_boolean *) data; + bfd_boolean *failedp = data; int count; Elf_Internal_Shdr *rel_hdr; unsigned int idx; @@ -2427,21 +2670,18 @@ mips_elf64_write_relocs (abfd, sec, data) } static void -mips_elf64_write_rel (abfd, sec, rel_hdr, count, data) - bfd *abfd; - asection *sec; - Elf_Internal_Shdr *rel_hdr; - int *count; - PTR data; +mips_elf64_write_rel (bfd *abfd, asection *sec, + Elf_Internal_Shdr *rel_hdr, + int *count, void *data) { - bfd_boolean *failedp = (bfd_boolean *) data; + bfd_boolean *failedp = data; Elf64_Mips_External_Rel *ext_rel; unsigned int idx; asymbol *last_sym = 0; int last_sym_idx = 0; - rel_hdr->sh_size = (bfd_vma)(rel_hdr->sh_entsize * *count); - rel_hdr->contents = (PTR) bfd_alloc (abfd, rel_hdr->sh_size); + rel_hdr->sh_size = rel_hdr->sh_entsize * *count; + rel_hdr->contents = bfd_alloc (abfd, rel_hdr->sh_size); if (rel_hdr->contents == NULL) { *failedp = TRUE; @@ -2470,6 +2710,8 @@ mips_elf64_write_rel (abfd, sec, rel_hdr, count, data) sym = *ptr->sym_ptr_ptr; if (sym == last_sym) n = last_sym_idx; + else if (bfd_is_abs_section (sym->section) && sym->value == 0) + n = STN_UNDEF; else { last_sym = sym; @@ -2526,21 +2768,18 @@ mips_elf64_write_rel (abfd, sec, rel_hdr, count, data) } static void -mips_elf64_write_rela (abfd, sec, rela_hdr, count, data) - bfd *abfd; - asection *sec; - Elf_Internal_Shdr *rela_hdr; - int *count; - PTR data; +mips_elf64_write_rela (bfd *abfd, asection *sec, + Elf_Internal_Shdr *rela_hdr, + int *count, void *data) { - bfd_boolean *failedp = (bfd_boolean *) data; + bfd_boolean *failedp = data; Elf64_Mips_External_Rela *ext_rela; unsigned int idx; asymbol *last_sym = 0; int last_sym_idx = 0; - rela_hdr->sh_size = (bfd_vma)(rela_hdr->sh_entsize * *count); - rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size); + rela_hdr->sh_size = rela_hdr->sh_entsize * *count; + rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size); if (rela_hdr->contents == NULL) { *failedp = TRUE; @@ -2569,6 +2808,8 @@ mips_elf64_write_rela (abfd, sec, rela_hdr, count, data) sym = *ptr->sym_ptr_ptr; if (sym == last_sym) n = last_sym_idx; + else if (bfd_is_abs_section (sym->section) && sym->value == 0) + n = STN_UNDEF; else { last_sym = sym; @@ -2628,8 +2869,7 @@ mips_elf64_write_rela (abfd, sec, rela_hdr, count, data) /* Set the right machine number for a MIPS ELF file. */ static bfd_boolean -mips_elf64_object_p (abfd) - bfd *abfd; +mips_elf64_object_p (bfd *abfd) { unsigned long mach; @@ -2647,8 +2887,7 @@ mips_elf64_object_p (abfd) /* Depending on the target vector we generate some version of Irix executables or "normal" MIPS ELF ABI executables. */ static irix_compat_t -elf64_mips_irix_compat (abfd) - bfd *abfd; +elf64_mips_irix_compat (bfd *abfd) { if ((abfd->xvec == &bfd_elf64_bigmips_vec) || (abfd->xvec == &bfd_elf64_littlemips_vec)) @@ -2659,12 +2898,10 @@ elf64_mips_irix_compat (abfd) /* Support for core dump NOTE sections. */ static bfd_boolean -elf64_mips_grok_prstatus (abfd, note) - bfd *abfd; - Elf_Internal_Note *note; +elf64_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) { int offset; - unsigned int raw_size; + unsigned int size; switch (note->descsz) { @@ -2680,20 +2917,18 @@ elf64_mips_grok_prstatus (abfd, note) /* pr_reg */ offset = 112; - raw_size = 360; + size = 360; break; } /* Make a ".reg/999" section. */ return _bfd_elfcore_make_pseudosection (abfd, ".reg", - raw_size, note->descpos + offset); + size, note->descpos + offset); } static bfd_boolean -elf64_mips_grok_psinfo (abfd, note) - bfd *abfd; - Elf_Internal_Note *note; +elf64_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) { switch (note->descsz) { @@ -2779,10 +3014,10 @@ const struct elf_size_info mips_elf64_size_info = sizeof (Elf64_External_Sym), sizeof (Elf64_External_Dyn), sizeof (Elf_External_Note), - 4, /* hash-table entry size */ - 3, /* internal relocations per external relocations */ + 4, /* hash-table entry size */ + 3, /* internal relocations per external relocations */ 64, /* arch_size */ - 8, /* file_align */ + 3, /* log_file_align */ ELFCLASS64, EV_CURRENT, bfd_elf64_write_out_phdrs, @@ -2803,11 +3038,6 @@ const struct elf_size_info mips_elf64_size_info = #define ELF_ARCH bfd_arch_mips #define ELF_MACHINE_CODE EM_MIPS -/* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses - a value of 0x1000, and we are compatible. - FIXME: How does this affect NewABI? */ -#define ELF_MAXPAGESIZE 0x1000 - #define elf_backend_collect TRUE #define elf_backend_type_change_ok TRUE #define elf_backend_can_gc_sections TRUE @@ -2826,12 +3056,15 @@ const struct elf_size_info mips_elf64_size_info = #define elf_backend_create_dynamic_sections \ _bfd_mips_elf_create_dynamic_sections #define elf_backend_check_relocs _bfd_mips_elf_check_relocs +#define elf_backend_merge_symbol_attribute \ + _bfd_mips_elf_merge_symbol_attribute #define elf_backend_adjust_dynamic_symbol \ _bfd_mips_elf_adjust_dynamic_symbol #define elf_backend_always_size_sections \ _bfd_mips_elf_always_size_sections #define elf_backend_size_dynamic_sections \ _bfd_mips_elf_size_dynamic_sections +#define elf_backend_init_index_section _bfd_elf_init_1_index_section #define elf_backend_relocate_section _bfd_mips_elf_relocate_section #define elf_backend_finish_dynamic_symbol \ _bfd_mips_elf_finish_dynamic_symbol @@ -2844,6 +3077,8 @@ const struct elf_size_info mips_elf64_size_info = #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook +#define elf_backend_copy_indirect_symbol \ + _bfd_mips_elf_copy_indirect_symbol #define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol #define elf_backend_ignore_discarded_relocs \ _bfd_mips_elf_ignore_discarded_relocs @@ -2856,7 +3091,6 @@ const struct elf_size_info mips_elf64_size_info = #define elf_backend_grok_psinfo elf64_mips_grok_psinfo #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO) -#define elf_backend_plt_header_size 0 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations work better/work only in RELA, so we default to this. */ @@ -2870,6 +3104,7 @@ const struct elf_size_info mips_elf64_size_info = MIPS-specific function only applies to IRIX5, which had no 64-bit ABI. */ #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line +#define bfd_elf64_find_inliner_info _bfd_mips_elf_find_inliner_info #define bfd_elf64_new_section_hook _bfd_mips_elf_new_section_hook #define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents #define bfd_elf64_bfd_get_relocated_section_contents \ @@ -2887,13 +3122,14 @@ const struct elf_size_info mips_elf64_size_info = #define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound #define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc +#define bfd_elf64_bfd_relax_section _bfd_mips_relax_section /* MIPS ELF64 archive functions. */ #define bfd_elf64_archive_functions extern bfd_boolean bfd_elf64_archive_slurp_armap - PARAMS ((bfd *)); + (bfd *); extern bfd_boolean bfd_elf64_archive_write_armap - PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int)); + (bfd *, unsigned int, struct orl *, unsigned int, int); #define bfd_elf64_archive_slurp_extended_name_table \ _bfd_archive_coff_slurp_extended_name_table #define bfd_elf64_archive_construct_extended_name_table \ @@ -2916,9 +3152,10 @@ extern bfd_boolean bfd_elf64_archive_write_armap #define TARGET_BIG_SYM bfd_elf64_bigmips_vec #define TARGET_BIG_NAME "elf64-bigmips" -#include "elf64-target.h" +#define ELF_MAXPAGESIZE 0x10000 +#define ELF_COMMONPAGESIZE 0x1000 -#define INCLUDED_TARGET_FILE /* More a type of flag. */ +#include "elf64-target.h" /* The SYSV-style 'traditional' (n)64 NewABI. */ #undef TARGET_LITTLE_SYM @@ -2926,10 +3163,17 @@ extern bfd_boolean bfd_elf64_archive_write_armap #undef TARGET_BIG_SYM #undef TARGET_BIG_NAME -#define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec -#define TARGET_LITTLE_NAME "elf64-tradlittlemips" -#define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec -#define TARGET_BIG_NAME "elf64-tradbigmips" +#undef ELF_MAXPAGESIZE +#undef ELF_COMMONPAGESIZE + +#define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec +#define TARGET_LITTLE_NAME "elf64-tradlittlemips" +#define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec +#define TARGET_BIG_NAME "elf64-tradbigmips" + +#define ELF_MAXPAGESIZE 0x10000 +#define ELF_COMMONPAGESIZE 0x1000 +#define elf64_bed elf64_tradbed /* Include the target file again for this target. */ #include "elf64-target.h"