[clang] 6738cfe - Mark CXX module initializer with PACBTI attributes (#133716)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 25 03:04:37 PDT 2025
Author: Victor Campos
Date: 2025-04-25T11:04:34+01:00
New Revision: 6738cfe0a40af2754000346ff090ebb2115ce15f
URL: https://github.com/llvm/llvm-project/commit/6738cfe0a40af2754000346ff090ebb2115ce15f
DIFF: https://github.com/llvm/llvm-project/commit/6738cfe0a40af2754000346ff090ebb2115ce15f.diff
LOG: Mark CXX module initializer with PACBTI attributes (#133716)
The CXX module initializer function, which is called at program startup,
needs to be tagged with Pointer Authentication and Branch Target
Identification marks whenever relevant.
Before this patch, in CPUs set up for PACBTI execution, the function
wasn't protected with return address signing and no BTI instruction was
inserted at the start of it, thus leading to an execution fault.
This patch fixes the issue by marking the function with the function
attributes related to PAC and BTI if relevant.
Added:
clang/test/CodeGenCXX/cxx20-module-initializer-pacbti.cpp
Modified:
clang/lib/CodeGen/CGDeclCXX.cpp
clang/lib/CodeGen/Targets/AArch64.cpp
clang/lib/CodeGen/Targets/ARM.cpp
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp
index 303d21e6152fe..8a214da6bf628 100644
--- a/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/clang/lib/CodeGen/CGDeclCXX.cpp
@@ -448,6 +448,11 @@ llvm::Function *CodeGenModule::CreateGlobalInitOrCleanUpFunction(
if (Linkage == llvm::GlobalVariable::InternalLinkage)
SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);
+ else {
+ SetLLVMFunctionAttributes(GlobalDecl(), FI, Fn, false);
+ SetLLVMFunctionAttributesForDefinition(nullptr, Fn);
+ getTargetCodeGenInfo().setTargetAttributes(nullptr, Fn, *this);
+ }
Fn->setCallingConv(getRuntimeCC());
diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp
index 77e225d197343..f098f09ebf581 100644
--- a/clang/lib/CodeGen/Targets/AArch64.cpp
+++ b/clang/lib/CodeGen/Targets/AArch64.cpp
@@ -136,13 +136,15 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo {
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
CodeGen::CodeGenModule &CGM) const override {
- const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
- if (!FD)
+ auto *Fn = dyn_cast<llvm::Function>(GV);
+ if (!Fn)
return;
+ const auto *FD = dyn_cast_or_null<FunctionDecl>(D);
TargetInfo::BranchProtectionInfo BPI(CGM.getLangOpts());
- if (const auto *TA = FD->getAttr<TargetAttr>()) {
+ if (FD && FD->hasAttr<TargetAttr>()) {
+ const auto *TA = FD->getAttr<TargetAttr>();
ParsedTargetAttr Attr =
CGM.getTarget().parseTargetAttr(TA->getFeaturesStr());
if (!Attr.BranchProtection.empty()) {
@@ -152,7 +154,6 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo {
assert(Error.empty());
}
}
- auto *Fn = cast<llvm::Function>(GV);
setBranchProtectionFnAttributes(BPI, *Fn);
}
diff --git a/clang/lib/CodeGen/Targets/ARM.cpp b/clang/lib/CodeGen/Targets/ARM.cpp
index dddf51a827159..68f9e01856486 100644
--- a/clang/lib/CodeGen/Targets/ARM.cpp
+++ b/clang/lib/CodeGen/Targets/ARM.cpp
@@ -134,14 +134,13 @@ class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
CodeGen::CodeGenModule &CGM) const override {
- if (GV->isDeclaration())
+ auto *Fn = dyn_cast<llvm::Function>(GV);
+ if (!Fn)
return;
- const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
- if (!FD)
- return;
- auto *Fn = cast<llvm::Function>(GV);
+ const auto *FD = dyn_cast_or_null<FunctionDecl>(D);
- if (const auto *TA = FD->getAttr<TargetAttr>()) {
+ if (FD && FD->hasAttr<TargetAttr>()) {
+ const auto *TA = FD->getAttr<TargetAttr>();
ParsedTargetAttr Attr =
CGM.getTarget().parseTargetAttr(TA->getFeaturesStr());
if (!Attr.BranchProtection.empty()) {
@@ -174,10 +173,10 @@ class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
setBranchProtectionFnAttributes(BPI, (*Fn));
}
- const ARMInterruptAttr *Attr = FD->getAttr<ARMInterruptAttr>();
- if (!Attr)
+ if (!FD || !FD->hasAttr<ARMInterruptAttr>())
return;
+ const ARMInterruptAttr *Attr = FD->getAttr<ARMInterruptAttr>();
const char *Kind;
switch (Attr->getInterrupt()) {
case ARMInterruptAttr::Generic: Kind = ""; break;
diff --git a/clang/test/CodeGenCXX/cxx20-module-initializer-pacbti.cpp b/clang/test/CodeGenCXX/cxx20-module-initializer-pacbti.cpp
new file mode 100644
index 0000000000000..dc66b0090e568
--- /dev/null
+++ b/clang/test/CodeGenCXX/cxx20-module-initializer-pacbti.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple thumbv8.1m.main-unknown-none-eabi -emit-module-interface -target-feature +pacbti -msign-return-address=all -mbranch-target-enforce -std=c++20 %s -o %t.pcm
+// RUN: %clang_cc1 -triple thumbv8.1m.main-unknown-none-eabi -std=c++20 %t.pcm -emit-llvm -o - | \
+// RUN: FileCheck --check-prefixes=CHECK,CHECK-PAC-ARM %s
+
+// RUN: %clang_cc1 -triple aarch64-unknown-none-elf -emit-module-interface -target-feature +pacbti -msign-return-address=all -msign-return-address-key=b_key -mbranch-target-enforce -std=c++20 %s -o %t.pcm
+// RUN: %clang_cc1 -triple aarch64-unknown-none-elf -std=c++20 %t.pcm -emit-llvm -o - | \
+// RUN: FileCheck --check-prefixes=CHECK,CHECK-PAC-AARCH64 %s
+
+// CHECK: define void @_ZGIW3foo() #0
+// CHECK-PAC-ARM: attributes #0 = { noinline nounwind "branch-target-enforcement" "no-trapping-math"="true" "sign-return-address"="all" "sign-return-address-key"="a_key" "stack-protector-buffer-size"="8" "target-features"="+armv8.1-m.main,+pacbti,+thumb-mode" }
+// CHECK-PAC-AARCH64: attributes #0 = { noinline nounwind "branch-target-enforcement" "no-trapping-math"="true" "sign-return-address"="all" "sign-return-address-key"="b_key" "stack-protector-buffer-size"="8" "target-features"="+pacbti" }
+
+module;
+
+export module foo;
+
+export void func();
More information about the cfe-commits
mailing list