Skip to content

Commit 054f614

Browse files
committed
[BOLT] Do run negate-ra-state rewriting passes on all functions
- if a BinaryFunction did not contain any .cfi_negate_ra_state, we can skip MarkRAStates and InsertNegateRAStatePass. This can happen with handwritten assembly, or if the binary was compiled in a way that drops DWARF tables.
1 parent 0c28761 commit 054f614

File tree

4 files changed

+21
-2
lines changed

4 files changed

+21
-2
lines changed

bolt/include/bolt/Core/BinaryFunction.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ class BinaryFunction {
148148
PF_MEMEVENT = 4, /// Profile has mem events.
149149
};
150150

151+
void setContainedNegateRAState() { HadNegateRAState = true; }
152+
bool containedNegateRAState() { return HadNegateRAState; }
151153
void setInitialRAState(bool State) { InitialRAState = State; }
152154
bool getInitialRAState() { return InitialRAState; }
153155

@@ -224,6 +226,10 @@ class BinaryFunction {
224226
/// Current state of the function.
225227
State CurrentState{State::Empty};
226228

229+
/// Indicates if the Function contained .cfi-negate-ra-state. These are not
230+
/// read from the binary. This boolean is used when deciding to run the
231+
/// .cfi-negate-ra-state rewriting passes on a function or not.
232+
bool HadNegateRAState{false};
227233
bool InitialRAState{false};
228234

229235
/// A list of symbols associated with the function entry point.

bolt/lib/Core/Exceptions.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,7 @@ bool CFIReaderWriter::fillCFIInfoFor(BinaryFunction &Function) const {
647647
// DW_CFA_GNU_window_save and DW_CFA_AARCH64_negate_ra_state just use the
648648
// same id but mean different things. The latter is used in AArch64.
649649
if (Function.getBinaryContext().isAArch64()) {
650+
Function.setContainedNegateRAState();
650651
// The location OpNegateRAState CFIs are needed
651652
// depends on the order of BasicBlocks, which changes during
652653
// optimizations. Instead of adding OpNegateRAState CFIs, an annotation

bolt/lib/Passes/InsertNegateRAStatePass.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,13 @@ void InsertNegateRAState::fixUnknownStates(BinaryFunction &BF) {
137137

138138
Error InsertNegateRAState::runOnFunctions(BinaryContext &BC) {
139139
ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {
140-
runOnFunction(BF);
140+
if (BF.containedNegateRAState()) {
141+
// We can skip functions which did not include negate-ra-state CFIs. This
142+
// includes code using pac-ret hardening as well, if the binary is
143+
// compiled with `-fno-exceptions -fno-unwind-tables
144+
// -fno-asynchronous-unwind-tables`
145+
runOnFunction(BF);
146+
}
141147
};
142148

143149
ParallelUtilities::runOnEachFunction(

bolt/lib/Passes/MarkRAStates.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,13 @@ void MarkRAStates::runOnFunction(BinaryFunction &BF) {
127127

128128
Error MarkRAStates::runOnFunctions(BinaryContext &BC) {
129129
ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {
130-
runOnFunction(BF);
130+
if (BF.containedNegateRAState()) {
131+
// We can skip functions which did not include negate-ra-state CFIs. This
132+
// includes code using pac-ret hardening as well, if the binary is
133+
// compiled with `-fno-exceptions -fno-unwind-tables
134+
// -fno-asynchronous-unwind-tables`
135+
runOnFunction(BF);
136+
}
131137
};
132138

133139
ParallelUtilities::runOnEachFunction(

0 commit comments

Comments
 (0)