From: Rafael Espindola Date: Wed, 3 Feb 2016 21:02:48 +0000 (+0000) Subject: Fix addend computation for IRELATIVE relocations. X-Git-Tag: llvmorg-3.9.0-rc1~15189 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9e3f84bf95e1f53f0d3f2115f42442a17d70f9cf;p=platform%2Fupstream%2Fllvm.git Fix addend computation for IRELATIVE relocations. llvm-svn: 259692 --- diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 8f3ab01..391fe39 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -285,6 +285,18 @@ template void RelocationSection::writeTo(uint8_t *Buf) { bool NeedsGot = Body && Target->needsGot(Type, *Body); bool CBP = canBePreempted(Body, NeedsGot); + if (IsRela) { + auto R = static_cast(RI); + auto S = static_cast(P); + uintX_t A = NeedsGot ? 0 : R.r_addend; + if (CBP) + S->r_addend = A; + else if (Body) + S->r_addend = Body->getVA() + 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 void RelocationSection::writeTo(uint8_t *Buf) { P->r_offset = Body->getGotVA(); else P->r_offset = C.getOffset(RI.r_offset) + C.OutSec->getVA(); - - if (!IsRela) - continue; - - auto R = static_cast(RI); - auto S = static_cast(P); - uintX_t A = NeedsGot ? 0 : R.r_addend; - if (CBP) - S->r_addend = A; - else if (Body) - S->r_addend = Body->getVA() + A; - else - S->r_addend = getLocalRelTarget(File, R, A); } } diff --git a/lld/test/ELF/gnu-ifunc-relative.s b/lld/test/ELF/gnu-ifunc-relative.s new file mode 100644 index 0000000..94c76a8 --- /dev/null +++ b/lld/test/ELF/gnu-ifunc-relative.s @@ -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