[llvm] [BOLT][binary-analysis] Fix pac-ret scanner's "major limitation" (PR #136664)
Gergely Bálint via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 22 06:10:56 PDT 2025
https://github.com/bgergely0 updated https://github.com/llvm/llvm-project/pull/136664
>From 1deada421efad6d9587b906773bf36b1bca38631 Mon Sep 17 00:00:00 2001
From: Gergely Balint <gergely.balint at arm.com>
Date: Tue, 22 Apr 2025 09:31:47 +0200
Subject: [PATCH 1/2] [BOLT] Fix pac-ret binary analysis tool's CFI issue
- llvm-bolt-binary-analysis, and other tools which don't produce a
binary as output can be run without NegateRAState CFIs.
- during FillCFIInfo, added a better error message about NegateRAState
CFIs when running llvm-bolt.
- updated docs.
- updated a unit test about NegateRAState CFI handling.
---
bolt/docs/BinaryAnalysis.md | 6 ------
bolt/include/bolt/Core/Exceptions.h | 6 +++++-
bolt/lib/Core/Exceptions.cpp | 15 ++++++++++++---
bolt/lib/Rewrite/RewriteInstance.cpp | 3 ++-
bolt/test/AArch64/dw_cfa_gnu_window_save.test | 6 +++---
5 files changed, 22 insertions(+), 14 deletions(-)
diff --git a/bolt/docs/BinaryAnalysis.md b/bolt/docs/BinaryAnalysis.md
index 9f0f018980517..b13410cd96355 100644
--- a/bolt/docs/BinaryAnalysis.md
+++ b/bolt/docs/BinaryAnalysis.md
@@ -180,12 +180,6 @@ The following are current known cases of false negatives:
[prototype branch](
https://github.com/llvm/llvm-project/compare/main...kbeyls:llvm-project:bolt-gadget-scanner-prototype).
-BOLT cannot currently handle functions with `cfi_negate_ra_state` correctly,
-i.e. any binaries built with `-mbranch-protection=pac-ret`. The scanner is meant
-to be used on specifically such binaries, so this is a major limitation! Work is
-going on in PR [#120064](https://github.com/llvm/llvm-project/pull/120064) to
-fix this.
-
## How to add your own binary analysis
_TODO: this section needs to be written. Ideally, we should have a simple
diff --git a/bolt/include/bolt/Core/Exceptions.h b/bolt/include/bolt/Core/Exceptions.h
index f10cf776f0943..54e7fc50078da 100644
--- a/bolt/include/bolt/Core/Exceptions.h
+++ b/bolt/include/bolt/Core/Exceptions.h
@@ -37,7 +37,8 @@ class BinaryFunction;
/// BinaryFunction, as well as rewriting CFI sections.
class CFIReaderWriter {
public:
- explicit CFIReaderWriter(BinaryContext &BC, const DWARFDebugFrame &EHFrame);
+ explicit CFIReaderWriter(BinaryContext &BC, const DWARFDebugFrame &EHFrame,
+ StringRef ToolName);
bool fillCFIInfoFor(BinaryFunction &Function) const;
@@ -56,9 +57,12 @@ class CFIReaderWriter {
const FDEsMap &getFDEs() const { return FDEs; }
+ StringRef getToolName() const { return ToolName; }
+
private:
BinaryContext &BC;
FDEsMap FDEs;
+ StringRef ToolName;
};
/// Parse an existing .eh_frame and invoke the callback for each
diff --git a/bolt/lib/Core/Exceptions.cpp b/bolt/lib/Core/Exceptions.cpp
index 0b2e63b8ca6a7..cbb29a05bee20 100644
--- a/bolt/lib/Core/Exceptions.cpp
+++ b/bolt/lib/Core/Exceptions.cpp
@@ -463,8 +463,10 @@ void BinaryFunction::updateEHRanges() {
const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
CFIReaderWriter::CFIReaderWriter(BinaryContext &BC,
- const DWARFDebugFrame &EHFrame)
+ const DWARFDebugFrame &EHFrame,
+ StringRef ToolName)
: BC(BC) {
+ this->ToolName = ToolName;
// Prepare FDEs for fast lookup
for (const dwarf::FrameEntry &Entry : EHFrame.entries()) {
const auto *CurFDE = dyn_cast<dwarf::FDE>(&Entry);
@@ -632,8 +634,15 @@ bool CFIReaderWriter::fillCFIInfoFor(BinaryFunction &Function) const {
// DW_CFA_GNU_window_save and DW_CFA_GNU_NegateRAState just use the same
// id but mean different things. The latter is used in AArch64.
if (Function.getBinaryContext().isAArch64()) {
- Function.addCFIInstruction(
- Offset, MCCFIInstruction::createNegateRAState(nullptr));
+ // .cfi_negate_ra_state is only needed for tools producing binaries (so
+ // BOLT itself). Other BOLT-based tools (perf2bolt, merge-fdata,
+ // llvm-bolt-binary-analysis, etc.) can safely drop this CFI.
+ if (getToolName() == "llvm-bolt") {
+ BC.errs() << "BOLT-ERROR: pointer authentication is not supported "
+ "yet. Please compile "
+ "your target binary using '-mbranch-protection=none'.\n";
+ exit(1);
+ }
break;
}
if (opts::Verbosity >= 1)
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 69fb736d7bde0..6dc7cad4f538c 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -2048,7 +2048,8 @@ Error RewriteInstance::readSpecialSections() {
Expected<const DWARFDebugFrame *> EHFrameOrError = BC->DwCtx->getEHFrame();
if (!EHFrameOrError)
report_error("expected valid eh_frame section", EHFrameOrError.takeError());
- CFIRdWrt.reset(new CFIReaderWriter(*BC, *EHFrameOrError.get()));
+ StringRef ToolName = llvm::sys::path::stem(Argv[0]);
+ CFIRdWrt.reset(new CFIReaderWriter(*BC, *EHFrameOrError.get(), ToolName));
processSectionMetadata();
diff --git a/bolt/test/AArch64/dw_cfa_gnu_window_save.test b/bolt/test/AArch64/dw_cfa_gnu_window_save.test
index 2e044b399720a..97b257ee04666 100644
--- a/bolt/test/AArch64/dw_cfa_gnu_window_save.test
+++ b/bolt/test/AArch64/dw_cfa_gnu_window_save.test
@@ -1,8 +1,8 @@
-# Check that llvm-bolt can handle DW_CFA_GNU_window_save on AArch64.
+# Check that llvm-bolt refuses binaries with DW_CFA_GNU_window_save on AArch64.
RUN: yaml2obj %p/Inputs/dw_cfa_gnu_window_save.yaml &> %t.exe
-RUN: llvm-bolt %t.exe -o %t.bolt 2>&1 | FileCheck %s
+RUN not: llvm-bolt %t.exe -o %t.bolt 2>&1 | FileCheck %s
CHECK-NOT: paciasp
CHECK-NOT: autiasp
-CHECK-NOT: ERROR: unable to fill CFI.
+CHECK: BOLT-ERROR: pointer authentication is not supported yet.
>From 9e95938895222debdae1d1892c26bf0fc202cde0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Gergely=20B=C3=A1lint?=
<50703923+bgergely0 at users.noreply.github.com>
Date: Tue, 22 Apr 2025 15:10:48 +0200
Subject: [PATCH 2/2] [BOLT] Fix dw_cfa_gnu_window_save.test
change "RUN not:" to "RUN: not"
Co-authored-by: Anatoly Trosinenko <anatoly.trosinenko at gmail.com>
---
bolt/test/AArch64/dw_cfa_gnu_window_save.test | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bolt/test/AArch64/dw_cfa_gnu_window_save.test b/bolt/test/AArch64/dw_cfa_gnu_window_save.test
index 97b257ee04666..aed7c73f6a704 100644
--- a/bolt/test/AArch64/dw_cfa_gnu_window_save.test
+++ b/bolt/test/AArch64/dw_cfa_gnu_window_save.test
@@ -1,7 +1,7 @@
# Check that llvm-bolt refuses binaries with DW_CFA_GNU_window_save on AArch64.
RUN: yaml2obj %p/Inputs/dw_cfa_gnu_window_save.yaml &> %t.exe
-RUN not: llvm-bolt %t.exe -o %t.bolt 2>&1 | FileCheck %s
+RUN: not llvm-bolt %t.exe -o %t.bolt 2>&1 | FileCheck %s
CHECK-NOT: paciasp
CHECK-NOT: autiasp
More information about the llvm-commits
mailing list