* 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.
This commit is contained in:
parent
98eedd63d0
commit
add55e1f31
|
@ -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>
|
2001-11-20 Nick Clifton <nickc@cambridge.redhat.com>
|
||||||
|
|
||||||
* config/tc-avr.c (md_apply_fix3): Fix typo introduced by
|
* config/tc-avr.c (md_apply_fix3): Fix typo introduced by
|
||||||
|
|
|
@ -734,6 +734,9 @@ static const char *mips_isa_to_str PARAMS ((int));
|
||||||
static const char *mips_cpu_to_str PARAMS ((int));
|
static const char *mips_cpu_to_str PARAMS ((int));
|
||||||
static int validate_mips_insn PARAMS ((const struct mips_opcode *));
|
static int validate_mips_insn PARAMS ((const struct mips_opcode *));
|
||||||
static void show PARAMS ((FILE *, char *, int *, int *));
|
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(). */
|
/* Return values of my_getSmallExpression(). */
|
||||||
|
|
||||||
|
@ -10218,6 +10221,25 @@ mips_force_relocation (fixp)
|
||||||
|| fixp->fx_r_type == BFD_RELOC_PCREL_LO16));
|
|| 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. */
|
/* Apply a fixup to the object file. */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -10257,25 +10279,12 @@ md_apply_fix3 (fixP, valP, seg)
|
||||||
#ifdef OBJ_ELF
|
#ifdef OBJ_ELF
|
||||||
if (fixP->fx_addsy != NULL && OUTPUT_FLAVOR == bfd_target_elf_flavour)
|
if (fixP->fx_addsy != NULL && OUTPUT_FLAVOR == bfd_target_elf_flavour)
|
||||||
{
|
{
|
||||||
if (S_GET_OTHER (fixP->fx_addsy) == STO_MIPS16
|
if (mips_need_elf_addend_fixup (fixP))
|
||||||
|| ((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))))
|
|
||||||
|
|
||||||
{
|
{
|
||||||
valueT symval = S_GET_VALUE (fixP->fx_addsy);
|
valueT symval = S_GET_VALUE (fixP->fx_addsy);
|
||||||
|
|
||||||
value -= symval;
|
value -= symval;
|
||||||
if (value != 0
|
if (value != 0 && ! fixP->fx_pcrel)
|
||||||
&& ! fixP->fx_pcrel
|
|
||||||
&& fixP->fx_r_type != BFD_RELOC_MIPS_GPREL)
|
|
||||||
{
|
{
|
||||||
/* In this case, the bfd_install_relocation routine will
|
/* In this case, the bfd_install_relocation routine will
|
||||||
incorrectly add the symbol value back in. We just want
|
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
|
/* To support a PC relative reloc when generating embedded PIC code
|
||||||
for ECOFF, we use a Cygnus extension. We check for that here to
|
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. */
|
make sure that we don't let such a reloc escape normally. */
|
||||||
|
|
Loading…
Reference in New Issue