https://github.com/atrosinenko updated https://github.com/llvm/llvm-project/pull/141573
>From c5a7fea9925c9d4aebf948c9e3d7f0af47893fb7 Mon Sep 17 00:00:00 2001 From: Anatoly Trosinenko <atrosine...@accesssoftek.com> Date: Mon, 26 May 2025 22:28:55 +0300 Subject: [PATCH 1/3] [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 16e010adbeb5f..af8d4cc60de57 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -4638,6 +4638,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) { @@ -4652,6 +4659,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; @@ -4662,6 +4670,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 54976a03e10c3f2a58d89aec16923919cc40b5ec Mon Sep 17 00:00:00 2001 From: Anatoly Trosinenko <atrosine...@accesssoftek.com> Date: Wed, 4 Jun 2025 16:34:47 +0300 Subject: [PATCH 2/3] 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 af8d4cc60de57..c30bf42cb569d 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -4638,11 +4638,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 @@ -4659,7 +4659,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; @@ -4670,7 +4670,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 ec1fe0c2bfc6ef0c90c219374d2caf43b396ec9a Mon Sep 17 00:00:00 2001 From: Anatoly Trosinenko <atrosine...@accesssoftek.com> Date: Wed, 4 Jun 2025 17:36:20 +0300 Subject: [PATCH 3/3] 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"{{.*}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits