@@ -376,9 +376,9 @@ class PacRetAnalysis
376376 }
377377};
378378
379- static std::shared_ptr<Report> tryCheckReturn ( const BinaryContext &BC,
380- const MCInstReference &Inst,
381- const State &S) {
379+ static std::shared_ptr<Report>
380+ shouldReportReturnGadget ( const BinaryContext &BC, const MCInstReference &Inst,
381+ const State &S) {
382382 static const GadgetKind RetKind (" non-protected ret found" );
383383 if (!BC.MIB ->isReturn (Inst))
384384 return nullptr ;
@@ -408,8 +408,8 @@ static std::shared_ptr<Report> tryCheckReturn(const BinaryContext &BC,
408408}
409409
410410FunctionAnalysisResult
411- Analysis::computeDfState (BinaryFunction &BF,
412- MCPlusBuilder::AllocatorIdTy AllocatorId) {
411+ Analysis::findGadgets (BinaryFunction &BF,
412+ MCPlusBuilder::AllocatorIdTy AllocatorId) {
413413 FunctionAnalysisResult Result;
414414
415415 PacRetAnalysis PRA (BF, AllocatorId, {});
@@ -425,40 +425,39 @@ Analysis::computeDfState(BinaryFunction &BF,
425425 MCInstReference Inst (&BB, I);
426426 const State &S = *PRA.getStateAt (Inst);
427427
428- if (auto Report = tryCheckReturn (BC, Inst, S))
428+ if (auto Report = shouldReportReturnGadget (BC, Inst, S))
429429 Result.Diagnostics .push_back (Report);
430430 }
431431 }
432+ return Result;
433+ }
432434
433- if (Result.Diagnostics .empty ())
434- return Result;
435-
436- // Redo the analysis, but now also track which instructions last wrote
437- // to any of the registers in RetRegsWithGadgets, so that better
438- // diagnostics can be produced.
435+ void Analysis::computeDetailedInfo (BinaryFunction &BF,
436+ MCPlusBuilder::AllocatorIdTy AllocatorId,
437+ FunctionAnalysisResult &Result) {
438+ BinaryContext &BC = BF.getBinaryContext ();
439439
440+ // Collect the affected registers across all gadgets found in this function.
440441 SmallSet<MCPhysReg, 4 > RegsToTrack;
441442 for (auto Report : Result.Diagnostics )
442- for (MCPhysReg Reg : Report->getAffectedRegisters ())
443- RegsToTrack.insert (Reg);
444-
443+ RegsToTrack.insert_range (Report->getAffectedRegisters ());
445444 std::vector<MCPhysReg> RegsToTrackVec (RegsToTrack.begin (), RegsToTrack.end ());
446445
446+ // Re-compute the analysis with register tracking.
447447 PacRetAnalysis PRWIA (BF, AllocatorId, RegsToTrackVec);
448448 PRWIA.run ();
449449 LLVM_DEBUG ({
450450 dbgs () << " After detailed PacRetAnalysis:\n " ;
451451 BF.dump ();
452452 });
453453
454+ // Augment gadget reports.
454455 for (auto Report : Result.Diagnostics ) {
455456 LLVM_DEBUG (
456457 { traceInst (BC, " Attaching clobbering info to" , Report->Location ); });
457458 Report->setOverwritingInstrs (PRWIA.getLastClobberingInsts (
458459 Report->Location , BF, Report->getAffectedRegisters ()));
459460 }
460-
461- return Result;
462461}
463462
464463void Analysis::runOnFunction (BinaryFunction &BF,
@@ -472,10 +471,16 @@ void Analysis::runOnFunction(BinaryFunction &BF,
472471 if (!BF.hasCFG ())
473472 return ;
474473
475- FunctionAnalysisResult FAR = computeDfState (BF, AllocatorId);
474+ FunctionAnalysisResult FAR = findGadgets (BF, AllocatorId);
476475 if (FAR.Diagnostics .empty ())
477476 return ;
478477
478+ // Redo the analysis, but now also track which instructions last wrote
479+ // to any of the registers in RetRegsWithGadgets, so that better
480+ // diagnostics can be produced.
481+
482+ computeDetailedInfo (BF, AllocatorId, FAR);
483+
479484 // `runOnFunction` is typically getting called from multiple threads in
480485 // parallel. Therefore, use a lock to avoid data races when storing the
481486 // result of the analysis in the `AnalysisResults` map.
@@ -540,7 +545,7 @@ void GadgetReport::generateReport(raw_ostream &OS,
540545 << " instructions that write to the affected registers after any "
541546 " authentication are:\n " ;
542547 // Sort by address to ensure output is deterministic.
543- std::vector <MCInstReference> OI = OverwritingInstrs;
548+ SmallVector <MCInstReference> OI = OverwritingInstrs;
544549 llvm::sort (OI, [](const MCInstReference &A, const MCInstReference &B) {
545550 return A.getAddress () < B.getAddress ();
546551 });
0 commit comments