@@ -66,14 +66,12 @@ namespace PAuthGadgetScanner {
6666}
6767
6868[[maybe_unused]] static void traceReg (const BinaryContext &BC, StringRef Label,
69- ErrorOr< MCPhysReg> Reg) {
69+ MCPhysReg Reg) {
7070 dbgs () << " " << Label << " : " ;
71- if (Reg.getError ())
72- dbgs () << " (error)" ;
73- else if (*Reg == BC.MIB ->getNoRegister ())
71+ if (Reg == BC.MIB ->getNoRegister ())
7472 dbgs () << " (none)" ;
7573 else
76- dbgs () << BC.MRI ->getName (* Reg);
74+ dbgs () << BC.MRI ->getName (Reg);
7775 dbgs () << " \n " ;
7876}
7977
@@ -365,17 +363,15 @@ class SrcSafetyAnalysis {
365363 SmallVector<MCPhysReg> getRegsMadeSafeToDeref (const MCInst &Point,
366364 const SrcState &Cur) const {
367365 SmallVector<MCPhysReg> Regs;
368- const MCPhysReg NoReg = BC.MIB ->getNoRegister ();
369366
370367 // A signed pointer can be authenticated, or
371- ErrorOr<MCPhysReg> AutReg = BC. MIB -> getAuthenticatedReg (Point) ;
372- if (AutReg && * AutReg != NoReg )
368+ bool Dummy = false ;
369+ if (auto AutReg = BC. MIB -> getWrittenAuthenticatedReg (Point, Dummy) )
373370 Regs.push_back (*AutReg);
374371
375372 // ... a safe address can be materialized, or
376- MCPhysReg NewAddrReg = BC.MIB ->getMaterializedAddressRegForPtrAuth (Point);
377- if (NewAddrReg != NoReg)
378- Regs.push_back (NewAddrReg);
373+ if (auto NewAddrReg = BC.MIB ->getMaterializedAddressRegForPtrAuth (Point))
374+ Regs.push_back (*NewAddrReg);
379375
380376 // ... an address can be updated in a safe manner, producing the result
381377 // which is as trusted as the input address.
@@ -391,13 +387,20 @@ class SrcSafetyAnalysis {
391387 SmallVector<MCPhysReg> getRegsMadeTrusted (const MCInst &Point,
392388 const SrcState &Cur) const {
393389 SmallVector<MCPhysReg> Regs;
394- const MCPhysReg NoReg = BC.MIB ->getNoRegister ();
395390
396391 // An authenticated pointer can be checked, or
397- MCPhysReg CheckedReg =
392+ std::optional< MCPhysReg> CheckedReg =
398393 BC.MIB ->getAuthCheckedReg (Point, /* MayOverwrite=*/ false );
399- if (CheckedReg != NoReg && Cur.SafeToDerefRegs [CheckedReg])
400- Regs.push_back (CheckedReg);
394+ if (CheckedReg && Cur.SafeToDerefRegs [*CheckedReg])
395+ Regs.push_back (*CheckedReg);
396+
397+ // ... a pointer can be authenticated by an instruction that always checks
398+ // the pointer, or
399+ bool IsChecked = false ;
400+ std::optional<MCPhysReg> AutReg =
401+ BC.MIB ->getWrittenAuthenticatedReg (Point, IsChecked);
402+ if (AutReg && IsChecked)
403+ Regs.push_back (*AutReg);
401404
402405 if (CheckerSequenceInfo.contains (&Point)) {
403406 MCPhysReg CheckedReg;
@@ -413,9 +416,8 @@ class SrcSafetyAnalysis {
413416 }
414417
415418 // ... a safe address can be materialized, or
416- MCPhysReg NewAddrReg = BC.MIB ->getMaterializedAddressRegForPtrAuth (Point);
417- if (NewAddrReg != NoReg)
418- Regs.push_back (NewAddrReg);
419+ if (auto NewAddrReg = BC.MIB ->getMaterializedAddressRegForPtrAuth (Point))
420+ Regs.push_back (*NewAddrReg);
419421
420422 // ... an address can be updated in a safe manner, producing the result
421423 // which is as trusted as the input address.
@@ -738,25 +740,27 @@ shouldReportReturnGadget(const BinaryContext &BC, const MCInstReference &Inst,
738740 if (!BC.MIB ->isReturn (Inst))
739741 return std::nullopt ;
740742
741- ErrorOr<MCPhysReg> MaybeRetReg = BC.MIB ->getRegUsedAsRetDest (Inst);
742- if (MaybeRetReg.getError ()) {
743+ bool IsAuthenticated = false ;
744+ std::optional<MCPhysReg> RetReg =
745+ BC.MIB ->getRegUsedAsRetDest (Inst, IsAuthenticated);
746+ if (!RetReg) {
743747 return make_generic_report (
744748 Inst, " Warning: pac-ret analysis could not analyze this return "
745749 " instruction" );
746750 }
747- MCPhysReg RetReg = *MaybeRetReg;
751+ if (IsAuthenticated)
752+ return std::nullopt ;
753+
748754 LLVM_DEBUG ({
749755 traceInst (BC, " Found RET inst" , Inst);
750- traceReg (BC, " RetReg" , RetReg);
751- traceReg (BC, " Authenticated reg " , BC. MIB -> getAuthenticatedReg (Inst) );
756+ traceReg (BC, " RetReg" , * RetReg);
757+ traceRegMask (BC, " SafeToDerefRegs " , S. SafeToDerefRegs );
752758 });
753- if (BC.MIB ->isAuthenticationOfReg (Inst, RetReg))
754- return std::nullopt ;
755- LLVM_DEBUG ({ traceRegMask (BC, " SafeToDerefRegs" , S.SafeToDerefRegs ); });
756- if (S.SafeToDerefRegs [RetReg])
759+
760+ if (S.SafeToDerefRegs [*RetReg])
757761 return std::nullopt ;
758762
759- return make_gadget_report (RetKind, Inst, RetReg);
763+ return make_gadget_report (RetKind, Inst, * RetReg);
760764}
761765
762766static std::optional<PartialReport<MCPhysReg>>
@@ -772,7 +776,7 @@ shouldReportCallGadget(const BinaryContext &BC, const MCInstReference &Inst,
772776 if (IsAuthenticated)
773777 return std::nullopt ;
774778
775- assert (DestReg != BC.MIB ->getNoRegister ());
779+ assert (DestReg != BC.MIB ->getNoRegister () && " Valid register expected " );
776780 LLVM_DEBUG ({
777781 traceInst (BC, " Found call inst" , Inst);
778782 traceReg (BC, " Call destination reg" , DestReg);
@@ -789,19 +793,19 @@ shouldReportSigningOracle(const BinaryContext &BC, const MCInstReference &Inst,
789793 const SrcState &S) {
790794 static const GadgetKind SigningOracleKind (" signing oracle found" );
791795
792- MCPhysReg SignedReg = BC.MIB ->getSignedReg (Inst);
793- if (SignedReg == BC. MIB -> getNoRegister () )
796+ std::optional< MCPhysReg> SignedReg = BC.MIB ->getSignedReg (Inst);
797+ if (! SignedReg)
794798 return std::nullopt ;
795799
796800 LLVM_DEBUG ({
797801 traceInst (BC, " Found sign inst" , Inst);
798- traceReg (BC, " Signed reg" , SignedReg);
802+ traceReg (BC, " Signed reg" , * SignedReg);
799803 traceRegMask (BC, " TrustedRegs" , S.TrustedRegs );
800804 });
801- if (S.TrustedRegs [SignedReg])
805+ if (S.TrustedRegs [* SignedReg])
802806 return std::nullopt ;
803807
804- return make_gadget_report (SigningOracleKind, Inst, SignedReg);
808+ return make_gadget_report (SigningOracleKind, Inst, * SignedReg);
805809}
806810
807811template <typename T> static void iterateOverInstrs (BinaryFunction &BF, T Fn) {
0 commit comments