forked from OSchip/llvm-project
Fix addend computation for IRELATIVE relocations.
llvm-svn: 259692
This commit is contained in:
parent
f99f0d5a7e
commit
9e3f84bf95
|
@ -285,6 +285,18 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
|
|||
bool NeedsGot = Body && Target->needsGot(Type, *Body);
|
||||
bool CBP = canBePreempted(Body, NeedsGot);
|
||||
|
||||
if (IsRela) {
|
||||
auto R = static_cast<const Elf_Rela &>(RI);
|
||||
auto S = static_cast<Elf_Rela *>(P);
|
||||
uintX_t A = NeedsGot ? 0 : R.r_addend;
|
||||
if (CBP)
|
||||
S->r_addend = A;
|
||||
else if (Body)
|
||||
S->r_addend = Body->getVA<ELFT>() + A;
|
||||
else
|
||||
S->r_addend = getLocalRelTarget(File, R, A);
|
||||
}
|
||||
|
||||
// For a symbol with STT_GNU_IFUNC type, we always create a PLT and
|
||||
// a GOT entry for the symbol, and emit an IRELATIVE reloc rather than
|
||||
// the usual JUMP_SLOT reloc for the GOT entry. For the details, you
|
||||
|
@ -318,19 +330,6 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
|
|||
P->r_offset = Body->getGotVA<ELFT>();
|
||||
else
|
||||
P->r_offset = C.getOffset(RI.r_offset) + C.OutSec->getVA();
|
||||
|
||||
if (!IsRela)
|
||||
continue;
|
||||
|
||||
auto R = static_cast<const Elf_Rela &>(RI);
|
||||
auto S = static_cast<Elf_Rela *>(P);
|
||||
uintX_t A = NeedsGot ? 0 : R.r_addend;
|
||||
if (CBP)
|
||||
S->r_addend = A;
|
||||
else if (Body)
|
||||
S->r_addend = Body->getVA<ELFT>() + A;
|
||||
else
|
||||
S->r_addend = getLocalRelTarget(File, R, A);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
|
||||
// RUN: ld.lld -static %t.o -o %tout
|
||||
// RUN: llvm-readobj -r -t %tout | FileCheck %s
|
||||
// REQUIRES: x86
|
||||
|
||||
.type foo STT_GNU_IFUNC
|
||||
.globl foo
|
||||
.type foo, @function
|
||||
foo:
|
||||
ret
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
call foo
|
||||
|
||||
// CHECK: Section ({{.*}}) .rela.plt {
|
||||
// CHECK-NEXT: R_X86_64_IRELATIVE - 0x[[ADDR:.*]]
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: Name: foo
|
||||
// CHECK-NEXT: Value: 0x[[ADDR]]
|
||||
// CHECK-NEXT: Size: 0
|
||||
// CHECK-NEXT: Binding: Global
|
||||
// CHECK-NEXT: Type: GNU_IFunc
|
Loading…
Reference in New Issue