https://github.com/bgergely0 updated 
https://github.com/llvm/llvm-project/pull/165227

From 080eaf921417c6fd2241e0578e0890b1aafa1bfa Mon Sep 17 00:00:00 2001
From: Gergely Balint <[email protected]>
Date: Mon, 27 Oct 2025 09:29:54 +0000
Subject: [PATCH 1/2] [BOLT][PAC] Warn about synchronous unwind tables

BOLT currently ignores functions with synchronous PAuth DWARF info.
When more than 10% of functions get ignored for inconsistencies, we
should emit a warning to only use asynchronous unwind tables.

See also: #165215
---
 bolt/lib/Passes/PointerAuthCFIAnalyzer.cpp    |  8 ++++-
 .../AArch64/pacret-synchronous-unwind.cpp     | 32 +++++++++++++++++++
 2 files changed, 39 insertions(+), 1 deletion(-)
 create mode 100644 bolt/test/runtime/AArch64/pacret-synchronous-unwind.cpp

diff --git a/bolt/lib/Passes/PointerAuthCFIAnalyzer.cpp 
b/bolt/lib/Passes/PointerAuthCFIAnalyzer.cpp
index 91030544d2b88..cc28ca47c26b1 100644
--- a/bolt/lib/Passes/PointerAuthCFIAnalyzer.cpp
+++ b/bolt/lib/Passes/PointerAuthCFIAnalyzer.cpp
@@ -133,11 +133,17 @@ Error 
PointerAuthCFIAnalyzer::runOnFunctions(BinaryContext &BC) {
   ParallelUtilities::runOnEachFunction(
       BC, ParallelUtilities::SchedulingPolicy::SP_INST_LINEAR, WorkFun,
       SkipPredicate, "PointerAuthCFIAnalyzer");
+
+  float IgnoredPercent = (100.0 * FunctionsIgnored) / Total;
   BC.outs() << "BOLT-INFO: PointerAuthCFIAnalyzer ran on " << Total
             << " functions. Ignored " << FunctionsIgnored << " functions "
-            << format("(%.2lf%%)", (100.0 * FunctionsIgnored) / Total)
+            << format("(%.2lf%%)", IgnoredPercent)
             << " because of CFI inconsistencies\n";
 
+  if (IgnoredPercent >= 10.0)
+    BC.outs() << "BOLT-WARNING: PointerAuthCFIAnalyzer only supports "
+                 "asynchronous unwind tables.\n";
+
   return Error::success();
 }
 
diff --git a/bolt/test/runtime/AArch64/pacret-synchronous-unwind.cpp 
b/bolt/test/runtime/AArch64/pacret-synchronous-unwind.cpp
new file mode 100644
index 0000000000000..e90882833323d
--- /dev/null
+++ b/bolt/test/runtime/AArch64/pacret-synchronous-unwind.cpp
@@ -0,0 +1,32 @@
+// Test to demonstrate that functions compiled with synchronous unwind tables
+// are ignored by the PointerAuthCFIAnalyzer.
+// Exception handling is needed to have _any_ unwind tables, otherwise the
+// PointerAuthCFIAnalyzer does not run on these functions, so it does not 
ignore
+// any function.
+//
+// REQUIRES: system-linux,bolt-runtime
+//
+// RUN: %clangxx --target=aarch64-unknown-linux-gnu \
+// RUN: -mbranch-protection=pac-ret \
+// RUN: -fno-asynchronous-unwind-tables \
+// RUN: %s -o %t.exe -Wl,-q
+// RUN: llvm-bolt %t.exe -o %t.bolt | FileCheck %s --check-prefix=CHECK
+//
+// CHECK: PointerAuthCFIAnalyzer ran on 3 functions. Ignored
+// CHECK-NOT: 0 functions (0.00%) because of CFI inconsistencies
+// CHECK-SAME: 1 functions (33.33%) because of CFI inconsistencies
+// CHECK-NEXT: PointerAuthCFIAnalyzer only supports asynchronous unwind tables
+
+#include <cstdio>
+#include <stdexcept>
+
+void foo() { throw std::runtime_error("Exception from foo()."); }
+
+int main() {
+  try {
+    foo();
+  } catch (const std::exception &e) {
+    printf("Exception caught: %s\n", e.what());
+  }
+  return 0;
+}

From bd53804b5f88809e44377d03d0a484b2fbefb220 Mon Sep 17 00:00:00 2001
From: Gergely Balint <[email protected]>
Date: Tue, 28 Oct 2025 09:23:08 +0000
Subject: [PATCH 2/2] [BOLT] Use opts::Verbosity in PointerAuthCFIAnalyzer

---
 bolt/lib/Passes/PointerAuthCFIAnalyzer.cpp    | 27 ++++++++++++-------
 bolt/test/AArch64/negate-ra-state-incorrect.s |  2 +-
 2 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/bolt/lib/Passes/PointerAuthCFIAnalyzer.cpp 
b/bolt/lib/Passes/PointerAuthCFIAnalyzer.cpp
index cc28ca47c26b1..e4efb11356a3d 100644
--- a/bolt/lib/Passes/PointerAuthCFIAnalyzer.cpp
+++ b/bolt/lib/Passes/PointerAuthCFIAnalyzer.cpp
@@ -28,6 +28,10 @@
 
 using namespace llvm;
 
+namespace opts {
+extern llvm::cl::opt<unsigned> Verbosity;
+} // namespace opts
+
 namespace llvm {
 namespace bolt {
 
@@ -43,9 +47,10 @@ bool PointerAuthCFIAnalyzer::runOnFunction(BinaryFunction 
&BF) {
         // Not all functions have .cfi_negate_ra_state in them. But if one 
does,
         // we expect psign/pauth instructions to have the hasNegateRAState
         // annotation.
-        BC.outs() << "BOLT-INFO: inconsistent RAStates in function "
-                  << BF.getPrintName()
-                  << ": ptr sign/auth inst without .cfi_negate_ra_state\n";
+        if (opts::Verbosity >= 1)
+          BC.outs() << "BOLT-INFO: inconsistent RAStates in function "
+                    << BF.getPrintName()
+                    << ": ptr sign/auth inst without .cfi_negate_ra_state\n";
         std::lock_guard<std::mutex> Lock(IgnoreMutex);
         BF.setIgnored();
         return false;
@@ -65,9 +70,10 @@ bool PointerAuthCFIAnalyzer::runOnFunction(BinaryFunction 
&BF) {
       if (BC.MIB->isPSignOnLR(Inst)) {
         if (RAState) {
           // RA signing instructions should only follow unsigned RA state.
-          BC.outs() << "BOLT-INFO: inconsistent RAStates in function "
-                    << BF.getPrintName()
-                    << ": ptr signing inst encountered in Signed RA state\n";
+          if (opts::Verbosity >= 1)
+            BC.outs() << "BOLT-INFO: inconsistent RAStates in function "
+                      << BF.getPrintName()
+                      << ": ptr signing inst encountered in Signed RA state\n";
           std::lock_guard<std::mutex> Lock(IgnoreMutex);
           BF.setIgnored();
           return false;
@@ -75,10 +81,11 @@ bool PointerAuthCFIAnalyzer::runOnFunction(BinaryFunction 
&BF) {
       } else if (BC.MIB->isPAuthOnLR(Inst)) {
         if (!RAState) {
           // RA authenticating instructions should only follow signed RA state.
-          BC.outs() << "BOLT-INFO: inconsistent RAStates in function "
-                    << BF.getPrintName()
-                    << ": ptr authenticating inst encountered in Unsigned RA "
-                       "state\n";
+          if (opts::Verbosity >= 1)
+            BC.outs() << "BOLT-INFO: inconsistent RAStates in function "
+                      << BF.getPrintName()
+                      << ": ptr authenticating inst encountered in Unsigned RA 
"
+                         "state\n";
           std::lock_guard<std::mutex> Lock(IgnoreMutex);
           BF.setIgnored();
           return false;
diff --git a/bolt/test/AArch64/negate-ra-state-incorrect.s 
b/bolt/test/AArch64/negate-ra-state-incorrect.s
index 390b3b824d6bc..68a6fc008ab06 100644
--- a/bolt/test/AArch64/negate-ra-state-incorrect.s
+++ b/bolt/test/AArch64/negate-ra-state-incorrect.s
@@ -8,7 +8,7 @@
 
 # RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o
 # RUN: %clang %cflags  %t.o -o %t.exe -Wl,-q
-# RUN: llvm-bolt %t.exe -o %t.exe.bolt --no-threads | FileCheck %s 
--check-prefix=CHECK-BOLT
+# RUN: llvm-bolt %t.exe -o %t.exe.bolt -v=1 --no-threads | FileCheck %s 
--check-prefix=CHECK-BOLT
 
 # CHECK-BOLT: BOLT-INFO: inconsistent RAStates in function foo: ptr 
authenticating inst encountered in Unsigned RA state
 # CHECK-BOLT: BOLT-INFO: inconsistent RAStates in function bar: ptr signing 
inst encountered in Signed RA state

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to