# 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.
