Skip to content

Commit 19f983e

Browse files
committed
Factor out CFGUnawareAnalysis & trivial simplifications
1 parent 47e619b commit 19f983e

File tree

1 file changed

+54
-44
lines changed

1 file changed

+54
-44
lines changed

bolt/lib/Passes/PAuthGadgetScanner.cpp

Lines changed: 54 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ static void printInstsShort(raw_ostream &OS,
242242
}
243243
}
244244

245-
raw_ostream &operator<<(raw_ostream &OS, const SrcState &S) {
245+
static raw_ostream &operator<<(raw_ostream &OS, const SrcState &S) {
246246
OS << "src-state<";
247247
if (S.empty()) {
248248
OS << "empty";
@@ -432,8 +432,7 @@ class SrcSafetyAnalysis {
432432
SrcStatePrinter P(BC);
433433
LLVM_DEBUG({
434434
dbgs() << " SrcSafetyAnalysis::ComputeNext(";
435-
BC.InstPrinter->printInst(&const_cast<MCInst &>(Point), 0, "", *BC.STI,
436-
dbgs());
435+
BC.InstPrinter->printInst(&Point, 0, "", *BC.STI, dbgs());
437436
dbgs() << ", ";
438437
P.print(dbgs(), Cur);
439438
dbgs() << ")\n";
@@ -611,6 +610,42 @@ class DataflowSrcSafetyAnalysis
611610
StringRef getAnnotationName() const { return "DataflowSrcSafetyAnalysis"; }
612611
};
613612

613+
/// A helper base class for implementing a simplified counterpart of a dataflow
614+
/// analysis for functions without CFG information.
615+
template <typename StateTy> class CFGUnawareAnalysis {
616+
BinaryContext &BC;
617+
BinaryFunction &BF;
618+
MCPlusBuilder::AllocatorIdTy AllocId;
619+
unsigned StateAnnotationIndex;
620+
621+
void cleanStateAnnotations() {
622+
for (auto &I : BF.instrs())
623+
BC.MIB->removeAnnotation(I.second, StateAnnotationIndex);
624+
}
625+
626+
protected:
627+
CFGUnawareAnalysis(BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocId,
628+
StringRef AnnotationName)
629+
: BC(BF.getBinaryContext()), BF(BF), AllocId(AllocId) {
630+
StateAnnotationIndex = BC.MIB->getOrCreateAnnotationIndex(AnnotationName);
631+
}
632+
633+
void setState(MCInst &Inst, const StateTy &S) {
634+
// Check if we need to remove an old annotation (this is the case if
635+
// this is the second, detailed run of the analysis).
636+
if (BC.MIB->hasAnnotation(Inst, StateAnnotationIndex))
637+
BC.MIB->removeAnnotation(Inst, StateAnnotationIndex);
638+
// Attach the state.
639+
BC.MIB->addAnnotation(Inst, StateAnnotationIndex, S, AllocId);
640+
}
641+
642+
const StateTy &getState(const MCInst &Inst) const {
643+
return BC.MIB->getAnnotationAs<StateTy>(Inst, StateAnnotationIndex);
644+
}
645+
646+
~CFGUnawareAnalysis() { cleanStateAnnotations(); }
647+
};
648+
614649
// A simplified implementation of DataflowSrcSafetyAnalysis for functions
615650
// lacking CFG information.
616651
//
@@ -645,15 +680,10 @@ class DataflowSrcSafetyAnalysis
645680
// of instructions without labels in between. These sequences can be processed
646681
// the same way basic blocks are processed by data-flow analysis, assuming
647682
// pessimistically that all registers are unsafe at the start of each sequence.
648-
class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis {
683+
class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis,
684+
public CFGUnawareAnalysis<SrcState> {
685+
using SrcSafetyAnalysis::BC;
649686
BinaryFunction &BF;
650-
MCPlusBuilder::AllocatorIdTy AllocId;
651-
unsigned StateAnnotationIndex;
652-
653-
void cleanStateAnnotations() {
654-
for (auto &I : BF.instrs())
655-
BC.MIB->removeAnnotation(I.second, StateAnnotationIndex);
656-
}
657687

658688
/// Creates a state with all registers marked unsafe (not to be confused
659689
/// with empty state).
@@ -665,9 +695,8 @@ class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis {
665695
CFGUnawareSrcSafetyAnalysis(BinaryFunction &BF,
666696
MCPlusBuilder::AllocatorIdTy AllocId,
667697
ArrayRef<MCPhysReg> RegsToTrackInstsFor)
668-
: SrcSafetyAnalysis(BF, RegsToTrackInstsFor), BF(BF), AllocId(AllocId) {
669-
StateAnnotationIndex =
670-
BC.MIB->getOrCreateAnnotationIndex("CFGUnawareSrcSafetyAnalysis");
698+
: SrcSafetyAnalysis(BF, RegsToTrackInstsFor),
699+
CFGUnawareAnalysis(BF, AllocId, "CFGUnawareSrcSafetyAnalysis"), BF(BF) {
671700
}
672701

673702
void run() override {
@@ -686,23 +715,17 @@ class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis {
686715
S = createUnsafeState();
687716
}
688717

689-
// Check if we need to remove an old annotation (this is the case if
690-
// this is the second, detailed, run of the analysis).
691-
if (BC.MIB->hasAnnotation(Inst, StateAnnotationIndex))
692-
BC.MIB->removeAnnotation(Inst, StateAnnotationIndex);
693718
// Attach the state *before* this instruction executes.
694-
BC.MIB->addAnnotation(Inst, StateAnnotationIndex, S, AllocId);
719+
setState(Inst, S);
695720

696721
// Compute the state after this instruction executes.
697722
S = computeNext(Inst, S);
698723
}
699724
}
700725

701726
const SrcState &getStateBefore(const MCInst &Inst) const override {
702-
return BC.MIB->getAnnotationAs<SrcState>(Inst, StateAnnotationIndex);
727+
return getState(Inst);
703728
}
704-
705-
~CFGUnawareSrcSafetyAnalysis() { cleanStateAnnotations(); }
706729
};
707730

708731
std::shared_ptr<SrcSafetyAnalysis>
@@ -786,7 +809,7 @@ struct DstState {
786809
bool operator!=(const DstState &RHS) const { return !((*this) == RHS); }
787810
};
788811

789-
raw_ostream &operator<<(raw_ostream &OS, const DstState &S) {
812+
static raw_ostream &operator<<(raw_ostream &OS, const DstState &S) {
790813
OS << "dst-state<";
791814
if (S.empty()) {
792815
OS << "empty";
@@ -962,8 +985,7 @@ class DstSafetyAnalysis {
962985
DstStatePrinter P(BC);
963986
LLVM_DEBUG({
964987
dbgs() << " DstSafetyAnalysis::ComputeNext(";
965-
BC.InstPrinter->printInst(&const_cast<MCInst &>(Point), 0, "", *BC.STI,
966-
dbgs());
988+
BC.InstPrinter->printInst(&Point, 0, "", *BC.STI, dbgs());
967989
dbgs() << ", ";
968990
P.print(dbgs(), Cur);
969991
dbgs() << ")\n";
@@ -1108,15 +1130,10 @@ class DataflowDstSafetyAnalysis
11081130
StringRef getAnnotationName() const { return "DataflowDstSafetyAnalysis"; }
11091131
};
11101132

1111-
class CFGUnawareDstSafetyAnalysis : public DstSafetyAnalysis {
1133+
class CFGUnawareDstSafetyAnalysis : public DstSafetyAnalysis,
1134+
public CFGUnawareAnalysis<DstState> {
1135+
using DstSafetyAnalysis::BC;
11121136
BinaryFunction &BF;
1113-
MCPlusBuilder::AllocatorIdTy AllocId;
1114-
unsigned StateAnnotationIndex;
1115-
1116-
void cleanStateAnnotations() {
1117-
for (auto &I : BF.instrs())
1118-
BC.MIB->removeAnnotation(I.second, StateAnnotationIndex);
1119-
}
11201137

11211138
DstState createUnsafeState() const {
11221139
return DstState(NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters());
@@ -1126,9 +1143,8 @@ class CFGUnawareDstSafetyAnalysis : public DstSafetyAnalysis {
11261143
CFGUnawareDstSafetyAnalysis(BinaryFunction &BF,
11271144
MCPlusBuilder::AllocatorIdTy AllocId,
11281145
ArrayRef<MCPhysReg> RegsToTrackInstsFor)
1129-
: DstSafetyAnalysis(BF, RegsToTrackInstsFor), BF(BF), AllocId(AllocId) {
1130-
StateAnnotationIndex =
1131-
BC.MIB->getOrCreateAnnotationIndex("CFGUnawareDstSafetyAnalysis");
1146+
: DstSafetyAnalysis(BF, RegsToTrackInstsFor),
1147+
CFGUnawareAnalysis(BF, AllocId, "CFGUnawareDstSafetyAnalysis"), BF(BF) {
11321148
}
11331149

11341150
void run() override {
@@ -1146,23 +1162,17 @@ class CFGUnawareDstSafetyAnalysis : public DstSafetyAnalysis {
11461162
S = createUnsafeState();
11471163
}
11481164

1149-
// Check if we need to remove an old annotation (this is the case if
1150-
// this is the second, detailed, run of the analysis).
1151-
if (BC.MIB->hasAnnotation(Inst, StateAnnotationIndex))
1152-
BC.MIB->removeAnnotation(Inst, StateAnnotationIndex);
11531165
// Attach the state *after* this instruction executes.
1154-
BC.MIB->addAnnotation(Inst, StateAnnotationIndex, S, AllocId);
1166+
setState(Inst, S);
11551167

11561168
// Compute the next state.
11571169
S = computeNext(Inst, S);
11581170
}
11591171
}
11601172

11611173
const DstState &getStateAfter(const MCInst &Inst) const override {
1162-
return BC.MIB->getAnnotationAs<DstState>(Inst, StateAnnotationIndex);
1174+
return getState(Inst);
11631175
}
1164-
1165-
~CFGUnawareDstSafetyAnalysis() { cleanStateAnnotations(); }
11661176
};
11671177

11681178
std::shared_ptr<DstSafetyAnalysis>

0 commit comments

Comments
 (0)