Skip to content

Commit 53ab95c

Browse files
committed
Rename classes, add an explanation
1 parent bb7858a commit 53ab95c

File tree

2 files changed

+66
-41
lines changed

2 files changed

+66
-41
lines changed

bolt/include/bolt/Passes/PAuthGadgetScanner.h

Lines changed: 52 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -196,23 +196,48 @@ raw_ostream &operator<<(raw_ostream &OS, const MCInstReference &);
196196

197197
namespace PAuthGadgetScanner {
198198

199+
// The report classes are designed to be used in an immutable manner.
200+
// When an issue report is constructed in multiple steps, an attempt is made
201+
// to distinguish intermediate and final results at the type level.
202+
//
203+
// Here is an overview of issue life-cycle:
204+
// * an analysis (SrcSafetyAnalysis at now, DstSafetyAnalysis will be added
205+
// later to support the detection of authentication oracles) computes register
206+
// state for each instruction in the function.
207+
// * each instruction is checked to be a gadget of some kind, taking the
208+
// computed state into account. If a gadget is found, its kind and location
209+
// are stored into a subclass of Diagnostic wrapped into BriefReport<ReqT>.
210+
// * if any issue is to be reported for the function, the same analysis is
211+
// re-run to collect extra information to provide to the user. Which extra
212+
// information can be requested depends on the particular analysis (for
213+
// example, SrcSafetyAnalysis is able to compute the set of instructions
214+
// clobbering the particular register, thus ReqT is MCPhysReg). At this stage,
215+
// `FinalReport`s are created.
216+
//
217+
// Here, the subclasses of Diagnostic store the pieces of information which
218+
// are kept unchanged since they are collected on the first run of the analysis.
219+
// BriefReport<T>::RequestedDetails, on the other hand, is replaced with
220+
// FinalReport::Details computed by the second run of the analysis.
221+
199222
/// Description of a gadget kind that can be detected. Intended to be
200-
/// statically allocated to be attached to reports by reference.
223+
/// statically allocated and attached to reports by reference.
201224
class GadgetKind {
202225
const char *Description;
203226

204227
public:
228+
/// Wraps a description string which must be a string literal.
205229
GadgetKind(const char *Description) : Description(Description) {}
206230

207231
StringRef getDescription() const { return Description; }
208232
};
209233

210-
/// Base report located at some instruction, without any additional information.
211-
struct Report {
234+
/// Basic diagnostic information, which is kept unchanged since it is collected
235+
/// on the first run of the analysis.
236+
struct Diagnostic {
212237
MCInstReference Location;
213238

214-
Report(MCInstReference Location) : Location(Location) {}
215-
virtual ~Report() {}
239+
Diagnostic(MCInstReference Location) : Location(Location) {}
240+
virtual ~Diagnostic() {}
216241

217242
virtual void generateReport(raw_ostream &OS,
218243
const BinaryContext &BC) const = 0;
@@ -221,27 +246,27 @@ struct Report {
221246
StringRef IssueKind) const;
222247
};
223248

224-
struct GadgetReport : public Report {
249+
struct GadgetDiagnostic : public Diagnostic {
225250
// The particular kind of gadget that is detected.
226251
const GadgetKind &Kind;
227252

228-
GadgetReport(const GadgetKind &Kind, MCInstReference Location)
229-
: Report(Location), Kind(Kind) {}
253+
GadgetDiagnostic(const GadgetKind &Kind, MCInstReference Location)
254+
: Diagnostic(Location), Kind(Kind) {}
230255

231256
void generateReport(raw_ostream &OS, const BinaryContext &BC) const override;
232257
};
233258

234259
/// Report with a free-form message attached.
235-
struct GenericReport : public Report {
260+
struct GenericDiagnostic : public Diagnostic {
236261
std::string Text;
237-
GenericReport(MCInstReference Location, StringRef Text)
238-
: Report(Location), Text(Text) {}
262+
GenericDiagnostic(MCInstReference Location, StringRef Text)
263+
: Diagnostic(Location), Text(Text) {}
239264
virtual void generateReport(raw_ostream &OS,
240265
const BinaryContext &BC) const override;
241266
};
242267

243268
/// An information about an issue collected on the slower, detailed,
244-
/// run of an analysis.
269+
/// run of the analysis.
245270
class ExtraInfo {
246271
public:
247272
virtual void print(raw_ostream &OS, const MCInstReference Location) const = 0;
@@ -260,35 +285,34 @@ class ClobberingInfo : public ExtraInfo {
260285

261286
/// A brief version of a report that can be further augmented with the details.
262287
///
263-
/// It is common for a particular type of gadget detector to be tied to some
264-
/// specific kind of analysis. If an issue is returned by that detector, it may
265-
/// be further augmented with the detailed info in an analysis-specific way,
266-
/// or just be left as-is (f.e. if a free-form warning was reported).
288+
/// A half-baked report produced on the first run of the analysis. An extra,
289+
/// analysis-specific information may be requested to be collected on the
290+
/// second run.
267291
template <typename T> struct BriefReport {
268-
BriefReport(std::shared_ptr<Report> Issue,
292+
BriefReport(std::shared_ptr<Diagnostic> Issue,
269293
const std::optional<T> RequestedDetails)
270294
: Issue(Issue), RequestedDetails(RequestedDetails) {}
271295

272-
std::shared_ptr<Report> Issue;
296+
std::shared_ptr<Diagnostic> Issue;
273297
std::optional<T> RequestedDetails;
274298
};
275299

276-
/// A detailed version of a report.
277-
struct DetailedReport {
278-
DetailedReport(std::shared_ptr<Report> Issue,
279-
std::shared_ptr<ExtraInfo> Details)
300+
/// A final version of the report.
301+
struct FinalReport {
302+
FinalReport(std::shared_ptr<Diagnostic> Issue,
303+
std::shared_ptr<ExtraInfo> Details)
280304
: Issue(Issue), Details(Details) {}
281305

282-
std::shared_ptr<Report> Issue;
306+
std::shared_ptr<Diagnostic> Issue;
283307
std::shared_ptr<ExtraInfo> Details;
284308
};
285309

286310
struct FunctionAnalysisResult {
287-
std::vector<DetailedReport> Diagnostics;
311+
std::vector<FinalReport> Diagnostics;
288312
};
289313

290314
/// A helper class storing per-function context to be instantiated by Analysis.
291-
class FunctionAnalysis {
315+
class FunctionAnalysisContext {
292316
BinaryContext &BC;
293317
BinaryFunction &BF;
294318
MCPlusBuilder::AllocatorIdTy AllocatorId;
@@ -304,8 +328,9 @@ class FunctionAnalysis {
304328
void handleSimpleReports(SmallVector<BriefReport<MCPhysReg>> &Reports);
305329

306330
public:
307-
FunctionAnalysis(BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocatorId,
308-
bool PacRetGadgetsOnly)
331+
FunctionAnalysisContext(BinaryFunction &BF,
332+
MCPlusBuilder::AllocatorIdTy AllocatorId,
333+
bool PacRetGadgetsOnly)
309334
: BC(BF.getBinaryContext()), BF(BF), AllocatorId(AllocatorId),
310335
PacRetGadgetsOnly(PacRetGadgetsOnly) {}
311336

bolt/lib/Passes/PAuthGadgetScanner.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -715,15 +715,15 @@ SrcSafetyAnalysis::create(BinaryFunction &BF,
715715

716716
static BriefReport<MCPhysReg> make_generic_report(MCInstReference Location,
717717
StringRef Text) {
718-
auto Report = std::make_shared<GenericReport>(Location, Text);
718+
auto Report = std::make_shared<GenericDiagnostic>(Location, Text);
719719
return BriefReport<MCPhysReg>(Report, std::nullopt);
720720
}
721721

722722
template <typename T>
723723
static BriefReport<T> make_report(const GadgetKind &Kind,
724724
MCInstReference Location,
725725
T RequestedDetails) {
726-
auto Report = std::make_shared<GadgetReport>(Kind, Location);
726+
auto Report = std::make_shared<GadgetDiagnostic>(Kind, Location);
727727
return BriefReport<T>(Report, RequestedDetails);
728728
}
729729

@@ -821,7 +821,7 @@ collectRegsToTrack(ArrayRef<BriefReport<MCPhysReg>> Reports) {
821821
return SmallVector<MCPhysReg>(RegsToTrack.begin(), RegsToTrack.end());
822822
}
823823

824-
void FunctionAnalysis::findUnsafeUses(
824+
void FunctionAnalysisContext::findUnsafeUses(
825825
SmallVector<BriefReport<MCPhysReg>> &Reports) {
826826
auto Analysis = SrcSafetyAnalysis::create(BF, AllocatorId, {});
827827
LLVM_DEBUG({ dbgs() << "Running src register safety analysis...\n"; });
@@ -855,7 +855,7 @@ void FunctionAnalysis::findUnsafeUses(
855855
});
856856
}
857857

858-
void FunctionAnalysis::augmentUnsafeUseReports(
858+
void FunctionAnalysisContext::augmentUnsafeUseReports(
859859
ArrayRef<BriefReport<MCPhysReg>> Reports) {
860860
SmallVector<MCPhysReg> RegsToTrack = collectRegsToTrack(Reports);
861861
// Re-compute the analysis with register tracking.
@@ -881,7 +881,7 @@ void FunctionAnalysis::augmentUnsafeUseReports(
881881
}
882882
}
883883

884-
void FunctionAnalysis::handleSimpleReports(
884+
void FunctionAnalysisContext::handleSimpleReports(
885885
SmallVector<BriefReport<MCPhysReg>> &Reports) {
886886
// Before re-running the detailed analysis, process the reports which do not
887887
// need any additional details to be attached.
@@ -892,7 +892,7 @@ void FunctionAnalysis::handleSimpleReports(
892892
llvm::erase_if(Reports, [](const auto &R) { return !R.RequestedDetails; });
893893
}
894894

895-
void FunctionAnalysis::run() {
895+
void FunctionAnalysisContext::run() {
896896
LLVM_DEBUG({
897897
dbgs() << "Analyzing function " << BF.getPrintName()
898898
<< ", AllocatorId = " << AllocatorId << "\n";
@@ -908,7 +908,7 @@ void FunctionAnalysis::run() {
908908

909909
void Analysis::runOnFunction(BinaryFunction &BF,
910910
MCPlusBuilder::AllocatorIdTy AllocatorId) {
911-
FunctionAnalysis FA(BF, AllocatorId, PacRetGadgetsOnly);
911+
FunctionAnalysisContext FA(BF, AllocatorId, PacRetGadgetsOnly);
912912
FA.run();
913913

914914
const FunctionAnalysisResult &FAR = FA.getResult();
@@ -954,8 +954,8 @@ static void reportFoundGadgetInSingleBBSingleRelatedInst(
954954
}
955955
}
956956

957-
void Report::printBasicInfo(raw_ostream &OS, const BinaryContext &BC,
958-
StringRef IssueKind) const {
957+
void Diagnostic::printBasicInfo(raw_ostream &OS, const BinaryContext &BC,
958+
StringRef IssueKind) const {
959959
BinaryFunction *BF = Location.getFunction();
960960
BinaryBasicBlock *BB = Location.getBasicBlock();
961961

@@ -968,8 +968,8 @@ void Report::printBasicInfo(raw_ostream &OS, const BinaryContext &BC,
968968
BC.printInstruction(OS, Location, Location.getAddress(), BF);
969969
}
970970

971-
void GadgetReport::generateReport(raw_ostream &OS,
972-
const BinaryContext &BC) const {
971+
void GadgetDiagnostic::generateReport(raw_ostream &OS,
972+
const BinaryContext &BC) const {
973973
printBasicInfo(OS, BC, Kind.getDescription());
974974
}
975975

@@ -1007,8 +1007,8 @@ void ClobberingInfo::print(raw_ostream &OS,
10071007
printRelatedInstrs(OS, Location, ClobberingInstrs);
10081008
}
10091009

1010-
void GenericReport::generateReport(raw_ostream &OS,
1011-
const BinaryContext &BC) const {
1010+
void GenericDiagnostic::generateReport(raw_ostream &OS,
1011+
const BinaryContext &BC) const {
10121012
printBasicInfo(OS, BC, Text);
10131013
}
10141014

@@ -1029,7 +1029,7 @@ Error Analysis::runOnFunctions(BinaryContext &BC) {
10291029
for (BinaryFunction *BF : BC.getAllBinaryFunctions()) {
10301030
if (!AnalysisResults.count(BF))
10311031
continue;
1032-
for (const DetailedReport &R : AnalysisResults[BF].Diagnostics) {
1032+
for (const FinalReport &R : AnalysisResults[BF].Diagnostics) {
10331033
R.Issue->generateReport(outs(), BC);
10341034
if (R.Details)
10351035
R.Details->print(outs(), R.Issue->Location);

0 commit comments

Comments
 (0)