# Phase 1+2+3 — sister-bug + hallucination fixes (Phase C+6½) All fixes land in `crates/xenia-kernel/src/exports.rs`. No `state.rs` changes (re-uses the `register_unimplemented_export` API introduced in C+6). ## Phase 1 — Class-E sister sweep (8 ords) For each, behavior verification per CLI directive: | ord | name | reg-kind change | body verified | severity | notes | |---|---|---|---|---|---| | 0x003 | DbgPrint | `register_export` → `register_unimplemented_export` | reads cstring at gpr[3], logs, sets gpr[3]=0 — harmless side effect | LOW (rename only, body kept) | Body retains `tracing::info!` for diagnostics; only Phase A emitter goes silent. | | 0x119 | RtlCaptureContext | `register_export` → `register_unimplemented_export` | writes ctx.gpr[0..32] to guest mem at *gpr[3] — guest-visible side effect retained | LOW | Body kept; Phase A emitter silent. | | 0x13B | sprintf | `register_export` → `register_unimplemented_export` | naïve fmt→dest copy (no varargs interpretation); harmless | LOW | Body kept; Phase A emitter silent. | | 0x147 | RtlUnwind | `register_export` → `register_unimplemented_export` | `tracing::warn!` only — no-op | LOW | Body kept; Phase A emitter silent. | | 0x14D | _vsnprintf | `register_export` → `register_unimplemented_export` | naïve fmt→dest copy; harmless | LOW | Body kept; Phase A emitter silent. | | 0x1A5 | __C_specific_handler | `register_export` → `register_unimplemented_export` | logs + returns ExceptionContinueSearch (1) | LOW | Body kept; Phase A emitter silent. | | 0x257 | XeKeysConsoleSignatureVerification | `register_export` → `register_unimplemented_export` | `stub_success` (gpr[3]=0) — no-op | LOW | Body kept; Phase A emitter silent. | | 0x259 | StfsCreateDevice | `register_export` → `register_unimplemented_export` | `stub_success` | LOW — **drives tid=7→tid=2 advance** | C+6 noted this specifically. Verified +11 advance in Phase 4 diff. | | 0x25A | StfsControlDevice | `register_export` → `register_unimplemented_export` | `stub_success` | LOW | Body kept; Phase A emitter silent. | **Total Phase 1: 9 LOW-severity rename-only fixes** (all bodies kept intact; only emitter coverage suppressed to match canary's syscall-thunk silence). ## Phase 2 — Hallucinated import behavior fixes (2 ords) ### ord 0x82 — `KeQueryInterruptTime` (CRITICAL) | step | action | |---|---| | 1. Verified ours's pre-fix body | `ke_query_ideal_processor`: returned `thread.ideal_processor` u8 via `gpr[3]`. | | 2. Verified canary's body | `KeQueryInterruptTime_entry` (xboxkrnl_misc.cc:119-127): returns `bundle->interrupt_time` u64 via gpr[3]. | | 3. Verified canary's shim status | DECLARED (`xboxkrnl_misc.cc:127`) — both engines emit Phase A events. NOT class E. | | 4. Body fix | New `fn ke_query_interrupt_time` returns synthetic `0x0000_0001_0000_0000` (monotonic u64, matches `ke_query_system_time` static-fake pattern). | | 5. Registration fix | `register_export(0x82, "KeQueryInterruptTime", ke_query_interrupt_time)`. | | 6. Old body | `fn ke_query_ideal_processor` DELETED. Scheduler's `ideal_ref` method retained (used by `NtSetInformationThread::ThreadIdealProcessor`). | | 7. Test | New unit test `ke_query_interrupt_time_returns_synthetic_u64` asserts non-zero u64 (> u32::MAX), guarding against regression to a byte-sized return. | ### ord 0x98 — `KeSetBackgroundProcessors` (CRITICAL) | step | action | |---|---| | 1. Verified ours's pre-fix body | `ke_set_ideal_processor`: set `thread.ideal_processor = ctx.gpr[4] as u8`, returned prev. **Active wrong state mutation.** | | 2. Verified canary's body | NOT DECLARED. Canary routes through syscall thunk → no state mutation. Effective semantics: no-op. | | 3. Verified canary's shim status | Class E (table-entry-only). Phase A emits NOTHING for this ord. | | 4. Body fix | Body replaced with `stub_success` (no state mutation, matches canary's no-op semantics). | | 5. Registration fix | `register_unimplemented_export(0x98, "KeSetBackgroundProcessors", stub_success)`. Suppresses Phase A emitter (matches canary). | | 6. Old body | `fn ke_set_ideal_processor` DELETED. Scheduler's `set_ideal_ref` method retained (used by `NtSetInformationThread::ThreadIdealProcessor`). | | 7. Test | Renamed `ke_set_ideal_processor_round_trips` → `scheduler_ideal_processor_round_trips`, exercises the scheduler methods directly (still validating the round-trip relied on by `nt_set_information_thread`). | ## Phase 3 — Additional findings **None.** Phase 0's full ord scan surfaced exactly 2 hallucinations (both already flagged by C+6) and 11 class-E candidates (10 new + 1 C+6 already fixed). No ghost ords. No other name mismatches. ## LOC footprint | section | LOC delta | |---|---| | Registration calls (10 lines changed + 30 lines of comment context) | +35 net | | `fn ke_query_interrupt_time` (12 lines including doc) | +12 | | Removed `fn ke_set_ideal_processor` body | -10 | | Removed `fn ke_query_ideal_processor` body | -12 | | Doc-block replacing both above | +35 | | Unit test rename + new `ke_query_interrupt_time` test | +20 | | **Total** | **~80 net additive** | All changes in `crates/xenia-kernel/src/exports.rs`. State.rs untouched (reused C+6's `register_unimplemented_export` API). Diff tool untouched. Canary untouched. ## Behavior verification summary Per the CLI directive "DO NOT JUST RENAME": every fix in this session had a body-level verification step. Specifically: * **Phase 1 (9 ords)**: bodies retained as-is. Verified each body is harmless side-effect-only OR `stub_success`. No behavior change; only emitter coverage adjusted. * **Phase 2 (2 ords)**: bodies replaced. ord 0x82's new body returns semantically-correct u64 (vs. wrong u8 ideal-processor). ord 0x98's body removed (no state mutation, matches canary's no-op syscall thunk). Both Phase 2 hallucinated ords are LATENT in the current 50M run (0 hits in event log) — fix prevents future divergence when boot progresses past current matched-prefix horizon.