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

@@ -1462,10 +1462,11 @@ fn nt_create_event(ctx: &mut PpcContext, mem: &GuestMemory, state: &mut KernelSt
signaled,
waiters: Vec::new(),
});
state.audit_create(
state.audit_create_with_ctx(
handle,
if manual_reset { "Event/Manual" } else { "Event/Auto" },
ctx.lr as u32,
ctx,
mem,
"NtCreateEvent",
);
if handle_ptr != 0 {
@@ -1484,7 +1485,7 @@ fn nt_create_semaphore(ctx: &mut PpcContext, mem: &GuestMemory, state: &mut Kern
max,
waiters: Vec::new(),
});
state.audit_create(handle, "Semaphore", ctx.lr as u32, "NtCreateSemaphore");
state.audit_create_with_ctx(handle, "Semaphore", ctx, mem, "NtCreateSemaphore");
if handle_ptr != 0 {
mem.write_u32(handle_ptr, handle);
}
@@ -1516,10 +1517,11 @@ fn nt_create_timer(ctx: &mut PpcContext, mem: &GuestMemory, state: &mut KernelSt
callback_arg: 0,
waiters: Vec::new(),
});
state.audit_create(
state.audit_create_with_ctx(
handle,
if timer_type == 0 { "Timer/Manual" } else { "Timer/Auto" },
ctx.lr as u32,
ctx,
mem,
"NtCreateTimer",
);
if handle_ptr != 0 {