[llvm] [BOLT][binary-analysis] Add initial pac-ret gadget scanner (PR #122304)

Anatoly Trosinenko via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 20 04:30:06 PST 2025


================
@@ -0,0 +1,543 @@
+//===- bolt/Passes/NonPacProtectedRetAnalysis.cpp -------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a pass that looks for any AArch64 return instructions
+// that may not be protected by PAuth authentication instructions when needed.
+//
+//===----------------------------------------------------------------------===//
+
+#include "bolt/Passes/NonPacProtectedRetAnalysis.h"
+#include "bolt/Core/ParallelUtilities.h"
+#include "bolt/Passes/DataflowAnalysis.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/Support/Format.h"
+#include <memory>
+
+#define DEBUG_TYPE "bolt-nonpacprotectedret"
+
+namespace llvm {
+namespace bolt {
+
+raw_ostream &operator<<(raw_ostream &OS, const MCInstInBBReference &Ref) {
+  OS << "MCInstBBRef<";
+  if (Ref.BB == nullptr)
+    OS << "BB:(null)";
+  else
+    OS << "BB:" << Ref.BB->getName() << ":" << Ref.BBIndex;
+  OS << ">";
+  return OS;
+}
+
+raw_ostream &operator<<(raw_ostream &OS, const MCInstInBFReference &Ref) {
+  OS << "MCInstBFRef<";
+  if (Ref.BF == nullptr)
+    OS << "BF:(null)";
+  else
+    OS << "BF:" << Ref.BF->getPrintName() << ":" << Ref.getOffset();
+  OS << ">";
+  return OS;
+}
+
+raw_ostream &operator<<(raw_ostream &OS, const MCInstReference &Ref) {
+  switch (Ref.ParentKind) {
+  case MCInstReference::BasicBlockParent:
+    OS << Ref.U.BBRef;
+    return OS;
+  case MCInstReference::FunctionParent:
+    OS << Ref.U.BFRef;
+    return OS;
+  }
+  llvm_unreachable("");
+}
+
+raw_ostream &operator<<(raw_ostream &OS, const GeneralDiagnostic &Diag) {
+  OS << "diag<'" << Diag.Text << "'>";
+  return OS;
+}
+
+namespace NonPacProtectedRetAnalysis {
+
+raw_ostream &operator<<(raw_ostream &OS, const Gadget &G) {
+  OS << "pac-ret<Ret:" << G.RetInst << ", ";
+  OS << "gadget<Overwriting:[";
+  for (auto Ref : G.OverwritingRetRegInst)
+    OS << Ref << " ";
+  OS << "]>>";
+  return OS;
+}
+
+raw_ostream &operator<<(raw_ostream &OS, const GenDiag &Diag) {
+  OS << "pac-ret<Ret:" << Diag.RetInst << ", " << Diag.Diag << ">";
+  return OS;
+}
+
+raw_ostream &operator<<(raw_ostream &OS, const Annotation &Diag) {
+  OS << "pac-ret<Ret:" << Diag.RetInst << ">";
+  return OS;
+}
+
+void Annotation::print(raw_ostream &OS) const { OS << *this; }
+void Gadget::print(raw_ostream &OS) const { OS << *this; }
+void GenDiag::print(raw_ostream &OS) const { OS << *this; }
----------------
atrosinenko wrote:

IIUC writing `Annotation` to stream via `<<` is non-polymorphic here (i.e. virtual `print(OS)` calls `operator<<(OS, Annotation)` and not vice versa). Is that intentional?

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


More information about the llvm-commits mailing list