Skip to content

Commit d9531c6

Browse files
committed
Rename classes, add an explanation
1 parent f39f21e commit d9531c6

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
@@ -198,23 +198,48 @@ raw_ostream &operator<<(raw_ostream &OS, const MCInstReference &);
198198

199199
namespace PAuthGadgetScanner {
200200

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

206229
public:
230+
/// Wraps a description string which must be a string literal.
207231
GadgetKind(const char *Description) : Description(Description) {}
208232

209233
StringRef getDescription() const { return Description; }
210234
};
211235

212-
/// Base report located at some instruction, without any additional information.
213-
struct Report {
236+
/// Basic diagnostic information, which is kept unchanged since it is collected
237+
/// on the first run of the analysis.
238+
struct Diagnostic {
214239
MCInstReference Location;
215240

216-
Report(MCInstReference Location) : Location(Location) {}
217-
virtual ~Report() {}
241+
Diagnostic(MCInstReference Location) : Location(Location) {}
242+
virtual ~Diagnostic() {}
218243

219244
virtual void generateReport(raw_ostream &OS,
220245
const BinaryContext &BC) const = 0;
@@ -223,27 +248,27 @@ struct Report {
223248
StringRef IssueKind) const;
224249
};
225250

226-
struct GadgetReport : public Report {
251+
struct GadgetDiagnostic : public Diagnostic {
227252
// The particular kind of gadget that is detected.
228253
const GadgetKind &Kind;
229254

230-
GadgetReport(const GadgetKind &Kind, MCInstReference Location)
231-
: Report(Location), Kind(Kind) {}
255+
GadgetDiagnostic(const GadgetKind &Kind, MCInstReference Location)
256+
: Diagnostic(Location), Kind(Kind) {}
232257

233258
void generateReport(raw_ostream &OS, const BinaryContext &BC) const override;
234259
};
235260

236261
/// Report with a free-form message attached.
237-
struct GenericReport : public Report {
262+
struct GenericDiagnostic : public Diagnostic {
238263
std::string Text;
239-
GenericReport(MCInstReference Location, StringRef Text)
240-
: Report(Location), Text(Text) {}
264+
GenericDiagnostic(MCInstReference Location, StringRef Text)
265+
: Diagnostic(Location), Text(Text) {}
241266
virtual void generateReport(raw_ostream &OS,
242267
const BinaryContext &BC) const override;
243268
};
244269

245270
/// An information about an issue collected on the slower, detailed,
246-
/// run of an analysis.
271+
/// run of the analysis.
247272
class ExtraInfo {
248273
public:
249274
virtual void print(raw_ostream &OS, const MCInstReference Location) const = 0;
@@ -262,35 +287,34 @@ class ClobberingInfo : public ExtraInfo {
262287

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

274-
std::shared_ptr<Report> Issue;
298+
std::shared_ptr<Diagnostic> Issue;
275299
std::optional<T> RequestedDetails;
276300
};
277301

278-
/// A detailed version of a report.
279-
struct DetailedReport {
280-
DetailedReport(std::shared_ptr<Report> Issue,
281-
std::shared_ptr<ExtraInfo> Details)
302+
/// A final version of the report.
303+
struct FinalReport {
304+
FinalReport(std::shared_ptr<Diagnostic> Issue,
305+
std::shared_ptr<ExtraInfo> Details)
282306
: Issue(Issue), Details(Details) {}
283307

284-
std::shared_ptr<Report> Issue;
308+
std::shared_ptr<Diagnostic> Issue;
285309
std::shared_ptr<ExtraInfo> Details;
286310
};
287311

288312
struct FunctionAnalysisResult {
289-
std::vector<DetailedReport> Diagnostics;
313+
std::vector<FinalReport> Diagnostics;
290314
};
291315

292316
/// A helper class storing per-function context to be instantiated by Analysis.
293-
class FunctionAnalysis {
317+
class FunctionAnalysisContext {
294318
BinaryContext &BC;
295319
BinaryFunction &BF;
296320
MCPlusBuilder::AllocatorIdTy AllocatorId;
@@ -306,8 +330,9 @@ class FunctionAnalysis {
306330
void handleSimpleReports(SmallVector<BriefReport<MCPhysReg>> &Reports);
307331

308332
public:
309-
FunctionAnalysis(BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocatorId,
310-
bool PacRetGadgetsOnly)
333+
FunctionAnalysisContext(BinaryFunction &BF,
334+
MCPlusBuilder::AllocatorIdTy AllocatorId,
335+
bool PacRetGadgetsOnly)
311336
: BC(BF.getBinaryContext()), BF(BF), AllocatorId(AllocatorId),
312337
PacRetGadgetsOnly(PacRetGadgetsOnly) {}
313338

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)