summaryrefslogtreecommitdiff
path: root/gnu/usr.bin/binutils
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2004-03-01 21:41:52 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2004-03-01 21:41:52 +0000
commita15cbb8885cb5bbed4a734850e04c50e371f77fc (patch)
tree83dd55d94c81c4e98bd1efd9e9386119879c9a00 /gnu/usr.bin/binutils
parent1a04845acc9e4f92f68f0583baaffe5b1b963d68 (diff)
Correctly compute pc-relative relocation addend for amd64.
ok deraadt@
Diffstat (limited to 'gnu/usr.bin/binutils')
-rw-r--r--gnu/usr.bin/binutils/gas/config/tc-i386.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/gnu/usr.bin/binutils/gas/config/tc-i386.c b/gnu/usr.bin/binutils/gas/config/tc-i386.c
index 71ddb20a042..2c187675fec 100644
--- a/gnu/usr.bin/binutils/gas/config/tc-i386.c
+++ b/gnu/usr.bin/binutils/gas/config/tc-i386.c
@@ -4343,6 +4343,8 @@ md_apply_fix3 (fixP, valp, seg)
else if (use_rela_relocations)
{
fixP->fx_no_overflow = 1;
+ /* Remember value for tc_gen_reloc. */
+ fixP->fx_addnumber = value;
value = 0;
}
md_number_to_chars (p, value, fixP->fx_size);
@@ -4804,9 +4806,23 @@ tc_gen_reloc (section, fixp)
/* Use the rela in 64bit mode. */
else
{
- rel->addend = fixp->fx_offset;
- if (fixp->fx_pcrel)
- rel->addend -= fixp->fx_size;
+ if (!fixp->fx_pcrel)
+ rel->addend = fixp->fx_offset;
+ else
+ switch (code)
+ {
+ case BFD_RELOC_X86_64_PLT32:
+ case BFD_RELOC_X86_64_GOT32:
+ case BFD_RELOC_X86_64_GOTPCREL:
+ rel->addend = fixp->fx_offset - fixp->fx_size;
+ break;
+ default:
+ rel->addend = (section->vma
+ - fixp->fx_size
+ + fixp->fx_addnumber
+ + md_pcrel_from (fixp));
+ break;
+ }
}
rel->howto = bfd_reloc_type_lookup (stdoutput, code);