This repository has been archived on 2026-09-16. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
xenia-rs/.gitignore
MechaCat02 ac20afb1a9 analysis: complete, correct and faster XEX static analysis
Reworks the `dis --db` static-analysis pipeline. Everything here is derived
from the XEX alone; no run traces.

Completeness
- `.pdata` is now authoritative for function boundaries rather than a hint:
  all 23,073 linker-declared RUNTIME_FUNCTIONs are emitted and `end_address`
  is the declared end, not a prologue-walk guess. Adds tail-call targets
  (with a preceding-terminator fallback for the ~450 KB of .text `.pdata`
  leaves unclaimed): 12,156 -> 25,676 functions.
- New `jumptables.rs`: 394 switch tables / 6,356 case edges recovered from
  941 `bctr` sites. Table words are flagged `instructions.is_data` and kept
  out of the xref pass, and render as `.long` with case labels in `-o`.
- New `rtti.rs`: RTTI is not stripped in this title. 611 type descriptors,
  653 locators, 1,491 base-class records, giving a real inheritance graph
  with mdisp/pdisp/vdisp. Verified against the STL:
  std::out_of_range : std::logic_error : std::exception.
- New `xdbf.rs` + `xenia-xex/resources.rs`: the XDBF/SPA package the XEX
  names via its resource table -- 24 achievements (1000G, matching the
  project's independently derived figure), 888 localized strings across 6
  locales, 25 PNGs, title name/id/version. Located through the entry table,
  not a magic scan; a scan finds a phantom 7th string table where the entry
  table declares 6, which shifts every scan-derived language index.
- Strings scan extended to `.data`; metadata grows from 5 keys to 41.

Correctness
- `instructions.function` was a rolling window -- set at each function start
  and never cleared -- so every word in a `.pdata` gap was attributed to the
  preceding function. 55,227 rows were wrong and the bogus 100% attribution
  hid the gap. Now cleared at `end_address`; 0 wrong, honest 97.0%.
- Shift-JIS scanning accepted half-width katakana, which turned IEEE-754
  float tables into "Japanese" (`3f 66 66 66` = 0.9f reads as "fff"), and
  emitted escaped bytes rather than text. 837 mostly-noise rows -> 115 real
  strings, decoded via encoding_rs, with resync so a run starting one byte
  early reports the true address instead of mangling the first character.
- `indirect_dispatch_candidates` was a cross product, not a resolution: at
  vptr_offset 0 the (offset, slot) match hits nearly every class, so 6,556
  of 6,983 sites produced 1.80M of 1.81M rows (one site claiming 764
  callees) and the derived ind_call edges were 84% of the xrefs table. Adds
  `--max-indirect-candidates` (default 16); over-ceiling sites keep their
  row with a truthful count and a new `truncated` flag but emit no candidate
  rows and no xrefs. 1.81M -> 4,199 candidates, xrefs 2.16M -> 357k.
- xenia-xex: `TLS_INFO` and `DEFAULT_STACK_SIZE` header keys were swapped.
  `get_stack_size()` would have returned the TLS descriptor's file offset;
  it has no callers today, so nothing regressed.

Performance
- DuckDB autocommits per statement, so row-at-a-time INSERT paid a
  transaction + WAL flush per row: 221k rows took 20 minutes and the 1.8M
  candidate rows ~59 more, for an 81-minute build that never finished. One
  big transaction fixes the time but not the cause (uncommitted state grew
  to 16.6 GB RSS). Every table above a few thousand rows now uses the
  Appender; each converted sink documents why its key cannot collide or
  dedupes first. 2m20s wall, 486 MB peak, DB 635 MB -> 318 MB.

Also: 6 new SQL views, `zq.py` gains switch/switches/classes/class/str/
xdbf/ach, and an `analysis_report` example that runs the passes without
building a database. 80 tests pass (29 new).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-10 19:57:14 +02:00

35 lines
768 B
Plaintext

target/
*.iso
*.xiso
*.db
# Claude Code project data: transcripts, subagent logs, and (huge) agent git
# worktrees. ~71k files / 66 GB — must never be scanned by git or the editor.
.claude/
# Audit reports / pre-pass findings (local artifacts, not source)
audit-out/
audit-*.md
audit-runs/
exit-thread-state.json
zq_dis.py
zq_fn.py
# Run logs from stress harnesses and ad-hoc captures
*.stdout
*.stderr
*.log
# Runtime cache artifacts (vkd3d-proton / DXVK shader caches dropped into the
# working dir by the Wine canary build)
vkd3d-proton.cache*
*.dxvk-cache
# local analysis-DB backups (regenerable; too large to track)
*.db.bak*
sylpheed.db.bak-*
sylpheed.db.pre-*.bak
# full-disassembly listings from `dis -o` (133 MB on a retail title, regenerable)
*.asm