From 86bc38c4bb42f51b05630aee8d1b5a338679eaa9 Mon Sep 17 00:00:00 2001 From: Gergely Balint Date: Tue, 29 Apr 2025 10:04:58 +0200 Subject: [PATCH] [BOLT][AArch64] Allow binary-analysis and heatmaptool to run with pac-ret binaries - OpNegateRAState support is only needed for tools that produce binaries. --- bolt/docs/BinaryAnalysis.md | 6 ------ bolt/lib/Core/BinaryFunction.cpp | 26 +++++++++++++++++++++++--- 2 files changed, 23 insertions(+), 9 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/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp index 184a4462b356a..cf18774c26034 100644 --- a/bolt/lib/Core/BinaryFunction.cpp +++ b/bolt/lib/Core/BinaryFunction.cpp @@ -65,6 +65,8 @@ extern cl::opt StrictMode; extern cl::opt UpdateDebugSections; extern cl::opt Verbosity; +extern bool BinaryAnalysisMode; +extern bool HeatmapMode; extern bool processAllFunctions(); static cl::opt CheckEncoding( @@ -2760,13 +2762,19 @@ struct CFISnapshot { } case MCCFIInstruction::OpAdjustCfaOffset: case MCCFIInstruction::OpWindowSave: - case MCCFIInstruction::OpNegateRAState: case MCCFIInstruction::OpNegateRAStateWithPC: case MCCFIInstruction::OpLLVMDefAspaceCfa: case MCCFIInstruction::OpLabel: case MCCFIInstruction::OpValOffset: llvm_unreachable("unsupported CFI opcode"); break; + case MCCFIInstruction::OpNegateRAState: + if (!(opts::BinaryAnalysisMode || opts::HeatmapMode)) { + llvm_unreachable("BOLT-ERROR: binaries using pac-ret hardening (e.g. " + "as produced by '-mbranch-protection=pac-ret') are " + "currently not supported by BOLT."); + } + break; case MCCFIInstruction::OpRememberState: case MCCFIInstruction::OpRestoreState: case MCCFIInstruction::OpGnuArgsSize: @@ -2900,13 +2908,19 @@ struct CFISnapshotDiff : public CFISnapshot { return CFAReg == Instr.getRegister() && CFAOffset == Instr.getOffset(); case MCCFIInstruction::OpAdjustCfaOffset: case MCCFIInstruction::OpWindowSave: - case MCCFIInstruction::OpNegateRAState: case MCCFIInstruction::OpNegateRAStateWithPC: case MCCFIInstruction::OpLLVMDefAspaceCfa: case MCCFIInstruction::OpLabel: case MCCFIInstruction::OpValOffset: llvm_unreachable("unsupported CFI opcode"); return false; + case MCCFIInstruction::OpNegateRAState: + if (!(opts::BinaryAnalysisMode || opts::HeatmapMode)) { + llvm_unreachable("BOLT-ERROR: binaries using pac-ret hardening (e.g. " + "as produced by '-mbranch-protection=pac-ret') are " + "currently not supported by BOLT."); + } + break; case MCCFIInstruction::OpRememberState: case MCCFIInstruction::OpRestoreState: case MCCFIInstruction::OpGnuArgsSize: @@ -3051,13 +3065,19 @@ BinaryFunction::unwindCFIState(int32_t FromState, int32_t ToState, break; case MCCFIInstruction::OpAdjustCfaOffset: case MCCFIInstruction::OpWindowSave: - case MCCFIInstruction::OpNegateRAState: case MCCFIInstruction::OpNegateRAStateWithPC: case MCCFIInstruction::OpLLVMDefAspaceCfa: case MCCFIInstruction::OpLabel: case MCCFIInstruction::OpValOffset: llvm_unreachable("unsupported CFI opcode"); break; + case MCCFIInstruction::OpNegateRAState: + if (!(opts::BinaryAnalysisMode || opts::HeatmapMode)) { + llvm_unreachable("BOLT-ERROR: binaries using pac-ret hardening (e.g. " + "as produced by '-mbranch-protection=pac-ret') are " + "currently not supported by BOLT."); + } + break; case MCCFIInstruction::OpGnuArgsSize: // do not affect CFI state break;