diff --git a/llvm/lib/Target/TargetLoweringObjectFile.cpp b/llvm/lib/Target/TargetLoweringObjectFile.cpp index 343bcce80e3a1..ae31cd90b37ab 100644 --- a/llvm/lib/Target/TargetLoweringObjectFile.cpp +++ b/llvm/lib/Target/TargetLoweringObjectFile.cpp @@ -17,6 +17,7 @@ #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" +#include "llvm/IR/GlobalValue.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Mangler.h" #include "llvm/IR/Module.h" @@ -226,6 +227,20 @@ void TargetLoweringObjectFile::emitPseudoProbeDescMetadata( } } +static bool containsConstantPtrAuth(const Constant *C) { + if (isa(C)) + return true; + + if (isa(C) || isa(C)) + return false; + + for (const Value *Op : C->operands()) + if (containsConstantPtrAuth(cast(Op))) + return true; + + return false; +} + /// getKindForGlobal - This is a top-level target-independent classifier for /// a global object. Given a global variable and information from the TM, this /// function classifies the global in a target independent manner. This function @@ -327,6 +342,10 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalObject *GO, } } else { + // The dynamic linker always needs to fix PtrAuth relocations up. + if (containsConstantPtrAuth(C)) + return SectionKind::getReadOnlyWithRel(); + // In static, ROPI and RWPI relocation models, the linker will resolve // all addresses, so the relocation entries will actually be constants by // the time the app starts up. However, we can't put this into a diff --git a/llvm/test/CodeGen/AArch64/ptrauth-global-no-pic.ll b/llvm/test/CodeGen/AArch64/ptrauth-global-no-pic.ll new file mode 100644 index 0000000000000..fbcbcb2a84b54 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/ptrauth-global-no-pic.ll @@ -0,0 +1,51 @@ +; RUN: llc -mtriple aarch64-elf --relocation-model=static -mattr=+pauth < %s | FileCheck %s +; RUN: llc -mtriple aarch64-elf --relocation-model=dynamic-no-pic -mattr=+pauth < %s | FileCheck %s + +;; A constant value, use .rodata +; CHECK: .section .rodata,"a",@progbits +; CHECK: .globl Const +; CHECK: Const: +; CHECK: .xword 37 + +;; An AUTH reloc is needed, use .data.rel.ro +; CHECK: .section .data.rel.ro,"aw",@progbits +; CHECK: .globl PtrAuthExtern +; CHECK: PtrAuthExtern: +; CHECK: .xword ConstExtern@AUTH(da,0) + +; CHECK: .globl PtrAuth +; CHECK: PtrAuth: +; CHECK: .xword Const@AUTH(da,0) + +; CHECK: .globl PtrAuthExternNested1 +; CHECK: PtrAuthExternNested1: +; CHECK: .xword ConstExtern@AUTH(da,0) + +;; The address could be filled statically, use .rodata +; CHECK: .section .rodata,"a",@progbits +; CHECK: .globl PtrAuthExternNested2 +; CHECK: PtrAuthExternNested2: +; CHECK: .xword PtrAuthExtern + +;; An AUTH reloc is needed, use .data.rel.ro +; CHECK: .section .data.rel.ro,"aw",@progbits +; CHECK: .globl PtrAuthNested1 +; CHECK: PtrAuthNested1: +; CHECK: .xword Const@AUTH(da,0) + +;; The address could be filled statically, use .rodata +; CHECK: .section .rodata,"a",@progbits +; CHECK: .globl PtrAuthNested2 +; CHECK: PtrAuthNested2: +; CHECK: .xword PtrAuth + +@ConstExtern = external global i64 +@Const = constant i64 37 + +@PtrAuthExtern = constant ptr ptrauth (ptr @ConstExtern, i32 2) +@PtrAuth = constant ptr ptrauth (ptr @Const, i32 2) + +@PtrAuthExternNested1 = constant { ptr } { ptr ptrauth (ptr @ConstExtern, i32 2) } +@PtrAuthExternNested2 = constant { ptr } { ptr @PtrAuthExtern } +@PtrAuthNested1 = constant { ptr } { ptr ptrauth (ptr @Const, i32 2) } +@PtrAuthNested2 = constant { ptr } { ptr @PtrAuth }