[clang] [AArch64][FMV] Enable PAuth and BTI hardening of resolver functions (PR #141573)
Anatoly Trosinenko via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 14 11:44:52 PDT 2025
https://github.com/atrosinenko updated https://github.com/llvm/llvm-project/pull/141573
>From 3e625155a44a88ec8f276f8c25379bec1a153e38 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko <atrosinenko at accesssoftek.com>
Date: Mon, 26 May 2025 22:28:55 +0300
Subject: [PATCH 1/4] [AArch64][FMV] Enable PAuth and BTI hardening of resolver
functions
---
clang/lib/CodeGen/CodeGenModule.cpp | 9 +++++++
.../CodeGen/ptrauth-resolver-attributes.c | 25 +++++++++++++++++++
2 files changed, 34 insertions(+)
create mode 100644 clang/test/CodeGen/ptrauth-resolver-attributes.c
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index c8866f15745c2..e3ca1761cf85a 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -4757,6 +4757,13 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) {
if (FD->isTargetMultiVersion() || FD->isTargetClonesMultiVersion())
AddDeferredMultiVersionResolverToEmit(GD);
+ auto SetResolverAttrs = [&](llvm::Function &Resolver) {
+ TargetInfo::BranchProtectionInfo BPI(getLangOpts());
+ TargetCodeGenInfo::setBranchProtectionFnAttributes(BPI, Resolver);
+ TargetCodeGenInfo::setPointerAuthFnAttributes(CodeGenOpts.PointerAuth,
+ Resolver);
+ };
+
// For cpu_specific, don't create an ifunc yet because we don't know if the
// cpu_dispatch will be emitted in this translation unit.
if (ShouldReturnIFunc) {
@@ -4771,6 +4778,7 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) {
"", Resolver, &getModule());
GIF->setName(ResolverName);
SetCommonAttributes(FD, GIF);
+ SetResolverAttrs(cast<llvm::Function>(*Resolver));
if (ResolverGV)
replaceDeclarationWith(ResolverGV, GIF);
return GIF;
@@ -4781,6 +4789,7 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) {
assert(isa<llvm::GlobalValue>(Resolver) && !ResolverGV &&
"Resolver should be created for the first time");
SetCommonAttributes(FD, cast<llvm::GlobalValue>(Resolver));
+ SetResolverAttrs(cast<llvm::Function>(*Resolver));
return Resolver;
}
diff --git a/clang/test/CodeGen/ptrauth-resolver-attributes.c b/clang/test/CodeGen/ptrauth-resolver-attributes.c
new file mode 100644
index 0000000000000..8bdedd2c549be
--- /dev/null
+++ b/clang/test/CodeGen/ptrauth-resolver-attributes.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -mbranch-target-enforce -msign-return-address=all -emit-llvm %s -o - | FileCheck --check-prefixes=CHECK,BTI-SIGNRA %s
+// RUN: %clang_cc1 -triple arm64-apple-ios -mbranch-target-enforce -msign-return-address=all -emit-llvm %s -o - | FileCheck --check-prefixes=CHECK,BTI-SIGNRA %s
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-returns -fptrauth-auth-traps -emit-llvm %s -o - | FileCheck --check-prefixes=CHECK,PAUTHTEST %s
+// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-returns -fptrauth-auth-traps -emit-llvm %s -o - | FileCheck --check-prefixes=CHECK,PAUTHTEST %s
+
+// Check that resolver functions generated by clang have the correct attributes.
+
+int __attribute__((target_clones("crc", "default"))) ftc(void) { return 0; }
+
+int __attribute__((target_version("crc"))) fmv(void) { return 0; }
+int __attribute__((target_version("default"))) fmv(void) { return 0; }
+
+// CHECK: define{{.*}} i32 @ftc._Mcrc() #0
+// CHECK: define{{.*}} ptr @ftc.resolver() #1
+// CHECK: define{{.*}} i32 @fmv._Mcrc() #0
+// CHECK: define{{.*}} i32 @fmv.default() #2
+// CHECK: define{{.*}} i32 @ftc.default() #2
+// CHECK: define{{.*}} ptr @fmv.resolver() #1
+
+// BTI-SIGNRA: attributes #0 = { {{.*}}"branch-target-enforcement" {{.*}}"sign-return-address"="all" "sign-return-address-key"="a_key"{{.*}} }
+// BTI-SIGNRA: attributes #1 = { {{.*}}"branch-target-enforcement" {{.*}}"sign-return-address"="all" "sign-return-address-key"="a_key"{{.*}} }
+// BTI-SIGNRA: attributes #2 = { {{.*}}"branch-target-enforcement" {{.*}}"sign-return-address"="all" "sign-return-address-key"="a_key"{{.*}} }
+// PAUTHTEST: attributes #0 = { {{.*}}"ptrauth-auth-traps" "ptrauth-calls" "ptrauth-returns"{{.*}} }
+// PAUTHTEST: attributes #1 = { {{.*}}"ptrauth-auth-traps" "ptrauth-calls" "ptrauth-returns"{{.*}} }
+// PAUTHTEST: attributes #2 = { {{.*}}"ptrauth-auth-traps" "ptrauth-calls" "ptrauth-returns"{{.*}} }
>From 6d63e7e1a9b5399d4c6478acc3cad03b0e0ff583 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko <atrosinenko at accesssoftek.com>
Date: Wed, 4 Jun 2025 16:34:47 +0300
Subject: [PATCH 2/4] Use setTargetAttributes function
---
clang/lib/CodeGen/CodeGenModule.cpp | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index e3ca1761cf85a..51f9f85c7f561 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -4757,11 +4757,11 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) {
if (FD->isTargetMultiVersion() || FD->isTargetClonesMultiVersion())
AddDeferredMultiVersionResolverToEmit(GD);
- auto SetResolverAttrs = [&](llvm::Function &Resolver) {
- TargetInfo::BranchProtectionInfo BPI(getLangOpts());
- TargetCodeGenInfo::setBranchProtectionFnAttributes(BPI, Resolver);
- TargetCodeGenInfo::setPointerAuthFnAttributes(CodeGenOpts.PointerAuth,
- Resolver);
+ auto SetResolverAttrs = [&](llvm::Function *Resolver) {
+ // Set the default target-specific attributes, such as PAC and BTI ones on
+ // AArch64. Not passing Decl to prevent setting unrelated attributes,
+ // as Resolver can be shared by multiple declarations.
+ getTargetCodeGenInfo().setTargetAttributes(/*D=*/nullptr, Resolver, *this);
};
// For cpu_specific, don't create an ifunc yet because we don't know if the
@@ -4778,7 +4778,7 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) {
"", Resolver, &getModule());
GIF->setName(ResolverName);
SetCommonAttributes(FD, GIF);
- SetResolverAttrs(cast<llvm::Function>(*Resolver));
+ SetResolverAttrs(cast<llvm::Function>(Resolver));
if (ResolverGV)
replaceDeclarationWith(ResolverGV, GIF);
return GIF;
@@ -4789,7 +4789,7 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) {
assert(isa<llvm::GlobalValue>(Resolver) && !ResolverGV &&
"Resolver should be created for the first time");
SetCommonAttributes(FD, cast<llvm::GlobalValue>(Resolver));
- SetResolverAttrs(cast<llvm::Function>(*Resolver));
+ SetResolverAttrs(cast<llvm::Function>(Resolver));
return Resolver;
}
>From 2d74565fa5b0313a603447823d851b13ef324f6c Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko <atrosinenko at accesssoftek.com>
Date: Wed, 4 Jun 2025 17:36:20 +0300
Subject: [PATCH 3/4] test: accept functions and attribute groups in any order
---
.../CodeGen/ptrauth-resolver-attributes.c | 24 +++++++++----------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/clang/test/CodeGen/ptrauth-resolver-attributes.c b/clang/test/CodeGen/ptrauth-resolver-attributes.c
index 8bdedd2c549be..a1239604226a0 100644
--- a/clang/test/CodeGen/ptrauth-resolver-attributes.c
+++ b/clang/test/CodeGen/ptrauth-resolver-attributes.c
@@ -10,16 +10,16 @@ int __attribute__((target_clones("crc", "default"))) ftc(void) { return 0; }
int __attribute__((target_version("crc"))) fmv(void) { return 0; }
int __attribute__((target_version("default"))) fmv(void) { return 0; }
-// CHECK: define{{.*}} i32 @ftc._Mcrc() #0
-// CHECK: define{{.*}} ptr @ftc.resolver() #1
-// CHECK: define{{.*}} i32 @fmv._Mcrc() #0
-// CHECK: define{{.*}} i32 @fmv.default() #2
-// CHECK: define{{.*}} i32 @ftc.default() #2
-// CHECK: define{{.*}} ptr @fmv.resolver() #1
+// CHECK-DAG: define{{.*}} i32 @ftc._Mcrc() #[[ATTR_CRC:[0-9]+]]
+// CHECK-DAG: define{{.*}} i32 @ftc.default() #[[ATTR_DEFAULT:[0-9]+]]
+// CHECK-DAG: define{{.*}} ptr @ftc.resolver() #[[ATTR_RESOLVER:[0-9]+]]
+// CHECK-DAG: define{{.*}} i32 @fmv._Mcrc() #[[ATTR_CRC]]
+// CHECK-DAG: define{{.*}} i32 @fmv.default() #[[ATTR_DEFAULT]]
+// CHECK-DAG: define{{.*}} ptr @fmv.resolver() #[[ATTR_RESOLVER]]
-// BTI-SIGNRA: attributes #0 = { {{.*}}"branch-target-enforcement" {{.*}}"sign-return-address"="all" "sign-return-address-key"="a_key"{{.*}} }
-// BTI-SIGNRA: attributes #1 = { {{.*}}"branch-target-enforcement" {{.*}}"sign-return-address"="all" "sign-return-address-key"="a_key"{{.*}} }
-// BTI-SIGNRA: attributes #2 = { {{.*}}"branch-target-enforcement" {{.*}}"sign-return-address"="all" "sign-return-address-key"="a_key"{{.*}} }
-// PAUTHTEST: attributes #0 = { {{.*}}"ptrauth-auth-traps" "ptrauth-calls" "ptrauth-returns"{{.*}} }
-// PAUTHTEST: attributes #1 = { {{.*}}"ptrauth-auth-traps" "ptrauth-calls" "ptrauth-returns"{{.*}} }
-// PAUTHTEST: attributes #2 = { {{.*}}"ptrauth-auth-traps" "ptrauth-calls" "ptrauth-returns"{{.*}} }
+// BTI-SIGNRA-DAG: attributes #[[ATTR_CRC]] = { {{.*}}"branch-target-enforcement" {{.*}}"sign-return-address"="all" "sign-return-address-key"="a_key"{{.*}} }
+// BTI-SIGNRA-DAG: attributes #[[ATTR_RESOLVER]] = { {{.*}}"branch-target-enforcement" {{.*}}"sign-return-address"="all" "sign-return-address-key"="a_key"{{.*}} }
+// BTI-SIGNRA-DAG: attributes #[[ATTR_DEFAULT]] = { {{.*}}"branch-target-enforcement" {{.*}}"sign-return-address"="all" "sign-return-address-key"="a_key"{{.*}} }
+// PAUTHTEST-DAG: attributes #[[ATTR_CRC]] = { {{.*}}"ptrauth-auth-traps" "ptrauth-calls" "ptrauth-returns"{{.*}} }
+// PAUTHTEST-DAG: attributes #[[ATTR_RESOLVER]] = { {{.*}}"ptrauth-auth-traps" "ptrauth-calls" "ptrauth-returns"{{.*}} }
+// PAUTHTEST-DAG: attributes #[[ATTR_DEFAULT]] = { {{.*}}"ptrauth-auth-traps" "ptrauth-calls" "ptrauth-returns"{{.*}} }
>From 23a5407776bb7aa27b4fd07f5221c265fb080b1e Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko <atrosinenko at accesssoftek.com>
Date: Mon, 14 Jul 2025 21:33:40 +0300
Subject: [PATCH 4/4] Move new test file to AArch64/ subdirectory
---
clang/test/CodeGen/{ => AArch64}/ptrauth-resolver-attributes.c | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename clang/test/CodeGen/{ => AArch64}/ptrauth-resolver-attributes.c (100%)
diff --git a/clang/test/CodeGen/ptrauth-resolver-attributes.c b/clang/test/CodeGen/AArch64/ptrauth-resolver-attributes.c
similarity index 100%
rename from clang/test/CodeGen/ptrauth-resolver-attributes.c
rename to clang/test/CodeGen/AArch64/ptrauth-resolver-attributes.c
More information about the cfe-commits
mailing list