[Audit] --audit-r3-dump-bytes: dump N bytes at r3 when probe fires
AUDIT-059 round 15 — diagnostic. When `--audit-r3-dump-bytes=N` is set, every `--audit-pc-probe-hex` fire emits a paired `AUDIT-R3-DUMP` line with N bytes of guest memory from r3 as u32 lanes (4-byte aligned, cap 256B). Sized for the 80-byte stack-local struct at sub_82452DC0's `r31+96` (probe sub_8245B000 entry where r3 IS the struct ptr). Settable via `XENIA_AUDIT_R3_DUMP_BYTES` env. Read-only; lockstep digest unaffected (empty-set fast path in fire_audit_pc_probe_if_match). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -270,6 +270,15 @@ pub struct KernelState {
|
||||
/// unaffected. Settable via `--audit-mem-read-hex` /
|
||||
/// `XENIA_AUDIT_MEM_READ`.
|
||||
pub audit_mem_read_addr: Option<u32>,
|
||||
/// AUDIT-052 — diagnostic. When set, each `AUDIT-PC-PROBE` fire
|
||||
/// additionally emits an `AUDIT-R3-DUMP` line with N bytes of guest
|
||||
/// memory dumped from `r3` as `u32` lanes (4-byte aligned only).
|
||||
/// Sized for audit-051's 80-byte stack-local struct at `r31+96`
|
||||
/// inside `sub_82452DC0` (probe `sub_8245B000` entry where
|
||||
/// `r3 == parent's r31+96`). Read-only; lockstep digest unaffected.
|
||||
/// Settable via `--audit-r3-dump-bytes` /
|
||||
/// `XENIA_AUDIT_R3_DUMP_BYTES`.
|
||||
pub audit_r3_dump_bytes: Option<u32>,
|
||||
/// M12 — diagnostic. PCs at which to emit a structured JSONL record
|
||||
/// per fire, designed for diffing against xenia-canary's
|
||||
/// `--log_lr_on_pc` patch output. Each line carries
|
||||
@@ -355,6 +364,7 @@ impl KernelState {
|
||||
branch_probe_pcs: std::collections::HashSet::new(),
|
||||
audit_pc_probe_pcs: std::collections::HashSet::new(),
|
||||
audit_mem_read_addr: None,
|
||||
audit_r3_dump_bytes: None,
|
||||
lr_trace_pcs: std::collections::HashSet::new(),
|
||||
lr_trace_writer: None,
|
||||
dump_addrs: Vec::new(),
|
||||
@@ -886,6 +896,28 @@ impl KernelState {
|
||||
addr, val, vt, m0, m6, pc, tid, cycle,
|
||||
);
|
||||
}
|
||||
// AUDIT-052 — dump N bytes of guest memory from r3 as u32 lanes
|
||||
// when `audit_r3_dump_bytes` is set. Sized for the 80-byte
|
||||
// stack-local struct at sub_82452DC0's `r31+96` (probe is
|
||||
// sub_8245B000 entry where r3 IS the struct ptr). Output
|
||||
// format: `AUDIT-R3-DUMP pc=… r3=… +0x00=… +0x04=… …`.
|
||||
if let Some(n) = self.audit_r3_dump_bytes {
|
||||
let n = n.min(256) & !3u32; // cap 256B, 4-byte align
|
||||
let mut out = String::with_capacity(64 + (n as usize) * 16);
|
||||
use std::fmt::Write as _;
|
||||
let _ = write!(
|
||||
&mut out,
|
||||
"AUDIT-R3-DUMP pc={:#010x} tid={} cycle={} r3={:#010x}",
|
||||
pc, tid, cycle, r3,
|
||||
);
|
||||
let mut off: u32 = 0;
|
||||
while off < n {
|
||||
let v = mem.read_u32(r3.wrapping_add(off));
|
||||
let _ = write!(&mut out, " +0x{:02x}={:#010x}", off, v);
|
||||
off = off.wrapping_add(4);
|
||||
}
|
||||
println!("{}", out);
|
||||
}
|
||||
}
|
||||
|
||||
/// M12 — diagnostic. If the live PC for HW slot `hw_id` is in
|
||||
|
||||
Reference in New Issue
Block a user