diff options
author | Hans Wennborg <hans@hanshq.net> | 2019-01-17 13:47:57 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2019-01-17 13:47:57 +0000 |
commit | 2a67ca16156ee1eb5019ef65e34d0177318b4ba2 (patch) | |
tree | 9d5c3a65dca394f5d1b89e744ac7737f2a43f6c3 | |
parent | ba56cf7a8e8c89a06fc154398cfb8fc1376af232 (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.cpp | 2 | ||||
-rw-r--r-- | test/ELF/aarch64-gnu-ifunc-address-pie.s | 44 |
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: ] |