From add55e1f31f174c2eb0b596fbfd9396f4b416814 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 21 Nov 2001 11:24:13 +0000 Subject: [PATCH] * config/tc-mips.c (mips_need_elf_addend_fixup): New, extracted from... (md_apply_fix3): ...here. Don't prevent the symbol value being subtracted twice from GPREL addends. (tc_gen_reloc): Add the symbol value to a GPREL addend if it was subtracted by the previous function. --- gas/ChangeLog | 8 +++++++ gas/config/tc-mips.c | 52 +++++++++++++++++++++++++++++++------------- 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index f9101c07bd..9440e1447a 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,11 @@ +2001-11-21 Richard Sandiford + + * config/tc-mips.c (mips_need_elf_addend_fixup): New, extracted from... + (md_apply_fix3): ...here. Don't prevent the symbol value being + subtracted twice from GPREL addends. + (tc_gen_reloc): Add the symbol value to a GPREL addend if it was + subtracted by the previous function. + 2001-11-20 Nick Clifton * config/tc-avr.c (md_apply_fix3): Fix typo introduced by diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index 5c3da07c8b..92ce286853 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -734,6 +734,9 @@ static const char *mips_isa_to_str PARAMS ((int)); static const char *mips_cpu_to_str PARAMS ((int)); static int validate_mips_insn PARAMS ((const struct mips_opcode *)); static void show PARAMS ((FILE *, char *, int *, int *)); +#ifdef OBJ_ELF +static int mips_need_elf_addend_fixup PARAMS ((fixS *)); +#endif /* Return values of my_getSmallExpression(). */ @@ -10218,6 +10221,25 @@ mips_force_relocation (fixp) || fixp->fx_r_type == BFD_RELOC_PCREL_LO16)); } +#ifdef OBJ_ELF +static int +mips_need_elf_addend_fixup (fixP) + fixS *fixP; +{ + return (S_GET_OTHER (fixP->fx_addsy) == STO_MIPS16 + || ((S_IS_WEAK (fixP->fx_addsy) + || S_IS_EXTERN (fixP->fx_addsy)) + && !S_IS_COMMON (fixP->fx_addsy)) + || (symbol_used_in_reloc_p (fixP->fx_addsy) + && (((bfd_get_section_flags (stdoutput, + S_GET_SEGMENT (fixP->fx_addsy)) + & SEC_LINK_ONCE) != 0) + || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)), + ".gnu.linkonce", + sizeof (".gnu.linkonce") - 1)))); +} +#endif + /* Apply a fixup to the object file. */ void @@ -10257,25 +10279,12 @@ md_apply_fix3 (fixP, valP, seg) #ifdef OBJ_ELF if (fixP->fx_addsy != NULL && OUTPUT_FLAVOR == bfd_target_elf_flavour) { - if (S_GET_OTHER (fixP->fx_addsy) == STO_MIPS16 - || ((S_IS_WEAK (fixP->fx_addsy) - || S_IS_EXTERN (fixP->fx_addsy)) - && !S_IS_COMMON (fixP->fx_addsy)) - || (symbol_used_in_reloc_p (fixP->fx_addsy) - && (((bfd_get_section_flags (stdoutput, - S_GET_SEGMENT (fixP->fx_addsy)) - & SEC_LINK_ONCE) != 0) - || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)), - ".gnu.linkonce", - sizeof (".gnu.linkonce") - 1)))) - + if (mips_need_elf_addend_fixup (fixP)) { valueT symval = S_GET_VALUE (fixP->fx_addsy); value -= symval; - if (value != 0 - && ! fixP->fx_pcrel - && fixP->fx_r_type != BFD_RELOC_MIPS_GPREL) + if (value != 0 && ! fixP->fx_pcrel) { /* In this case, the bfd_install_relocation routine will incorrectly add the symbol value back in. We just want @@ -12251,6 +12260,19 @@ tc_gen_reloc (section, fixp) } } +#ifdef OBJ_ELF + /* md_apply_fix3 has a double-subtraction hack to get + bfd_install_relocation to behave nicely. GPREL relocations are + handled correctly without this hack, so undo it here. We can't + stop md_apply_fix3 from subtracting twice in the first place since + the fake addend is required for variant frags above. */ + if (fixp->fx_addsy != NULL && OUTPUT_FLAVOR == bfd_target_elf_flavour + && code == BFD_RELOC_MIPS_GPREL + && reloc->addend != 0 + && mips_need_elf_addend_fixup (fixp)) + reloc->addend += S_GET_VALUE (fixp->fx_addsy); +#endif + /* To support a PC relative reloc when generating embedded PIC code for ECOFF, we use a Cygnus extension. We check for that here to make sure that we don't let such a reloc escape normally. */ -- 2.34.1