From 0a75bc687f02ef9beab4a08491d92e88085aea59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikolas=20H=C3=A4m=C3=A4l=C3=A4inen?= Date: Fri, 30 Oct 2026 13:14:15 +0200 Subject: [PATCH] feat(db,emitter,tui,cg,analyzer): resolve jump-vector _LVO equates and preserve biased EAPCIndex code cells - Add BuildJumpVectorLVOMap, FormatVectoredOpStr, and SortedJumpVectorSlots in internal/db to resolve non-zero disp(aN) jump-vector calls/jumps to _LVO_ equates (with duplicate-target disambiguation and disp==0 EAAddrInd parity guard). - Emit _LVO_ equ blocks in src/equates.i (and single-file header) and format vectored operands across emitter, TUI listing/XRefs, call graph (cg), hunks disasm, and hunks search. - Fix multi-element CellDataB/CellDataW/CellDataL emission in emitter and CLI disasm/search. - Scope Step 6 interior-label CODE cell invalidation in stage2DiscoverCode to HUNK_RELOC32 targets and exclude biased d8(PC,Xn) (EAPCIndex) base addresses from dataReadTargets so instructions containing biased index base labels (e.g. hunk6:0x0BF4) are preserved and emit interior equ definitions. - Wrap pre-analysis cell cleanup in applyCodeHintsBatch inside ctrl.WithActiveSeg. --- MANUAL.md | 36 ++-- cmd/hunks/agent_cmds.go | 100 ++++++++--- internal/analyzer/stage2_code.go | 13 +- internal/callgraph/callgraph.go | 62 ++++++- internal/db/controller.go | 287 ++++++++++++++++++++++++++++++- internal/emitter/emitter.go | 95 +++++++--- internal/emitter/emitter_test.go | 134 +++++++++++++++ internal/tui/listing.go | 15 +- internal/tui/popups.go | 7 +- 9 files changed, 663 insertions(+), 86 deletions(-) diff --git a/MANUAL.md b/MANUAL.md index 8abd49d..c3372ac 100644 --- a/MANUAL.md +++ b/MANUAL.md @@ -521,11 +521,11 @@ hunks -m frontier cg hunk3:LAB_3_2649E --code Output: ```text === Incoming Callers (up to depth 2) === - ◄── hunk5:LAB_5_2A71A (+2A79E, via jsr 402(a5)) - ◄── hunk5:LAB_5_24BE8 (+24EB8, via jsr 498(a5)) + ◄── hunk5:LAB_5_2A71A (+2A79E, via jsr _LVO_LAB_3_2649E(a5)) + ◄── hunk5:LAB_5_24BE8 (+24EB8, via jsr _LVO_LAB_5_2A71A(a5)) ◄── hunk6:LAB_6_0020C (+0020C, via jmp) ◄── hunk6:LAB_6_001AC (+001AC, via jmp) - ◄── hunk9:LAB_9_068F8 (+069A2, via jsr 402(a5)) + ◄── hunk9:LAB_9_068F8 (+069A2, via jsr _LVO_LAB_3_2649E(a5)) === Target Function === hunk3:LAB_3_2649E [UNRENAMED] [+2649E] — 15 insts, 56 bytes [XDEF] @@ -544,16 +544,16 @@ LAB_3_2649E: +264D2 rts === Caller Site Snippets === - From hunk5:LAB_5_2A71A (+2A79E, via jsr 402(a5)): + From hunk5:LAB_5_2A71A (+2A79E, via jsr _LVO_LAB_3_2649E(a5)): +2A792: move.w 12(a2),d0 +2A796: moveq #4,d1 +2A798: moveq #64,d2 - >> +2A79E: jsr 402(a5) ; -> hunk3:LAB_3_2649E + >> +2A79E: jsr _LVO_LAB_3_2649E(a5) ; -> hunk3:LAB_3_2649E +2A7A2: movem.l (a7)+,d7/a0-a4 ``` Notice how `--code` reveals: 1. `LAB_3_2649E` calls the Paula audio routine `LAB_3_0005E` (`HW: AUD0LCH..AUD3LCH`). -2. Every caller across `hunk5`, `hunk6`, and `hunk9` invokes it via `jsr 402(a5)`. +2. Every caller across `hunk5`, `hunk6`, and `hunk9` invokes it via `jsr _LVO_LAB_3_2649E(a5)` (offset `402`). 3. The caller snippet at `+2A79E` shows the exact register arguments (`d0` = pitch/period, `d1` = sound effect ID `< $0F`, `d2` = volume `64`). #### 4. Edit `src//*.asm` Directly & Track Bottom-Up Progress @@ -655,15 +655,15 @@ hunks -m frontier tui 2. Press `g`, type `+2503E` (or `hunk5:LAB_5_25036`), and press `Enter`. 3. Cursor lands on: ```text - +2503E jsr 498(a5) ; → hunk5:LAB_5_2A71A + +2503E jsr _LVO_LAB_5_2A71A(a5) ; → hunk5:LAB_5_2A71A ``` -4. Press `Enter` on that line: the TUI resolves `498(a5)` through the `hunk6` vector table and jumps directly to `LAB_5_2A71A` (`+2A71A`). -5. Press `x` on `LAB_5_2A71A`: the **XREFs** popup opens listing every direct and `jsr 498(a5)` caller across `hunk5`, `hunk6`, `hunk8`, and `hunk9`: +4. Press `Enter` on that line: the TUI resolves `_LVO_LAB_5_2A71A(a5)` (`498(a5)`) through the `hunk6` vector table and jumps directly to `LAB_5_2A71A` (`+2A71A`). +5. Press `x` on `LAB_5_2A71A`: the **XREFs** popup opens listing every direct and `jsr _LVO_LAB_5_2A71A(a5)` caller across `hunk5`, `hunk6`, `hunk8`, and `hunk9`: ```text - hunk5 +24EB8 VEC_CALL (in LAB_5_24E84) jsr 498(a5) - hunk5 +2503E VEC_CALL (in LAB_5_25036) jsr 498(a5) + hunk5 +24EB8 VEC_CALL (in LAB_5_24E84) jsr _LVO_LAB_5_2A71A(a5) + hunk5 +2503E VEC_CALL (in LAB_5_25036) jsr _LVO_LAB_5_2A71A(a5) hunk6 +0020C CODE_BRANCH (in LAB_6_0001A) jmp LAB_5_2A71A.l - hunk8 +007EE VEC_CALL (in LAB_8_007EA) jsr 498(a5) + hunk8 +007EE VEC_CALL (in LAB_8_007EA) jsr _LVO_LAB_5_2A71A(a5) ``` 6. Select any caller and press `Enter` to jump to it (automatically switching segments if in another hunk), or press `Backspace` / `-` to return. @@ -696,15 +696,15 @@ This guarantees zero symbol collisions across hunks (even when two hunks have la Emitted `; XREF:` comments above labels list the **enclosing caller label** and **instruction mnemonic** (deduplicated and wrapped at 4 callers per line), never synthetic memory addresses: - **Same-hunk reference:** `; XREF: LAB_0_00000 (beq.b), LAB_0_00046 (bsr.b)` - **Cross-hunk reference:** `; XREF: hunk5:LAB_5_27772 (addi.l)` -- **Jump-vector reference:** `; XREF: hunk5:LAB_5_24E84 (jsr 498(a5)), hunk6:LAB_6_0001A (jmp)` +- **Jump-vector reference:** `; XREF: hunk5:LAB_5_24E84 (jsr _LVO_LAB_5_2A71A(a5)), hunk6:LAB_6_0001A (jmp)` Every caller listed in `; XREF:` can be jumped to immediately in `src/hunk*.asm` via `rg "^