[llvm] [AArch64] Make IFUNC opt-in rather than opt-out. (PR #171648)
Harald van Dijk via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 18 11:41:45 PST 2025
https://github.com/hvdijk updated https://github.com/llvm/llvm-project/pull/171648
>From 4c10c68c71c3952f955e56c8d351ddfa70d3980b Mon Sep 17 00:00:00 2001
From: Harald van Dijk <hdijk at accesssoftek.com>
Date: Thu, 18 Dec 2025 19:41:32 +0000
Subject: [PATCH] [AArch64] Make IFUNC opt-in rather than opt-out.
IFUNCs require loader support, so for arbitrary environments, the safe
assumption is to assume that they are not supported. In particular,
aarch64-linux-pauthtest may be used with musl, and was wrongly detected
as supporting IFUNCs.
With IFUNC support now being detected more reliably, this also removes
the check for PAuth support. If both are supported, either would work.
---
llvm/include/llvm/TargetParser/Triple.h | 2 +-
llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 30 ++++---------------
llvm/test/CodeGen/AArch64/ptrauth-reloc.ll | 14 ++++-----
3 files changed, 14 insertions(+), 32 deletions(-)
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index fee8f36c369f7..e8aa43a2337c7 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -770,7 +770,7 @@ class Triple {
bool isOSGlibc() const {
return (getOS() == Triple::Linux || getOS() == Triple::KFreeBSD ||
getOS() == Triple::Hurd) &&
- !isAndroid() && !isMusl();
+ !isAndroid() && !isMusl() && getEnvironment() != Triple::PAuthTest;
}
/// Tests whether the OS is AIX.
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index 87256352faccd..e11bf436b84fa 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -2419,30 +2419,14 @@ void AArch64AsmPrinter::emitAddress(MCRegister Reg, const MCExpr *Expr,
}
}
-static bool targetSupportsPAuthRelocation(const Triple &TT,
- const MCExpr *Target,
- const MCExpr *DSExpr) {
- // No released version of glibc supports PAuth relocations.
- if (TT.isOSGlibc() || TT.isMusl())
- return false;
-
- // We emit PAuth constants as IRELATIVE relocations in cases where the
- // constant cannot be represented as a PAuth relocation:
- // 1) There is a deactivation symbol.
- // 2) The signed value is not a symbol.
- return !DSExpr && !isa<MCConstantExpr>(Target);
-}
-
static bool targetSupportsIRelativeRelocation(const Triple &TT) {
// IFUNCs are ELF-only.
if (!TT.isOSBinFormatELF())
return false;
- // musl doesn't support IFUNCs.
- if (TT.isMusl())
- return false;
-
- return true;
+ // IFUNCs are supported on glibc, bionic, and some but not all of the BSDs.
+ return TT.isOSGlibc() || TT.isAndroid() || TT.isOSFreeBSD() ||
+ TT.isOSDragonFly() || TT.isOSNetBSD();
}
// Emit an ifunc resolver that returns a signed pointer to the specified target,
@@ -2501,10 +2485,8 @@ const MCExpr *AArch64AsmPrinter::emitPAuthRelocationAsIRelative(
bool HasAddressDiversity, bool IsDSOLocal, const MCExpr *DSExpr) {
const Triple &TT = TM.getTargetTriple();
- // We only emit an IRELATIVE relocation if the target supports IRELATIVE and
- // does not support the kind of PAuth relocation that we are trying to emit.
- if (targetSupportsPAuthRelocation(TT, Target, DSExpr) ||
- !targetSupportsIRelativeRelocation(TT))
+ // We only emit an IRELATIVE relocation if the target supports IRELATIVE.
+ if (!targetSupportsIRelativeRelocation(TT))
return nullptr;
// For now, only the DA key is supported.
@@ -2634,7 +2616,7 @@ AArch64AsmPrinter::lowerConstantPtrAuth(const ConstantPtrAuth &CPA) {
uint64_t Disc = CPA.getDiscriminator()->getZExtValue();
- // Check if we need to represent this with an IRELATIVE and emit it if so.
+ // Check if we can represent this with an IRELATIVE and emit it if so.
if (auto *IFuncSym = emitPAuthRelocationAsIRelative(
Sym, Disc, AArch64PACKey::ID(KeyID), CPA.hasAddressDiscriminator(),
BaseGVB && BaseGVB->isDSOLocal(), DSExpr))
diff --git a/llvm/test/CodeGen/AArch64/ptrauth-reloc.ll b/llvm/test/CodeGen/AArch64/ptrauth-reloc.ll
index f2d080644e93e..14f5571fc2deb 100644
--- a/llvm/test/CodeGen/AArch64/ptrauth-reloc.ll
+++ b/llvm/test/CodeGen/AArch64/ptrauth-reloc.ll
@@ -176,19 +176,19 @@
@g = external global i32
@g.ref.ia.65536 = constant ptr ptrauth (ptr @g, i32 0, i64 65536)
-;--- err-disc-elf.ll
+;--- err-disc-gnu.ll
-; RUN: not llc < err-disc-elf.ll -mtriple aarch64-elf -mattr=+pauth 2>&1 \
-; RUN: | FileCheck %s --check-prefix=CHECK-ERR-DISC-ELF
-; RUN: not llc < err-disc-elf.ll -mtriple aarch64-elf -mattr=+pauth \
+; RUN: not llc < err-disc-gnu.ll -mtriple aarch64-linux-gnu -mattr=+pauth 2>&1 \
+; RUN: | FileCheck %s --check-prefix=CHECK-ERR-DISC-GNU
+; RUN: not llc < err-disc-gnu.ll -mtriple aarch64-linux-gnu -mattr=+pauth \
; RUN: -global-isel -verify-machineinstrs -global-isel-abort=1 2>&1 \
-; RUN: | FileCheck %s --check-prefix=CHECK-ERR-DISC-ELF
+; RUN: | FileCheck %s --check-prefix=CHECK-ERR-DISC-GNU
@g = external global i32
@ds = external global i8
-; CHECK-ERR-DISC-ELF-NOT: error: AArch64 PAC Discriminator '65537' out of range [0, 0xFFFF]
+; CHECK-ERR-DISC-GNU-NOT: error: AArch64 PAC Discriminator '65537' out of range [0, 0xFFFF]
@g.ref.da.65537 = constant ptr ptrauth (ptr @g, i32 2, i64 65537, ptr @g.ref.da.65537, ptr @ds)
-; CHECK-ERR-DISC-ELF: error: AArch64 PAC Discriminator '65538' out of range [0, 0xFFFF]
+; CHECK-ERR-DISC-GNU: error: AArch64 PAC Discriminator '65538' out of range [0, 0xFFFF]
@g.ref.da.65538 = constant ptr ptrauth (ptr @g, i32 2, i64 65538, ptr null, ptr @ds)
More information about the llvm-commits
mailing list