aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2019-01-17 13:47:57 +0000
committerHans Wennborg <hans@hanshq.net>2019-01-17 13:47:57 +0000
commit2a67ca16156ee1eb5019ef65e34d0177318b4ba2 (patch)
tree9d5c3a65dca394f5d1b89e744ac7737f2a43f6c3
parentba56cf7a8e8c89a06fc154398cfb8fc1376af232 (diff)
Merging r351335:
------------------------------------------------------------------------ r351335 | psmith | 2019-01-16 14:24:02 +0100 (Wed, 16 Jan 2019) | 17 lines [ELF][AArch64] Add R_AARCH64_PLT_PAGE_PC to isRelExpr As a follow on to D56666 (r351186) there is a case when taking the address of an ifunc when linking -pie that can generate a spurious can't create dynamic relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol in readonly segment. Specifically the case is where the ifunc is in the same translation unit as the address taker, so given -fpie the compiler knows the ifunc is defined in the executable so it can use a non-got-generating relocation. The error message is due to R_AARCH64_PLT_PAGE_PC not being added to isRelExpr, its non PLT equivalent R_AARCH64_PAGE_PC is already in isRelExpr. Differential Revision: https://reviews.llvm.org/D56724 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/lld/branches/release_80@351446 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--ELF/Relocations.cpp2
-rw-r--r--test/ELF/aarch64-gnu-ifunc-address-pie.s44
2 files changed, 45 insertions, 1 deletions
diff --git a/ELF/Relocations.cpp b/ELF/Relocations.cpp
index 812468896..9ffe8a9cc 100644
--- a/ELF/Relocations.cpp
+++ b/ELF/Relocations.cpp
@@ -356,7 +356,7 @@ static bool needsGot(RelExpr Expr) {
static bool isRelExpr(RelExpr Expr) {
return isRelExprOneOf<R_PC, R_GOTREL, R_GOTREL_FROM_END, R_MIPS_GOTREL,
R_PPC_CALL, R_PPC_CALL_PLT, R_AARCH64_PAGE_PC,
- R_RELAX_GOT_PC>(Expr);
+ R_AARCH64_PLT_PAGE_PC, R_RELAX_GOT_PC>(Expr);
}
// Returns true if a given relocation can be computed at link-time.
diff --git a/test/ELF/aarch64-gnu-ifunc-address-pie.s b/test/ELF/aarch64-gnu-ifunc-address-pie.s
new file mode 100644
index 000000000..3db9070db
--- /dev/null
+++ b/test/ELF/aarch64-gnu-ifunc-address-pie.s
@@ -0,0 +1,44 @@
+# REQUIRES: aarch64
+# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
+# RUN: ld.lld -pie %t.o -o %tout
+# RUN: llvm-objdump -D %tout | FileCheck %s
+# RUN: llvm-readobj -r %tout | FileCheck %s -check-prefix=CHECK-RELOCS
+
+# Test that when we take the address of a preemptible ifunc using -fpie, we can
+# handle the case when the ifunc is in the same translation unit as the address
+# taker. In this case the compiler knows that ifunc is not defined in a shared
+# library so it can use a non got generating relative reference.
+.text
+.globl myfunc
+.type myfunc,@gnu_indirect_function
+myfunc:
+ ret
+
+.text
+.globl main
+.type main,@function
+main:
+ adrp x8, myfunc
+ add x8, x8, :lo12: myfunc
+ ret
+
+# CHECK: 0000000000010000 myfunc:
+# CHECK-NEXT: 10000: c0 03 5f d6 ret
+# CHECK: 0000000000010004 main:
+# CHECK-NEXT: 10004: 08 00 00 90 adrp x8, #0
+# x8 = 0x10000
+# CHECK-NEXT: 10008: 08 41 00 91 add x8, x8, #16
+# x8 = 0x10010 = .plt for myfunc
+# CHECK-NEXT: 1000c: c0 03 5f d6 ret
+# CHECK-NEXT: Disassembly of section .plt:
+# CHECK-NEXT: 0000000000010010 .plt:
+# CHECK-NEXT: 10010: 90 00 00 90 adrp x16, #65536
+# CHECK-NEXT: 10014: 11 02 40 f9 ldr x17, [x16]
+# CHECK-NEXT: 10018: 10 02 00 91 add x16, x16, #0
+# CHECK-NEXT: 1001c: 20 02 1f d6 br x17
+
+# CHECK-RELOCS: Relocations [
+# CHECK-RELOCS-NEXT: Section {{.*}} .rela.plt {
+# CHECK-RELOCS-NEXT: 0x20000 R_AARCH64_IRELATIVE - 0x10000
+# CHECK-RELOCS-NEXT: }
+# CHECK-RELOCS-NEXT: ]