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>
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:
- MATCH — ours's name == canary's name. Most exports.
- 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.
- 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:130 → KeQueryInterruptTime |
| 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:166 → KeSetBackgroundProcessors |
| 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).