mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-27 22:45:39 -04:00
702b94fd7d
- PhaseEnd_Phase10.md: resident engine blob byte-identical from source (8e17e02f) at 100% INCLUDE_ASM; the binary-agnostic toolchain proven on a real 2nd binary; main still 143dbb89 - docs/SETUP.md §6.7: the resident first-instantiation + the reusable flat-blob <bin> recipe (per-binary OBJS prune, build_path=build, flat config, leading-data-word-as-rodata); 2 new Ghidra tools in the inventory (R21) - rule R24 (per-binary compiler/SDK provenance — resident is PsyQ 4.7 vs EXE 4.0) - worklog archived CURRENT_PHASE.md -> phase-ends/logs/Phase10.md (R19) - bumps project version 1.9.0 -> 1.10.0
103 lines
9.4 KiB
Markdown
103 lines
9.4 KiB
Markdown
# CURRENT_PHASE — Phase 10: Resident engine blob (splat config + all-asm byte-match)
|
|
|
|
**Generation:** Gen2 (phase 3 of the 8→9→**10**→11→{12,13}→14 arc) · **Started:** 2026-06-15
|
|
**Plan approved:** yes (gate 1 passed) · **Effort:** planning Max (done); execution xHigh (T2→Max if the split fights)
|
|
**Plan file:** `/home/musashi/.claude/plans/plan-mode-enabled-max-giggly-hollerith.md`
|
|
|
|
## Milestone (gate 2)
|
|
`make build BINARY=resident && make check BINARY=resident` → SHA1 **`8e17e02ff8954d07c979449198f7e1645046b353`**
|
|
at 100% INCLUDE_ASM, with `main` still **`143dbb89f34491258bbc27810d0a12ec8b43a8dd`** (no regression).
|
|
|
|
## Target facts (verified this session)
|
|
- File: `extracted/retail/MAIN.CD.dir/FILE_010.dir/1.1` — **365,404 B**, SHA1 `8e17e02f…`, PAC **type-1 (uncompressed)**, gitignored, manifest-verified.
|
|
- Load **vram 0x800CEDF8** (Phase-3 T6b proven); `VRAM_BASE`=0x800CEDF8 (fileoff 0→vram). Computed **end vram 0x80128154** (4 B under overlay slot 0x80128158 — boundary corroboration).
|
|
- First word = data `0x00000036`; code at +0x04. **Flat image, NO header segment.**
|
|
- Alias `resident`, basename `resident`. Paths: `build/resident/`, `config/splat.resident.yaml`, `config/check.resident.sha`, `config/symbols.resident.txt`, `.run/sig.resident.jsonl`, `asm/resident/`, `src/resident/`.
|
|
|
|
## Decisions locked (owner-confirmed 2026-06-15)
|
|
- Ghidra = **second program** in the `bfm` project (not a region in main).
|
|
- **Defer** EXE→resident pointer table (Q#2) to Phase 11/12.
|
|
- **Keep stacked** `symbol_addrs_path: [config/symbols.us.txt, config/symbols.resident.txt]` — 0 func syms in the resident window, 27 shared engine globals in symbols.us.txt the blob references; byte-identity is symbol-name-independent (no relocations).
|
|
- c-mode INCLUDE_ASM (match-ready); asm-mode is the de-risk fallback for the milestone.
|
|
|
|
## Tasks
|
|
- [x] **T1 — Scaffold `resident` instance + prove no-op on `main`** (xHigh) ✅ DONE
|
|
- Makefile: `BINARIES += resident`; `resident_*` block; per-binary OBJS prune-list (`<bin>_ASM_DIR`/`SRC_DIR` + `$(BINARIES)`-derived prune); per-binary `UNDEF_SYMS`/`UNDEF_FUNCS` aliases (resident→`build/resident/undefined_*`).
|
|
- `config/splat.resident.yaml` (flat, no header, no gp_value, single code seg c-mode, stacked symbols, per-binary asm/src/build/undefined paths, find_file_boundaries False).
|
|
- `config/check.resident.sha` (seed `8e17e02f… resident`); `config/symbols.resident.txt` (provenance banner, count=0).
|
|
- Exit: (a) main `make clean&&extract&&build&&check`→`143dbb89…` (refactor is a no-op); (b) `make extract BINARY=resident` completes; (c) interleave check: `make build BINARY=main` after a resident extract still green.
|
|
- [x] **T2 — Iterate split to byte-identical (THE milestone)** (xHigh) ✅ DONE — **MILESTONE REACHED**
|
|
- Converge subseg boundaries vs SHA1; handle leading data word; confirm -G0 (grep `($gp)`); ld_interleave only if a rodata island appears.
|
|
- Exit: clean-rebuild → `8e17e02f…`, last byte @0x80128154; main re-verified `143dbb89…`. **→ progress report to Drew.**
|
|
- [x] **T3 — Close per-binary tooling gaps** (xHigh) ✅ DONE
|
|
- `diff_settings.py` + `tools/progress.py` + `tools/difficulty.py` + `tools/dup_report.py` get a `resident` entry; `expected` made per-binary-safe (no sibling clobber).
|
|
- Exit: `make report BINARY=resident` shows 100% INCLUDE_ASM; `make expected BINARY=resident` no-clobber; main report unchanged.
|
|
- [x] **T4 — Ghidra 2nd program + seed `config/symbols.resident.txt`** (xHigh) ✅ DONE
|
|
- **+ parameterized `make sig-refresh` by BINARY** (per-binary GHIDRA_PROG; resident → `.run/sig.resident.jsonl`).
|
|
- Import blob as 2nd program @0x800CEDF8 (MCP stopped for the lock); auto-analysis + PsyQ sigs + DetectPsyQ; light seeding; export blob-only symbols (R13/R15, never merged into symbols.us.txt).
|
|
- Exit: rebuild still `8e17e02f…` (symbols don't change bytes); R9 persistence; R23 stop-MCP-before-commit.
|
|
- [ ] **Phase close** — P7 checkbox sweep; gate-2 milestone confirm (Drew); PhaseEnd_Phase10.md (Tier-1 Max); archive CURRENT_PHASE.md→logs/Phase10.md (R19); R18 recap; P8 hard stop.
|
|
|
|
## Commit cadence
|
|
Per-task checkpoint commits, each byte-gated (R20 + Phase 8/9 precedent). Claude commits locally; **Drew pushes** (R6). T4 commit includes Ghidra DB → **stop MCP first** (R23).
|
|
|
|
## Key finding (T4, 2026-06-15) — resident is PsyQ **4.7.0**, not 4.0.0
|
|
DetectPsyQ on the imported resident program reports **PsyQ Version = 470** (the EXE is 4.0.0); the import
|
|
associated a `psyq470` source archive alongside `psyq400`; the one PsyQ-signature hit in-range is `DsMix`
|
|
(libsnd → the resident holds the sound driver). **Drew (2026-06-15): the archive.org PsyQ link has the 4.7
|
|
libs.** Provenance (G5): detected, to be CONFIRMED in Phase 11/12 by linking real 4.7 libs and byte-matching.
|
|
**Implication:** the resident's PsyQ library linking (Phase 11/12) uses **4.7**, not the EXE's 4.0 — so the
|
|
4.7 `.LIB`s are a needed asset (R20: stage the hard-to-source tooling). Does NOT affect the Phase-10
|
|
byte-match (100% INCLUDE_ASM, no resident code compiled yet).
|
|
**DECISION (Drew 2026-06-15): DEFER the 4.7 `.LIB`s to Phase 11 START (archive.org link); CARRY this
|
|
finding into PhaseEnd_Phase10 "Notes for Future Phases" so Phase 11 fetches+sha-verifies them then. Phase 10
|
|
needs nothing from PsyQ 4.7.** → also record provenance in docs/memory-map.md.
|
|
|
|
## Blockers
|
|
(none)
|
|
|
|
## Worklog
|
|
- 2026-06-15: Phase planned (Max), 3 Explore + 1 Plan agent; gate-1 approved. Beginning T1.
|
|
- 2026-06-15: **T1 DONE.** Makefile: `BINARIES += resident`; `resident_*` block; per-binary
|
|
`ASM_DIR`/`SRC_DIR` + `$(BINARIES)`-derived OBJS prune-list; per-binary `UNDEF_SYMS`/`UNDEF_FUNCS`.
|
|
New: `config/splat.resident.yaml` (flat, no header, no gp_value, single `c` seg @0x800CEDF8,
|
|
stacked symbols, per-binary undefined paths under build/resident/), `config/check.resident.sha`
|
|
(8e17e02f…), `config/symbols.resident.txt` (R13 banner, 0 entries). **Gates all green:** (a) main
|
|
clean rebuild → `143dbb89…` (refactor = no-op); (b) `make extract BINARY=resident` → 144 INCLUDE_ASM
|
|
stubs, src/resident/resident.c + .ld @vram 0x800CEDF8; (c) main OBJS still 81 (excludes resident)
|
|
+ main rebuild `143dbb89…` with resident on disk (prune isolates). `src/resident/*.c` left untracked
|
|
WIP (reshaped by T2 boundary carving — commit at T2). Committed config+Makefile checkpoint.
|
|
- 2026-06-15: **T2 DONE — MILESTONE REACHED.** Mapped the blob structure vs the bytes:
|
|
word0 = data header (0x36); clean code 0x4..0x4610 (145 funcs, 0 embedded jtbls/trap-ops);
|
|
data tail 0x4610..EOF (pointer tables + 78.5 KB zero run). Split = `[0x0, rodata, hdr]` +
|
|
`[0x4, c, resident]` + `[0x4610, data, tail]`. Two fixes found: (1) leading word before code
|
|
fights section_order → emit it as **rodata** (no-dot; section_order places .rodata first) — a
|
|
1-word analogue of main's island, NO ld_interleave; (2) `build_path: build` (not build/resident)
|
|
so the .ld's object paths match the Makefile's `build/asm/**`+`build/src/**` rules.
|
|
**`make build BINARY=resident` → `8e17e02f…` BYTE-IDENTICAL** (365,404 B, end vram 0x80128154);
|
|
-G0 confirmed (0 gp refs); R22 clean-rebuild green; main still `143dbb89…`. src/resident/resident.c
|
|
(143 stubs) now committed (boundaries final). asm/resident/** regenerated (gitignored, like main).
|
|
- 2026-06-15: **T3 DONE.** `resident` entries added to diff_settings.py + progress/difficulty/dup_report.
|
|
Two real bugs fixed: (1) dup_report crashed on the absent `.run/sig.resident.jsonl` → now writes a
|
|
placeholder + exits 0 (sig is a T4 Ghidra export); (2) progress.py listed MAIN's LINKED libs for
|
|
resident → scoped `linked_subsegs()` to BINARY==main (library linking is the EXE's layout, Phase 8).
|
|
`expected` made per-binary-safe (merge-copy, no `rm -rf expected/build` sibling clobber — verified
|
|
both baselines coexist). Reports: resident = 0 REAL / 143 stubs / 100% INCLUDE_ASM; main UNCHANGED
|
|
(52 REAL / 959 LINKED / 50.24%). Carried into T4: parameterize `make sig-refresh` by BINARY.
|
|
- 2026-06-15: **T4 DONE.** New reusable tooling: `tools/ghidra_import_raw.sh` (BinaryLoader + base +
|
|
PSX:LE:32 — the Gen2 raw-blob importer, reusable for Phase-13 overlays) and
|
|
`tools/ghidra_scripts/DefineFunctions.java` (seed splat's validated boundaries — raw-binary
|
|
auto-analysis finds only the reachable subset). Imported the resident as the bfm project's **4th
|
|
program** `resident` @0x800CEDF8; auto-analysis (PsyQ sigs) → **PsyQ 4.7.0 detected** + `DsMix`
|
|
(libsnd) named. Defined splat's 143 boundaries (created=120/existed=23/failed=0); **R9-verified
|
|
143 funcs persisted** via read-only sig-refresh. Seeded `config/symbols.resident.txt` with `DsMix`
|
|
(R13 candidate); re-extract applied it; **resident + main both clean-rebuild byte-identical** (R22).
|
|
Makefile: per-binary `GHIDRA_PROG` → `make sig-refresh BINARY=resident`. dup_report now real
|
|
(6 byte-identical groups intra-resident — Phase-11 dedup fodder). Ghidra DB committed (R23, MCP
|
|
stopped): new `resident` program (00000003.*) + main's incidental db.15→db.16 no-op renumber.
|
|
**4.7 libs DEFERRED to Phase 11 (Drew) — carry to PhaseEnd Notes.**
|
|
- 2026-06-15: **T5 / phase close.** P7 checkbox sweep complete (all 4 tasks + roadmap items met).
|
|
Final clean-rebuild proof presented; **Drew confirmed gate 2.** SETUP §6.7 extended with the
|
|
flat-blob recipe + 2 new tools (R21). PhaseEnd_Phase10.md written (Tier-1 Max). Rule R24 proposed
|
|
(per-binary SDK provenance). This worklog archived → logs/Phase10.md (R19). v1.9.0 → v1.10.0.
|