[patch] gas: MIPS64/ELF: Another RELA problem
Maciej W. Rozycki
macro@ds2.pg.gda.pl
Wed Jun 12 05:55:00 GMT 2002
Hello,
I've discovered another problem with RELA relocations -- for certain
cases the symbol's value is subtracted twice, under the assumption
bfd_install_relocation() will add it incorrectly. For RELA relocations it
never does so, because howto->special_function is bfd_elf_generic_reloc()
and it closes relocation processing if
!reloc_entry->howto->partial_inplace.
Here is a fix that works for me. Given the following source:
$ cat r_mips_64.s
.data
.space 32
.globl foo
foo:
.space 32
bar:
.dword foo+24
I get the following result now:
$ mips64el-linux-as -64 -EL -o r_mips_64-0.o r_mips_64.s
$ mips64el-linux-objdump -r r_mips_64-0.o
r_mips_64-0.o: file format elf64-tradlittlemips
RELOCATION RECORDS FOR [.data]:
OFFSET TYPE VALUE
0000000000000040 R_MIPS_64 foo+0xfffffffffffffff8
and the following one after the fix:
$ mips64el-linux-as -64 -EL -o r_mips_64-1.o r_mips_64.s
$ mips64el-linux-objdump -r r_mips_64-1.o
r_mips_64-1.o: file format elf64-tradlittlemips
RELOCATION RECORDS FOR [.data]:
OFFSET TYPE VALUE
0000000000000040 R_MIPS_64 foo+0x0000000000000018
OK to apply?
2002-06-12 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
* config/tc-mips.c (md_apply_fix3): Don't subtract the symbol's
value twice for RELA relocations.
BTW, this whole bfd_install_relocation() and add/subtract twice
implementation seems seriously broken for me. It was already discussed
here a few times. I can't recall reasons for not fixing it properly
before, but maybe it's now the right time to do so? Or do we want to
carry the broken code forever?
Maciej
--
+ Maciej W. Rozycki, Technical University of Gdansk, Poland +
+--------------------------------------------------------------+
+ e-mail: macro@ds2.pg.gda.pl, PGP key available +
binutils-2.12.90-20020607-mips-md_apply_fix3-rela.patch
diff -up --recursive --new-file binutils.macro/gas/config/tc-mips.c binutils/gas/config/tc-mips.c
--- binutils.macro/gas/config/tc-mips.c 2002-06-07 03:25:25.000000000 +0000
+++ binutils/gas/config/tc-mips.c 2002-06-11 23:56:34.000000000 +0000
@@ -10875,10 +10875,13 @@ md_apply_fix3 (fixP, valP, seg)
{
if (mips_need_elf_addend_fixup (fixP))
{
+ reloc_howto_type *howto;
valueT symval = S_GET_VALUE (fixP->fx_addsy);
value -= symval;
- if (value != 0 && ! fixP->fx_pcrel)
+
+ howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
+ if (value != 0 && howto->partial_inplace && ! fixP->fx_pcrel)
{
/* In this case, the bfd_install_relocation routine will
incorrectly add the symbol value back in. We just want
@@ -10896,12 +10899,8 @@ md_apply_fix3 (fixP, valP, seg)
leave the matching HI16 in-place addends as zero. */
if (fixP->fx_r_type != BFD_RELOC_HI16_S)
{
- reloc_howto_type *howto;
bfd_vma contents, mask, field;
- howto = bfd_reloc_type_lookup (stdoutput,
- fixP->fx_r_type);
-
contents = bfd_get_bits (fixP->fx_frag->fr_literal
+ fixP->fx_where,
fixP->fx_size * 8,
More information about the Binutils
mailing list