diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2004-03-01 21:41:52 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2004-03-01 21:41:52 +0000 |
commit | a15cbb8885cb5bbed4a734850e04c50e371f77fc (patch) | |
tree | 83dd55d94c81c4e98bd1efd9e9386119879c9a00 | |
parent | 1a04845acc9e4f92f68f0583baaffe5b1b963d68 (diff) |
Correctly compute pc-relative relocation addend for amd64.
ok deraadt@
-rw-r--r-- | gnu/usr.bin/binutils/gas/config/tc-i386.c | 22 |
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); |