aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <rdsandiford@googlemail.com>2001-11-21 11:24:13 +0000
committerRichard Sandiford <rdsandiford@googlemail.com>2001-11-21 11:24:13 +0000
commitadd55e1f31f174c2eb0b596fbfd9396f4b416814 (patch)
tree8afb88ea22241edbe3ec288ceece5b2398cacada
parent98eedd63d0fbc8dcbe13095c49a78665cb60ce4b (diff)
downloadgdb-add55e1f31f174c2eb0b596fbfd9396f4b416814.zip
gdb-add55e1f31f174c2eb0b596fbfd9396f4b416814.tar.gz
gdb-add55e1f31f174c2eb0b596fbfd9396f4b416814.tar.bz2
* 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.
-rw-r--r--gas/ChangeLog8
-rw-r--r--gas/config/tc-mips.c52
2 files changed, 45 insertions, 15 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index f9101c0..9440e14 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,11 @@
+2001-11-21 Richard Sandiford <rsandifo@redhat.com>
+
+ * 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 <nickc@cambridge.redhat.com>
* 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 5c3da07..92ce286 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. */