Skip to content

Commit 1deada4

Browse files
committed
[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.
1 parent 6196b4e commit 1deada4

File tree

5 files changed

+22
-14
lines changed

5 files changed

+22
-14
lines changed

bolt/docs/BinaryAnalysis.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,6 @@ The following are current known cases of false negatives:
180180
[prototype branch](
181181
https://github.com/llvm/llvm-project/compare/main...kbeyls:llvm-project:bolt-gadget-scanner-prototype).
182182

183-
BOLT cannot currently handle functions with `cfi_negate_ra_state` correctly,
184-
i.e. any binaries built with `-mbranch-protection=pac-ret`. The scanner is meant
185-
to be used on specifically such binaries, so this is a major limitation! Work is
186-
going on in PR [#120064](https://github.com/llvm/llvm-project/pull/120064) to
187-
fix this.
188-
189183
## How to add your own binary analysis
190184

191185
_TODO: this section needs to be written. Ideally, we should have a simple

bolt/include/bolt/Core/Exceptions.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ class BinaryFunction;
3737
/// BinaryFunction, as well as rewriting CFI sections.
3838
class CFIReaderWriter {
3939
public:
40-
explicit CFIReaderWriter(BinaryContext &BC, const DWARFDebugFrame &EHFrame);
40+
explicit CFIReaderWriter(BinaryContext &BC, const DWARFDebugFrame &EHFrame,
41+
StringRef ToolName);
4142

4243
bool fillCFIInfoFor(BinaryFunction &Function) const;
4344

@@ -56,9 +57,12 @@ class CFIReaderWriter {
5657

5758
const FDEsMap &getFDEs() const { return FDEs; }
5859

60+
StringRef getToolName() const { return ToolName; }
61+
5962
private:
6063
BinaryContext &BC;
6164
FDEsMap FDEs;
65+
StringRef ToolName;
6266
};
6367

6468
/// Parse an existing .eh_frame and invoke the callback for each

bolt/lib/Core/Exceptions.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -463,8 +463,10 @@ void BinaryFunction::updateEHRanges() {
463463
const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
464464

465465
CFIReaderWriter::CFIReaderWriter(BinaryContext &BC,
466-
const DWARFDebugFrame &EHFrame)
466+
const DWARFDebugFrame &EHFrame,
467+
StringRef ToolName)
467468
: BC(BC) {
469+
this->ToolName = ToolName;
468470
// Prepare FDEs for fast lookup
469471
for (const dwarf::FrameEntry &Entry : EHFrame.entries()) {
470472
const auto *CurFDE = dyn_cast<dwarf::FDE>(&Entry);
@@ -632,8 +634,15 @@ bool CFIReaderWriter::fillCFIInfoFor(BinaryFunction &Function) const {
632634
// DW_CFA_GNU_window_save and DW_CFA_GNU_NegateRAState just use the same
633635
// id but mean different things. The latter is used in AArch64.
634636
if (Function.getBinaryContext().isAArch64()) {
635-
Function.addCFIInstruction(
636-
Offset, MCCFIInstruction::createNegateRAState(nullptr));
637+
// .cfi_negate_ra_state is only needed for tools producing binaries (so
638+
// BOLT itself). Other BOLT-based tools (perf2bolt, merge-fdata,
639+
// llvm-bolt-binary-analysis, etc.) can safely drop this CFI.
640+
if (getToolName() == "llvm-bolt") {
641+
BC.errs() << "BOLT-ERROR: pointer authentication is not supported "
642+
"yet. Please compile "
643+
"your target binary using '-mbranch-protection=none'.\n";
644+
exit(1);
645+
}
637646
break;
638647
}
639648
if (opts::Verbosity >= 1)

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2048,7 +2048,8 @@ Error RewriteInstance::readSpecialSections() {
20482048
Expected<const DWARFDebugFrame *> EHFrameOrError = BC->DwCtx->getEHFrame();
20492049
if (!EHFrameOrError)
20502050
report_error("expected valid eh_frame section", EHFrameOrError.takeError());
2051-
CFIRdWrt.reset(new CFIReaderWriter(*BC, *EHFrameOrError.get()));
2051+
StringRef ToolName = llvm::sys::path::stem(Argv[0]);
2052+
CFIRdWrt.reset(new CFIReaderWriter(*BC, *EHFrameOrError.get(), ToolName));
20522053

20532054
processSectionMetadata();
20542055

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# Check that llvm-bolt can handle DW_CFA_GNU_window_save on AArch64.
1+
# Check that llvm-bolt refuses binaries with DW_CFA_GNU_window_save on AArch64.
22

33
RUN: yaml2obj %p/Inputs/dw_cfa_gnu_window_save.yaml &> %t.exe
4-
RUN: llvm-bolt %t.exe -o %t.bolt 2>&1 | FileCheck %s
4+
RUN not: llvm-bolt %t.exe -o %t.bolt 2>&1 | FileCheck %s
55

66
CHECK-NOT: paciasp
77
CHECK-NOT: autiasp
8-
CHECK-NOT: ERROR: unable to fill CFI.
8+
CHECK: BOLT-ERROR: pointer authentication is not supported yet.

0 commit comments

Comments
 (0)