0
0
mirror of https://github.com/llvm/llvm-project.git synced 2025-04-27 13:36:07 +00:00
Anatoly Trosinenko 2927050dd4
[BOLT] Gadget scanner: refine class names and debug output (NFC) ()
Scanning functions without CFG information as well as the detection of
authentication oracles requires introducing more classes related to
register state analysis. To make the future code easier to understand,
rename several classes beforehand.

To detect authentication oracles, one has to query the properties of
*output* operands of authentication instructions *after* the instruction
is executed - this requires adding another analysis that iterates over
the instructions in reverse order, and a corresponding state class.

As the main difference of the existing `State` class is that it stores
the properties of source register operands of the instructions before
the instruction's execution, rename it to `SrcState` and
`PacRetAnalysis` to `SrcSafetyAnalysis`.

Apply minor adjustments to the debug output along the way.
2025-04-10 20:54:05 +03:00

172 lines
8.9 KiB
ArmAsm

// 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
// 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
// inside the scanner.
.globl simple
.type simple,@function
simple:
paciasp
stp x29, x30, [sp, #-0x10]!
b 1f
1:
autiza x0
blr x0
ldp x29, x30, [sp], #0x10
autiasp
ret
.size simple, .-simple
// CHECK-LABEL:Analyzing in function simple, AllocatorId 1
// CHECK-NEXT: Binary Function "simple" {
// CHECK-NEXT: Number : 1
// CHECK-NEXT: State : CFG constructed
// ...
// CHECK: BB Layout : [[BB0:[0-9a-zA-Z.]+]], [[BB1:[0-9a-zA-Z.]+]]
// CHECK-NEXT: }
// CHECK-NEXT: [[BB0]] (3 instructions, align : 1)
// CHECK-NEXT: Entry Point
// CHECK-NEXT: 00000000: paciasp
// CHECK-NEXT: 00000004: stp x29, x30, [sp, #-0x10]!
// CHECK-NEXT: 00000008: b [[BB1]]
// CHECK-NEXT: Successors: [[BB1]]
// CHECK-EMPTY:
// CHECK-NEXT: [[BB1]] (5 instructions, align : 1)
// CHECK-NEXT: Predecessors: [[BB0]]
// CHECK-NEXT: 0000000c: autiza x0
// CHECK-NEXT: 00000010: blr x0
// CHECK-NEXT: 00000014: ldp x29, x30, [sp], #0x10
// CHECK-NEXT: 00000018: autiasp
// CHECK-NEXT: 0000001c: ret
// CHECK-EMPTY:
// CHECK-NEXT: DWARF CFI Instructions:
// CHECK-NEXT: <empty>
// CHECK-NEXT: End of Function "simple"
// CHECK-EMPTY:
// CHECK-NEXT: Running src register safety analysis...
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( hint #25, src-state<SafeToDerefRegs: LR W30 W30_HI , Insts: >)
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: , Insts: >)
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( stp x29, x30, [sp, #-0x10]!, src-state<SafeToDerefRegs: , Insts: >)
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: , Insts: >)
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( b [[BB1]], src-state<SafeToDerefRegs: , Insts: >)
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: , Insts: >)
// CHECK-NEXT: SrcSafetyAnalysis::Confluence(
// CHECK-NEXT: State 1: src-state<empty>
// CHECK-NEXT: State 2: src-state<SafeToDerefRegs: , Insts: >)
// CHECK-NEXT: merged state: src-state<SafeToDerefRegs: , Insts: >
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( autiza x0, src-state<SafeToDerefRegs: , Insts: >)
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: W0 X0 W0_HI , Insts: >)
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( blr x0, src-state<SafeToDerefRegs: W0 X0 W0_HI , Insts: >)
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: , Insts: >)
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( ldp x29, x30, [sp], #0x10, src-state<SafeToDerefRegs: , Insts: >)
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: , Insts: >)
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( hint #29, src-state<SafeToDerefRegs: , Insts: >)
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , Insts: >)
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( ret x30, src-state<SafeToDerefRegs: LR W30 W30_HI , Insts: >)
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , Insts: >)
// CHECK-NEXT: SrcSafetyAnalysis::Confluence(
// CHECK-NEXT: State 1: src-state<SafeToDerefRegs: , Insts: >
// CHECK-NEXT: State 2: src-state<SafeToDerefRegs: , Insts: >)
// CHECK-NEXT: merged state: src-state<SafeToDerefRegs: , Insts: >
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( autiza x0, src-state<SafeToDerefRegs: , Insts: >)
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: W0 X0 W0_HI , Insts: >)
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( blr x0, src-state<SafeToDerefRegs: W0 X0 W0_HI , Insts: >)
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: , Insts: >)
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( ldp x29, x30, [sp], #0x10, src-state<SafeToDerefRegs: , Insts: >)
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: , Insts: >)
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( hint #29, src-state<SafeToDerefRegs: , Insts: >)
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , Insts: >)
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( ret x30, src-state<SafeToDerefRegs: LR W30 W30_HI , Insts: >)
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , Insts: >)
// CHECK-NEXT: After src register safety analysis:
// CHECK-NEXT: Binary Function "simple" {
// CHECK-NEXT: Number : 1
// CHECK-NEXT: State : CFG constructed
// ...
// CHECK: BB Layout : [[BB0]], [[BB1]]
// CHECK-NEXT: }
// CHECK-NEXT: [[BB0]] (3 instructions, align : 1)
// CHECK-NEXT: Entry Point
// CHECK-NEXT: 00000000: paciasp # SrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, Insts: >
// CHECK-NEXT: 00000004: stp x29, x30, [sp, #-0x10]! # SrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, Insts: >
// CHECK-NEXT: 00000008: b [[BB1]] # SrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, Insts: >
// CHECK-NEXT: Successors: [[BB1]]
// CHECK-EMPTY:
// CHECK-NEXT: [[BB1]] (5 instructions, align : 1)
// CHECK-NEXT: Predecessors: [[BB0]]
// CHECK-NEXT: 0000000c: autiza x0 # SrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, Insts: >
// CHECK-NEXT: 00000010: blr x0 # SrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, Insts: >
// CHECK-NEXT: 00000014: ldp x29, x30, [sp], #0x10 # SrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, Insts: >
// CHECK-NEXT: 00000018: autiasp # SrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, Insts: >
// CHECK-NEXT: 0000001c: ret # SrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, Insts: >
// CHECK-EMPTY:
// CHECK-NEXT: DWARF CFI Instructions:
// CHECK-NEXT: <empty>
// CHECK-NEXT: End of Function "simple"
// CHECK-EMPTY:
// PAUTH-NEXT: Found call inst: 00000000: blr x0 # SrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, Insts: >
// PAUTH-NEXT: Call destination reg: X0
// PAUTH-NEXT: SafeToDerefRegs: W0 X0 W0_HI{{[ \t]*$}}
// CHECK-NEXT: Found RET inst: 00000000: ret # SrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, Insts: >
// CHECK-NEXT: RetReg: LR
// CHECK-NEXT: Authenticated reg: (none)
// CHECK-NEXT: SafeToDerefRegs: LR W30 W30_HI{{[ \t]*$}}
.globl clobber
.type clobber,@function
clobber:
mov w30, #0
ret
.size clobber, .-clobber
// CHECK-LABEL:Analyzing in function clobber, AllocatorId 1
// ...
// CHECK: Running src register safety analysis...
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( mov w30, #0x0, src-state<SafeToDerefRegs: LR W30 W30_HI , Insts: >)
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: W30_HI , Insts: >)
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( ret x30, src-state<SafeToDerefRegs: W30_HI , Insts: >)
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: W30_HI , Insts: >)
// CHECK-NEXT: After src register safety analysis:
// CHECK-NEXT: Binary Function "clobber" {
// ...
// CHECK: End of Function "clobber"
// The above output was printed after first run of analysis
// CHECK-EMPTY:
// CHECK-NEXT: Found RET inst: 00000000: ret # SrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, Insts: >
// CHECK-NEXT: RetReg: LR
// CHECK-NEXT: Authenticated reg: (none)
// CHECK-NEXT: SafeToDerefRegs: W30_HI{{[ \t]*$}}
// CHECK-EMPTY:
// CHECK-NEXT: Running detailed src register safety analysis...
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( mov w30, #0x0, src-state<SafeToDerefRegs: LR W30 W30_HI , Insts: [0]()>)
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: W30_HI , Insts: [0](0x{{[0-9a-f]+}} )>)
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( ret x30, src-state<SafeToDerefRegs: W30_HI , Insts: [0](0x{{[0-9a-f]+}} )>)
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: W30_HI , Insts: [0](0x{{[0-9a-f]+}} )>)
// CHECK-NEXT: After detailed src register safety analysis:
// CHECK-NEXT: Binary Function "clobber" {
// ...
// CHECK: End of Function "clobber"
// The analysis was re-computed with register tracking, as an issue was found in this function.
// Iterating over the reports and attaching clobbering info:
// CHECK-EMPTY:
// CHECK-NEXT: Attaching clobbering info to: 00000000: ret # SrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, Insts: [0](0x{{[0-9a-f]+}} )>
// CHECK-LABEL:Analyzing in function main, AllocatorId 1
.globl main
.type main,@function
main:
ret
.size main, .-main