llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-bolt Author: Anatoly Trosinenko (atrosinenko) <details> <summary>Changes</summary> On AArch64 it is possible for an auth instruction to either return an invalid address value on failure (without FEAT_FPAC) or generate an error (with FEAT_FPAC). It thus may be possible to never emit explicit pointer checks, if the target CPU is known to support FEAT_FPAC. This commit implements an --auth-traps-on-failure command line option, which essentially makes "safe-to-dereference" and "trusted" register properties identical and disables scanning for authentication oracles completely. --- Patch is 53.54 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/139778.diff 8 Files Affected: - (modified) bolt/lib/Passes/PAuthGadgetScanner.cpp (+74-38) - (modified) bolt/test/binary-analysis/AArch64/cmdline-args.test (+1) - (modified) bolt/test/binary-analysis/AArch64/gs-pauth-authentication-oracles.s (+4-2) - (modified) bolt/test/binary-analysis/AArch64/gs-pauth-calls.s (+3-2) - (modified) bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s (+104-73) - (modified) bolt/test/binary-analysis/AArch64/gs-pauth-jump-table.s (+4-2) - (modified) bolt/test/binary-analysis/AArch64/gs-pauth-signing-oracles.s (+31-24) - (modified) bolt/test/binary-analysis/AArch64/gs-pauth-tail-calls.s (+97-87) ``````````diff diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp b/bolt/lib/Passes/PAuthGadgetScanner.cpp index 4bd1ccb4520c1..592a1acce1bd4 100644 --- a/bolt/lib/Passes/PAuthGadgetScanner.cpp +++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp @@ -14,6 +14,7 @@ #include "bolt/Passes/PAuthGadgetScanner.h" #include "bolt/Core/ParallelUtilities.h" #include "bolt/Passes/DataflowAnalysis.h" +#include "bolt/Utils/CommandLineOpts.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallSet.h" #include "llvm/MC/MCInst.h" @@ -26,6 +27,11 @@ namespace llvm { namespace bolt { namespace PAuthGadgetScanner { +static cl::opt<bool> AuthTrapsOnFailure( + "auth-traps-on-failure", + cl::desc("Assume authentication instructions always trap on failure"), + cl::cat(opts::BinaryAnalysisCategory)); + [[maybe_unused]] static void traceInst(const BinaryContext &BC, StringRef Label, const MCInst &MI) { dbgs() << " " << Label << ": "; @@ -332,6 +338,34 @@ class SrcSafetyAnalysis { return Clobbered; } + std::optional<MCPhysReg> getRegMadeTrustedByChecking(const MCInst &Inst, + SrcState Cur) const { + // This functions cannot return multiple registers. This is never the case + // on AArch64. + std::optional<MCPhysReg> RegCheckedByInst = + BC.MIB->getAuthCheckedReg(Inst, /*MayOverwrite=*/false); + if (RegCheckedByInst && Cur.SafeToDerefRegs[*RegCheckedByInst]) + return *RegCheckedByInst; + + auto It = CheckerSequenceInfo.find(&Inst); + if (It == CheckerSequenceInfo.end()) + return std::nullopt; + + MCPhysReg RegCheckedBySequence = It->second.first; + const MCInst *FirstCheckerInst = It->second.second; + + // FirstCheckerInst should belong to the same basic block (see the + // assertion in DataflowSrcSafetyAnalysis::run()), meaning it was + // deterministically processed a few steps before this instruction. + const SrcState &StateBeforeChecker = getStateBefore(*FirstCheckerInst); + + // The sequence checks the register, but it should be authenticated before. + if (!StateBeforeChecker.SafeToDerefRegs[RegCheckedBySequence]) + return std::nullopt; + + return RegCheckedBySequence; + } + // Returns all registers that can be treated as if they are written by an // authentication instruction. SmallVector<MCPhysReg> getRegsMadeSafeToDeref(const MCInst &Point, @@ -354,18 +388,38 @@ class SrcSafetyAnalysis { Regs.push_back(DstAndSrc->first); } + // Make sure explicit checker sequence keeps register safe-to-dereference + // when the register would be clobbered according to the regular rules: + // + // ; LR is safe to dereference here + // mov x16, x30 ; start of the sequence, LR is s-t-d right before + // xpaclri ; clobbers LR, LR is not safe anymore + // cmp x30, x16 + // b.eq 1f ; end of the sequence: LR is marked as trusted + // brk 0x1234 + // 1: + // ; at this point LR would be marked as trusted, + // ; but not safe-to-dereference + // + // or even just + // + // ; X1 is safe to dereference here + // ldr x0, [x1, #8]! + // ; X1 is trusted here, but it was clobbered due to address write-back + if (auto CheckedReg = getRegMadeTrustedByChecking(Point, Cur)) + Regs.push_back(*CheckedReg); + return Regs; } // Returns all registers made trusted by this instruction. SmallVector<MCPhysReg> getRegsMadeTrusted(const MCInst &Point, const SrcState &Cur) const { + assert(!AuthTrapsOnFailure && "Use getRegsMadeSafeToDeref instead"); SmallVector<MCPhysReg> Regs; // An authenticated pointer can be checked, or - std::optional<MCPhysReg> CheckedReg = - BC.MIB->getAuthCheckedReg(Point, /*MayOverwrite=*/false); - if (CheckedReg && Cur.SafeToDerefRegs[*CheckedReg]) + if (auto CheckedReg = getRegMadeTrustedByChecking(Point, Cur)) Regs.push_back(*CheckedReg); // ... a pointer can be authenticated by an instruction that always checks @@ -376,19 +430,6 @@ class SrcSafetyAnalysis { if (AutReg && IsChecked) Regs.push_back(*AutReg); - if (CheckerSequenceInfo.contains(&Point)) { - MCPhysReg CheckedReg; - const MCInst *FirstCheckerInst; - std::tie(CheckedReg, FirstCheckerInst) = CheckerSequenceInfo.at(&Point); - - // FirstCheckerInst should belong to the same basic block (see the - // assertion in DataflowSrcSafetyAnalysis::run()), meaning it was - // deterministically processed a few steps before this instruction. - const SrcState &StateBeforeChecker = getStateBefore(*FirstCheckerInst); - if (StateBeforeChecker.SafeToDerefRegs[CheckedReg]) - Regs.push_back(CheckedReg); - } - // ... a safe address can be materialized, or if (auto NewAddrReg = BC.MIB->getMaterializedAddressRegForPtrAuth(Point)) Regs.push_back(*NewAddrReg); @@ -432,28 +473,11 @@ class SrcSafetyAnalysis { BitVector Clobbered = getClobberedRegs(Point); SmallVector<MCPhysReg> NewSafeToDerefRegs = getRegsMadeSafeToDeref(Point, Cur); - SmallVector<MCPhysReg> NewTrustedRegs = getRegsMadeTrusted(Point, Cur); - - // Ideally, being trusted is a strictly stronger property than being - // safe-to-dereference. To simplify the computation of Next state, enforce - // this for NewSafeToDerefRegs and NewTrustedRegs. Additionally, this - // fixes the properly for "cumulative" register states in tricky cases - // like the following: - // - // ; LR is safe to dereference here - // mov x16, x30 ; start of the sequence, LR is s-t-d right before - // xpaclri ; clobbers LR, LR is not safe anymore - // cmp x30, x16 - // b.eq 1f ; end of the sequence: LR is marked as trusted - // brk 0x1234 - // 1: - // ; at this point LR would be marked as trusted, - // ; but not safe-to-dereference - // - for (auto TrustedReg : NewTrustedRegs) { - if (!is_contained(NewSafeToDerefRegs, TrustedReg)) - NewSafeToDerefRegs.push_back(TrustedReg); - } + // If authentication instructions trap on failure, safe-to-dereference + // registers are always trusted. + SmallVector<MCPhysReg> NewTrustedRegs = + AuthTrapsOnFailure ? NewSafeToDerefRegs + : getRegsMadeTrusted(Point, Cur); // Then, compute the state after this instruction is executed. SrcState Next = Cur; @@ -490,6 +514,11 @@ class SrcSafetyAnalysis { dbgs() << ")\n"; }); + // Being trusted is a strictly stronger property than being + // safe-to-dereference. + assert(!Next.TrustedRegs.test(Next.SafeToDerefRegs) && + "SafeToDerefRegs should contain all TrustedRegs"); + return Next; } @@ -1066,6 +1095,11 @@ class DataflowDstSafetyAnalysis } void run() override { + // As long as DstSafetyAnalysis is only computed to detect authentication + // oracles, it is a waste of time to compute it when authentication + // instructions are known to always trap on failure. + assert(!AuthTrapsOnFailure && + "DstSafetyAnalysis is useless with faulting auth"); for (BinaryBasicBlock &BB : Func) { if (auto CheckerInfo = BC.MIB->getAuthCheckedReg(BB)) { LLVM_DEBUG({ @@ -1536,6 +1570,8 @@ void FunctionAnalysisContext::findUnsafeDefs( SmallVector<PartialReport<MCPhysReg>> &Reports) { if (PacRetGadgetsOnly) return; + if (AuthTrapsOnFailure) + return; auto Analysis = DstSafetyAnalysis::create(BF, AllocatorId, {}); LLVM_DEBUG({ dbgs() << "Running dst register safety analysis...\n"; }); diff --git a/bolt/test/binary-analysis/AArch64/cmdline-args.test b/bolt/test/binary-analysis/AArch64/cmdline-args.test index 76f7c3ba0a1c7..27069436092b3 100644 --- a/bolt/test/binary-analysis/AArch64/cmdline-args.test +++ b/bolt/test/binary-analysis/AArch64/cmdline-args.test @@ -32,6 +32,7 @@ HELP-NEXT: OPTIONS: HELP-EMPTY: HELP-NEXT: BinaryAnalysis options: HELP-EMPTY: +HELP-NEXT: --auth-traps-on-failure - Assume authentication instructions always trap on failure HELP-NEXT: --scanners=<value> - which gadget scanners to run HELP-NEXT: =pacret - pac-ret: return address protection (subset of "pauth") HELP-NEXT: =pauth - All Pointer Authentication scanners diff --git a/bolt/test/binary-analysis/AArch64/gs-pauth-authentication-oracles.s b/bolt/test/binary-analysis/AArch64/gs-pauth-authentication-oracles.s index 5fdc223c43c6f..acec543b0aed4 100644 --- a/bolt/test/binary-analysis/AArch64/gs-pauth-authentication-oracles.s +++ b/bolt/test/binary-analysis/AArch64/gs-pauth-authentication-oracles.s @@ -1,6 +1,7 @@ // RUN: %clang %cflags -march=armv8.3-a %s -o %t.exe -// RUN: llvm-bolt-binary-analysis --scanners=pacret %t.exe 2>&1 | FileCheck -check-prefix=PACRET %s -// RUN: llvm-bolt-binary-analysis --scanners=pauth %t.exe 2>&1 | FileCheck %s +// RUN: llvm-bolt-binary-analysis --scanners=pacret %t.exe 2>&1 | FileCheck -check-prefix=PACRET %s +// RUN: llvm-bolt-binary-analysis --scanners=pauth --auth-traps-on-failure %t.exe 2>&1 | FileCheck -check-prefix=FPAC %s +// RUN: llvm-bolt-binary-analysis --scanners=pauth %t.exe 2>&1 | FileCheck %s // The detection of compiler-generated explicit pointer checks is tested in // gs-pauth-address-checks.s, for that reason only test here "dummy-load" and @@ -8,6 +9,7 @@ // detected per-instruction and per-BB. // PACRET-NOT: authentication oracle found in function +// FPAC-NOT: authentication oracle found in function .text diff --git a/bolt/test/binary-analysis/AArch64/gs-pauth-calls.s b/bolt/test/binary-analysis/AArch64/gs-pauth-calls.s index 5f49918c39c94..26ebe2d2436a1 100644 --- a/bolt/test/binary-analysis/AArch64/gs-pauth-calls.s +++ b/bolt/test/binary-analysis/AArch64/gs-pauth-calls.s @@ -1,6 +1,7 @@ // RUN: %clang %cflags -march=armv8.3-a %s -o %t.exe -// RUN: llvm-bolt-binary-analysis --scanners=pacret %t.exe 2>&1 | FileCheck -check-prefix=PACRET %s -// RUN: llvm-bolt-binary-analysis --scanners=pauth %t.exe 2>&1 | FileCheck %s +// RUN: llvm-bolt-binary-analysis --scanners=pacret %t.exe 2>&1 | FileCheck -check-prefix=PACRET %s +// RUN: llvm-bolt-binary-analysis --scanners=pauth --auth-traps-on-failure %t.exe 2>&1 | FileCheck %s +// RUN: llvm-bolt-binary-analysis --scanners=pauth %t.exe 2>&1 | FileCheck %s // PACRET-NOT: non-protected call found in function diff --git a/bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s b/bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s index 75341063ab816..e99599c7463c6 100644 --- a/bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s +++ b/bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s @@ -1,10 +1,14 @@ // REQUIRES: asserts // // RUN: %clang %cflags -march=armv8.3-a %s -o %t.exe -// RUN: llvm-bolt-binary-analysis --scanners=pacret -no-threads \ -// RUN: -debug-only bolt-pauth-scanner %t.exe 2>&1 | FileCheck %s -// RUN: llvm-bolt-binary-analysis --scanners=pauth -no-threads \ -// RUN: -debug-only bolt-pauth-scanner %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,PAUTH %s +// RUN: llvm-bolt-binary-analysis --scanners=pacret --no-threads \ +// RUN: -debug-only bolt-pauth-scanner %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,NOFPAC %s +// RUN: llvm-bolt-binary-analysis --scanners=pacret --no-threads --auth-traps-on-failure \ +// RUN: -debug-only bolt-pauth-scanner %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,FPAC %s +// RUN: llvm-bolt-binary-analysis --scanners=pauth --no-threads \ +// RUN: -debug-only bolt-pauth-scanner %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,NOFPAC,AUTH-ORACLES,PAUTH %s +// RUN: llvm-bolt-binary-analysis --scanners=pauth --no-threads --auth-traps-on-failure \ +// RUN: -debug-only bolt-pauth-scanner %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,FPAC,PAUTH %s // Check the debug output generated by PAuth gadget scanner to make sure the // that output is kept meaningful and to provide an overview of what happens @@ -61,30 +65,54 @@ simple: // CHECK-NEXT: State 1: src-state<empty> // CHECK-NEXT: State 2: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) // CHECK-NEXT: merged state: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: > -// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( autiza x0, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) -// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: , Insts: >) -// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( blr x0, src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: , Insts: >) -// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) -// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( ldp x29, x30, [sp], #0x10, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) -// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) -// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( hint #29, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) -// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >) -// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( ret x30, src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >) -// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >) -// CHECK-NEXT: DataflowSrcSafetyAnalysis::Confluence( -// CHECK-NEXT: State 1: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: > -// CHECK-NEXT: State 2: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) -// CHECK-NEXT: merged state: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: > -// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( autiza x0, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) -// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: , Insts: >) -// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( blr x0, src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: , Insts: >) -// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) -// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( ldp x29, x30, [sp], #0x10, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) -// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) -// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( hint #29, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) -// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >) -// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( ret x30, src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >) -// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >) +// NOFPAC-NEXT: SrcSafetyAnalysis::ComputeNext( autiza x0, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) +// NOFPAC-NEXT: .. result: (src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: , Insts: >) +// NOFPAC-NEXT: SrcSafetyAnalysis::ComputeNext( blr x0, src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: , Insts: >) +// NOFPAC-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) +// NOFPAC-NEXT: SrcSafetyAnalysis::ComputeNext( ldp x29, x30, [sp], #0x10, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) +// NOFPAC-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) +// NOFPAC-NEXT: SrcSafetyAnalysis::ComputeNext( hint #29, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) +// NOFPAC-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >) +// NOFPAC-NEXT: SrcSafetyAnalysis::ComputeNext( ret x30, src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >) +// NOFPAC-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >) +// NOFPAC-NEXT: DataflowSrcSafetyAnalysis::Confluence( +// NOFPAC-NEXT: State 1: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: > +// NOFPAC-NEXT: State 2: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) +// NOFPAC-NEXT: merged state: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: > +// NOFPAC-NEXT: SrcSafetyAnalysis::ComputeNext( autiza x0, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) +// NOFPAC-NEXT: .. result: (src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: , Insts: >) +// NOFPAC-NEXT: SrcSafetyAnalysis::ComputeNext( blr x0, src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: , Insts: >) +// NOFPAC-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) +// NOFPAC-NEXT: SrcSafetyAnalysis::ComputeNext( ldp x29, x30, [sp], #0x10, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) +// NOFPAC-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) +// NOFPAC-NEXT: SrcSafetyAnalysis::ComputeNext( hint #29, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) +// NOFPAC-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >) +// NOFPAC-NEXT: SrcSafetyAnalysis::ComputeNext( ret x30, src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >) +// NOFPAC-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >) +// FPAC-NEXT: SrcSafetyAnalysis::ComputeNext( autiza x0, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) +// FPAC-NEXT: .. result: (src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: W0 X0 W0_HI , Insts: >) +// FPAC-NEXT: SrcSafetyAnalysis::ComputeNext( blr x0, src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: W0 X0 W0_HI , Insts: >) +// FPAC-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) +// FPAC-NEXT: SrcSafetyAnalysis::ComputeNext( ldp x29, x30, [sp], #0x10, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) +// FPAC-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) +// FPAC-NEXT: SrcSafetyAnalysis::ComputeNext( hint #29, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) +// FPAC-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >) +// FPAC-NEXT: SrcSafetyAnalysis::ComputeNext( ret x30, src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >) +// FPAC-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >) +// FPAC-NEXT: DataflowSrcSafetyAnalysis::Confluence( +// FPAC-NEXT: State 1: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: > +// FPAC-NEXT: State 2: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) +// FPAC-NEXT: merged state: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: > +// FPAC-NEXT: SrcSafetyAnalysis::ComputeNext( autiza x0, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) +// FPAC-NEXT: .. result: (src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: W0 X0 W0_HI , Insts: >) +// FPAC-NEXT: SrcSafetyAnalysis::ComputeNext( blr x0, src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: W0 X0 W0_HI , Insts: >) +// FPAC-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) +// FPAC-NEXT: SrcSafetyAnalysis::ComputeNext( ldp x29, x30, [sp], #0x10, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) +// FPAC-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) +// FPAC-NEXT: SrcSafetyAnalysis::ComputeNext( hint #29, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >) +// FPAC-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >) +// FPAC-NEXT: SrcSafetyAnalysis::ComputeNext( ret x30, src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >) +// FPAC-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >) // CHECK-NEXT: After src register safety analysis: // CHECK-NEXT: Binary Function "simple" { // CHECK-NEXT: Number : 1 @@ -255,53 +283,56 @@ auth_oracle: // ... // CHECK: End of Function "auth_oracle" // ... -// PAUTH: ... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/139778 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits