X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felf64-mips.c;h=02acc572799ceba8962dd38c0029af5504703188;hb=bd695bcc90bf296d67a85cd49c6fe1879715e04e;hp=998c5df5b399956a84eb3a6e405ebeef7754f9b4;hpb=11a2be4ddc6e706b7a5c501af297a7cd6726a2b8;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c index 998c5df5b3..02acc57279 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. @@ -104,8 +104,6 @@ static void mips_elf64_write_rel (bfd *, asection *, Elf_Internal_Shdr *, int *, void *); static void mips_elf64_write_rela (bfd *, asection *, Elf_Internal_Shdr *, int *, void *); -static bfd_reloc_status_type mips_elf64_hi16_reloc - (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); static bfd_reloc_status_type mips_elf64_gprel16_reloc (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); static bfd_reloc_status_type mips_elf64_literal_reloc @@ -114,8 +112,6 @@ static bfd_reloc_status_type mips_elf64_gprel32_reloc (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); static bfd_reloc_status_type mips_elf64_shift6_reloc (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); -static bfd_reloc_status_type mips_elf64_got16_reloc - (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); static bfd_reloc_status_type mips16_jump_reloc (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); static bfd_reloc_status_type mips16_gprel_reloc @@ -155,7 +151,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 */ @@ -170,7 +166,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 */ @@ -185,7 +181,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 */ @@ -200,7 +196,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 */ @@ -218,7 +214,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 */ @@ -230,13 +226,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 */ @@ -251,7 +247,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 */ @@ -296,7 +292,7 @@ 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 */ @@ -311,7 +307,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] = 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 */ @@ -326,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 */ @@ -360,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 */ @@ -390,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 */ @@ -405,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 */ @@ -420,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 */ @@ -435,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 */ @@ -450,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 */ @@ -465,7 +461,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_LO16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -480,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 */ @@ -496,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 */ @@ -513,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 */ @@ -529,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 */ @@ -553,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 */ @@ -568,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 */ @@ -583,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 */ @@ -597,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 */ @@ -617,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 */ @@ -626,19 +622,173 @@ 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 */ }; /* The relocation table used for SHT_RELA sections. */ @@ -653,7 +803,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 */ @@ -668,7 +818,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 */ @@ -683,7 +833,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 */ @@ -698,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_REL32", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -716,7 +866,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 */ @@ -731,7 +881,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 */ @@ -746,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_LO16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -791,7 +941,7 @@ 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 */ @@ -806,7 +956,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] = 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 */ @@ -821,7 +971,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 */ @@ -855,7 +1005,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 */ @@ -885,7 +1035,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 */ @@ -900,7 +1050,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 */ @@ -915,7 +1065,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 */ @@ -930,7 +1080,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 */ @@ -945,7 +1095,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 */ @@ -960,7 +1110,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_LO16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -975,7 +1125,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 */ @@ -991,7 +1141,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 */ @@ -1008,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_B", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1024,7 +1174,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 */ @@ -1039,7 +1189,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 */ @@ -1054,7 +1204,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 */ @@ -1069,7 +1219,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 */ @@ -1084,7 +1234,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 */ @@ -1099,7 +1249,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 */ @@ -1113,7 +1263,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 */ @@ -1133,7 +1283,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 */ @@ -1142,23 +1292,138 @@ 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 */ }; -/* 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) */ @@ -1174,10 +1439,9 @@ static reloc_howto_type elf_mips16_jump_howto = 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) */ @@ -1188,9 +1452,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. */ + mips16_jump_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 = @@ -1233,7 +1606,7 @@ static reloc_howto_type elf_mips_gnu_rel16_s2 = 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_GNU_REL16_S2", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -1249,7 +1622,7 @@ static reloc_howto_type elf_mips_gnu_rela16_s2 = 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_GNU_REL16_S2", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1371,9 +1744,6 @@ mips_elf64_be_swap_reloc_out (bfd *abfd, const Elf_Internal_Rela *src, 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); @@ -1411,66 +1781,6 @@ mips_elf64_be_swap_reloca_out (bfd *abfd, const Elf_Internal_Rela *src, (Elf64_Mips_External_Rela *) dst); } -/* Do a R_MIPS_HI16 relocation. */ - -static bfd_reloc_status_type -mips_elf64_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry, - asymbol *symbol, void *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 != NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && (symbol->flags & BSF_LOCAL) != 0) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - if (reloc_entry->howto->partial_inplace) - { - 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 (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 a local symbol, we can handle it - just like an R_MIPS_HI16. */ - if (output_bfd != NULL - && ((symbol->flags & BSF_SECTION_SYM) != 0 - || (symbol->flags & BSF_LOCAL) == 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. */ @@ -1610,14 +1920,14 @@ mips_elf64_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, 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. */ + /* R_MIPS_LITERAL relocations are defined for local symbols only. */ if (output_bfd != NULL && (symbol->flags & BSF_SECTION_SYM) == 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. */ @@ -1653,8 +1963,7 @@ mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, bfd_vma relocation; bfd_vma val; - /* If we're relocating, and this is an external symbol, we don't want - to change anything. */ + /* R_MIPS_GPREL32 relocations are defined for local symbols only. */ if (output_bfd != NULL && (symbol->flags & BSF_SECTION_SYM) == 0 && (symbol->flags & BSF_LOCAL) != 0) @@ -1672,10 +1981,10 @@ mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, output_bfd = symbol->section->output_section->owner; } - ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, - 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; @@ -1685,7 +1994,7 @@ mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, 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; /* Set val to the offset into the section or symbol. */ @@ -1716,28 +2025,19 @@ mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, the rest is at bits 6-10. The bitpos already got right by the howto. */ static bfd_reloc_status_type -mips_elf64_shift6_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry, - asymbol *symbol, void *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 != NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && (symbol->flags & BSF_LOCAL) != 0) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - if (reloc_entry->howto->partial_inplace) { reloc_entry->addend = ((reloc_entry->addend & 0x00007c0) | (reloc_entry->addend & 0x00000800) >> 9); } - return bfd_reloc_continue; + return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, + error_message); } /* Handle a mips16 jump. */ @@ -1780,14 +2080,11 @@ mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, { bfd_boolean relocatable; bfd_reloc_status_type ret; + bfd_byte *location; bfd_vma gp; - unsigned short extend = 0; - unsigned short insn = 0; - bfd_signed_vma val; - bfd_vma relocation; - /* If we're relocating, and this is an external symbol with no - addend, we don't want to change anything. */ + /* 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 && (symbol->flags & BSF_LOCAL) != 0) @@ -1809,55 +2106,16 @@ mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, if (ret != bfd_reloc_ok) return ret; - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; + 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, relocatable, + data, gp); + _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable, + location); - /* Set val to the offset into the section or symbol. */ - val = reloc_entry->addend; - - if (reloc_entry->howto->partial_inplace) - { - /* 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); - val += ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f); - } - - _bfd_mips_elf_sign_extend(val, 16); - - /* Adjust val for the final section location and GP value. If we - are producing relocatable output, we don't want to do this for - an external symbol. */ - if (! relocatable - || (symbol->flags & BSF_SECTION_SYM) != 0) - val += relocation - gp; - - if (reloc_entry->howto->partial_inplace) - { - bfd_put_16 (abfd, - (extend & 0xf800) | ((val >> 11) & 0x1f) | (val & 0x7e0), - (bfd_byte *) data + reloc_entry->address); - bfd_put_16 (abfd, - (insn & 0xffe0) | (val & 0x1f), - (bfd_byte *) data + reloc_entry->address + 2); - } - else - reloc_entry->addend = val; - - if (relocatable) - reloc_entry->address += input_section->output_offset; - else if (((val & ~0xffff) != ~0xffff) && ((val & ~0xffff) != 0)) - return bfd_reloc_overflow; - - return bfd_reloc_ok; + return ret; } /* A mapping from BFD reloc types to MIPS ELF reloc types. */ @@ -1903,7 +2161,28 @@ 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. */ @@ -1916,6 +2195,7 @@ bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, /* 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++) @@ -1924,12 +2204,15 @@ bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, 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: @@ -1949,10 +2232,6 @@ 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: @@ -1963,6 +2242,13 @@ mips_elf64_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p) 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]; @@ -2057,7 +2343,7 @@ mips_elf64_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage, 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++; @@ -2088,7 +2374,7 @@ mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect, arelent *relent; bfd_vma i; int entsize; - reloc_howto_type *howto_table; + bfd_boolean rela_p; allocated = bfd_malloc (rel_hdr->sh_size); if (allocated == NULL) @@ -2106,9 +2392,9 @@ mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect, || 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; @@ -2193,7 +2479,7 @@ mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect, 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; @@ -2221,7 +2507,7 @@ mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect, relent->addend = rela.r_addend; - relent->howto = &howto_table[(int) type]; + relent->howto = mips_elf64_rtype_to_howto (type, rela_p); ++relent; } @@ -2283,7 +2569,7 @@ mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect, 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; @@ -2425,6 +2711,8 @@ mips_elf64_write_rel (bfd *abfd, asection *sec, 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; @@ -2521,6 +2809,8 @@ mips_elf64_write_rela (bfd *abfd, asection *sec, 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; @@ -2612,7 +2902,7 @@ static bfd_boolean elf64_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) { int offset; - unsigned int raw_size; + unsigned int size; switch (note->descsz) { @@ -2628,14 +2918,14 @@ elf64_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *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 @@ -2725,8 +3015,8 @@ 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 */ 3, /* log_file_align */ ELFCLASS64, @@ -2749,11 +3039,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 @@ -2864,9 +3149,12 @@ 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" +/* 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 INCLUDED_TARGET_FILE /* More a type of flag. */ +#include "elf64-target.h" /* The SYSV-style 'traditional' (n)64 NewABI. */ #undef TARGET_LITTLE_SYM @@ -2874,10 +3162,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 + +#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" + +/* The SVR4 MIPS ABI says that this should be 0x10000, and Linux uses + page sizes of up to that limit, so we need to respect it. */ +#define ELF_MAXPAGESIZE 0x10000 +#define elf64_bed elf64_tradbed /* Include the target file again for this target. */ #include "elf64-target.h"