[llvm] [BOLT] Gadget scanner: analyze functions without CFG information (PR #133461)

Kristof Beyls via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 7 05:32:36 PDT 2025


================
@@ -458,14 +448,141 @@ class PacRetAnalysis
     }
     std::vector<MCInstReference> Result;
     for (const MCInst *Inst : LastWritingInsts) {
-      MCInstInBBReference Ref = MCInstInBBReference::get(Inst, BF);
-      assert(Ref.BB != nullptr && "Expected Inst to be found");
+      MCInstReference Ref = MCInstReference::get(Inst, BF);
+      assert(Ref && "Expected Inst to be found");
       Result.push_back(MCInstReference(Ref));
     }
     return Result;
   }
 };
 
+class PacRetDFAnalysis
+    : public PacRetAnalysis,
+      public DataflowAnalysis<PacRetDFAnalysis, State, /*Backward=*/false,
+                              PacStatePrinter> {
+  using DFParent =
+      DataflowAnalysis<PacRetDFAnalysis, State, false, PacStatePrinter>;
+  friend DFParent;
+
+  using PacRetAnalysis::BC;
+  using PacRetAnalysis::computeNext;
+
+public:
+  PacRetDFAnalysis(BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocId,
+                   const std::vector<MCPhysReg> &RegsToTrackInstsFor)
+      : PacRetAnalysis(BF, RegsToTrackInstsFor), DFParent(BF, AllocId) {}
+
+  ErrorOr<const State &> getStateBefore(const MCInst &Inst) const override {
+    return DFParent::getStateBefore(Inst);
+  }
+
+  void run() override { DFParent::run(); }
+
+protected:
+  void preflight() {}
+
+  State getStartingStateAtBB(const BinaryBasicBlock &BB) {
+    if (BB.isEntryPoint())
+      return createEntryState();
+
+    return State();
+  }
+
+  State getStartingStateAtPoint(const MCInst &Point) { return State(); }
+
+  void doConfluence(State &StateOut, const State &StateIn) {
+    PacStatePrinter P(BC);
+    LLVM_DEBUG({
+      dbgs() << " PacRetAnalysis::Confluence(\n";
+      dbgs() << "   State 1: ";
+      P.print(dbgs(), StateOut);
+      dbgs() << "\n";
+      dbgs() << "   State 2: ";
+      P.print(dbgs(), StateIn);
+      dbgs() << ")\n";
+    });
+
+    StateOut.merge(StateIn);
+
+    LLVM_DEBUG({
+      dbgs() << "   merged state: ";
+      P.print(dbgs(), StateOut);
+      dbgs() << "\n";
+    });
+  }
+
+  StringRef getAnnotationName() const { return "PacRetAnalysis"; }
+};
+
+class NoCFGPacRetAnalysis : public PacRetAnalysis {
+  BinaryFunction &BF;
+  MCPlusBuilder::AllocatorIdTy AllocId;
+  unsigned StateAnnotationIndex;
+
+  void cleanStateAnnotations() {
+    for (auto &I : BF.instrs())
+      BC.MIB->removeAnnotation(I.second, StateAnnotationIndex);
+  }
+
+  /// Creates a State with all registers marked unsafe (not to be confused
+  /// with empty state).
+  State createUnsafeState() const {
+    return State(NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters());
+  }
+
+public:
+  NoCFGPacRetAnalysis(BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocId,
+                      const std::vector<MCPhysReg> &RegsToTrackInstsFor)
+      : PacRetAnalysis(BF, RegsToTrackInstsFor), BF(BF), AllocId(AllocId) {
+    StateAnnotationIndex =
+        BC.MIB->getOrCreateAnnotationIndex("NoCFGPacRetAnalysis");
+  }
+
+  void run() override {
+    State S = createEntryState();
+    for (auto &I : BF.instrs()) {
+      MCInst &Inst = I.second;
+
+      // If there is a label before this instruction, it is possible that it
+      // can be jumped-to, thus conservatively resetting S. As an exception,
+      // let's ignore any labels at the beginning of the function, as at least
+      // one label is expected there.
+      if (BF.hasLabelAt(I.first) && &Inst != &BF.instrs().begin()->second)
+        S = createUnsafeState();
+
+      // Check if we need to remove an old annotation (this is the case if
+      // this is the second, detailed, run of the analysis).
+      if (BC.MIB->hasAnnotation(Inst, StateAnnotationIndex))
+        BC.MIB->removeAnnotation(Inst, StateAnnotationIndex);
+      // Attach the state *before* this instruction.
----------------
kbeyls wrote:

Maybe "// Attach the state *before* this instruction executes."?

https://github.com/llvm/llvm-project/pull/133461


More information about the llvm-commits mailing list