[llvm] 8521bd2 - [BOLT][AArch64] Handle PAuth call instructions in isIndirectCall (#133227)

via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 8 03:23:13 PDT 2025


Author: Anatoly Trosinenko
Date: 2025-04-08T13:23:10+03:00
New Revision: 8521bd2424bf144ce1d176a3c93d414c4c138104

URL: https://github.com/llvm/llvm-project/commit/8521bd2424bf144ce1d176a3c93d414c4c138104
DIFF: https://github.com/llvm/llvm-project/commit/8521bd2424bf144ce1d176a3c93d414c4c138104.diff

LOG: [BOLT][AArch64] Handle PAuth call instructions in isIndirectCall (#133227)

Handle `BLRA*` opcodes in AArch64MCPlusBuilder::isIndirectCall, update
getRegUsedAsCallDest accordingly.

Added: 
    

Modified: 
    bolt/include/bolt/Core/MCPlusBuilder.h
    bolt/lib/Passes/PAuthGadgetScanner.cpp
    bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
    llvm/lib/Target/AArch64/AArch64InstrInfo.h

Removed: 
    


################################################################################
diff  --git a/bolt/include/bolt/Core/MCPlusBuilder.h b/bolt/include/bolt/Core/MCPlusBuilder.h
index b5ad219cfc796..cf37a984da93f 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -577,12 +577,12 @@ class MCPlusBuilder {
     return getNoRegister();
   }
 
-  /// Returns the register used as call destination, or no-register, if not
-  /// an indirect call. Sets IsAuthenticatedInternally if the instruction
-  /// accepts a signed pointer as its operand and authenticates it internally.
+  /// Returns the register used as the destination of an indirect branch or call
+  /// instruction. Sets IsAuthenticatedInternally if the instruction accepts
+  /// a signed pointer as its operand and authenticates it internally.
   virtual MCPhysReg
-  getRegUsedAsCallDest(const MCInst &Inst,
-                       bool &IsAuthenticatedInternally) const {
+  getRegUsedAsIndirectBranchDest(const MCInst &Inst,
+                                 bool &IsAuthenticatedInternally) const {
     llvm_unreachable("not implemented");
     return getNoRegister();
   }

diff  --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index df9e87bd4e999..a7c22b23e4364 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -498,14 +498,16 @@ static std::shared_ptr<Report>
 shouldReportCallGadget(const BinaryContext &BC, const MCInstReference &Inst,
                        const State &S) {
   static const GadgetKind CallKind("non-protected call found");
-  if (!BC.MIB->isCall(Inst) && !BC.MIB->isBranch(Inst))
+  if (!BC.MIB->isIndirectCall(Inst) && !BC.MIB->isIndirectBranch(Inst))
     return nullptr;
 
   bool IsAuthenticated = false;
-  MCPhysReg DestReg = BC.MIB->getRegUsedAsCallDest(Inst, IsAuthenticated);
-  if (IsAuthenticated || DestReg == BC.MIB->getNoRegister())
+  MCPhysReg DestReg =
+      BC.MIB->getRegUsedAsIndirectBranchDest(Inst, IsAuthenticated);
+  if (IsAuthenticated)
     return nullptr;
 
+  assert(DestReg != BC.MIB->getNoRegister());
   LLVM_DEBUG({
     traceInst(BC, "Found call inst", Inst);
     traceReg(BC, "Call destination reg", DestReg);

diff  --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
index 0d1908f91e514..106f0a880d780 100644
--- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
+++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
@@ -10,6 +10,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "AArch64InstrInfo.h"
 #include "AArch64MCSymbolizer.h"
 #include "MCTargetDesc/AArch64AddressingModes.h"
 #include "MCTargetDesc/AArch64FixupKinds.h"
@@ -277,15 +278,14 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
     }
   }
 
-  MCPhysReg
-  getRegUsedAsCallDest(const MCInst &Inst,
-                       bool &IsAuthenticatedInternally) const override {
-    assert(isCall(Inst) || isBranch(Inst));
-    IsAuthenticatedInternally = false;
+  MCPhysReg getRegUsedAsIndirectBranchDest(
+      const MCInst &Inst, bool &IsAuthenticatedInternally) const override {
+    assert(isIndirectCall(Inst) || isIndirectBranch(Inst));
 
     switch (Inst.getOpcode()) {
     case AArch64::BR:
     case AArch64::BLR:
+      IsAuthenticatedInternally = false;
       return Inst.getOperand(0).getReg();
     case AArch64::BRAA:
     case AArch64::BRAB:
@@ -298,9 +298,7 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
       IsAuthenticatedInternally = true;
       return Inst.getOperand(0).getReg();
     default:
-      if (isIndirectCall(Inst) || isIndirectBranch(Inst))
-        llvm_unreachable("Unhandled indirect branch");
-      return getNoRegister();
+      llvm_unreachable("Unhandled indirect branch or call");
     }
   }
 
@@ -699,7 +697,7 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
   }
 
   bool isIndirectCall(const MCInst &Inst) const override {
-    return Inst.getOpcode() == AArch64::BLR;
+    return isIndirectCallOpcode(Inst.getOpcode());
   }
 
   MCPhysReg getSpRegister(int Size) const {

diff  --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.h b/llvm/lib/Target/AArch64/AArch64InstrInfo.h
index b3d3ec1455c8b..0ffaca9af4006 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.h
@@ -726,6 +726,19 @@ static inline bool isIndirectBranchOpcode(int Opc) {
   return false;
 }
 
+static inline bool isIndirectCallOpcode(unsigned Opc) {
+  switch (Opc) {
+  case AArch64::BLR:
+  case AArch64::BLRAA:
+  case AArch64::BLRAB:
+  case AArch64::BLRAAZ:
+  case AArch64::BLRABZ:
+    return true;
+  default:
+    return false;
+  }
+}
+
 static inline bool isPTrueOpcode(unsigned Opc) {
   switch (Opc) {
   case AArch64::PTRUE_B:


        


More information about the llvm-commits mailing list