From b20f993df887ee5f478a4eedd349e41f0a305d1a Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Tue, 15 Jan 2019 11:17:03 +0000 Subject: [PATCH] [ELF][AArch64] Add missing PLT relocations to isStaticLinkTimeConstant r347650 fixed pr38074 for AArch64 for static linking. It added two new RelExpr instances R_AARCH64_GOT_PAGE_PC_PLT and R_GOT_PLT. These need to be added to isStaticLinkTimeConstant so that the address of an ifunc can be taken when building a shared library. fixes pr40250 Differential Revision: https://reviews.llvm.org/D56666 llvm-svn: 351186 --- lld/ELF/Relocations.cpp | 6 ++--- lld/test/ELF/aarch64-gnu-ifunc-address.s | 40 ++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 lld/test/ELF/aarch64-gnu-ifunc-address.s diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index c10e561..8124688 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -374,8 +374,8 @@ static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym, if (isRelExprOneOf(E)) @@ -383,7 +383,7 @@ static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym, // These never do, except if the entire file is position dependent or if // only the low bits are used. - if (E == R_GOT || E == R_PLT || E == R_TLSDESC) + if (E == R_GOT || E == R_GOT_PLT || E == R_PLT || E == R_TLSDESC) return Target->usesOnlyLowPageBits(Type) || !Config->Pic; if (Sym.IsPreemptible) diff --git a/lld/test/ELF/aarch64-gnu-ifunc-address.s b/lld/test/ELF/aarch64-gnu-ifunc-address.s new file mode 100644 index 0000000..9321fe3 --- /dev/null +++ b/lld/test/ELF/aarch64-gnu-ifunc-address.s @@ -0,0 +1,40 @@ +# REQUIRES: aarch64 +# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o +# RUN: ld.lld -shared %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 in a shared object +# we get R_AARCH64_GLOB_DAT to the symbol as it could be defined in another +# link unit and preempt our definition. +.text +.globl myfunc +.type myfunc,@gnu_indirect_function +myfunc: + ret + +.text +.globl main +.type main,@function +main: + adrp x8, :got:myfunc + ldr x8, [x8, :got_lo12:myfunc] + ret +# CHECK: 0000000000010004 main: +# x8 = 0x30000 +# CHECK-NEXT: 10004: 08 01 00 90 adrp x8, #131072 +# x8 = 0x300e0 = .got entry for myfunc with R_AARCH64_GLOB_DAT +# CHECK-NEXT: 10008: 08 71 40 f9 ldr x8, [x8, #224] +# CHECK-NEXT: 1000c: c0 03 5f d6 ret + +# CHECK: Disassembly of section .got: +# CHECK-NEXT: 00000000000300e0 .got: + +# CHECK-RELOCS: Relocations [ +# CHECK-RELOCS-NEXT: Section {{.*}} .rela.dyn { +# CHECK-RELOCS-NEXT: 0x300E0 R_AARCH64_GLOB_DAT myfunc 0x0 +# CHECK-RELOCS-NEXT: } +# CHECK-RELOCS-NEXT: Section {{.*}} .rela.plt { +# CHECK-RELOCS-NEXT: 0x20018 R_AARCH64_JUMP_SLOT myfunc 0x0 +# CHECK-RELOCS-NEXT: } +# CHECK-RELOCS-NEXT: ] -- 2.7.4