Files
xenia-rs/README.md
MechaCat02 c694bb3f43 Initial commit: xenia-rs workspace for Xbox 360 RE
Rust reimplementation of the xenia Xbox 360 emulator targeting reverse-
engineering and preservation, initially scoped to Project Sylpheed.

Includes:
- XEX2 loader (LZX decompression, AES decryption, PE parsing)
- XISO / XGD2 disc image VFS
- PPC interpreter with 200+ opcodes and VMX128 decoding
- Static analyzer: functions, cross-references, labels, asm + SQLite output
- HLE kernel covering the xboxkrnl/xam subset used by Sylpheed init
- Debugger with in-memory and SQLite-backed execution tracing
- `xenia-rs` CLI with extract/dis/exec commands that produce cumulative,
  superset SQLite databases and opt-in instruction/import/branch traces

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-16 23:14:56 +02:00

133 lines
5.2 KiB
Markdown

# 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 <xex-or-iso> [-o <out-dir>] [--db <sqlite-path>]
```
Writes `<name>.pe` (decompressed/decrypted PE image) and `<name>.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 <xex-or-iso> [-o <asm-file>] [--db <sqlite-path>] [--quiet]
```
Runs function + cross-reference analysis and produces:
- assembly text to stdout or `-o <file>` (unless `--quiet`)
- optional SQLite DB with the **base tables + disasm tables**:
`functions`, `labels`, `instructions`, `xrefs`
### `exec` — interpret with tracing
```sh
xenia-rs exec <xex-or-iso> [-n <max-instrs>] [--db <sqlite-path>]
[--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 <iso> --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.