[llvm] [PAC][ELF] Place AUTH constants in .data.rel.ro for position dependent code (PR #150418)
Daniil Kovalev via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 24 06:32:15 PDT 2025
https://github.com/kovdan01 created https://github.com/llvm/llvm-project/pull/150418
For AArch64 target machine, effective relocation model on Windows and Darwin is always PIC, while for ELF targets Static is used when DynamicNoPIC is requested (see `getEffectiveRelocModel` in AArch64TargetMachine.cpp).
This resulted in using .rodata section for AUTH constants, which is wrong since these are filled with AUTH dynamic relocs and require the section to be writeable during dynamic relocation resolving.
This patch adds a check ensuring if the constant itself or one of the nested constants are AUTH ones. If so, use .data.rel.ro section.
>From f6170f2a1143470459c13d9f0254322ee817d660 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Thu, 24 Jul 2025 16:21:02 +0300
Subject: [PATCH] [PAC][ELF] Place AUTH constants in .data.rel.ro for position
dependent code
For AArch64 target machine, effective relocation model on Windows and
Darwin is always PIC, while for ELF targets Static is used when DynamicNoPIC
is requested (see `getEffectiveRelocModel` in AArch64TargetMachine.cpp).
This resulted in using .rodata section for AUTH constants, which is
wrong since these are filled with AUTH dynamic relocs and require the
section to be writeable during dynamic relocation resolving.
This patch adds a check ensuring if the constant itself or one of the nested
constants are AUTH ones. If so, use .data.rel.ro section.
---
llvm/lib/Target/TargetLoweringObjectFile.cpp | 19 ++++++-
.../CodeGen/AArch64/ptrauth-global-no-pic.ll | 51 +++++++++++++++++++
2 files changed, 68 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-global-no-pic.ll
diff --git a/llvm/lib/Target/TargetLoweringObjectFile.cpp b/llvm/lib/Target/TargetLoweringObjectFile.cpp
index 9b03e85ca45bf..246509b28cd9c 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"
@@ -220,6 +221,20 @@ void TargetLoweringObjectFile::emitPseudoProbeDescMetadata(MCStreamer &Streamer,
}
}
+static bool containsConstantPtrAuth(const Constant *C) {
+ if (isa<ConstantPtrAuth>(C))
+ return true;
+
+ if (isa<BlockAddress>(C) || isa<GlobalValue>(C))
+ return false;
+
+ for (const Value *Op : C->operands())
+ if (containsConstantPtrAuth(cast<Constant>(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,9 +342,9 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalObject *GO,
// mergable section, because the linker doesn't take relocations into
// consideration when it tries to merge entries in the section.
Reloc::Model ReloModel = TM.getRelocationModel();
- if (ReloModel == Reloc::Static || ReloModel == Reloc::ROPI ||
+ if ((ReloModel == Reloc::Static || ReloModel == Reloc::ROPI ||
ReloModel == Reloc::RWPI || ReloModel == Reloc::ROPI_RWPI ||
- !C->needsDynamicRelocation())
+ !C->needsDynamicRelocation()) && !containsConstantPtrAuth(C))
return SectionKind::getReadOnly();
// Otherwise, the dynamic linker needs to fix it up, put it in the
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..651f384ef6497
--- /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 -filetype=asm -o - %s | FileCheck %s
+; RUN: llc -mtriple aarch64-elf --relocation-model=dynamic-no-pic -mattr=+pauth -filetype=asm -o - %s | FileCheck %s
+
+;; A constant value, use .rodata
+; CHECK: .section .rodata,"a", at progbits
+; CHECK: .globl Const
+; CHECK: Const:
+; CHECK: .xword 37
+
+;; An AUTH reloc is needed, use .data.rel.ro
+; CHECK: .section .data.rel.ro,"aw", at progbits
+; CHECK: .globl PtrAuthExtern
+; CHECK: PtrAuthExtern:
+; CHECK: .xword ConstExtern at AUTH(da,0)
+
+; CHECK: .globl PtrAuth
+; CHECK: PtrAuth:
+; CHECK: .xword Const at AUTH(da,0)
+
+; CHECK: .globl PtrAuthExternNested1
+; CHECK: PtrAuthExternNested1:
+; CHECK: .xword ConstExtern at AUTH(da,0)
+
+;; The address could be filled statically, use .rodata
+; CHECK: .section .rodata,"a", at progbits
+; CHECK: .globl PtrAuthExternNested2
+; CHECK: PtrAuthExternNested2:
+; CHECK: .xword PtrAuthExtern
+
+;; An AUTH reloc is needed, use .data.rel.ro
+; CHECK: .section .data.rel.ro,"aw", at progbits
+; CHECK: .globl PtrAuthNested1
+; CHECK: PtrAuthNested1:
+; CHECK: .xword Const at AUTH(da,0)
+
+;; The address could be filled statically, use .rodata
+; CHECK: .section .rodata,"a", at progbits
+; CHECK: .globl PtrAuthNested2
+; CHECK: PtrAuthNested2:
+; CHECK: .xword PtrAuth
+
+ at ConstExtern = external global i64
+ at Const = constant i64 37
+
+ at PtrAuthExtern = constant ptr ptrauth (ptr @ConstExtern, i32 2)
+ at PtrAuth = constant ptr ptrauth (ptr @Const, i32 2)
+
+ at PtrAuthExternNested1 = constant { ptr } { ptr ptrauth (ptr @ConstExtern, i32 2) }
+ at PtrAuthExternNested2 = constant { ptr } { ptr @PtrAuthExtern }
+ at PtrAuthNested1 = constant { ptr } { ptr ptrauth (ptr @Const, i32 2) }
+ at PtrAuthNested2 = constant { ptr } { ptr @PtrAuth }
More information about the llvm-commits
mailing list