From 30ac9238dfbbddadd84b277a9cae57a006aac265 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Thu, 18 Dec 2003 10:23:10 +0000 Subject: [PATCH] bfd/ * elf32-mips.c (elf_mips_howto_table_rel): Replace all uses of mips_elf_generic_reloc with _bfd_mips_elf_generic_reloc. Use _bfd_mips_elf_hi16_reloc for R_MIPS_HI16 and R_MIPS_GNU_REL_HI16, _bfd_mips_elf_lo16_reloc for R_MIPS_LO16 and R_MIPS_GNU_REL_LO16, and _bfd_mips_elf_got16_reloc for R_MIPS_GOT16. Change rightshift to 16 for R_MIPS_HI16 and R_MIPS_GNU_REL_HI16. (mips_elf_generic_reloc, struct mips_hi16, mips_elf_hi16_reloc) (mips_elf_lo16_reloc, mips_elf_got16_reloc): Delete. (_bfd_mips_elf32_gprel16_reloc): Remove special case. (mips_elf_gprel32_reloc, mips32_64bit_reloc): Likewise. * elf64-mips.c (mips_elf64_howto_table_rel): Replace all uses of mips_elf_generic_reloc with _bfd_mips_elf_generic_reloc. Use _bfd_mips_elf_hi16_reloc for R_MIPS_HI16, _bfd_mips_elf_lo16_reloc for R_MIPS_LO16 and _bfd_mips_elf_got16_reloc for R_MIPS_GOT16. Change R_MIPS_HI16's rightshift to 16. (mips_elf64_howto_table_rela): Replace all uses of mips_elf_generic_reloc with _bfd_mips_elf_generic_reloc. Use _bfd_mips_elf_generic_reloc for R_MIPS_GOT16 as well. (mips_elf64_hi16_reloc, mips_elf64_got16_reloc): Delete. (mips_elf64_shift6_reloc): Remove special case. Use _bfd_mips_elf_generic_reloc instead of returning bfd_reloc_continue. * elfn32-mips.c (prev_reloc_section): Delete. (prev_reloc_address, prev_reloc_addend): Delete. (elf_mips_howto_table_rel, elf_mips_howto_table_rela): As for elf64-mips.c (GET_RELOC_ADDEND, SET_RELOC_ADDEND): Delete. (mips_elf_generic_reloc, struct mips_hi16, mips_elf_hi16_reloc) (mips_elf_lo16_reloc, mips_elf_got16_reloc): Delete. (mips_elf_gprel16_reloc): Delete use of GET_RELOC_ADDEND. (mips_elf_literal_reloc, mips_elf_gprel32_reloc): Likewise. (mips16_jump_reloc, mips16_gprel_reloc): Likewise. (mips_elf_shift6_reloc): Likewise. Delete use of SET_RELOC_ADDEND. * elfxx-mips.c (_bfd_mips_elf_gprel16_with_gp): Use _bfd_relocate_contents to install an in-place addend. (mips_hi16): New structure. (mips_hi16_list): Moved from elf32-mips.c. (_bfd_mips_elf_hi16_reloc, _bfd_mips_elf_got16_reloc): New functions. (_bfd_mips_elf_lo16_reloc, _bfd_mips_elf_generic_reloc): New functions. (mips_elf_calculate_relocation): Assume addend is unshifted. (_bfd_mips_elf_relocate_section): Don't apply the howto rightshift on top of the usual high-part shift. Don't shift the addend right before calling mips_elf_calculate_relocation. * elfxx-mips.h (_bfd_mips_elf_hi16_reloc): Declare. (_bfd_mips_elf_got16_reloc, _bfd_mips_elf_lo16_reloc): Declare. (_bfd_mips_elf_generic_reloc): Declare. gas/ * config/tc-mips.c (mips_need_elf_addend_fixup): Delete. (md_apply_fix3): Remove bfd_install_relocation workarounds. (tc_gen_reloc): Likewise. Factor handling of pc-relative relocations and treat fx_addnumber as relative to the relocation address. gas/testsuite/ * gas/mips/mips16-jalx.d: Use -mabi=o64. * gas/mips/mips16.d: Likewise. * gas/mips/elf-rel17.[sd]: New test. * gas/mips/mips.exp: Run it. --- bfd/ChangeLog | 52 ++++ bfd/elf32-mips.c | 357 +++---------------------- bfd/elf64-mips.c | 203 +++++---------- bfd/elfn32-mips.c | 377 +++++---------------------- bfd/elfxx-mips.c | 258 +++++++++++++++--- bfd/elfxx-mips.h | 8 + gas/ChangeLog | 7 + gas/config/tc-mips.c | 148 +++-------- gas/testsuite/ChangeLog | 7 + gas/testsuite/gas/mips/elf-rel17.d | 13 + gas/testsuite/gas/mips/elf-rel17.s | 3 + gas/testsuite/gas/mips/mips.exp | 1 + gas/testsuite/gas/mips/mips16-jalx.d | 2 +- gas/testsuite/gas/mips/mips16.d | 2 +- 14 files changed, 516 insertions(+), 922 deletions(-) create mode 100644 gas/testsuite/gas/mips/elf-rel17.d create mode 100644 gas/testsuite/gas/mips/elf-rel17.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 4b354be12f..d818058a31 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,55 @@ +2003-12-18 Richard Sandiford + + * elf32-mips.c (elf_mips_howto_table_rel): Replace all uses of + mips_elf_generic_reloc with _bfd_mips_elf_generic_reloc. Use + _bfd_mips_elf_hi16_reloc for R_MIPS_HI16 and R_MIPS_GNU_REL_HI16, + _bfd_mips_elf_lo16_reloc for R_MIPS_LO16 and R_MIPS_GNU_REL_LO16, + and _bfd_mips_elf_got16_reloc for R_MIPS_GOT16. Change rightshift + to 16 for R_MIPS_HI16 and R_MIPS_GNU_REL_HI16. + (mips_elf_generic_reloc, struct mips_hi16, mips_elf_hi16_reloc) + (mips_elf_lo16_reloc, mips_elf_got16_reloc): Delete. + (_bfd_mips_elf32_gprel16_reloc): Remove special case. + (mips_elf_gprel32_reloc, mips32_64bit_reloc): Likewise. + + * elf64-mips.c (mips_elf64_howto_table_rel): Replace all uses of + mips_elf_generic_reloc with _bfd_mips_elf_generic_reloc. Use + _bfd_mips_elf_hi16_reloc for R_MIPS_HI16, _bfd_mips_elf_lo16_reloc + for R_MIPS_LO16 and _bfd_mips_elf_got16_reloc for R_MIPS_GOT16. + Change R_MIPS_HI16's rightshift to 16. + (mips_elf64_howto_table_rela): Replace all uses of + mips_elf_generic_reloc with _bfd_mips_elf_generic_reloc. + Use _bfd_mips_elf_generic_reloc for R_MIPS_GOT16 as well. + (mips_elf64_hi16_reloc, mips_elf64_got16_reloc): Delete. + (mips_elf64_shift6_reloc): Remove special case. Use + _bfd_mips_elf_generic_reloc instead of returning bfd_reloc_continue. + + * elfn32-mips.c (prev_reloc_section): Delete. + (prev_reloc_address, prev_reloc_addend): Delete. + (elf_mips_howto_table_rel, elf_mips_howto_table_rela): As for + elf64-mips.c + (GET_RELOC_ADDEND, SET_RELOC_ADDEND): Delete. + (mips_elf_generic_reloc, struct mips_hi16, mips_elf_hi16_reloc) + (mips_elf_lo16_reloc, mips_elf_got16_reloc): Delete. + (mips_elf_gprel16_reloc): Delete use of GET_RELOC_ADDEND. + (mips_elf_literal_reloc, mips_elf_gprel32_reloc): Likewise. + (mips16_jump_reloc, mips16_gprel_reloc): Likewise. + (mips_elf_shift6_reloc): Likewise. Delete use of SET_RELOC_ADDEND. + + * elfxx-mips.c (_bfd_mips_elf_gprel16_with_gp): Use + _bfd_relocate_contents to install an in-place addend. + (mips_hi16): New structure. + (mips_hi16_list): Moved from elf32-mips.c. + (_bfd_mips_elf_hi16_reloc, _bfd_mips_elf_got16_reloc): New functions. + (_bfd_mips_elf_lo16_reloc, _bfd_mips_elf_generic_reloc): New functions. + (mips_elf_calculate_relocation): Assume addend is unshifted. + (_bfd_mips_elf_relocate_section): Don't apply the howto rightshift + on top of the usual high-part shift. Don't shift the addend right + before calling mips_elf_calculate_relocation. + + * elfxx-mips.h (_bfd_mips_elf_hi16_reloc): Declare. + (_bfd_mips_elf_got16_reloc, _bfd_mips_elf_lo16_reloc): Declare. + (_bfd_mips_elf_generic_reloc): Declare. + 2003-12-16 Eric Youngdale Nick Clifton diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c index 299c39546b..27b1c4b0b4 100644 --- a/bfd/elf32-mips.c +++ b/bfd/elf32-mips.c @@ -47,14 +47,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define ECOFF_SIGNED_32 #include "ecoffswap.h" -static bfd_reloc_status_type mips_elf_generic_reloc - (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); -static bfd_reloc_status_type mips_elf_hi16_reloc - (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); -static bfd_reloc_status_type mips_elf_lo16_reloc - (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); -static bfd_reloc_status_type mips_elf_got16_reloc - (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); static bfd_reloc_status_type gprel32_with_gp (bfd *, asymbol *, arelent *, asection *, bfd_boolean, void *, bfd_vma); static bfd_reloc_status_type mips_elf_gprel32_reloc @@ -120,7 +112,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_NONE", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -135,7 +127,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -150,7 +142,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_32", /* name */ TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ @@ -165,7 +157,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_REL32", /* name */ TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ @@ -183,7 +175,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = /* This needs complex overflow detection, because the upper four bits must match the PC + 4. */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_26", /* name */ TRUE, /* partial_inplace */ 0x03ffffff, /* src_mask */ @@ -192,13 +184,13 @@ static reloc_howto_type elf_mips_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_elf_hi16_reloc, /* special_function */ + _bfd_mips_elf_hi16_reloc, /* special_function */ "R_MIPS_HI16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -213,7 +205,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_lo16_reloc, /* special_function */ + _bfd_mips_elf_lo16_reloc, /* special_function */ "R_MIPS_LO16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -258,7 +250,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_got16_reloc, /* special_function */ + _bfd_mips_elf_got16_reloc, /* special_function */ "R_MIPS_GOT16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -273,7 +265,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_PC16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -288,7 +280,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_CALL16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -324,7 +316,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 6, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_SHIFT5", /* name */ TRUE, /* partial_inplace */ 0x000007c0, /* src_mask */ @@ -341,7 +333,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 6, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_SHIFT6", /* name */ TRUE, /* partial_inplace */ 0x000007c4, /* src_mask */ @@ -371,7 +363,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_DISP", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -386,7 +378,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_PAGE", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -401,7 +393,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_OFST", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -416,7 +408,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_HI16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -431,7 +423,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_LO16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -446,7 +438,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_SUB", /* name */ TRUE, /* partial_inplace */ MINUS_ONE, /* src_mask */ @@ -466,7 +458,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_HIGHER", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -481,7 +473,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_HIGHEST", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -496,7 +488,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_CALL_HI16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -511,7 +503,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_CALL_LO16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -526,7 +518,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_SCN_DISP", /* name */ TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ @@ -547,7 +539,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_JALR", /* name */ FALSE, /* partial_inplace */ 0x00000000, /* src_mask */ @@ -611,13 +603,13 @@ static reloc_howto_type elf_mips16_gprel_howto = /* High 16 bits of symbol value, pc-relative. */ static reloc_howto_type elf_mips_gnu_rel_hi16 = HOWTO (R_MIPS_GNU_REL_HI16, /* type */ - 0, /* rightshift */ + 16, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_hi16_reloc, /* special_function */ + _bfd_mips_elf_hi16_reloc, /* special_function */ "R_MIPS_GNU_REL_HI16", /* name */ TRUE, /* partial_inplace */ 0xffff, /* src_mask */ @@ -633,7 +625,7 @@ static reloc_howto_type elf_mips_gnu_rel_lo16 = TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_lo16_reloc, /* special_function */ + _bfd_mips_elf_lo16_reloc, /* special_function */ "R_MIPS_GNU_REL_LO16", /* name */ TRUE, /* partial_inplace */ 0xffff, /* src_mask */ @@ -649,7 +641,7 @@ static reloc_howto_type elf_mips_gnu_rel16_s2 = TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GNU_REL16_S2", /* name */ TRUE, /* partial_inplace */ 0xffff, /* src_mask */ @@ -665,7 +657,7 @@ static reloc_howto_type elf_mips_gnu_pcrel64 = TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_PC64", /* name */ TRUE, /* partial_inplace */ MINUS_ONE, /* src_mask */ @@ -681,7 +673,7 @@ static reloc_howto_type elf_mips_gnu_pcrel32 = TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_PC32", /* name */ TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ @@ -720,260 +712,6 @@ static reloc_howto_type elf_mips_gnu_vtentry_howto = 0, /* dst_mask */ FALSE); /* pcrel_offset */ -/* We use this instead of bfd_elf_generic_reloc because the latter - gets the handling of zero addends wrong. */ -static bfd_reloc_status_type -mips_elf_generic_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; - } - - /* Just go on, nothing to see here. */ - return bfd_reloc_continue; -} - -/* Do a R_MIPS_HI16 relocation. This has to be done in combination - with a R_MIPS_LO16 reloc, because there is a carry from the LO16 to - the HI16. Here we just save the information we need; we do the - actual relocation when we see the LO16. - - MIPS ELF requires that the LO16 immediately follow the HI16. As a - GNU extension, for non-pc-relative relocations, we permit an - arbitrary number of HI16 relocs to be associated with a single LO16 - reloc. This extension permits gcc to output the HI and LO relocs - itself. - - This cannot be done for PC-relative relocations because both the HI16 - and LO16 parts of the relocations must be done relative to the LO16 - part, and there can be carry to or borrow from the HI16 part. */ - -struct mips_hi16 -{ - struct mips_hi16 *next; - bfd_byte *addr; - bfd_vma addend; -}; - -/* FIXME: This should not be a static variable. */ - -static struct mips_hi16 *mips_hi16_list; - -static bfd_reloc_status_type -mips_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry, - asymbol *symbol, void *data, asection *input_section, - bfd *output_bfd, char **error_message) -{ - bfd_reloc_status_type ret; - bfd_vma relocation; - struct mips_hi16 *n; - - /* 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; - } - - ret = bfd_reloc_ok; - - if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0) - { - bfd_boolean relocatable; - bfd_vma gp; - - if (ret == bfd_reloc_undefined) - abort (); - - if (output_bfd != NULL) - relocatable = TRUE; - else - { - relocatable = FALSE; - output_bfd = symbol->section->output_section->owner; - } - - ret = mips_elf_final_gp (output_bfd, symbol, relocatable, - error_message, &gp); - if (ret != bfd_reloc_ok) - return ret; - - relocation = gp - reloc_entry->address; - } - else - { - if (bfd_is_und_section (symbol->section) && output_bfd == NULL) - ret = bfd_reloc_undefined; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - } - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - /* Save the information, and let LO16 do the actual relocation. */ - n = bfd_malloc (sizeof *n); - if (n == NULL) - return bfd_reloc_outofrange; - n->addr = (bfd_byte *) data + reloc_entry->address; - n->addend = relocation; - n->next = mips_hi16_list; - mips_hi16_list = n; - - if (output_bfd != NULL) - reloc_entry->address += input_section->output_offset; - - return ret; -} - -/* Do a R_MIPS_LO16 relocation. This is a straightforward 16 bit - inplace relocation; this function exists in order to do the - R_MIPS_HI16 relocation described above. */ - -static bfd_reloc_status_type -mips_elf_lo16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, - void *data, asection *input_section, bfd *output_bfd, - char **error_message) -{ - arelent gp_disp_relent; - - if (mips_hi16_list != NULL) - { - struct mips_hi16 *l; - - l = mips_hi16_list; - while (l != NULL) - { - unsigned long insn; - unsigned long val; - unsigned long vallo; - struct mips_hi16 *next; - - if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0) - { - gp_disp_relent = *reloc_entry; - reloc_entry = &gp_disp_relent; - reloc_entry->addend = l->addend; - } - else - { - /* Do the HI16 relocation. Note that we actually don't need - to know anything about the LO16 itself, except where to - find the low 16 bits of the addend needed by the LO16. */ - insn = bfd_get_32 (abfd, l->addr); - vallo = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); - /* The low order 16 bits are always treated as a signed - value. */ - vallo = ((vallo & 0xffff) ^ 0x8000) - 0x8000; - val = ((insn & 0xffff) << 16) + vallo; - val += l->addend; - - /* If PC-relative, we need to subtract out the address of the LO - half of the HI/LO. (The actual relocation is relative - to that instruction.) */ - if (reloc_entry->howto->pc_relative) - val -= reloc_entry->address; - - /* At this point, "val" has the value of the combined HI/LO - pair. If the low order 16 bits (which will be used for - the LO16 insn) are negative, then we will need an - adjustment for the high order 16 bits. */ - val += 0x8000; - val = (val >> 16) & 0xffff; - - insn &= ~ (bfd_vma) 0xffff; - insn |= val; - bfd_put_32 (abfd, insn, l->addr); - } - - next = l->next; - free (l); - l = next; - } - - mips_hi16_list = NULL; - } - else if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0) - { - bfd_reloc_status_type ret; - bfd_vma gp, relocation; - - /* FIXME: Does this case ever occur? */ - - ret = mips_elf_final_gp (output_bfd, symbol, TRUE, error_message, &gp); - if (ret != bfd_reloc_ok) - return ret; - - relocation = gp - reloc_entry->address; - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - gp_disp_relent = *reloc_entry; - reloc_entry = &gp_disp_relent; - reloc_entry->addend = relocation - 4; - } - - /* Now do the LO16 reloc in the usual way. */ - return mips_elf_generic_reloc (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message); -} - -/* 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_elf_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 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; - } - - return mips_elf_hi16_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. */ @@ -1078,16 +816,6 @@ _bfd_mips_elf32_gprel16_reloc (bfd *abfd, arelent *reloc_entry, 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 != NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && (symbol->flags & BSF_LOCAL) != 0) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - if (output_bfd != NULL) relocatable = TRUE; else @@ -1118,17 +846,6 @@ mips_elf_gprel32_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. */ - if (output_bfd != NULL - && (symbol->flags & BSF_SECTION_SYM) == 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 != NULL) relocatable = TRUE; else @@ -1194,20 +911,16 @@ gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry, sign extension. */ static bfd_reloc_status_type -mips32_64bit_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, - void *data, asection *input_section, bfd *output_bfd, - char **error_message) +mips32_64bit_reloc (bfd *abfd, arelent *reloc_entry, + asymbol *symbol ATTRIBUTE_UNUSED, + void *data, asection *input_section, + bfd *output_bfd, char **error_message) { bfd_reloc_status_type r; arelent reloc32; unsigned long val; bfd_size_type addr; - r = mips_elf_generic_reloc (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message); - if (r != bfd_reloc_continue) - return r; - /* Do a normal 32 bit relocation on the lower 32 bits. */ reloc32 = *reloc_entry; if (bfd_big_endian (abfd)) diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c index 998c5df5b3..ca0ed6ea43 100644 --- a/bfd/elf64-mips.c +++ b/bfd/elf64-mips.c @@ -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 */ @@ -633,7 +629,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_JALR", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -653,7 +649,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 +664,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 +679,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 +694,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 +712,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 +727,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 +742,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 +787,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 +802,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 +817,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 +851,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 +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_64", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -900,7 +896,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 +911,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 +926,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 +941,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 +956,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 +971,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 +987,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 +1004,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 +1020,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 +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_HIGHER", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1054,7 +1050,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 +1065,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 +1080,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 +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_SCN_DISP", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1113,7 +1109,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 +1129,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 */ @@ -1149,7 +1145,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_JALR", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1233,7 +1229,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 +1245,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 */ @@ -1411,66 +1407,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. */ @@ -1716,28 +1652,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. */ diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c index 49cf898191..2bfbf625e5 100644 --- a/bfd/elfn32-mips.c +++ b/bfd/elfn32-mips.c @@ -47,14 +47,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define ECOFF_SIGNED_32 #include "ecoffswap.h" -static bfd_reloc_status_type mips_elf_generic_reloc - (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); -static bfd_reloc_status_type mips_elf_hi16_reloc - (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); -static bfd_reloc_status_type mips_elf_lo16_reloc - (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); -static bfd_reloc_status_type mips_elf_got16_reloc - (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); static bfd_boolean mips_elf_assign_gp (bfd *, bfd_vma *); static bfd_reloc_status_type mips_elf_final_gp @@ -95,10 +87,6 @@ static irix_compat_t elf_n32_mips_irix_compat extern const bfd_target bfd_elf32_nbigmips_vec; extern const bfd_target bfd_elf32_nlittlemips_vec; -static asection *prev_reloc_section = NULL; -static bfd_vma prev_reloc_address = -1; -static bfd_vma prev_reloc_addend = 0; - /* Nonzero if ABFD is using the N32 ABI. */ #define ABI_N32_P(abfd) \ ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0) @@ -126,7 +114,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_NONE", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -141,7 +129,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -156,7 +144,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_32", /* name */ TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ @@ -171,7 +159,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_REL32", /* name */ TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ @@ -189,7 +177,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = /* This needs complex overflow detection, because the upper four bits must match the PC + 4. */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_26", /* name */ TRUE, /* partial_inplace */ 0x03ffffff, /* src_mask */ @@ -201,13 +189,13 @@ static reloc_howto_type elf_mips_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_elf_hi16_reloc, /* special_function */ + _bfd_mips_elf_hi16_reloc, /* special_function */ "R_MIPS_HI16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -222,7 +210,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_lo16_reloc, /* special_function */ + _bfd_mips_elf_lo16_reloc, /* special_function */ "R_MIPS_LO16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -267,7 +255,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_got16_reloc, /* special_function */ + _bfd_mips_elf_got16_reloc, /* special_function */ "R_MIPS_GOT16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -282,7 +270,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_PC16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -297,7 +285,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_CALL16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -333,7 +321,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 6, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_SHIFT5", /* name */ TRUE, /* partial_inplace */ 0x000007c0, /* src_mask */ @@ -363,7 +351,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_64", /* name */ TRUE, /* partial_inplace */ MINUS_ONE, /* src_mask */ @@ -378,7 +366,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_DISP", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -393,7 +381,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_PAGE", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -408,7 +396,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_OFST", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -423,7 +411,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_HI16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -438,7 +426,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_LO16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -453,7 +441,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_SUB", /* name */ TRUE, /* partial_inplace */ MINUS_ONE, /* src_mask */ @@ -469,7 +457,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_INSERT_A", /* name */ TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ @@ -486,7 +474,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_INSERT_B", /* name */ TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ @@ -502,7 +490,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_DELETE", /* name */ TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ @@ -526,7 +514,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_CALL_HI16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -541,7 +529,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_CALL_LO16", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -556,7 +544,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_SCN_DISP", /* name */ TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ @@ -570,7 +558,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_REL16", /* name */ TRUE, /* partial_inplace */ 0xffff, /* src_mask */ @@ -590,7 +578,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_RELGOT", /* name */ TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ @@ -606,7 +594,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_JALR", /* name */ FALSE, /* partial_inplace */ 0x00000000, /* src_mask */ @@ -626,7 +614,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_NONE", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -641,7 +629,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -656,7 +644,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_32", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -671,7 +659,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_REL32", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -689,7 +677,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = /* This needs complex overflow detection, because the upper 36 bits must match the PC + 4. */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_26", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -704,7 +692,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_HI16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -719,7 +707,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_LO16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -764,7 +752,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_got16_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -779,7 +767,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_PC16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -794,7 +782,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_CALL16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -828,7 +816,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 6, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_SHIFT5", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -858,7 +846,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_64", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -873,7 +861,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_DISP", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -888,7 +876,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_PAGE", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -903,7 +891,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_OFST", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -918,7 +906,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_HI16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -933,7 +921,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GOT_LO16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -948,7 +936,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_SUB", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -964,7 +952,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_INSERT_A", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -981,7 +969,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_INSERT_B", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -997,7 +985,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_DELETE", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1012,7 +1000,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_HIGHER", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1027,7 +1015,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_HIGHEST", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1042,7 +1030,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_CALL_HI16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1057,7 +1045,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_CALL_LO16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1072,7 +1060,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_SCN_DISP", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1087,7 +1075,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_REL16", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1107,7 +1095,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_RELGOT", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1123,7 +1111,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_JALR", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -1207,7 +1195,7 @@ static reloc_howto_type elf_mips_gnu_rel16_s2 = TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_GNU_REL16_S2", /* name */ TRUE, /* partial_inplace */ 0x0000ffff, /* src_mask */ @@ -1223,224 +1211,13 @@ static reloc_howto_type elf_mips_gnu_rela16_s2 = TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips_elf_generic_reloc, /* special_function */ + _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 */ -/* This is derived from bfd_elf_generic_reloc. NewABI allows us to have - several relocations against the same address. The addend is derived - from the addends of preceding relocations. If we don't need to - do something special, we simply keep track of the addend. */ - -#define GET_RELOC_ADDEND(obfd, sym, entry, sec) \ -{ \ - /* If we're relocating, and this is an external symbol, we don't \ - want to change anything. */ \ - if ((obfd) != NULL \ - && ((sym)->flags & BSF_SECTION_SYM) == 0 \ - && (! (entry)->howto->partial_inplace \ - || (entry)->addend == 0)) \ - { \ - (entry)->address += (sec)->output_offset; \ - return bfd_reloc_ok; \ - } \ - \ - /* The addend of combined relocs is remembered and left for \ - subsequent relocs. */ \ - if (prev_reloc_address != (entry)->address \ - || prev_reloc_section != (sec)) \ - { \ - prev_reloc_section = (sec); \ - prev_reloc_address = (entry)->address; \ - prev_reloc_addend = (entry)->addend; \ - } \ - else \ - (entry)->addend = prev_reloc_addend; \ -} - -#define SET_RELOC_ADDEND(entry) \ -{ \ - prev_reloc_addend = (entry)->addend; \ -} - -static bfd_reloc_status_type -mips_elf_generic_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) -{ - GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section) - - return bfd_reloc_continue; -} - -/* Do a R_MIPS_HI16 relocation. This has to be done in combination - with a R_MIPS_LO16 reloc, because there is a carry from the LO16 to - the HI16. Here we just save the information we need; we do the - actual relocation when we see the LO16. - - MIPS ELF requires that the LO16 immediately follow the HI16. As a - GNU extension, for non-pc-relative relocations, we permit an - arbitrary number of HI16 relocs to be associated with a single LO16 - reloc. This extension permits gcc to output the HI and LO relocs - itself. - - This cannot be done for PC-relative relocations because both the HI16 - and LO16 parts of the relocations must be done relative to the LO16 - part, and there can be carry to or borrow from the HI16 part. */ - -struct mips_hi16 -{ - struct mips_hi16 *next; - bfd_byte *addr; - bfd_vma addend; -}; - -/* FIXME: This should not be a static variable. */ - -static struct mips_hi16 *mips_hi16_list; - -static bfd_reloc_status_type -mips_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry, - asymbol *symbol, void *data, asection *input_section, - bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED) -{ - bfd_reloc_status_type ret; - bfd_vma relocation; - struct mips_hi16 *n; - - GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section) - - ret = bfd_reloc_ok; - - if (bfd_is_und_section (symbol->section) && output_bfd == NULL) - ret = bfd_reloc_undefined; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - /* Save the information, and let LO16 do the actual relocation. */ - n = bfd_malloc (sizeof *n); - if (n == NULL) - return bfd_reloc_outofrange; - n->addr = (bfd_byte *) data + reloc_entry->address; - n->addend = relocation; - n->next = mips_hi16_list; - mips_hi16_list = n; - - if (output_bfd != NULL) - reloc_entry->address += input_section->output_offset; - - return ret; -} - -/* Do a R_MIPS_LO16 relocation. This is a straightforward 16 bit - inplace relocation; this function exists in order to do the - R_MIPS_HI16 relocation described above. */ - -static bfd_reloc_status_type -mips_elf_lo16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, - void *data, asection *input_section, bfd *output_bfd, - char **error_message) -{ - if (mips_hi16_list != NULL) - { - struct mips_hi16 *l; - - l = mips_hi16_list; - while (l != NULL) - { - unsigned long insn; - unsigned long val; - unsigned long vallo; - struct mips_hi16 *next; - - /* Do the HI16 relocation. Note that we actually don't need - to know anything about the LO16 itself, except where to - find the low 16 bits of the addend needed by the LO16. */ - insn = bfd_get_32 (abfd, l->addr); - vallo = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); - - /* The low order 16 bits are always treated as a signed - value. */ - vallo = ((vallo & 0xffff) ^ 0x8000) - 0x8000; - val = ((insn & 0xffff) << 16) + vallo; - val += l->addend; - - /* If PC-relative, we need to subtract out the address of the LO - half of the HI/LO. (The actual relocation is relative - to that instruction.) */ - if (reloc_entry->howto->pc_relative) - val -= reloc_entry->address; - - /* At this point, "val" has the value of the combined HI/LO - pair. If the low order 16 bits (which will be used for - the LO16 insn) are negative, then we will need an - adjustment for the high order 16 bits. */ - val += 0x8000; - val = (val >> 16) & 0xffff; - - insn &= ~ (bfd_vma) 0xffff; - insn |= val; - bfd_put_32 (abfd, insn, l->addr); - - next = l->next; - free (l); - l = next; - } - - mips_hi16_list = NULL; - } - - /* Now do the LO16 reloc in the usual way. */ - return mips_elf_generic_reloc (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message); -} - -/* 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_elf_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_elf_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 mips_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. */ @@ -1542,8 +1319,6 @@ mips_elf_gprel16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry, bfd_reloc_status_type ret; bfd_vma gp; - GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section) - if (output_bfd != NULL) relocatable = TRUE; else @@ -1573,8 +1348,6 @@ mips_elf_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, bfd_reloc_status_type ret; bfd_vma gp; - GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section) - /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */ if (output_bfd != NULL) relocatable = TRUE; @@ -1606,8 +1379,6 @@ mips_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, bfd_reloc_status_type ret; bfd_vma gp; - GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section) - /* R_MIPS_GPREL32 relocations are defined for local symbols only. */ if (output_bfd != NULL && (symbol->flags & BSF_SECTION_SYM) == 0 @@ -1684,36 +1455,33 @@ gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry, the rest is at bits 6-10. The bitpos already got right by the howto. */ static bfd_reloc_status_type -mips_elf_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_elf_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, + void *data, asection *input_section, bfd *output_bfd, + char **error_message) { - GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section) - if (reloc_entry->howto->partial_inplace) { reloc_entry->addend = ((reloc_entry->addend & 0x00007c0) | (reloc_entry->addend & 0x00000800) >> 9); } - SET_RELOC_ADDEND (reloc_entry) - - 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. */ static bfd_reloc_status_type -mips16_jump_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry, - asymbol *symbol, void *data ATTRIBUTE_UNUSED, - asection *input_section, bfd *output_bfd, +mips16_jump_reloc (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc_entry ATTRIBUTE_UNUSED, + asymbol *symbol ATTRIBUTE_UNUSED, + void *data ATTRIBUTE_UNUSED, + asection *input_section, bfd *output_bfd ATTRIBUTE_UNUSED, char **error_message ATTRIBUTE_UNUSED) { static bfd_boolean warned = FALSE; - GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section) - /* FIXME. */ if (! warned) (*_bfd_error_handler) @@ -1739,8 +1507,6 @@ mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, bfd_signed_vma val; bfd_vma relocation; - GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section) - if (output_bfd != NULL) relocatable = TRUE; else @@ -1804,9 +1570,6 @@ mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, return bfd_reloc_ok; } - -#undef GET_RELOC_ADDEND -#undef SET_RELOC_ADDEND /* A mapping from BFD reloc types to MIPS ELF reloc types. */ diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 1af0f98001..7bcdb1115b 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -1082,8 +1082,8 @@ _bfd_mips_elf_gprel16_with_gp (bfd *abfd, asymbol *symbol, bfd_boolean relocatable, void *data, bfd_vma gp) { bfd_vma relocation; - unsigned long insn = 0; bfd_signed_vma val; + bfd_reloc_status_type status; if (bfd_is_com_section (symbol->section)) relocation = 0; @@ -1099,13 +1099,7 @@ _bfd_mips_elf_gprel16_with_gp (bfd *abfd, asymbol *symbol, /* Set val to the offset into the section or symbol. */ val = reloc_entry->addend; - if (reloc_entry->howto->partial_inplace) - { - insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); - val += insn & 0xffff; - } - - _bfd_mips_elf_sign_extend(val, 16); + _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 @@ -1116,16 +1110,215 @@ _bfd_mips_elf_gprel16_with_gp (bfd *abfd, asymbol *symbol, if (reloc_entry->howto->partial_inplace) { - insn = (insn & ~0xffff) | (val & 0xffff); - bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address); + status = _bfd_relocate_contents (reloc_entry->howto, abfd, val, + (bfd_byte *) data + + reloc_entry->address); + if (status != bfd_reloc_ok) + return status; } 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; +} + +/* Used to store a REL high-part relocation such as R_MIPS_HI16 or + R_MIPS_GOT16. REL is the relocation, INPUT_SECTION is the section + that contains the relocation field and DATA points to the start of + INPUT_SECTION. */ + +struct mips_hi16 +{ + struct mips_hi16 *next; + bfd_byte *data; + asection *input_section; + arelent rel; +}; + +/* FIXME: This should not be a static variable. */ + +static struct mips_hi16 *mips_hi16_list; + +/* A howto special_function for REL *HI16 relocations. We can only + calculate the correct value once we've seen the partnering + *LO16 relocation, so just save the information for later. + + The ABI requires that the *LO16 immediately follow the *HI16. + However, as a GNU extension, we permit an arbitrary number of + *HI16s to be associated with a single *LO16. This significantly + simplies the relocation handling in gcc. */ + +bfd_reloc_status_type +_bfd_mips_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry, + asymbol *symbol ATTRIBUTE_UNUSED, void *data, + asection *input_section, bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) +{ + struct mips_hi16 *n; + + if (reloc_entry->address > input_section->_cooked_size) + return bfd_reloc_outofrange; + + n = bfd_malloc (sizeof *n); + if (n == NULL) + return bfd_reloc_outofrange; + + n->next = mips_hi16_list; + n->data = data; + n->input_section = input_section; + n->rel = *reloc_entry; + mips_hi16_list = n; + + if (output_bfd != NULL) + reloc_entry->address += input_section->output_offset; + + return bfd_reloc_ok; +} + +/* A howto special_function for REL R_MIPS_GOT16 relocations. This is just + like any other 16-bit relocation when applied to global symbols, but is + treated in the same as R_MIPS_HI16 when applied to local symbols. */ + +bfd_reloc_status_type +_bfd_mips_elf_got16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, + void *data, asection *input_section, + bfd *output_bfd, char **error_message) +{ + if ((symbol->flags & (BSF_GLOBAL | BSF_WEAK)) != 0 + || bfd_is_und_section (bfd_get_section (symbol)) + || bfd_is_com_section (bfd_get_section (symbol))) + /* The relocation is against a global symbol. */ + return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, + error_message); + + return _bfd_mips_elf_hi16_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message); +} + +/* A howto special_function for REL *LO16 relocations. The *LO16 itself + is a straightforward 16 bit inplace relocation, but we must deal with + any partnering high-part relocations as well. */ + +bfd_reloc_status_type +_bfd_mips_elf_lo16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, + void *data, asection *input_section, + bfd *output_bfd, char **error_message) +{ + bfd_vma vallo; + + if (reloc_entry->address > input_section->_cooked_size) + return bfd_reloc_outofrange; + + vallo = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); + while (mips_hi16_list != NULL) + { + bfd_reloc_status_type ret; + struct mips_hi16 *hi; + + hi = mips_hi16_list; + + /* R_MIPS_GOT16 relocations are something of a special case. We + want to install the addend in the same way as for a R_MIPS_HI16 + relocation (with a rightshift of 16). However, since GOT16 + relocations can also be used with global symbols, their howto + has a rightshift of 0. */ + if (hi->rel.howto->type == R_MIPS_GOT16) + hi->rel.howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, R_MIPS_HI16, FALSE); + + /* VALLO is a signed 16-bit number. Bias it by 0x8000 so that any + carry or borrow will induce a change of +1 or -1 in the high part. */ + hi->rel.addend += (vallo + 0x8000) & 0xffff; + + /* R_MIPS_GNU_REL_HI16 relocations are relative to the address of the + lo16 relocation, not their own address. If we're calculating the + final value, and hence subtracting the "PC", subtract the offset + of the lo16 relocation from here. */ + if (output_bfd == NULL && hi->rel.howto->type == R_MIPS_GNU_REL_HI16) + hi->rel.addend -= reloc_entry->address - hi->rel.address; + + ret = _bfd_mips_elf_generic_reloc (abfd, &hi->rel, symbol, hi->data, + hi->input_section, output_bfd, + error_message); + if (ret != bfd_reloc_ok) + return ret; + + mips_hi16_list = hi->next; + free (hi); + } + + return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, + error_message); +} + +/* A generic howto special_function. This calculates and installs the + relocation itself, thus avoiding the oft-discussed problems in + bfd_perform_relocation and bfd_install_relocation. */ + +bfd_reloc_status_type +_bfd_mips_elf_generic_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) +{ + bfd_signed_vma val; + bfd_reloc_status_type status; + bfd_boolean relocatable; + + relocatable = (output_bfd != NULL); + + if (reloc_entry->address > input_section->_cooked_size) + return bfd_reloc_outofrange; + + /* Build up the field adjustment in VAL. */ + val = 0; + if (!relocatable || (symbol->flags & BSF_SECTION_SYM) != 0) + { + /* Either we're calculating the final field value or we have a + relocation against a section symbol. Add in the section's + offset or address. */ + val += symbol->section->output_section->vma; + val += symbol->section->output_offset; + } + + if (!relocatable) + { + /* We're calculating the final field value. Add in the symbol's value + and, if pc-relative, subtract the address of the field itself. */ + val += symbol->value; + if (reloc_entry->howto->pc_relative) + { + val -= input_section->output_section->vma; + val -= input_section->output_offset; + val -= reloc_entry->address; + } + } + + /* VAL is now the final adjustment. If we're keeping this relocation + in the output file, and if the relocation uses a separate addend, + we just need to add VAL to that addend. Otherwise we need to add + VAL to the relocation field itself. */ + if (relocatable && !reloc_entry->howto->partial_inplace) + reloc_entry->addend += val; + else + { + /* Add in the separate addend, if any. */ + val += reloc_entry->addend; + + /* Add VAL to the relocation field. */ + status = _bfd_relocate_contents (reloc_entry->howto, abfd, val, + (bfd_byte *) data + + reloc_entry->address); + if (status != bfd_reloc_ok) + return status; + } + + if (relocatable) + reloc_entry->address += input_section->output_offset; return bfd_reloc_ok; } @@ -3203,7 +3396,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, break; case R_MIPS_GNU_REL16_S2: - value = symbol + _bfd_mips_elf_sign_extend (addend << 2, 18) - p; + value = symbol + _bfd_mips_elf_sign_extend (addend, 18) - p; overflowed_p = mips_elf_overflow_p (value, 18); value = (value >> 2) & howto->dst_mask; break; @@ -3226,9 +3419,9 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, R_MIPS_26 case here. */ case R_MIPS_26: if (local_p) - value = (((addend << 2) | ((p + 4) & 0xf0000000)) + symbol) >> 2; + value = ((addend | ((p + 4) & 0xf0000000)) + symbol) >> 2; else - value = (_bfd_mips_elf_sign_extend (addend << 2, 28) + symbol) >> 2; + value = (_bfd_mips_elf_sign_extend (addend, 28) + symbol) >> 2; value &= howto->dst_mask; break; @@ -6067,7 +6260,6 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, addend = mips_elf_obtain_contents (howto, rel, input_bfd, contents); addend &= howto->src_mask; - addend <<= howto->rightshift; /* For some kinds of relocations, the ADDEND is a combination of the addend stored in two different @@ -6131,6 +6323,8 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, | ((addend & 0x7e00000) >> 16) | (addend & 0x1f)); } + else + addend <<= howto->rightshift; } else addend = rel->r_addend; @@ -6170,33 +6364,25 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, /* Adjust the addend appropriately. */ addend += local_sections[r_symndx]->output_offset; - if (howto->partial_inplace) + if (rela_relocation_p) + /* If this is a RELA relocation, just update the addend. */ + rel->r_addend = addend; + else { - /* If the relocation is for a R_MIPS_HI16 or R_MIPS_GOT16, - then we only want to write out the high-order 16 bits. - The subsequent R_MIPS_LO16 will handle the low-order bits. - */ - if (r_type == R_MIPS_HI16 || r_type == R_MIPS_GOT16 + if (r_type == R_MIPS_HI16 + || r_type == R_MIPS_GOT16 || r_type == R_MIPS_GNU_REL_HI16) addend = mips_elf_high (addend); else if (r_type == R_MIPS_HIGHER) addend = mips_elf_higher (addend); else if (r_type == R_MIPS_HIGHEST) addend = mips_elf_highest (addend); - } + else + addend >>= howto->rightshift; - if (rela_relocation_p) - /* If this is a RELA relocation, just update the addend. - We have to cast away constness for REL. */ - rel->r_addend = addend; - else - { - /* Otherwise, we have to write the value back out. Note - that we use the source mask, rather than the - destination mask because the place to which we are - writing will be source of the addend in the final - link. */ - addend >>= howto->rightshift; + /* We use the source mask, rather than the destination + mask because the place to which we are writing will be + source of the addend in the final link. */ addend &= howto->src_mask; if (r_type == R_MIPS_64 && ! NEWABI_P (output_bfd)) @@ -6260,8 +6446,6 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, else use_saved_addend_p = FALSE; - addend >>= howto->rightshift; - /* Figure out what value we are supposed to relocate. */ switch (mips_elf_calculate_relocation (output_bfd, input_bfd, input_section, info, rel, diff --git a/bfd/elfxx-mips.h b/bfd/elfxx-mips.h index aef4e7b7b2..d3787e9ef9 100644 --- a/bfd/elfxx-mips.h +++ b/bfd/elfxx-mips.h @@ -103,6 +103,14 @@ extern bfd_reloc_status_type _bfd_mips_elf_gprel16_with_gp (bfd *, asymbol *, arelent *, asection *, bfd_boolean, void *, bfd_vma); extern bfd_reloc_status_type _bfd_mips_elf32_gprel16_reloc (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); +extern bfd_reloc_status_type _bfd_mips_elf_hi16_reloc + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); +extern bfd_reloc_status_type _bfd_mips_elf_got16_reloc + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); +extern bfd_reloc_status_type _bfd_mips_elf_lo16_reloc + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); +extern bfd_reloc_status_type _bfd_mips_elf_generic_reloc + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); extern unsigned long _bfd_elf_mips_mach (flagword); extern bfd_boolean _bfd_mips_relax_section diff --git a/gas/ChangeLog b/gas/ChangeLog index aec39ccda3..95408f681a 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2003-12-18 Richard Sandiford + + * config/tc-mips.c (mips_need_elf_addend_fixup): Delete. + (md_apply_fix3): Remove bfd_install_relocation workarounds. + (tc_gen_reloc): Likewise. Factor handling of pc-relative relocations + and treat fx_addnumber as relative to the relocation address. + 2003-12-18 Richard Sandiford * config/tc-mips.c (s_change_section): When parsing the MIPS-specific diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index e6997ca78f..eb5be496f2 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -11339,31 +11339,6 @@ mips_validate_fix (struct fix *fixP, asection *seg) return 1; } -#ifdef OBJ_ELF -static int -mips_need_elf_addend_fixup (fixS *fixP) -{ - if (S_GET_OTHER (fixP->fx_addsy) == STO_MIPS16) - return 1; - if (mips_pic == EMBEDDED_PIC - && S_IS_WEAK (fixP->fx_addsy)) - return 1; - if (mips_pic != EMBEDDED_PIC - && (S_IS_WEAK (fixP->fx_addsy) - || S_IS_EXTERNAL (fixP->fx_addsy)) - && !S_IS_COMMON (fixP->fx_addsy)) - return 1; - if (((bfd_get_section_flags (stdoutput, - S_GET_SEGMENT (fixP->fx_addsy)) - & (SEC_LINK_ONCE | SEC_MERGE)) != 0) - || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)), - ".gnu.linkonce", - sizeof (".gnu.linkonce") - 1)) - return 1; - return 0; -} -#endif - /* Apply a fixup to the object file. */ void @@ -11389,61 +11364,6 @@ md_apply_fix3 (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) buf = (bfd_byte *) (fixP->fx_frag->fr_literal + fixP->fx_where); - /* If we aren't adjusting this fixup to be against the section - symbol, we need to adjust the value. */ -#ifdef OBJ_ELF - if (fixP->fx_addsy != NULL && OUTPUT_FLAVOR == bfd_target_elf_flavour) - { - if (mips_need_elf_addend_fixup (fixP) - && howto->partial_inplace - && fixP->fx_r_type != BFD_RELOC_GPREL16 - && fixP->fx_r_type != BFD_RELOC_GPREL32 - && fixP->fx_r_type != BFD_RELOC_MIPS16_GPREL) - { - /* In this case, the bfd_install_relocation routine will - incorrectly add the symbol value back in. We just want - the addend to appear in the object file. - - The condition above used to include - "&& (! fixP->fx_pcrel || howto->pcrel_offset)". - - However, howto can't be trusted here, because we - might change the reloc type in tc_gen_reloc. We can - check howto->partial_inplace because that conversion - happens to preserve howto->partial_inplace; but it - does not preserve howto->pcrel_offset. I've just - eliminated the check, because all MIPS PC-relative - relocations are marked howto->pcrel_offset. - - howto->pcrel_offset was originally added for - R_MIPS_PC16, which is generated for code like - - globl g1 .text - .text - .space 20 - g1: - x: - bal g1 - */ - *valP -= S_GET_VALUE (fixP->fx_addsy); - } - - /* This code was generated using trial and error and so is - fragile and not trustworthy. If you change it, you should - rerun the elf-rel, elf-rel2, and empic testcases and ensure - they still pass. */ - if (fixP->fx_pcrel) - { - *valP += fixP->fx_frag->fr_address + fixP->fx_where; - - /* BFD's REL handling, for MIPS, is _very_ weird. - This gives the right results, but it can't possibly - be the way things are supposed to work. */ - *valP += fixP->fx_frag->fr_address + fixP->fx_where; - } - } -#endif - /* We are not done if this is a composite relocation to set up gp. */ if (fixP->fx_addsy == NULL && ! fixP->fx_pcrel && !(fixP->fx_r_type == BFD_RELOC_MIPS_SUB @@ -13406,52 +13326,49 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) as_fatal (_("Double check fx_r_type in tc-mips.c:tc_gen_reloc")); fixp->fx_r_type = BFD_RELOC_GPREL32; } - else if (fixp->fx_r_type == BFD_RELOC_PCREL_LO16) + else if (fixp->fx_pcrel) { - if (OUTPUT_FLAVOR == bfd_target_elf_flavour) - reloc->addend = fixp->fx_addnumber; + bfd_vma pcrel_address; + + /* Set PCREL_ADDRESS to this relocation's "PC". The PC for high + high-part relocs is the address of the low-part reloc. */ + if (fixp->fx_r_type == BFD_RELOC_PCREL_HI16_S) + { + assert (fixp->fx_next != NULL + && fixp->fx_next->fx_r_type == BFD_RELOC_PCREL_LO16); + pcrel_address = (fixp->fx_next->fx_where + + fixp->fx_next->fx_frag->fr_address); + } else + pcrel_address = reloc->address; + + if (OUTPUT_FLAVOR == bfd_target_elf_flavour) + { + /* At this point, fx_addnumber is "symbol offset - pcrel_address". + Relocations want only the symbol offset. */ + reloc->addend = fixp->fx_addnumber + pcrel_address; + } + else if (fixp->fx_r_type == BFD_RELOC_PCREL_LO16 + || fixp->fx_r_type == BFD_RELOC_PCREL_HI16_S) { - /* We use a special addend for an internal RELLO reloc. */ + /* We use a special addend for an internal RELLO or RELHI reloc. */ if (symbol_section_p (fixp->fx_addsy)) - reloc->addend = reloc->address - S_GET_VALUE (fixp->fx_subsy); + reloc->addend = pcrel_address - S_GET_VALUE (fixp->fx_subsy); else - reloc->addend = fixp->fx_addnumber + reloc->address; + reloc->addend = fixp->fx_addnumber + pcrel_address; } - } - else if (fixp->fx_r_type == BFD_RELOC_PCREL_HI16_S) - { - assert (fixp->fx_next != NULL - && fixp->fx_next->fx_r_type == BFD_RELOC_PCREL_LO16); - - /* The reloc is relative to the RELLO; adjust the addend - accordingly. */ - if (OUTPUT_FLAVOR == bfd_target_elf_flavour) - reloc->addend = fixp->fx_next->fx_addnumber; else { - /* We use a special addend for an internal RELHI reloc. */ - if (symbol_section_p (fixp->fx_addsy)) - reloc->addend = (fixp->fx_next->fx_frag->fr_address - + fixp->fx_next->fx_where - - S_GET_VALUE (fixp->fx_subsy)); + if (OUTPUT_FLAVOR != bfd_target_aout_flavour) + /* A gruesome hack which is a result of the gruesome gas reloc + handling. */ + reloc->addend = pcrel_address; else - reloc->addend = (fixp->fx_addnumber - + fixp->fx_next->fx_frag->fr_address - + fixp->fx_next->fx_where); + reloc->addend = -pcrel_address; } } - else if (fixp->fx_pcrel == 0 || OUTPUT_FLAVOR == bfd_target_elf_flavour) - reloc->addend = fixp->fx_addnumber; else - { - if (OUTPUT_FLAVOR != bfd_target_aout_flavour) - /* A gruesome hack which is a result of the gruesome gas reloc - handling. */ - reloc->addend = reloc->address; - else - reloc->addend = -reloc->address; - } + reloc->addend = fixp->fx_addnumber; /* If this is a variant frag, we may need to adjust the existing reloc and generate a new one. */ @@ -13500,8 +13417,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) reloc2->address = (reloc->address + (RELAX_RELOC2 (fixp->fx_frag->fr_subtype) - RELAX_RELOC1 (fixp->fx_frag->fr_subtype))); - reloc2->addend = fixp->fx_addnumber - S_GET_VALUE (fixp->fx_addsy) - + fixp->fx_frag->tc_frag_data.tc_fr_offset; + reloc2->addend = reloc->addend; reloc2->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_LO16); assert (reloc2->howto != NULL); diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index b6060430e1..829fb75bbe 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2003-12-18 Richard Sandiford + + * gas/mips/mips16-jalx.d: Use -mabi=o64. + * gas/mips/mips16.d: Likewise. + * gas/mips/elf-rel17.[sd]: New test. + * gas/mips/mips.exp: Run it. + 2003-12-17 Nick Clifton * gas/m32r/error.exp: Add parallel.s diff --git a/gas/testsuite/gas/mips/elf-rel17.d b/gas/testsuite/gas/mips/elf-rel17.d new file mode 100644 index 0000000000..8774ae26cb --- /dev/null +++ b/gas/testsuite/gas/mips/elf-rel17.d @@ -0,0 +1,13 @@ +#objdump: -dr +#as: -mabi=32 + +.*: file format .* + +Disassembly of section \.text: + +00000000 <.*>: +.*: 3c040000 lui a0,0x0 + .*: R_MIPS_HI16 x +.*: 24840000 addiu a0,a0,0 + .*: R_MIPS_LO16 x + \.\.\. diff --git a/gas/testsuite/gas/mips/elf-rel17.s b/gas/testsuite/gas/mips/elf-rel17.s new file mode 100644 index 0000000000..44ec0fab94 --- /dev/null +++ b/gas/testsuite/gas/mips/elf-rel17.s @@ -0,0 +1,3 @@ + la $4,x + .space 16 + .comm x,12 diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp index fa8a9a9648..2d515a96b6 100644 --- a/gas/testsuite/gas/mips/mips.exp +++ b/gas/testsuite/gas/mips/mips.exp @@ -670,6 +670,7 @@ if { [istarget mips*-*-*] } then { run_dump_test "elf-rel-got-n64" run_dump_test "elf-rel-xgot-n64" } + run_dump_test "elf-rel17" run_dump_test "${tmips}${el}empic" run_dump_test "empic2" diff --git a/gas/testsuite/gas/mips/mips16-jalx.d b/gas/testsuite/gas/mips/mips16-jalx.d index eeec2cb3a3..8af10660b2 100644 --- a/gas/testsuite/gas/mips/mips16-jalx.d +++ b/gas/testsuite/gas/mips/mips16-jalx.d @@ -1,5 +1,5 @@ #objdump: -dr -mmips:4000 -mmips:16 -#as: -mips3 -mtune=r4000 -mips16 +#as: -mips3 -mtune=r4000 -mips16 -mabi=o64 #name: mips16 jalx .*: file format .* Disassembly of section .text: diff --git a/gas/testsuite/gas/mips/mips16.d b/gas/testsuite/gas/mips/mips16.d index 1550529ac5..7169d69b84 100644 --- a/gas/testsuite/gas/mips/mips16.d +++ b/gas/testsuite/gas/mips/mips16.d @@ -1,5 +1,5 @@ #objdump: -dr -mmips:4000 -#as: -mips3 -mtune=r4000 +#as: -mips3 -mtune=r4000 -mabi=o64 #name: mips16 # Test the mips16 instruction set. -- 2.34.1