feat(kernel): KRNBUG-AUDIT-002 — multi-frame guest stack capture at handle creation

Adds `walk_guest_back_chain` (PPC EABI back-chain walker) and a
`record_create_with_stack` audit hook gated on `--trace-handles-focus`.
NtCreateEvent / NtCreateSemaphore / NtCreateTimer / XamTaskSchedule now
route through the new helper so focused handles capture up to 6 stack
frames at allocation time. Diagnostic-only, read-only memory access:
unfocused handles pay one HashSet lookup, focused ones pay six
back-chain dereferences. Lockstep determinism preserved.

End-to-end finding: handles 0x1004 (8-instance pool via static ctor at
0x8280F810), 0x100c (singleton built inside main()), 0x15e0 (singleton
in distinct cluster) are silph-framework dispatcher objects whose
producer code is unreached at -n 500M. The producer hunt now has class
ownership; vtable/RTTI readout is the next step.

Tests: 576 → 581 green. `--stable-digest -n 100M` instructions=100000002
unchanged. Master HEAD prior: 9d45efe.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-05-03 20:41:06 +02:00
parent 9d45efe5d5
commit 2a9fd1fc86
6 changed files with 403 additions and 7 deletions

View File

@@ -215,7 +215,6 @@ fn xam_task_schedule(ctx: &mut PpcContext, mem: &GuestMemory, state: &mut Kernel
let message_ptr = ctx.gpr[4] as u32;
let optional_ptr = ctx.gpr[5] as u32;
let handle_ptr = ctx.gpr[6] as u32;
let lr = ctx.lr as u32;
if optional_ptr != 0 {
let v1 = mem.read_u32(optional_ptr);
@@ -266,7 +265,7 @@ fn xam_task_schedule(ctx: &mut PpcContext, mem: &GuestMemory, state: &mut Kernel
if handle_ptr != 0 {
mem.write_u32(handle_ptr, handle);
}
state.audit_create(handle, "Thread", lr, "XamTaskSchedule");
state.audit_create_with_ctx(handle, "Thread", ctx, mem, "XamTaskSchedule");
tracing::info!(
"XamTaskSchedule: tid={} handle={:#x} hw={} callback={:#010x} message={:#010x}",
tid,