[lld] r347650 - [ELF] - Fix R_AARCH64_ADR_GOT_PAGE, R_AARCH64_LD64_GOT_LO12 handling against IFUNC symbols.
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 27 02:30:46 PST 2018
Author: grimar
Date: Tue Nov 27 02:30:46 2018
New Revision: 347650
URL: http://llvm.org/viewvc/llvm-project?rev=347650&view=rev
Log:
[ELF] - Fix R_AARCH64_ADR_GOT_PAGE, R_AARCH64_LD64_GOT_LO12 handling against IFUNC symbols.
This is https://bugs.llvm.org/show_bug.cgi?id=38074.
The issue is that when calling a function, LLD generates a
.got entry that points to the IFUNC resolver function when
instead, it should use the PLT entries properly for
handling the IFUNC.
So we should create a got entry that points to PLT entry,
which itself loads the value from
.got.plt, relocated with R_*_IRELATIVE to make things work.
Patch do that.
Differential revision: https://reviews.llvm.org/D54314
Added:
lld/trunk/test/ELF/aarch64-gnu-ifunc2.s
Modified:
lld/trunk/ELF/InputSection.cpp
lld/trunk/ELF/Relocations.cpp
lld/trunk/ELF/Relocations.h
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=347650&r1=347649&r2=347650&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Tue Nov 27 02:30:46 2018
@@ -605,6 +605,7 @@ static uint64_t getRelocTargetVA(const I
case R_ARM_SBREL:
return Sym.getVA(A) - getARMStaticBase(Sym);
case R_GOT:
+ case R_GOT_PLT:
case R_RELAX_TLS_GD_TO_IE_ABS:
return Sym.getGotVA() + A;
case R_GOTONLY_PC:
@@ -623,6 +624,7 @@ static uint64_t getRelocTargetVA(const I
case R_RELAX_TLS_GD_TO_IE_GOT_OFF:
return Sym.getGotOffset() + A;
case R_AARCH64_GOT_PAGE_PC:
+ case R_AARCH64_GOT_PAGE_PC_PLT:
case R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC:
return getAArch64Page(Sym.getGotVA() + A) - getAArch64Page(P);
case R_GOT_PC:
Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=347650&r1=347649&r2=347650&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Tue Nov 27 02:30:46 2018
@@ -324,8 +324,8 @@ static bool isAbsoluteValue(const Symbol
// Returns true if Expr refers a PLT entry.
static bool needsPlt(RelExpr Expr) {
- return isRelExprOneOf<R_PLT_PC, R_PPC_CALL_PLT, R_PLT, R_AARCH64_PLT_PAGE_PC>(
- Expr);
+ return isRelExprOneOf<R_PLT_PC, R_PPC_CALL_PLT, R_PLT, R_AARCH64_PLT_PAGE_PC,
+ R_GOT_PLT, R_AARCH64_GOT_PAGE_PC_PLT>(Expr);
}
// Returns true if Expr refers a GOT entry. Note that this function
@@ -334,7 +334,8 @@ static bool needsPlt(RelExpr Expr) {
static bool needsGot(RelExpr Expr) {
return isRelExprOneOf<R_GOT, R_GOT_OFF, R_HEXAGON_GOT, R_MIPS_GOT_LOCAL_PAGE,
R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_AARCH64_GOT_PAGE_PC,
- R_GOT_PC, R_GOT_FROM_END>(Expr);
+ R_AARCH64_GOT_PAGE_PC_PLT, R_GOT_PC, R_GOT_FROM_END,
+ R_GOT_PLT>(Expr);
}
// True if this expression is of the form Sym - X, where X is a position in the
@@ -417,8 +418,12 @@ static RelExpr toPlt(RelExpr Expr) {
return R_PLT_PC;
case R_AARCH64_PAGE_PC:
return R_AARCH64_PLT_PAGE_PC;
+ case R_AARCH64_GOT_PAGE_PC:
+ return R_AARCH64_GOT_PAGE_PC_PLT;
case R_ABS:
return R_PLT;
+ case R_GOT:
+ return R_GOT_PLT;
default:
return Expr;
}
@@ -746,7 +751,14 @@ static void addPltEntry(PltSection *Plt,
template <class ELFT> static void addGotEntry(Symbol &Sym) {
In.Got->addEntry(Sym);
- RelExpr Expr = Sym.isTls() ? R_TLS : R_ABS;
+ RelExpr Expr;
+ if (Sym.isTls())
+ Expr = R_TLS;
+ else if (Sym.isGnuIFunc())
+ Expr = R_PLT;
+ else
+ Expr = R_ABS;
+
uint64_t Off = Sym.getGotOffset();
// If a GOT slot value can be calculated at link-time, which is now,
Modified: lld/trunk/ELF/Relocations.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.h?rev=347650&r1=347649&r2=347650&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.h (original)
+++ lld/trunk/ELF/Relocations.h Tue Nov 27 02:30:46 2018
@@ -34,12 +34,19 @@ enum RelExpr {
R_ABS,
R_ADDEND,
R_AARCH64_GOT_PAGE_PC,
+ // The expression is used for IFUNC support. Describes PC-relative
+ // address of the memory page of GOT entry. This entry is used for
+ // a redirection to IPLT.
+ R_AARCH64_GOT_PAGE_PC_PLT,
R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC,
R_AARCH64_PAGE_PC,
R_AARCH64_PLT_PAGE_PC,
R_AARCH64_TLSDESC_PAGE,
R_ARM_SBREL,
R_GOT,
+ // The expression is used for IFUNC support. Evaluates to GOT entry,
+ // containing redirection to the IPLT.
+ R_GOT_PLT,
R_GOTONLY_PC,
R_GOTONLY_PC_FROM_END,
R_GOTREL,
Added: lld/trunk/test/ELF/aarch64-gnu-ifunc2.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/aarch64-gnu-ifunc2.s?rev=347650&view=auto
==============================================================================
--- lld/trunk/test/ELF/aarch64-gnu-ifunc2.s (added)
+++ lld/trunk/test/ELF/aarch64-gnu-ifunc2.s Tue Nov 27 02:30:46 2018
@@ -0,0 +1,52 @@
+# REQUIRES: aarch64
+# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
+# RUN: ld.lld -static %t.o -o %tout
+# RUN: llvm-objdump -D %tout | FileCheck %s
+# RUN: llvm-readobj -r %tout | FileCheck %s --check-prefix=RELOC
+
+# CHECK: Disassembly of section .text:
+# CHECK-NEXT: myfunc:
+# CHECK-NEXT: 210000:
+
+# CHECK: main:
+# adrp x8, 0x230000, 0x230000 == address in .got
+# CHECK-NEXT: 210004: {{.*}} adrp x8, #131072
+# CHECK-NEXT: 210008: {{.*}} ldr x8, [x8]
+# CHECK-NEXT: 21000c: {{.*}} ret
+
+# CHECK: Disassembly of section .plt:
+# CHECK-NEXT: .plt:
+# adrp x16, 0x220000, 0x220000 == address in .got.plt
+# CHECK-NEXT: 210010: {{.*}} adrp x16, #65536
+# CHECK-NEXT: 210014: {{.*}} ldr x17, [x16]
+# CHECK-NEXT: 210018: {{.*}} add x16, x16, #0
+# CHECK-NEXT: 21001c: {{.*}} br x17
+
+# CHECK: Disassembly of section .got.plt:
+# CHECK-NEXT: .got.plt:
+# CHECK-NEXT: 220000:
+
+# CHECK: Disassembly of section .got:
+# CHECK-NEXT: .got:
+# 0x210010 == address in .plt
+# CHECK-NEXT: 230000: 10 00 21 00
+
+# RELOC: Relocations [
+# RELOC-NEXT: Section {{.*}} .rela.plt {
+# RELOC-NEXT: 0x220000 R_AARCH64_IRELATIVE - 0x210000
+# RELOC-NEXT: }
+# RELOC-NEXT: ]
+
+.text
+.globl myfunc
+.type myfunc, at gnu_indirect_function
+myfunc:
+ ret
+
+.text
+.globl main
+.type main, at function
+main:
+ adrp x8, :got:myfunc
+ ldr x8, [x8, :got_lo12:myfunc]
+ ret
More information about the llvm-commits
mailing list