# xenia-rs Rust reimplementation of the Xbox 360 emulator [xenia](https://github.com/xenia-project/xenia), focused on **reverse-engineering and preservation** rather than full-speed play. The initial target is *Project Sylpheed — Arc of Deception*; getting the title disassembled, traced, and far enough into its init path to understand its engine. Heavy cross-reference to [xenia-canary](https://github.com/xenia-canary/xenia-canary) for CPU context setup, kernel export behavior, and XEX loading semantics. ## Status - **XEX loader** — XEX2 header parsing, LZX decompression, AES decryption, PE section parsing. - **VFS / XISO** — XGD2 dual-layer disc images (with the 0x0FD90000 partition offset). - **PPC interpreter** — 200+ opcodes, PowerPC 32/64-bit GPR/FPR, VMX128 decoding. - **Static analyzer** — function discovery (prolog/epilog heuristics), cross-references, labels, save/restore helper detection, assembly text + SQLite database output. - **Kernel HLE** — minimal subset driving Project Sylpheed: ~170 xboxkrnl + xam exports (critical sections, events, TLS, virtual memory, Vd stubs, XAM input/user/content). - **Debugger** — in-memory step/break, SQLite execution + import-call + branch tracing. Not yet: GPU (xenos/xe-shader), APU audio, HID, kernel scheduler, full threading, exception delivery. ## Workspace ``` crates/ xenia-types # shared primitive types, bitflags xenia-memory # guest memory, paged allocator, page table xenia-cpu # PPC decoder, interpreter, context xenia-xex # XEX2 loader, PE parser, LZX, AES xenia-vfs # XISO / disc-image reader xenia-kernel # HLE kernel state, exports, XAM xenia-gpu # (stub) Xenos command processor xenia-apu # (stub) XAudio xenia-hid # (stub) XInput xenia-debugger # in-memory trace, breakpoints, step modes xenia-analysis # function/xref analysis, assembly formatter, SQLite DbWriter xenia-app # `xenia-rs` CLI binary ``` ## CLI Build: ```sh cargo build --release ``` The binary `xenia-rs` accepts XEX2 files or ISO / XISO disc images as input (the loader auto-detects discs and extracts `default.xex`). ### `info` / `browse` / `disasm` Quick header / disc / first-N-instructions inspection. See `--help`. ### `extract` — unpack PE + metadata ```sh xenia-rs extract [-o ] [--db ] ``` Writes `.pe` (decompressed/decrypted PE image) and `.xex.json` (header metadata). With `--db`, also emits a SQLite database containing the **base tables**: `metadata`, `sections`, `imports`. ### `dis` — full disassembly ```sh xenia-rs dis [-o ] [--db ] [--quiet] ``` Runs function + cross-reference analysis and produces: - assembly text to stdout or `-o ` (unless `--quiet`) - optional SQLite DB with the **base tables + disasm tables**: `functions`, `labels`, `instructions`, `xrefs` ### `exec` — interpret with tracing ```sh xenia-rs exec [-n ] [--db ] [--trace-instructions] [--trace-imports] [--trace-branches] ``` Loads the title, initializes CPU state per xenia-canary, intercepts import thunks with HLE kernel calls, and interprets from the entry point. Without `-n`, runs until halt/fault. With `--db`, produces a DB that is a **superset of `dis --db`** plus opt-in trace tables: | flag | table | rows | |-------------------------|----------------|---------------------------------------------------------| | `--trace-instructions` | `exec_trace` | one row per interpreted instruction (PC, r3/r4, LR, SP) | | `--trace-imports` | `import_calls` | one row per kernel/XAM call (module, ordinal, args) | | `--trace-branches` | `branch_trace` | taken branches classified as `call`/`return`/`jump`/`branch` | ### Cumulative DB layering Each command's DB is a superset of the previous. A single `xenia-rs exec --db full.db --trace-instructions --trace-imports --trace-branches` produces the full picture in one pass — base tables, complete static disassembly, and runtime traces correlatable by address/cycle. ## Performance knobs - **`XENIA_DB_BATCH_SIZE`** — rows per streaming commit / trace-buffer flush (default `100_000`). Lower values reduce memory use; higher values reduce fsync overhead on slow disks. The DB writer uses `journal_mode=OFF`, `synchronous=OFF`, `locking_mode=EXCLUSIVE` and commits in batches; no `ANALYZE` is run at finalize. Indices are created after bulk insertion with progress messages. ## Example queries ```sql -- Top 20 kernel functions called during early init SELECT name, COUNT(*) FROM import_calls GROUP BY name ORDER BY 2 DESC LIMIT 20; -- All basic-block leaders (targets of taken branches) not already labelled SELECT DISTINCT bt.target FROM branch_trace bt LEFT JOIN labels l ON l.address = bt.target WHERE l.address IS NULL; -- Correlate a traced call site with its static disassembly SELECT et.cycle, i.disasm, i.ext_disasm FROM exec_trace et JOIN instructions i ON i.address = et.address WHERE et.address = 0x824AB748 ORDER BY et.cycle; ``` ## License BSD-3-Clause, matching upstream xenia.