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>
This commit is contained in:
110
audit-runs/phase-c13-game-dat-files-tbl/fix.diff
Normal file
110
audit-runs/phase-c13-game-dat-files-tbl/fix.diff
Normal file
@@ -0,0 +1,110 @@
|
||||
# Phase C+13 fix.diff — targeted excerpt
|
||||
# (full tree has many uncommitted prior-phase changes; this file
|
||||
# documents only the C+13 delta against the pre-C+13 state.)
|
||||
|
||||
## crates/xenia-kernel/src/exports.rs
|
||||
|
||||
### 1. New helper `is_disc_prefix` (~30 LOC, inserted near `STATUS_OBJECT_NAME_COLLISION`, ~line 1282)
|
||||
|
||||
```rust
|
||||
/// Phase C+13 — does `raw_path` start with a prefix that aliases the
|
||||
/// (read-only) game disc? Used to scope the synth-empty fallback in
|
||||
/// `open_vfs_file`: missing disc files report `STATUS_OBJECT_NAME_NOT_FOUND`
|
||||
/// (matching canary's `NtCreateFile_entry` for game-data lookups), while
|
||||
/// missing writable-partition paths keep the legacy zero-byte synth.
|
||||
///
|
||||
/// Mirrors the disc-mapped subset of `crate::path::DEVICE_PREFIXES`:
|
||||
/// - `game:\` — canary's symbolic-link alias for the disc
|
||||
/// (xenia-canary/src/xenia/kernel/kernel_state.cc registrations).
|
||||
/// - `d:\` / `D:\` — drive-letter alias for the disc.
|
||||
/// - `\Device\Cdrom0\` — NT device path for the disc.
|
||||
///
|
||||
/// Compares case-insensitively to match canary's path resolver.
|
||||
fn is_disc_prefix(raw_path: &str) -> bool {
|
||||
let lowered = raw_path.trim_start().to_ascii_lowercase();
|
||||
const DISC_PREFIXES: &[&str] = &[
|
||||
"game:\\",
|
||||
"game:/",
|
||||
"d:\\",
|
||||
"d:/",
|
||||
"\\device\\cdrom0\\",
|
||||
"\\device\\cdrom0/",
|
||||
];
|
||||
DISC_PREFIXES.iter().any(|p| lowered.starts_with(p))
|
||||
}
|
||||
```
|
||||
|
||||
### 2. `open_vfs_file` — capture raw path (after the `path` initialization, ~line 1314)
|
||||
|
||||
```rust
|
||||
// Phase C+13 — recover the raw (un-stripped) path so we can tell a
|
||||
// disc-aliased prefix (`game:\`, `d:\`, `\Device\Cdrom0\`) apart from a
|
||||
// writable-partition prefix (`\Device\Harddisk0\…`, `\??\`, raw "no
|
||||
// prefix" cases). The synth-empty fallback below covers both today but
|
||||
// canary's `NtCreateFile_entry` (xboxkrnl_io.cc:83-110) returns the
|
||||
// VFS lookup status verbatim, which is `STATUS_OBJECT_NAME_NOT_FOUND`
|
||||
// for any disc path that isn't in the ISO. Scoping the synth to
|
||||
// non-disc prefixes makes us match canary's behaviour for missing
|
||||
// game-data files (e.g. `game:\dat\files.tbl` at Phase C+13 idx 103862).
|
||||
let raw_path = crate::path::object_attributes_raw_name(mem, obj_attrs_ptr)
|
||||
.unwrap_or_default();
|
||||
```
|
||||
|
||||
### 3. `open_vfs_file` — short-circuit disc paths in the `Err(e)` synth-empty branch (~line 1413)
|
||||
|
||||
```rust
|
||||
Err(e) => {
|
||||
// Phase C+13 — scope the synth-empty fallback to non-disc
|
||||
// prefixes only. Canary's `NtCreateFile_entry` returns the VFS
|
||||
// result verbatim (xboxkrnl_io.cc:83-110); for a missing disc
|
||||
// file like `game:\dat\files.tbl` that's
|
||||
// `STATUS_OBJECT_NAME_NOT_FOUND`. Sylpheed handles NOT_FOUND
|
||||
// cleanly (next event in canary's trace at idx 103862 is
|
||||
// `RtlNtStatusToDosError(0xc0000034) -> 2`, then the boot
|
||||
// validator continues), so the synth was masking the
|
||||
// correct branch.
|
||||
//
|
||||
// Synth-empty is still kept for writable system partitions
|
||||
// (`\Device\Harddisk0\…`, `\Device\Mass*`, `\??\`, raw paths)
|
||||
// because those aren't backed by the disc — Canary mounts
|
||||
// them on host directories
|
||||
// ([xenia_main.cc:612-651](xenia-canary/src/xenia/app/xenia_main.cc));
|
||||
// ours skips the host mount for those and falls back to the
|
||||
// legacy stub to avoid regressing audit-006 / audit-018
|
||||
// disc-validation probes. `cache:/` was already routed to
|
||||
// `open_cache_file` upstream of this branch (AUDIT-038).
|
||||
if is_disc_prefix(&raw_path) {
|
||||
if handle_out != 0 {
|
||||
mem.write_u32(handle_out, 0);
|
||||
}
|
||||
write_io_status_block(
|
||||
mem,
|
||||
io_status_block,
|
||||
STATUS_OBJECT_NAME_NOT_FOUND as u32,
|
||||
0,
|
||||
);
|
||||
tracing::info!(
|
||||
"Disc path missing: raw={:?} norm={:?} err={} -> NOT_FOUND",
|
||||
raw_path,
|
||||
path,
|
||||
e
|
||||
);
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
// … existing synth-empty branch unchanged …
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Tests — 4 new tests inserted before `cache_resolve_strips_path_traversal` (~line 7838)
|
||||
|
||||
- `is_disc_prefix_recognises_disc_aliases` — unit test for the prefix classifier; covers `game:\`, `D:\`, `\Device\Cdrom0\`, and several non-disc prefixes that MUST return false.
|
||||
- `nt_create_file_game_prefix_missing_returns_not_found` — primary fix test (idx 103862 in canary's cold trace). Asserts `STATUS_OBJECT_NAME_NOT_FOUND`, null handle, and IOSB.status records NOT_FOUND.
|
||||
- `nt_create_file_cdrom_prefix_missing_returns_not_found` — `\Device\Cdrom0\` alias variant.
|
||||
- `nt_create_file_non_disc_prefix_missing_still_synthesizes` — regression guard: a missing `\Device\Harddisk0\Partition1\sys.bin` still gets a zero-byte synth (preserves audit-006 / audit-018 behaviour).
|
||||
|
||||
## Summary
|
||||
|
||||
Total: ~30 LOC engine code + ~95 LOC tests = ~125 LOC. Kernel tests 177 → 181.
|
||||
Stable digest shifts: `ad4f74ee324fdedb0bfdd4cc4c6468e9` → `e1dfcb1559f987b35012a7f2dc6d93f5`.
|
||||
Phase B `image_loaded_sha256` unchanged: `ea8d160e…`.
|
||||
Main cold-vs-cold matched prefix: **103862 → 104574 (+712)**.
|
||||
Reference in New Issue
Block a user