Skip to content

Commit e8149e4

Browse files
committed
[BOLT] Change RAState helpers (NFCI)
- unify isRAStateSigned and isRAStateUnsigned to a common getRAState, - unify setRASigned and setRAUnsigned into setRAState(MCInst, bool), - update users of these to match the new implementations.
1 parent 96688d4 commit e8149e4

File tree

4 files changed

+46
-50
lines changed

4 files changed

+46
-50
lines changed

bolt/include/bolt/Core/MCPlusBuilder.h

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,20 +1361,13 @@ class MCPlusBuilder {
13611361
/// Return true if \p Inst has RestoreState annotation.
13621362
bool hasRestoreState(const MCInst &Inst) const;
13631363

1364-
/// Stores RA Signed annotation on \p Inst.
1365-
void setRASigned(MCInst &Inst) const;
1364+
/// Sets kRASigned or kRAUnsigned annotation on \p Inst.
1365+
/// Fails if \p Inst has either annotation already set.
1366+
void setRAState(MCInst &Inst, bool State) const;
13661367

1367-
/// Return true if \p Inst has Signed RA annotation.
1368-
bool isRASigned(const MCInst &Inst) const;
1369-
1370-
/// Stores RA Unsigned annotation on \p Inst.
1371-
void setRAUnsigned(MCInst &Inst) const;
1372-
1373-
/// Return true if \p Inst has Unsigned RA annotation.
1374-
bool isRAUnsigned(const MCInst &Inst) const;
1375-
1376-
/// Return true if \p Inst doesn't have any annotation related to RA state.
1377-
bool isRAStateUnknown(const MCInst &Inst) const;
1368+
/// Return true if \p Inst has kRASigned annotation, false if it has
1369+
/// kRAUnsigned annotation, and std::nullopt if neither annotation is set.
1370+
std::optional<bool> getRAState(const MCInst &Inst) const;
13781371

13791372
/// Return true if the instruction is a call with an exception handling info.
13801373
virtual bool isInvoke(const MCInst &Inst) const {

bolt/lib/Core/MCPlusBuilder.cpp

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -186,26 +186,21 @@ bool MCPlusBuilder::hasRestoreState(const MCInst &Inst) const {
186186
return hasAnnotation(Inst, MCAnnotation::kRestoreState);
187187
}
188188

189-
void MCPlusBuilder::setRASigned(MCInst &Inst) const {
189+
void MCPlusBuilder::setRAState(MCInst &Inst, bool State) const {
190190
assert(!hasAnnotation(Inst, MCAnnotation::kRASigned));
191-
setAnnotationOpValue(Inst, MCAnnotation::kRASigned, true);
192-
}
193-
194-
bool MCPlusBuilder::isRASigned(const MCInst &Inst) const {
195-
return hasAnnotation(Inst, MCAnnotation::kRASigned);
196-
}
197-
198-
void MCPlusBuilder::setRAUnsigned(MCInst &Inst) const {
199191
assert(!hasAnnotation(Inst, MCAnnotation::kRAUnsigned));
200-
setAnnotationOpValue(Inst, MCAnnotation::kRAUnsigned, true);
192+
if (State)
193+
setAnnotationOpValue(Inst, MCAnnotation::kRASigned, true);
194+
else
195+
setAnnotationOpValue(Inst, MCAnnotation::kRAUnsigned, true);
201196
}
202197

203-
bool MCPlusBuilder::isRAUnsigned(const MCInst &Inst) const {
204-
return hasAnnotation(Inst, MCAnnotation::kRAUnsigned);
205-
}
206-
207-
bool MCPlusBuilder::isRAStateUnknown(const MCInst &Inst) const {
208-
return !(isRAUnsigned(Inst) || isRASigned(Inst));
198+
std::optional<bool> MCPlusBuilder::getRAState(const MCInst &Inst) const {
199+
if (hasAnnotation(Inst, MCAnnotation::kRASigned))
200+
return true;
201+
if (hasAnnotation(Inst, MCAnnotation::kRAUnsigned))
202+
return false;
203+
return std::nullopt;
209204
}
210205

211206
std::optional<MCLandingPad> MCPlusBuilder::getEHInfo(const MCInst &Inst) const {

bolt/lib/Passes/InsertNegateRAStatePass.cpp

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,25 +40,30 @@ void InsertNegateRAState::runOnFunction(BinaryFunction &BF) {
4040
coverFunctionFragmentStart(BF, FF);
4141
bool FirstIter = true;
4242
MCInst PrevInst;
43+
bool PrevRAState = false;
4344
// As this pass runs after function splitting, we should only check
4445
// consecutive instructions inside FunctionFragments.
4546
for (BinaryBasicBlock *BB : FF) {
4647
for (auto It = BB->begin(); It != BB->end(); ++It) {
4748
MCInst &Inst = *It;
4849
if (BC.MIB->isCFI(Inst))
4950
continue;
51+
auto RAState = BC.MIB->getRAState(Inst);
52+
if (!RAState) {
53+
BC.errs() << "BOLT-ERROR: unknown RAState after inferUnknownStates "
54+
<< " in function " << BF.getPrintName() << "\n";
55+
}
5056
if (!FirstIter) {
5157
// Consecutive instructions with different RAState means we need to
5258
// add a OpNegateRAState.
53-
if ((BC.MIB->isRASigned(PrevInst) && BC.MIB->isRAUnsigned(Inst)) ||
54-
(BC.MIB->isRAUnsigned(PrevInst) && BC.MIB->isRASigned(Inst))) {
59+
if (*RAState != PrevRAState)
5560
It = BF.addCFIInstruction(
5661
BB, It, MCCFIInstruction::createNegateRAState(nullptr));
57-
}
5862
} else {
5963
FirstIter = false;
6064
}
6165
PrevInst = *It;
66+
PrevRAState = *RAState;
6267
}
6368
}
6469
}
@@ -81,10 +86,15 @@ void InsertNegateRAState::coverFunctionFragmentStart(BinaryFunction &BF,
8186
});
8287
// If a function is already split in the input, the first FF can also start
8388
// with Signed state. This covers that scenario as well.
84-
if (BC.MIB->isRASigned(*((*FirstNonEmpty)->begin()))) {
89+
auto RAState = BC.MIB->getRAState(*(*FirstNonEmpty)->begin());
90+
if (!RAState) {
91+
BC.errs() << "BOLT-ERROR: unknown RAState after inferUnknownStates "
92+
<< " in function " << BF.getPrintName() << "\n";
93+
return;
94+
}
95+
if (*RAState)
8596
BF.addCFIInstruction(*FirstNonEmpty, (*FirstNonEmpty)->begin(),
8697
MCCFIInstruction::createNegateRAState(nullptr));
87-
}
8898
}
8999

90100
void InsertNegateRAState::inferUnknownStates(BinaryFunction &BF) {
@@ -96,15 +106,21 @@ void InsertNegateRAState::inferUnknownStates(BinaryFunction &BF) {
96106
if (BC.MIB->isCFI(Inst))
97107
continue;
98108

99-
if (!FirstIter && BC.MIB->isRAStateUnknown(Inst)) {
100-
if (BC.MIB->isRASigned(PrevInst) || BC.MIB->isPSignOnLR(PrevInst)) {
101-
BC.MIB->setRASigned(Inst);
102-
} else if (BC.MIB->isRAUnsigned(PrevInst) ||
103-
BC.MIB->isPAuthOnLR(PrevInst)) {
104-
BC.MIB->setRAUnsigned(Inst);
109+
auto RAState = BC.MIB->getRAState(Inst);
110+
if (!FirstIter && !RAState) {
111+
if (BC.MIB->isPSignOnLR(PrevInst))
112+
RAState = true;
113+
else if (BC.MIB->isPAuthOnLR(PrevInst))
114+
RAState = false;
115+
else {
116+
auto PrevRAState = BC.MIB->getRAState(PrevInst);
117+
RAState = PrevRAState ? *PrevRAState : false;
105118
}
119+
BC.MIB->setRAState(Inst, *RAState);
106120
} else {
107121
FirstIter = false;
122+
if (!RAState)
123+
BC.MIB->setRAState(Inst, BF.getInitialRAState());
108124
}
109125
PrevInst = Inst;
110126
}

bolt/lib/Passes/MarkRAStates.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,6 @@ bool MarkRAStates::runOnFunction(BinaryFunction &BF) {
7070
BF.setIgnored();
7171
return false;
7272
}
73-
// The signing instruction itself is unsigned, the next will be
74-
// signed.
75-
BC.MIB->setRAUnsigned(Inst);
7673
} else if (BC.MIB->isPAuthOnLR(Inst)) {
7774
if (!RAState) {
7875
// RA authenticating instructions should only follow signed RA state.
@@ -83,15 +80,10 @@ bool MarkRAStates::runOnFunction(BinaryFunction &BF) {
8380
BF.setIgnored();
8481
return false;
8582
}
86-
// The authenticating instruction itself is signed, but the next will be
87-
// unsigned.
88-
BC.MIB->setRASigned(Inst);
89-
} else if (RAState) {
90-
BC.MIB->setRASigned(Inst);
91-
} else {
92-
BC.MIB->setRAUnsigned(Inst);
9383
}
9484

85+
BC.MIB->setRAState(Inst, RAState);
86+
9587
// Updating RAState. All updates are valid from the next instruction.
9688
// Because the same instruction can have remember and restore, the order
9789
// here is relevant. This is the reason to loop over Annotations instead

0 commit comments

Comments
 (0)