Skip to content

Commit 44a46f2

Browse files
authored
merge main into amd-staging (#753)
2 parents e865154 + 2757b8f commit 44a46f2

File tree

135 files changed

+6625
-11285
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

135 files changed

+6625
-11285
lines changed
Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ intended audience is BOLT developers. The document is an updated version of the
1010
in assembly, or `OpNegateRAState` in BOLT sources. In this document, I will use
1111
**negate-ra-state** as a shorthand.
1212

13+
Note: there are two resolutions for CFI:
14+
- Call Frame Instruction: individual DWARF instruction, e.g. negate-ra-state
15+
- Control Flow Integrity: a security mechanism, e.g. pointer authentication.
16+
1317
## Introduction
1418

1519
### Pointer Authentication
@@ -104,9 +108,9 @@ negate-ra-state CFIs will become invalid during BasicBlock reordering.
104108
## Solution design
105109

106110
The implementation introduces two new passes:
107-
1. `MarkRAStatesPass`: assigns the RA state to each instruction based on the CFIs
108-
in the input binary
109-
2. `InsertNegateRAStatePass`: reads those assigned instruction RA states after
111+
1. `PointerAuthCFIAnalyzer`: assigns the RA state to each instruction based on
112+
the CFIs in the input binary
113+
2. `PointerAuthCFIFixup`: reads those assigned instruction RA states after
110114
optimizations, and emits `DW_CFA_AARCH64_negate_ra_state` CFIs at the correct
111115
places: wherever there is a state change between two consecutive instructions
112116
in the layout order.
@@ -129,7 +133,7 @@ instruction.
129133
This special case is handled by adding an `initialRAState` bool to each BinaryFunction.
130134
If the `Offset` the CFI refers to is zero, we don't store an annotation, but set
131135
the `initialRAState` in `FillCFIInfoFor`. This information is then used in
132-
`MarkRAStates`.
136+
`PointerAuthCFIAnalyzer`.
133137

134138
### Binaries without DWARF info
135139

@@ -146,7 +150,7 @@ In summary:
146150
- pointer auth is used, and we have DWARF CFIs: passes run, and rewrite the
147151
negate-ra-state CFI.
148152

149-
### MarkRAStates pass
153+
### PointerAuthCFIAnalyzer pass
150154

151155
This pass runs before optimizations reorder anything.
152156

@@ -173,9 +177,9 @@ what we have before the pass, and after it.
173177
| autiasp | negate-ra-state | signed |
174178
| ret | | unsigned |
175179

176-
##### Error handling in MarkRAState Pass:
180+
##### Error handling in PointerAuthCFIAnalyzer pass:
177181

178-
Whenever the MarkRAStates pass finds inconsistencies in the current
182+
Whenever the PointerAuthCFIAnalyzer pass finds inconsistencies in the current
179183
BinaryFunction, it marks the function as ignored using `BF.setIgnored()`. BOLT
180184
will not optimize this function but will emit it unchanged in the original section
181185
(`.bolt.org.text`).
@@ -188,16 +192,17 @@ The inconsistencies are as follows:
188192
Users will be informed about the number of ignored functions in the pass, the
189193
exact functions ignored, and the found inconsistency.
190194

191-
### InsertNegateRAStatePass
195+
### PointerAuthCFIFixup
192196

193-
This pass runs after optimizations. It performns the _inverse_ of MarkRAState pa s:
197+
This pass runs after optimizations. It performs the _inverse_ of PointerAuthCFIAnalyzer
198+
pass:
194199
1. it reads the RA state annotations attached to the instructions, and
195200
2. whenever the state changes, it adds a PseudoInstruction that holds an
196201
OpNegateRAState CFI.
197202

198203
##### Covering newly generated instructions:
199204

200-
Some BOLT passes can add new Instructions. In InsertNegateRAStatePass, we have
205+
Some BOLT passes can add new Instructions. In PointerAuthCFIFixup, we have
201206
to know what RA state these have.
202207

203208
> [!important]
@@ -224,7 +229,7 @@ freely. The only special case is function splitting. When a function is split,
224229
the split part becomes a new function in the emitted binary. For unwinding to
225230
work, it needs to "replay" all CFIs that lead up to the split point. BOLT does
226231
this for other CFIs. As negate-ra-state is not read (only stored as an Annotation),
227-
we have to do this manually in InsertNegateRAStatePass. Here, if the split part
232+
we have to do this manually in PointerAuthCFIFixup. Here, if the split part
228233
starts with an instruction that has Signed RA state, we add a negate-ra-state CFI
229234
to indicate this.
230235

bolt/include/bolt/Passes/MarkRAStates.h renamed to bolt/include/bolt/Passes/PointerAuthCFIAnalyzer.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,33 @@
1-
//===- bolt/Passes/MarkRAStates.cpp ---------------------------------===//
1+
//===- bolt/Passes/PointerAuthCFIAnalyzer.h -------------------------------===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
88
//
9-
// This file implements the MarkRAStates class.
9+
// This file implements the PointerAuthCFIAnalyzer class.
1010
//
1111
//===----------------------------------------------------------------------===//
12-
#ifndef BOLT_PASSES_MARK_RA_STATES
13-
#define BOLT_PASSES_MARK_RA_STATES
12+
#ifndef BOLT_PASSES_POINTER_AUTH_CFI_ANALYZER
13+
#define BOLT_PASSES_POINTER_AUTH_CFI_ANALYZER
1414

1515
#include "bolt/Passes/BinaryPasses.h"
1616
#include <mutex>
1717

1818
namespace llvm {
1919
namespace bolt {
2020

21-
class MarkRAStates : public BinaryFunctionPass {
21+
class PointerAuthCFIAnalyzer : public BinaryFunctionPass {
2222
// setIgnored() is not thread-safe, but the pass is running on functions in
2323
// parallel.
2424
std::mutex IgnoreMutex;
2525

2626
public:
27-
explicit MarkRAStates() : BinaryFunctionPass(false) {}
27+
explicit PointerAuthCFIAnalyzer(const cl::opt<bool> &PrintPass)
28+
: BinaryFunctionPass(PrintPass) {}
2829

29-
const char *getName() const override { return "mark-ra-states"; }
30+
const char *getName() const override { return "pointer-auth-cfi-analyzer"; }
3031

3132
/// Pass entry point
3233
Error runOnFunctions(BinaryContext &BC) override;

bolt/include/bolt/Passes/InsertNegateRAStatePass.h renamed to bolt/include/bolt/Passes/PointerAuthCFIFixup.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
1-
//===- bolt/Passes/InsertNegateRAStatePass.h ------------------------------===//
1+
//===- bolt/Passes/PointerAuthCFIFixup.h ----------------------------------===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
88
//
9-
// This file implements the InsertNegateRAStatePass class.
9+
// This file implements the PointerAuthCFIFixup class.
1010
//
1111
//===----------------------------------------------------------------------===//
12-
#ifndef BOLT_PASSES_INSERT_NEGATE_RA_STATE_PASS
13-
#define BOLT_PASSES_INSERT_NEGATE_RA_STATE_PASS
12+
#ifndef BOLT_PASSES_POINTER_AUTH_CFI_FIXUP
13+
#define BOLT_PASSES_POINTER_AUTH_CFI_FIXUP
1414

1515
#include "bolt/Passes/BinaryPasses.h"
1616

1717
namespace llvm {
1818
namespace bolt {
1919

20-
class InsertNegateRAState : public BinaryFunctionPass {
20+
class PointerAuthCFIFixup : public BinaryFunctionPass {
2121
public:
22-
explicit InsertNegateRAState() : BinaryFunctionPass(false) {}
22+
explicit PointerAuthCFIFixup(const cl::opt<bool> &PrintPass)
23+
: BinaryFunctionPass(PrintPass) {}
2324

24-
const char *getName() const override { return "insert-negate-ra-state-pass"; }
25+
const char *getName() const override { return "pointer-auth-cfi-fixup"; }
2526

2627
/// Pass entry point
2728
Error runOnFunctions(BinaryContext &BC) override;

bolt/lib/Core/Exceptions.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ bool CFIReaderWriter::fillCFIInfoFor(BinaryFunction &Function) const {
572572
if (Function.getBinaryContext().isAArch64()) {
573573
// Support for pointer authentication:
574574
// We need to annotate instructions that modify the RA State, to work
575-
// out the state of each instruction in MarkRAStates Pass.
575+
// out the state of each instruction in PointerAuthCFIAnalyzer Pass.
576576
if (Offset != 0)
577577
Function.setInstModifiesRAState(DW_CFA_remember_state, Offset);
578578
}
@@ -583,7 +583,7 @@ bool CFIReaderWriter::fillCFIInfoFor(BinaryFunction &Function) const {
583583
if (Function.getBinaryContext().isAArch64()) {
584584
// Support for pointer authentication:
585585
// We need to annotate instructions that modify the RA State, to work
586-
// out the state of each instruction in MarkRAStates Pass.
586+
// out the state of each instruction in PointerAuthCFIAnalyzer Pass.
587587
if (Offset != 0)
588588
Function.setInstModifiesRAState(DW_CFA_restore_state, Offset);
589589
}
@@ -652,15 +652,15 @@ bool CFIReaderWriter::fillCFIInfoFor(BinaryFunction &Function) const {
652652
// BasicBlocks, which changes during optimizations. Instead of adding
653653
// OpNegateRAState CFIs, an annotation is added to the instruction, to
654654
// mark that the instruction modifies the RA State. The actual state for
655-
// instructions are worked out in MarkRAStates based on these
655+
// instructions are worked out in PointerAuthCFIAnalyzer based on these
656656
// annotations.
657657
if (Offset != 0)
658658
Function.setInstModifiesRAState(DW_CFA_AARCH64_negate_ra_state,
659659
Offset);
660660
else
661661
// We cannot Annotate an instruction at Offset == 0.
662662
// Instead, we save the initial (Signed) state, and push it to
663-
// MarkRAStates' RAStateStack.
663+
// PointerAuthCFIAnalyzer's RAStateStack.
664664
Function.setInitialRAState(true);
665665
break;
666666
}

bolt/lib/Passes/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,18 @@ add_llvm_library(LLVMBOLTPasses
1717
IdenticalCodeFolding.cpp
1818
IndirectCallPromotion.cpp
1919
Inliner.cpp
20-
InsertNegateRAStatePass.cpp
2120
Instrumentation.cpp
2221
JTFootprintReduction.cpp
2322
LongJmp.cpp
2423
LoopInversionPass.cpp
2524
LivenessAnalysis.cpp
2625
MCF.cpp
27-
MarkRAStates.cpp
2826
PatchEntries.cpp
2927
PAuthGadgetScanner.cpp
3028
PettisAndHansen.cpp
3129
PLTCall.cpp
30+
PointerAuthCFIAnalyzer.cpp
31+
PointerAuthCFIFixup.cpp
3232
ProfileQualityStats.cpp
3333
RegAnalysis.cpp
3434
RegReAssign.cpp

bolt/lib/Passes/IdenticalCodeFolding.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,8 @@ namespace bolt {
377377
void IdenticalCodeFolding::initVTableReferences(const BinaryContext &BC) {
378378
for (const auto &[Address, Data] : BC.getBinaryData()) {
379379
// Filter out all symbols that are not vtables.
380-
if (!Data->getName().starts_with("_ZTV"))
380+
if (!Data->getName().starts_with("_ZTV") && // vtable
381+
!Data->getName().starts_with("_ZTCN")) // construction vtable
381382
continue;
382383
for (uint64_t I = Address, End = I + Data->getSize(); I < End; I += 8)
383384
setAddressUsedInVTable(I);
@@ -437,8 +438,9 @@ void IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
437438
NamedRegionTimer MarkFunctionsUnsafeToFoldTimer(
438439
"markFunctionsUnsafeToFold", "markFunctionsUnsafeToFold", "ICF breakdown",
439440
"ICF breakdown", opts::TimeICF);
440-
if (!BC.isX86())
441-
BC.outs() << "BOLT-WARNING: safe ICF is only supported for x86\n";
441+
if (!BC.isX86() && !BC.isAArch64())
442+
BC.outs()
443+
<< "BOLT-WARNING: safe ICF is only supported for x86 and AArch64\n";
442444
analyzeDataRelocations(BC);
443445
analyzeFunctions(BC);
444446
}

bolt/lib/Passes/MarkRAStates.cpp renamed to bolt/lib/Passes/PointerAuthCFIAnalyzer.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
//===- bolt/Passes/MarkRAStates.cpp ---------------------------------===//
1+
//===- bolt/Passes/PointerAuthCFIAnalyzer.cpp -----------------------------===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
88
//
9-
// This file implements the MarkRAStates class.
9+
// This file implements the PointerAuthCFIAnalyzer class.
1010
// Three CFIs have an influence on the RA State of an instruction:
1111
// - NegateRAState flips the RA State,
1212
// - RememberState pushes the RA State to a stack,
@@ -16,10 +16,10 @@
1616
// the RA State of each instruction, and save it as new MCAnnotations. The new
1717
// annotations are Signing, Signed, Authenticating and Unsigned. After
1818
// optimizations, .cfi_negate_ra_state CFIs are added to the places where the
19-
// state changes in InsertNegateRAStatePass.
19+
// state changes in PointerAuthCFIFixup.
2020
//
2121
//===----------------------------------------------------------------------===//
22-
#include "bolt/Passes/MarkRAStates.h"
22+
#include "bolt/Passes/PointerAuthCFIAnalyzer.h"
2323
#include "bolt/Core/BinaryFunction.h"
2424
#include "bolt/Core/ParallelUtilities.h"
2525
#include <cstdlib>
@@ -31,7 +31,7 @@ using namespace llvm;
3131
namespace llvm {
3232
namespace bolt {
3333

34-
bool MarkRAStates::runOnFunction(BinaryFunction &BF) {
34+
bool PointerAuthCFIAnalyzer::runOnFunction(BinaryFunction &BF) {
3535

3636
BinaryContext &BC = BF.getBinaryContext();
3737

@@ -110,7 +110,7 @@ bool MarkRAStates::runOnFunction(BinaryFunction &BF) {
110110
return true;
111111
}
112112

113-
Error MarkRAStates::runOnFunctions(BinaryContext &BC) {
113+
Error PointerAuthCFIAnalyzer::runOnFunctions(BinaryContext &BC) {
114114
std::atomic<uint64_t> FunctionsIgnored{0};
115115
ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {
116116
if (!runOnFunction(BF)) {
@@ -132,8 +132,8 @@ Error MarkRAStates::runOnFunctions(BinaryContext &BC) {
132132

133133
ParallelUtilities::runOnEachFunction(
134134
BC, ParallelUtilities::SchedulingPolicy::SP_INST_LINEAR, WorkFun,
135-
SkipPredicate, "MarkRAStates");
136-
BC.outs() << "BOLT-INFO: MarkRAStates ran on " << Total
135+
SkipPredicate, "PointerAuthCFIAnalyzer");
136+
BC.outs() << "BOLT-INFO: PointerAuthCFIAnalyzer ran on " << Total
137137
<< " functions. Ignored " << FunctionsIgnored << " functions "
138138
<< format("(%.2lf%%)", (100.0 * FunctionsIgnored) / Total)
139139
<< " because of CFI inconsistencies\n";

0 commit comments

Comments
 (0)