Files
xenia-rs/audit-runs/phase-c6half-sister-sweep/hallucination-audit.md
MechaCat02 ef93a4fa14 handoff: VSync/event-wedge fixes + iterate 2.A–2.BC research notes
Source changes (dormant parity infra, retained from iterate 2.AI/2.AO):
- xenia-kernel/exports.rs: nt_create_event manual_reset polarity +
  related event wiring
- xenia-gpu/mmio_region.rs: D1MODE_VBLANK_VLINE_STATUS hardcode parity

Also lands the audit-runs/ analysis notes (.md/.txt/.json digests) for the
iterate 2.x VSync/0x10e8/0x1004 wedge investigation. Raw trace dumps
(.jsonl/.gz/.csv/.stdout) and agent worktrees (.claude/) are gitignored as
regenerable local artifacts — see memory + HANDOFF for the running findings.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 07:19:08 +02:00

5.5 KiB

Phase 0 — Hallucination audit (Phase C+6½)

Method

For every xboxkrnl.exe ord ours registers in register_exports(), cross-reference against canary's xboxkrnl_table.inc (authoritative Xbox 360 ord→name mapping). Three classes of mismatch are possible:

  1. MATCH — ours's name == canary's name. Most exports.
  2. HALLUCINATION — ours's name ≠ canary's name at the same ord. The hallucinated name may be a real NT function that exists at a different ord on Xbox 360, making it look plausible.
  3. GHOST ORD — ours registers an ord canary's table doesn't have.

For each HALLUCINATION, additional severity classification:

  • CRITICAL — ours's stub body performs different semantics than canary's named function. Game gets wrong data on every call.
  • HIGH — ours's stub body is harmless (e.g. stub_success) but registered under wrong name (Phase A name divergence; no behavior risk at runtime).
  • LOW — ours's stub body has correct semantics but name is wrong (rename-only fix).

Headline

count category
147 total xboxkrnl ords ours registers
145 MATCH (name agrees with canary table)
2 HALLUCINATION
0 GHOST ORD (no ord registered in ours that canary's table lacks)

Hallucinations found

ord 0x82 — KeQueryInterruptTime

canary table xboxkrnl_table.inc:130KeQueryInterruptTime
canary shim xboxkrnl_misc.cc:119-127 — DECLARED, both engines emit Phase A events
ours-pre-fix KeQueryIdealProcessor body — returns thread.ideal_processor u8 via gpr[3]
canary semantics Returns 64-bit bundle->interrupt_time (kernel timer ISR's monotonic counter) via gpr[3]
severity CRITICAL — wildly different semantics. Game code reading the system interrupt-time counter for timing/scheduling decisions received a 1-byte processor index. Counter-value would clamp to 0..7 (or 0xFF for unset), producing nonsensical "timestamps" smaller than 1µs.
live in current run NO (0 hits in 50M-instr Phase A log; latent)
fix New body ke_query_interrupt_time returns a synthetic monotonic u64 (0x0000_0001_0000_0000), matching the KeQuerySystemTime static-fake pattern. Renamed in registration.

ord 0x98 — KeSetBackgroundProcessors

canary table xboxkrnl_table.inc:166KeSetBackgroundProcessors
canary shim NOT declared (table-entry-only — class E, syscall-thunk path emits NO Phase A events)
ours-pre-fix KeSetIdealProcessor body — sets thread.ideal_processor = ctx.gpr[4] as u8, returns prior value
canary semantics Configures background-processor affinity mask; canary stub is no-op (no DECLARE shim).
severity CRITICAL — ours actively performed wrong state mutation under the wrong semantic name. Game calling KeSetBackgroundProcessors to declare its CPUs-for-background-work set was instead pinning the calling thread's ideal-processor hint, which affects spawn-sibling placement decisions later.
live in current run NO (0 hits in 50M-instr Phase A log; latent)
fix Body replaced with stub_success no-op (matching canary's effective behavior since canary has no shim). Underlying Scheduler::set_ideal_ref/ideal_ref retained (used by NtSetInformationThread info-class ThreadIdealProcessor). Registered via register_unimplemented_export so Phase A emitter stays silent (matching canary's syscall-thunk).

No other hallucinations

Cross-reference covered all 147 ours-registered xboxkrnl ords. Both known hallucinations were the ones C+6 had already flagged out-of-scope for that session. No new hallucinations surfaced.

XAM table not audited in this pass (ours's registrations are in crates/xenia-kernel/src/xam.rs and Stage 1 already classified them MATCH at the same level of trust as xboxkrnl pre-C+6; no name-lookup asymmetries surfaced during C+6 framing diagnosis). Recommended as follow-up if a future Phase C+N first divergence is an XAM call-name mismatch.

Class E sister sweep candidates (Phase 1)

In addition to the 2 hallucinations, audited which ours-registered ords have NO DECLARE_XBOXKRNL_EXPORT shim in canary — these are class-E candidates for register_unimplemented_export:

ord canary name ours name already class-E?
0x003 DbgPrint DbgPrint NO — needs fix
0x03C IoDismountVolumeByFileHandle IoDismountVolumeByFileHandle YES (C+6)
0x098 KeSetBackgroundProcessors (hallucinated KeSetIdealProcessor) NO — Phase 2
0x119 RtlCaptureContext RtlCaptureContext NO — needs fix
0x13B sprintf sprintf NO — needs fix
0x147 RtlUnwind RtlUnwind NO — needs fix
0x14D _vsnprintf _vsnprintf NO — needs fix
0x1A5 __C_specific_handler __C_specific_handler NO — needs fix
0x257 XeKeysConsoleSignatureVerification XeKeysConsoleSignatureVerification NO — needs fix
0x259 StfsCreateDevice StfsCreateDevice NO — needs fix
0x25A StfsControlDevice StfsControlDevice NO — needs fix

11 ords total need the class-E rewire — 1 already fixed (0x03C in C+6), 9 + the 0x98 hallucination fixed here.

The C+6 sister-bugs note projected "12+" — the actual count is 11 (10 new + 1 already done). The two "unnamed" in the original list resolve to DbgPrint (ord 0x03, always present in C+6's analysis but not named explicitly in the sister-bugs list) and KeSetBackgroundProcessors (ord 0x98, originally listed under "different class" hallucinations but ALSO a class-E candidate since canary has no shim).