https://github.com/vhscampos created 
https://github.com/llvm/llvm-project/pull/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.

>From bb649666995a2642c5eea944e55c0a38503ed7bf Mon Sep 17 00:00:00 2001
From: Victor Campos <victor.cam...@arm.com>
Date: Fri, 28 Mar 2025 15:55:07 +0000
Subject: [PATCH] Mark CXX module initializer with PACBTI attributes

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.
---
 clang/lib/CodeGen/CGDeclCXX.cpp               |  6 ++++
 .../cxx20-module-initializer-pacbti.cpp       | 32 +++++++++++++++++++
 2 files changed, 38 insertions(+)
 create mode 100644 clang/test/CodeGenCXX/cxx20-module-initializer-pacbti.cpp

diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp
index a01fa157c2b26..0366e3977b812 100644
--- a/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/clang/lib/CodeGen/CGDeclCXX.cpp
@@ -818,6 +818,12 @@ void CodeGenModule::EmitCXXModuleInitFunc(Module *Primary) 
{
     Fn->addFnAttr("device-init");
   }
 
+  if (getTarget().isBranchProtectionSupportedArch(
+          getTarget().getTargetOpts().CPU)) {
+    TargetInfo::BranchProtectionInfo BPI(getLangOpts());
+    getTargetCodeGenInfo().setBranchProtectionFnAttributes(BPI, (*Fn));
+  }
+
   // We are done with the inits.
   AllImports.clear();
   PrioritizedCXXGlobalInits.clear();
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..7ebaa5e8f349e
--- /dev/null
+++ b/clang/test/CodeGenCXX/cxx20-module-initializer-pacbti.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple thumbv8.1m.main-unknown-none-eabi 
-emit-module-interface -target-feature +pacbti -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-BTI %s
+
+// RUN: %clang_cc1 -triple thumbv8.1m.main-unknown-none-eabi 
-emit-module-interface -target-feature +pacbti -msign-return-address=non-leaf 
-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 %s
+
+// RUN: %clang_cc1 -triple thumbv8.1m.main-unknown-none-eabi 
-emit-module-interface -target-feature +pacbti -msign-return-address=all 
-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-ALL %s
+
+// RUN: %clang_cc1 -triple thumbv8.1m.main-unknown-none-eabi 
-emit-module-interface -target-feature +pacbti -msign-return-address=non-leaf 
-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-BTI %s
+
+// 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-BTI-ALL %s
+
+// CHECK: define void @_ZGIW3foo() #0
+// CHECK-BTI: attributes #0 = { nounwind "branch-target-enforcement" }
+// CHECK-PAC: attributes #0 = { nounwind "sign-return-address"="non-leaf" 
"sign-return-address-key"="a_key" }
+// CHECK-PAC-ALL: attributes #0 = { nounwind "sign-return-address"="all" 
"sign-return-address-key"="a_key" }
+// CHECK-PAC-BTI: attributes #0 = { nounwind "branch-target-enforcement" 
"sign-return-address"="non-leaf" "sign-return-address-key"="a_key" }
+// CHECK-PAC-BTI-ALL: attributes #0 = { nounwind "branch-target-enforcement" 
"sign-return-address"="all" "sign-return-address-key"="a_key" }
+
+module;
+
+export module foo;
+
+export void func();

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to