Files
Fabian Hamm 13c895abff feat(xexdb): port import-thunk naming + schema-wide foreign keys
Carries `xenia-rs` `harvest/import-thunk-naming` (b4f19f1) across into the
lifted crate. That work was found UNCOMMITTED in the retired repo's working
tree on 2026-09-14 and exists nowhere else: absent from `iterate-4A`, absent
from this crate as lifted. CONSOLIDATION.md Phase 5 ends with "delete the local
clone" and Phase 7 drops the emulator, so it had a deletion scheduled against
it.

Not a cherry-pick. The lift's base is exactly the harvest's parent (8401d4d),
so each file was merged three-way -- lifted vs base vs harvest -- which is what
made the port reviewable: 10 conflicts, 9 of them pure rustfmt reflow from the
lift's formatting pass, and 1 semantic.

The semantic one is insertion ORDER. `xdbf_achievements.image_id` is now a
foreign key onto `xdbf_images(id)`, so the image rows must be inserted before
the achievement rows. The merge moved that block; the conflict was the stale
copy left at the old position.

What arrives:

* **Import-thunk recognition** (`imports.rs`, 338 lines). An XEX import is not
  a PLT jump: the linker emits a four-word thunk whose first two words are
  import RECORDS that the loader rewrites at module load. On disc they are
  still records, so a PowerPC-only decoder prints two meaningless `.long`s in
  front of an indirect branch. This maps every word of every thunk, and every
  direct branch into one, back to its `imports` row. Shape-validated rather
  than trusted: an entry is indexed only when the four words it points at
  actually have the thunk shape.

  Adds `instructions.import_address` (FK onto `imports.address`) and
  `import_role` (`'record'` | `'thunk'` | `'call'`, NULL iff import_address is
  NULL), plus an index. `tools/zq.py` gains `imp` and `impcalls`, and `dis`
  now names imports instead of printing `.long 0x01010194`.

* **Sixteen schema-wide foreign keys**, declared wherever a column is derived
  from another table. CREATE TABLE and insertion order become load-bearing.

  `functions` is deliberately NOT an FK parent and the golden test now asserts
  zero inbound FKs onto it: DuckDB implements UPDATE as delete+insert, so one
  inbound FK would make `functions.name` un-updatable and break
  `apply_re_symbols.sql`, which re-applies RE symbol names after every
  regeneration.

The database path needed no change in the binary: `DbWriter` builds its own
index inside `ingest_instructions` from `info.import_libraries`. Only the two
output paths (`enrich_section` for JSONL, `write_asm`) take it as an argument.

Verified: `cargo test -p sylpheed-xexdb` = 10 passed / 0 failed, including
`db_schema_golden` (41s, builds a real DuckDB) which locks the 16-FK set and
the no-FK-onto-functions rule. `cargo clippy -p sylpheed-xexdb --all-targets
-- -D warnings` clean; `cargo fmt --all --check` clean.

Stacked on #32 -- it ports into a crate that only exists there.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 20:43:16 +02:00

49 lines
1.6 KiB
Rust

// 🔴 THREE LINTS ARE OFF FOR THIS CRATE, WITH REASONS, RATHER THAN SILENTLY.
//
// * `needless_range_loop` — nine sites index `reg[r]` where **`r` is the
// PowerPC register number**. The index is the meaning; an iterator hides
// which GPR a pattern matched, which is the whole content of these passes.
// * `too_many_arguments` — five analysis passes take the image, its base, the
// section table, the function list and several output sinks. Bundling those
// into a struct moves the list rather than shortening it, and this code
// arrived whole from a retired repository: a refactor here would be an
// unreviewed edit dressed as a lint fix.
// * `type_complexity` — one return type in `vtables.rs`, same argument.
//
// Everything else clippy asked for was fixed, including every doc-indent site.
// See `docs/agents/CONSOLIDATION.md` Phase 3.
#![allow(
clippy::needless_range_loop,
clippy::too_many_arguments,
clippy::type_complexity
)]
pub mod db;
pub mod demangle;
pub mod disasm;
pub mod eh_scope;
pub mod formatter;
pub mod func;
pub mod funcptr_arrays;
pub mod imports;
pub mod ind_dispatch_typed;
pub mod indirect;
pub mod jumptables;
pub mod lookup;
pub mod ppc;
pub mod rtti;
pub mod sinks;
pub mod sql_views;
pub mod static_init;
pub mod strings;
pub mod vtables;
pub mod xdbf;
pub mod xref;
mod ordinals;
pub use db::{BranchTraceEntry, DbWriter, ExecTraceEntry, ImportCallEntry};
pub use disasm::{RichDisasmItem, enrich_section};
pub use imports::{ImportRole, ImportSites};
pub use ordinals::resolve_ordinal;
pub use xref::{Xref, XrefKind, XrefMap, resolve_source_label};