https://github.com/vhscampos updated 
https://github.com/llvm/llvm-project/pull/133716

>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 1/4] 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();

>From 6d23613662051546c0de1a1c9c0814147b47b425 Mon Sep 17 00:00:00 2001
From: Victor Campos <victor.cam...@arm.com>
Date: Fri, 4 Apr 2025 10:15:58 +0100
Subject: [PATCH 2/4] - Change patch to use existing function. - Modify
 setTargetAttributes function to work even without a function   declaration.

---
 clang/lib/CodeGen/CGDeclCXX.cpp   |  7 +------
 clang/lib/CodeGen/Targets/ARM.cpp | 13 +++++++------
 2 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp
index 0366e3977b812..50b1bdde88d07 100644
--- a/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/clang/lib/CodeGen/CGDeclCXX.cpp
@@ -793,6 +793,7 @@ void CodeGenModule::EmitCXXModuleInitFunc(Module *Primary) {
     }
     CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, ModuleInits,
                                                      GuardAddr);
+    getTargetCodeGenInfo().setTargetAttributes(nullptr, Fn, *this);
   }
 
   // We allow for the case that a module object is added to a linked binary
@@ -818,12 +819,6 @@ 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/lib/CodeGen/Targets/ARM.cpp 
b/clang/lib/CodeGen/Targets/ARM.cpp
index a6d9a5549355c..81475057194f1 100644
--- a/clang/lib/CodeGen/Targets/ARM.cpp
+++ b/clang/lib/CodeGen/Targets/ARM.cpp
@@ -136,12 +136,13 @@ class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
                            CodeGen::CodeGenModule &CGM) const override {
     if (GV->isDeclaration())
       return;
-    const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
-    if (!FD)
+    auto *Fn = dyn_cast<llvm::Function>(GV);
+    if (!Fn)
       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 +175,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;

>From 968bbfb22a946bc62ee79b98c307d63b3cac1359 Mon Sep 17 00:00:00 2001
From: Victor Campos <victor.cam...@arm.com>
Date: Fri, 4 Apr 2025 12:19:37 +0100
Subject: [PATCH 3/4] Extend new solution to AArch64

---
 clang/lib/CodeGen/Targets/AArch64.cpp         |  9 +++--
 .../cxx20-module-initializer-pacbti.cpp       | 40 +++++++++++++++++++
 2 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp 
b/clang/lib/CodeGen/Targets/AArch64.cpp
index 073ca3cc82690..449edd27ea07f 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/test/CodeGenCXX/cxx20-module-initializer-pacbti.cpp 
b/clang/test/CodeGenCXX/cxx20-module-initializer-pacbti.cpp
index 7ebaa5e8f349e..a7a0801d6c66c 100644
--- a/clang/test/CodeGenCXX/cxx20-module-initializer-pacbti.cpp
+++ b/clang/test/CodeGenCXX/cxx20-module-initializer-pacbti.cpp
@@ -18,12 +18,52 @@
 // 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
 
+// RUN: %clang_cc1 -triple aarch64-unknown-none-elf -emit-module-interface 
-target-feature +pacbti -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-BTI %s
+
+// RUN: %clang_cc1 -triple aarch64-unknown-none-elf -emit-module-interface 
-target-feature +pacbti -msign-return-address=non-leaf -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 %s
+
+// RUN: %clang_cc1 -triple aarch64-unknown-none-elf -emit-module-interface 
-target-feature +pacbti -msign-return-address=non-leaf 
-msign-return-address-key=b_key -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-BKEY %s
+
+// RUN: %clang_cc1 -triple aarch64-unknown-none-elf -emit-module-interface 
-target-feature +pacbti -msign-return-address=all -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-ALL %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 -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-ALL-BKEY %s
+
+// RUN: %clang_cc1 -triple aarch64-unknown-none-elf -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 aarch64-unknown-none-elf -std=c++20 %t.pcm 
-emit-llvm -o - | \
+// RUN: FileCheck --check-prefixes=CHECK,CHECK-PAC-BTI %s
+
+// RUN: %clang_cc1 -triple aarch64-unknown-none-elf -emit-module-interface 
-target-feature +pacbti -msign-return-address=non-leaf 
-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-BKEY-BTI %s
+
+// RUN: %clang_cc1 -triple aarch64-unknown-none-elf -emit-module-interface 
-target-feature +pacbti -msign-return-address=all -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-BTI-ALL %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-BKEY-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-BKEY: attributes #0 = { nounwind "sign-return-address"="non-leaf" 
"sign-return-address-key"="b_key" }
 // CHECK-PAC-ALL: attributes #0 = { nounwind "sign-return-address"="all" 
"sign-return-address-key"="a_key" }
+// CHECK-PAC-ALL-BKEY: attributes #0 = { nounwind "sign-return-address"="all" 
"sign-return-address-key"="b_key" }
 // CHECK-PAC-BTI: attributes #0 = { nounwind "branch-target-enforcement" 
"sign-return-address"="non-leaf" "sign-return-address-key"="a_key" }
+// CHECK-PAC-BKEY-BTI: attributes #0 = { nounwind "branch-target-enforcement" 
"sign-return-address"="non-leaf" "sign-return-address-key"="b_key" }
 // CHECK-PAC-BTI-ALL: attributes #0 = { nounwind "branch-target-enforcement" 
"sign-return-address"="all" "sign-return-address-key"="a_key" }
+// CHECK-PAC-BKEY-BTI-ALL: attributes #0 = { nounwind 
"branch-target-enforcement" "sign-return-address"="all" 
"sign-return-address-key"="b_key" }
 
 module;
 

>From 67d61479c0e10af02d22535e0ca5b35b7391a677 Mon Sep 17 00:00:00 2001
From: Victor Campos <victor.cam...@arm.com>
Date: Mon, 7 Apr 2025 14:09:04 +0100
Subject: [PATCH 4/4] Change the place where `setTargetAttributes` is called

---
 clang/lib/CodeGen/CGDeclCXX.cpp   | 3 ++-
 clang/lib/CodeGen/Targets/ARM.cpp | 2 --
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp
index 50b1bdde88d07..c1228501d7a20 100644
--- a/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/clang/lib/CodeGen/CGDeclCXX.cpp
@@ -447,6 +447,8 @@ llvm::Function 
*CodeGenModule::CreateGlobalInitOrCleanUpFunction(
 
   if (Linkage == llvm::GlobalVariable::InternalLinkage)
     SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);
+  else
+    getTargetCodeGenInfo().setTargetAttributes(nullptr, Fn, *this);
 
   Fn->setCallingConv(getRuntimeCC());
 
@@ -793,7 +795,6 @@ void CodeGenModule::EmitCXXModuleInitFunc(Module *Primary) {
     }
     CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, ModuleInits,
                                                      GuardAddr);
-    getTargetCodeGenInfo().setTargetAttributes(nullptr, Fn, *this);
   }
 
   // We allow for the case that a module object is added to a linked binary
diff --git a/clang/lib/CodeGen/Targets/ARM.cpp 
b/clang/lib/CodeGen/Targets/ARM.cpp
index 81475057194f1..043fe642c239d 100644
--- a/clang/lib/CodeGen/Targets/ARM.cpp
+++ b/clang/lib/CodeGen/Targets/ARM.cpp
@@ -134,8 +134,6 @@ class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
 
   void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
                            CodeGen::CodeGenModule &CGM) const override {
-    if (GV->isDeclaration())
-      return;
     auto *Fn = dyn_cast<llvm::Function>(GV);
     if (!Fn)
       return;

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

Reply via email to