feat(phase-19): T2 recovery tooling — canon_resident_calls + no-proto caller fix (3 matches)

- R14 finding: the 3 Phase-18 "implicit-int / propagate-first" near-misses are NOT
  implicit-int (reproduced each through the byte-gate). Real classes:
  (a) resident-callee LINK-miss: draft calls func_<ADDR> but the addr has a curated
      name (0x8004CFEC = ratan2) -> "undefined reference to func_8004CFEC". NEW
      tools/canon_resident_calls.py rewrites func_<ADDR> -> curated name (pure draft
      text, body bytes unchanged) -> run FIRST in the recovery pipeline.
  (b) shared-caller ARITY conflict: an engine_core.h caller macro declares the callee
      file-scope `extern void func_X(void)` then calls func_X(); the real def takes an
      arg -> "conflicting types". FIX = caller extern -> no-proto `extern void func_X();`
      (byte-neutral for the caller; compatible with promotion-safe params int/long/ptr).
- 3 matches banked in ov_SC01_077: func_8017209C (ratan2 rewrite), func_80147514 (s32),
  func_80168F40 (void*); 2 no-proto lines in src/shared/engine_core.h
- recovery pipeline: draft -> canon_resident_calls -> sig_unify -> harvest_verify --chunk 1
- make check-all 136/136 BYTE-IDENTICAL (full extract, R22); dedup 1450 validated/0 failed;
  0 NON_MATCHING in any default build (G4); fleet 56.64% (the 3 are ov_SC01_077-local,
  x134 propagation rides T3/Phase-20)
- cookbook §17a-3 corrected (R14/R16); SETUP tool inventory (R21); CURRENT_PHASE T2 done
This commit is contained in:
Drew T
2026-06-20 17:12:00 -06:00
parent dce768a269
commit 85afa0dc81
10 changed files with 492 additions and 113 deletions
+1
View File
@@ -669,6 +669,7 @@ Every script under `tools/` (plus the two report make-targets), grouped by purpo
| | `tools/dedup_propagate.py` | **(Phase 15, cookbook §14)** Match-once → propagate-many: lift a matched body, author a `DEFINE_func_<ADDR>()` macro in `src/shared/engine_core.h`, instantiate it at every onboarded overlay sharing that `h_exact`, byte-gate each (fail-closed), register in `dedup.us.yaml`. `--addr`/`--auto-from`/`--check-only`. `find_site` accepts brace on the same OR next line (Phase-15 fix — next-line-brace defs were silently un-propagated). |
| | `tools/sig_unify.py` | **(Phase 15, cookbook §14d)** Deterministic hard-tail recovery: unify a gate-failing draft's FULL signature set — callee externs **and** the draft's OWN definition signature — to the banked-canonical decls (`--overlay`/`--in`/`--out`); the whole-binary byte-gate stays the arbiter. Recovered 32 of 191 standalone-MATCH conflict-blocked drafts, zero agent tokens. |
| | `tools/gen_harvest_targets.py` / `tools/canon_draft_decls.py` / `tools/build_engine_types.py` | Callee-sig-aware target manifest (§14b/c) / callee-extern canonicalizer (§14c) / additive shared-types-header extractor (`src/shared/engine_types.h`, §14 struct). |
| | `tools/canon_resident_calls.py` | **(Phase 19 / T2, cookbook §17a-3a)** Link-miss recovery: rewrite each `func_<ADDR>` in a draft to the **curated** resident symbol name when that address has one in the stacked symbol files (`0x8004CFEC`→`ratan2`), so the linker resolves it. Pure draft-text (body bytes unchanged); **run FIRST** in the recovery pipeline `draft → canon_resident_calls → sig_unify → harvest_verify`. |
| | `config/dedup.us.yaml` / `src/shared/*.h` | The code-share registry + the shared bodies (one macro → N sites, byte-gated). |
| | `make report` / `make sig-refresh` / `make sig-overlays` | Convenience targets: reports (+`--cross`) / Ghidra signature-dump / Ghidra-free sign all 134 overlays. |
+90 -90
View File
@@ -1,95 +1,23 @@
# Unmatched difficulty inventory (generated by tools/difficulty.py — harvest queue)
unmatched functions : 1801
trivial (<=5 ins) : 14
non-jtbl leaves : 236 (best harvest targets)
unmatched functions : 858
trivial (<=5 ins) : 0
non-jtbl leaves : 108 (best harvest targets)
jump-table funcs : 58 (deferred — need the rodata-island workflow, Task 2')
## Easiest 120 unmatched (score asc) — the work queue
| score | name | nins | br | calls | jtbl | leaf |
|---|---|---|---|---|---|---|
| 3 | func_80147054 | 3 | 0 | 0 | - | Y |
| 3 | func_80147060 | 3 | 0 | 0 | - | Y |
| 3 | func_8014706C | 3 | 0 | 0 | - | Y |
| 3 | func_8014708C | 3 | 0 | 0 | - | Y |
| 3 | func_801470A0 | 3 | 0 | 0 | - | Y |
| 3 | func_801470B4 | 3 | 0 | 0 | - | Y |
| 4 | func_8012DFBC | 4 | 0 | 0 | - | Y |
| 4 | func_80165900 | 4 | 0 | 0 | - | Y |
| 5 | func_80129428 | 5 | 0 | 0 | - | Y |
| 5 | func_8012AD50 | 5 | 0 | 0 | - | Y |
| 5 | func_8012AD6C | 5 | 0 | 0 | - | Y |
| 5 | func_8012BF54 | 5 | 0 | 0 | - | Y |
| 5 | func_801472DC | 5 | 0 | 0 | - | Y |
| 5 | func_801658EC | 5 | 0 | 0 | - | Y |
| 6 | func_80148D24 | 6 | 0 | 0 | - | Y |
| 8 | func_80174684 | 8 | 0 | 0 | - | Y |
| 9 | func_8012A304 | 9 | 0 | 0 | - | Y |
| 9 | func_80151184 | 9 | 0 | 0 | - | Y |
| 9 | func_80174650 | 9 | 0 | 0 | - | Y |
| 10 | func_8012A0E0 | 8 | 0 | 1 | - | - |
| 10 | func_8013C964 | 10 | 0 | 0 | - | Y |
| 10 | func_8014C8C8 | 10 | 0 | 0 | - | Y |
| 10 | func_80150E84 | 8 | 0 | 1 | - | - |
| 10 | func_80150EA4 | 8 | 0 | 1 | - | - |
| 10 | func_80165A50 | 10 | 0 | 0 | - | Y |
| 11 | func_8012CC64 | 9 | 0 | 1 | - | - |
| 11 | func_8013C938 | 11 | 0 | 0 | - | Y |
| 11 | func_80143C74 | 9 | 0 | 1 | - | - |
| 11 | func_80147264 | 11 | 0 | 0 | - | Y |
| 11 | func_8014C860 | 11 | 0 | 0 | - | Y |
| 11 | func_80150BA4 | 9 | 0 | 1 | - | - |
| 11 | func_8017AE08 | 9 | 0 | 1 | - | - |
| 12 | func_8012CBA4 | 10 | 0 | 1 | - | - |
| 12 | func_8012CBCC | 10 | 0 | 1 | - | - |
| 12 | func_8012CBF4 | 10 | 0 | 1 | - | - |
| 12 | func_8013B568 | 12 | 0 | 0 | - | Y |
| 12 | func_80144A68 | 10 | 0 | 1 | - | - |
| 12 | func_80146D90 | 10 | 0 | 1 | - | - |
| 12 | func_8014B12C | 10 | 0 | 1 | - | - |
| 12 | func_8014B2A8 | 10 | 0 | 1 | - | - |
| 12 | func_8014B2D0 | 10 | 0 | 1 | - | - |
| 12 | func_80156648 | 10 | 0 | 1 | - | - |
| 12 | func_80172560 | 10 | 0 | 1 | - | - |
| 12 | func_80172738 | 10 | 0 | 1 | - | - |
| 12 | func_80173174 | 10 | 0 | 1 | - | - |
| 12 | func_8017427C | 10 | 0 | 1 | - | - |
| 12 | func_8017435C | 10 | 0 | 1 | - | - |
| 12 | func_80174784 | 10 | 0 | 1 | - | - |
| 12 | func_80174824 | 10 | 0 | 1 | - | - |
| 12 | func_8017A220 | 10 | 0 | 1 | - | - |
| 12 | func_8017A248 | 10 | 0 | 1 | - | - |
| 12 | func_8017A270 | 10 | 0 | 1 | - | - |
| 13 | func_8014AD7C | 11 | 0 | 1 | - | - |
| 13 | func_80165910 | 10 | 1 | 0 | - | Y |
| 13 | func_80179E48 | 11 | 0 | 1 | - | - |
| 13 | func_80179E74 | 11 | 0 | 1 | - | - |
| 14 | func_80129220 | 10 | 0 | 2 | - | - |
| 14 | func_8012A018 | 12 | 0 | 1 | - | - |
| 14 | func_80130AC4 | 11 | 1 | 0 | - | Y |
| 14 | func_80131C78 | 12 | 0 | 1 | - | - |
| 14 | func_8013A9F8 | 11 | 1 | 0 | - | Y |
| 14 | func_80146DB8 | 12 | 0 | 1 | - | - |
| 14 | func_8014BCC0 | 11 | 1 | 0 | - | Y |
| 14 | func_80153C44 | 12 | 0 | 1 | - | - |
| 14 | func_80155F80 | 12 | 0 | 1 | - | - |
| 14 | func_80172B14 | 12 | 0 | 1 | - | - |
| 14 | func_801737B8 | 12 | 0 | 1 | - | - |
| 14 | func_801738DC | 12 | 0 | 1 | - | - |
| 14 | func_80174C80 | 12 | 0 | 1 | - | - |
| 14 | func_80179F14 | 12 | 0 | 1 | - | - |
| 14 | func_8017A094 | 12 | 0 | 1 | - | - |
| 14 | func_8017A0C4 | 12 | 0 | 1 | - | - |
| 15 | func_8012E4C8 | 15 | 0 | 0 | - | Y |
| 15 | func_80131FA0 | 15 | 0 | 0 | - | Y |
| 15 | func_80131FDC | 15 | 0 | 0 | - | Y |
| 15 | func_801425CC | 15 | 0 | 0 | - | Y |
| 15 | func_80146994 | 13 | 0 | 1 | - | - |
| 15 | func_8014C568 | 13 | 0 | 1 | - | - |
| 15 | func_80151944 | 15 | 0 | 0 | - | Y |
| 15 | func_8015CC74 | 15 | 0 | 0 | - | Y |
| 15 | func_8015CFC0 | 15 | 0 | 0 | - | Y |
| 15 | func_8015D4E8 | 15 | 0 | 0 | - | Y |
| 15 | func_8015DAF8 | 15 | 0 | 0 | - | Y |
| 15 | func_8015DE58 | 15 | 0 | 0 | - | Y |
| 15 | func_8015E1B8 | 15 | 0 | 0 | - | Y |
@@ -104,27 +32,99 @@ jump-table funcs : 58 (deferred — need the rodata-island workflow, Task
| 15 | func_8016084C | 15 | 0 | 0 | - | Y |
| 15 | func_80160B34 | 15 | 0 | 0 | - | Y |
| 15 | func_80160EA4 | 15 | 0 | 0 | - | Y |
| 15 | func_80161A00 | 12 | 1 | 0 | - | Y |
| 15 | func_80161A30 | 12 | 1 | 0 | - | Y |
| 15 | func_80161A60 | 12 | 1 | 0 | - | Y |
| 15 | func_80165624 | 13 | 0 | 1 | - | - |
| 15 | func_8016CB84 | 15 | 0 | 0 | - | Y |
| 15 | func_8016FFA8 | 13 | 0 | 1 | - | - |
| 15 | func_801735B8 | 13 | 0 | 1 | - | - |
| 15 | func_801855A0 | 15 | 0 | 0 | - | Y |
| 15 | func_801855DC | 15 | 0 | 0 | - | Y |
| 15 | func_80185870 | 15 | 0 | 0 | - | Y |
| 15 | func_80185970 | 15 | 0 | 0 | - | Y |
| 15 | func_801867E0 | 15 | 0 | 0 | - | Y |
| 16 | func_8012A828 | 14 | 0 | 1 | - | - |
| 16 | func_8012A8B0 | 14 | 0 | 1 | - | - |
| 16 | func_8012BEE8 | 10 | 2 | 0 | - | Y |
| 16 | func_80144988 | 16 | 0 | 0 | - | Y |
| 16 | func_80146360 | 16 | 0 | 0 | - | Y |
| 16 | func_80146E98 | 10 | 2 | 0 | - | Y |
| 16 | func_8014B160 | 12 | 0 | 2 | - | - |
| 16 | func_8014C278 | 14 | 0 | 1 | - | - |
| 16 | func_801542A4 | 14 | 0 | 1 | - | - |
| 16 | func_80158AB4 | 12 | 0 | 2 | - | - |
| 16 | func_8015BE94 | 12 | 0 | 2 | - | - |
| 16 | func_8016197C | 10 | 2 | 0 | - | Y |
| 16 | func_8016F4C4 | 12 | 0 | 2 | - | - |
| 16 | func_801705C0 | 14 | 0 | 1 | - | - |
| 16 | func_801732C4 | 12 | 0 | 2 | - | - |
| 16 | func_8017331C | 12 | 0 | 2 | - | - |
| 16 | func_80173374 | 12 | 0 | 2 | - | - |
| 16 | func_80174554 | 12 | 0 | 2 | - | - |
| 16 | func_801745AC | 12 | 0 | 2 | - | - |
| 16 | func_8017EA2C | 12 | 0 | 2 | - | - |
| 17 | func_8015AD08 | 13 | 0 | 2 | - | - |
| 17 | func_8015CC0C | 13 | 0 | 2 | - | - |
| 17 | func_8015CF58 | 13 | 0 | 2 | - | - |
| 17 | func_8015D4B4 | 13 | 0 | 2 | - | - |
| 17 | func_8015E184 | 13 | 0 | 2 | - | - |
| 17 | func_8015EDD4 | 13 | 0 | 2 | - | - |
| 17 | func_8015F7A0 | 13 | 0 | 2 | - | - |
| 17 | func_80160B00 | 13 | 0 | 2 | - | - |
| 18 | func_8013B7AC | 18 | 0 | 0 | - | Y |
| 18 | func_80161208 | 14 | 0 | 2 | - | - |
| 18 | func_8016F0AC | 14 | 0 | 2 | - | - |
| 18 | func_801726D0 | 16 | 0 | 1 | - | - |
| 18 | func_801746A4 | 14 | 0 | 2 | - | - |
| 19 | func_80141C0C | 17 | 0 | 1 | - | - |
| 19 | func_80161C98 | 14 | 1 | 1 | - | - |
| 19 | func_80161D20 | 14 | 1 | 1 | - | - |
| 19 | func_80171928 | 17 | 0 | 1 | - | - |
| 19 | func_80175414 | 16 | 1 | 0 | - | Y |
| 19 | func_80181B58 | 17 | 0 | 1 | - | - |
| 19 | func_801829E0 | 17 | 0 | 1 | - | - |
| 20 | func_80146A6C | 18 | 0 | 1 | - | - |
| 20 | func_8014BD60 | 14 | 2 | 0 | - | Y |
| 20 | func_8014C168 | 14 | 2 | 0 | - | Y |
| 20 | func_80157788 | 16 | 0 | 2 | - | - |
| 20 | func_801577C8 | 16 | 0 | 2 | - | - |
| 20 | func_8016E918 | 17 | 1 | 0 | - | Y |
| 20 | func_80178970 | 15 | 1 | 1 | - | - |
| 20 | func_8017E0B4 | 14 | 0 | 3 | - | - |
| 20 | func_8017E6BC | 14 | 0 | 3 | - | - |
| 20 | func_8017E830 | 14 | 0 | 3 | - | - |
| 20 | func_80181B9C | 18 | 0 | 1 | - | - |
| 21 | func_80142740 | 14 | 1 | 2 | - | - |
| 21 | func_80158880 | 19 | 0 | 1 | - | - |
| 21 | func_801653B8 | 15 | 0 | 3 | - | - |
| 21 | func_8016DA30 | 19 | 0 | 1 | - | - |
| 21 | func_801710DC | 17 | 0 | 2 | - | - |
| 21 | func_801711FC | 15 | 0 | 3 | - | - |
| 21 | func_80175268 | 21 | 0 | 0 | - | Y |
| 21 | func_8017DD9C | 19 | 0 | 1 | - | - |
| 21 | func_80182FD0 | 19 | 0 | 1 | - | - |
| 22 | func_801427EC | 19 | 1 | 0 | - | Y |
| 22 | func_8014292C | 19 | 1 | 0 | - | Y |
| 22 | func_80142978 | 19 | 1 | 0 | - | Y |
| 22 | func_801429C4 | 19 | 1 | 0 | - | Y |
| 22 | func_801627E8 | 19 | 1 | 0 | - | Y |
| 22 | func_8016D64C | 15 | 1 | 2 | - | - |
| 22 | func_8016E778 | 20 | 0 | 1 | - | - |
| 22 | func_80172C50 | 20 | 0 | 1 | - | - |
| 22 | func_80175218 | 20 | 0 | 1 | - | - |
| 22 | func_80178B70 | 18 | 0 | 2 | - | - |
| 22 | func_8017B8E8 | 22 | 0 | 0 | - | Y |
| 22 | func_8017E128 | 18 | 0 | 2 | - | - |
| 22 | func_8017E170 | 17 | 1 | 1 | - | - |
| 22 | func_80184278 | 20 | 0 | 1 | - | - |
| 23 | func_8013373C | 18 | 1 | 1 | - | - |
| 23 | func_80138BE0 | 20 | 1 | 0 | - | Y |
| 23 | func_8015430C | 19 | 0 | 2 | - | - |
| 23 | func_80163408 | 21 | 0 | 1 | - | - |
| 23 | func_801741A8 | 17 | 0 | 3 | - | - |
| 23 | func_80182E30 | 19 | 0 | 2 | - | - |
| 23 | func_80185A94 | 16 | 1 | 2 | - | - |
| 24 | func_801288E8 | 22 | 0 | 1 | - | - |
| 24 | func_80128940 | 22 | 0 | 1 | - | - |
| 24 | func_80128998 | 22 | 0 | 1 | - | - |
| 24 | func_8013BC7C | 24 | 0 | 0 | - | Y |
| 24 | func_8014CCB4 | 22 | 0 | 1 | - | - |
| 24 | func_8014D04C | 22 | 0 | 1 | - | - |
| 24 | func_8014D3E0 | 22 | 0 | 1 | - | - |
| 24 | func_8014D738 | 22 | 0 | 1 | - | - |
| 24 | func_8014DF3C | 22 | 0 | 1 | - | - |
| 24 | func_8014E434 | 22 | 0 | 1 | - | - |
| 24 | func_8014E6A0 | 22 | 0 | 1 | - | - |
| 24 | func_8014E934 | 22 | 0 | 1 | - | - |
| 24 | func_8014ED28 | 22 | 0 | 1 | - | - |
| 24 | func_8014F1F4 | 22 | 0 | 1 | - | - |
| 24 | func_8014F468 | 22 | 0 | 1 | - | - |
| 24 | func_8014F6F4 | 22 | 0 | 1 | - | - |
| 24 | func_8014FBC0 | 22 | 0 | 1 | - | - |
| 24 | func_8014FCFC | 22 | 0 | 1 | - | - |
+152
View File
@@ -0,0 +1,152 @@
# EXE-wide duplicate function groups (generated by tools/dup_report.py)
# sig: .run/sig.ov_SC01_077.jsonl sha1=7a50e451e5a100d77579cb3c1979f9ec1782612f (2585 funcs, 2274 with nins>=8)
# Match the representative once -> share the body to the duplicates (h_exact = guaranteed
# byte-match; h_norm = same source, re-point any single address constant).
## h_exact (byte-identical) — nins>=8: 24 groups, 36 redundant (collapsible)
| score | nins | count | representative | duplicates |
|---|---|---|---|---|
| 328 | 41 | 8 | func_80151fb4 (0x80151fb4) | 0x801522cc 0x801525f4 0x80152ac8 0x80152c80 0x80152fbc 0x8015327c 0x80153550 |
| 186 | 93 | 2 | func_8014ffdc (0x8014ffdc) | 0x801502ec |
| 94 | 47 | 2 | func_8015dcb8 (0x8015dcb8) | 0x8015e018 |
| 90 | 18 | 5 | func_8015220c (0x8015220c) | 0x80152a08 0x80152efc 0x801531bc 0x80153490 |
| 57 | 19 | 3 | func_80134310 (0x80134310) | 0x80134a28 0x80134fb8 |
| 54 | 27 | 2 | func_801530e4 (0x801530e4) | 0x801533a4 |
| 42 | 21 | 2 | func_8017e668 (0x8017e668) | 0x8017e7dc |
| 40 | 20 | 2 | func_80170068 (0x80170068) | 0x80170100 |
| 39 | 13 | 3 | func_8015a1c8 (0x8015a1c8) | 0x8015ac90 0x8015cf24 |
| 38 | 19 | 2 | func_8015773c (0x8015773c) | 0x801585ec |
| 34 | 17 | 2 | func_8015bd8c (0x8015bd8c) | 0x8015bf04 |
| 32 | 16 | 2 | func_80169fe0 (0x80169fe0) | 0x8016dee0 |
| 28 | 14 | 2 | func_8012a828 (0x8012a828) | 0x8012a8b0 |
| 28 | 14 | 2 | func_8017e6bc (0x8017e6bc) | 0x8017e830 |
| 26 | 13 | 2 | func_8012931c (0x8012931c) | 0x80162fc0 |
| 26 | 13 | 2 | func_8015da5c (0x8015da5c) | 0x8015dfe4 |
| 24 | 8 | 3 | func_8015d524 (0x8015d524) | 0x8015fa24 0x80165c58 |
| 24 | 12 | 2 | func_8016f4c4 (0x8016f4c4) | 0x8017ea2c |
| 24 | 12 | 2 | func_8016f5e0 (0x8016f5e0) | 0x80170c44 |
| 22 | 11 | 2 | func_8016fb50 (0x8016fb50) | 0x8016fc64 |
| 20 | 10 | 2 | func_801732f4 (0x801732f4) | 0x801733a4 |
| 18 | 9 | 2 | func_801598bc (0x801598bc) | 0x80162414 |
| 16 | 8 | 2 | func_80150150 (0x80150150) | 0x80150460 |
| 16 | 8 | 2 | func_80168a88 (0x80168a88) | 0x8016ed6c |
## h_norm (structural) — nins>=8: 115 groups, 333 redundant (collapsible)
| score | nins | count | representative | duplicates |
|---|---|---|---|---|
| 384 | 8 | 48 | func_80128158 (0x80128158) | 0x80128178 0x80128198 0x801281b8 0x801281d8 0x801281f8 0x80128228 0x80128248 0x80128268 0x8012a8e8 0x80136c1c 0x80149704 0x80149724 0x80149788 0x80149864 0x801498c0 0x80149c94 0x80149cb4 0x8014a218 0x8014a4fc 0x8014a830 0x8014ab5c 0x8014abf0 0x80151110 0x80151924 0x80155f60 0x8015be74 0x8015bec4 0x8015bee4 0x8015ccb0 0x8015cffc 0x8015f360 0x80160ee0 0x80164db0 0x80168a88 0x8016ed6c 0x8016efa8 0x80172760 0x801747ac 0x801749a8 0x8017ade8 0x8017dacc 0x8017de64 0x8017e1b4 0x80180910 0x80182968 0x80183a50 0x8018448c |
| 384 | 12 | 32 | func_8014b160 (0x8014b160) | 0x80158ab4 0x8015be94 0x80161d58 0x80165a20 0x8016f494 0x8016f4c4 0x8016f5b0 0x8016f5e0 0x8016f680 0x8016f6b0 0x8016f7d4 0x8017041c 0x801704ec 0x801706e8 0x80170718 0x80170c14 0x80170c44 0x8017115c 0x801717f4 0x80171824 0x80171854 0x801732c4 0x8017331c 0x80173374 0x801733cc 0x80174158 0x801743c0 0x801744b0 0x80174554 0x801745ac 0x8017ea2c |
| 336 | 14 | 24 | func_80142740 (0x80142740) | 0x801555bc 0x80157e00 0x80158000 0x80158288 0x80159bac 0x8015a2a0 0x8015ad78 0x8015c08c 0x8015c750 0x8015d544 0x8015db34 0x8015de94 0x8015e1f4 0x8015e924 0x8015ee44 0x8015f048 0x8015f810 0x80160174 0x801603d8 0x80160888 0x8016fd7c 0x80183a70 0x80184aec |
| 330 | 22 | 15 | func_8014ccb4 (0x8014ccb4) | 0x8014d04c 0x8014d3e0 0x8014d738 0x8014df3c 0x8014e434 0x8014e6a0 0x8014e934 0x8014ed28 0x8014f1f4 0x8014f468 0x8014f6f4 0x8014fbc0 0x8014fcfc 0x80150480 |
| 328 | 41 | 8 | func_80151fb4 (0x80151fb4) | 0x801522cc 0x801525f4 0x80152ac8 0x80152c80 0x80152fbc 0x8015327c 0x80153550 |
| 224 | 14 | 16 | func_8016f540 (0x8016f540) | 0x8016f578 0x8016f610 0x8016f648 0x8017280c 0x80172920 0x80172cdc 0x80172de8 0x80173580 0x80173738 0x80173824 0x80173948 0x80173b88 0x801742e0 0x8017e6bc 0x8017e830 |
| 216 | 108 | 2 | func_8014dd8c (0x8014dd8c) | 0x8014e284 |
| 190 | 10 | 19 | func_8014b12c (0x8014b12c) | 0x8014b2a8 0x8014b2d0 0x8015e588 0x80171884 0x80172738 0x80172ed4 0x80172efc 0x80172f24 0x80173174 0x8017329c 0x801732f4 0x8017334c 0x801733a4 0x8017427c 0x8017435c 0x8017452c 0x80174584 0x801745dc |
| 190 | 95 | 2 | func_8014fe60 (0x8014fe60) | 0x80150170 |
| 186 | 93 | 2 | func_8014ffdc (0x8014ffdc) | 0x801502ec |
| 162 | 18 | 9 | func_80151980 (0x80151980) | 0x80152094 0x801523ac 0x80152868 0x80152ba8 0x80152d60 0x8015309c 0x8015335c 0x80153d34 |
| 150 | 75 | 2 | func_8012b8e4 (0x8012b8e4) | 0x8012ba10 |
| 150 | 30 | 5 | func_80152254 (0x80152254) | 0x80152a50 0x80152f44 0x80153204 0x801534d8 |
| 148 | 37 | 4 | func_80142838 (0x80142838) | 0x80142f68 0x801430f4 0x801432fc |
| 135 | 15 | 9 | func_8016fccc (0x8016fccc) | 0x8017018c 0x80170338 0x80170584 0x80170634 0x80170f38 0x80170fec 0x801710a0 0x801711fc |
| 124 | 62 | 2 | func_80145934 (0x80145934) | 0x80145a2c |
| 123 | 41 | 3 | func_8012b2cc (0x8012b2cc) | 0x8012b370 0x8012b414 |
| 118 | 59 | 2 | func_80176ff4 (0x80176ff4) | 0x80177340 |
| 114 | 57 | 2 | func_8012c354 (0x8012c354) | 0x8012c438 |
| 110 | 22 | 5 | func_80166244 (0x80166244) | 0x8016629c 0x801662f4 0x8016634c 0x801663a4 |
| 108 | 27 | 4 | func_801320d8 (0x801320d8) | 0x80132144 0x801321b0 0x8013221c |
| 108 | 18 | 6 | func_80170928 (0x80170928) | 0x80170970 0x801709b8 0x80170a00 0x80170a48 0x80170a90 |
| 96 | 24 | 4 | func_801428cc (0x801428cc) | 0x80142ffc 0x80143188 0x80143390 |
| 94 | 47 | 2 | func_8015dcb8 (0x8015dcb8) | 0x8015e018 |
| 90 | 18 | 5 | func_8015220c (0x8015220c) | 0x80152a08 0x80152efc 0x801531bc 0x80153490 |
| 88 | 44 | 2 | func_8015dbd4 (0x8015dbd4) | 0x8015df34 |
| 78 | 13 | 6 | func_8015da5c (0x8015da5c) | 0x8015dc84 0x8015dfe4 0x8015e84c 0x8015e880 0x8015e8b4 |
| 75 | 15 | 5 | func_8016f870 (0x8016f870) | 0x8016f920 0x8016fdf0 0x8016ff6c 0x8017027c |
| 74 | 37 | 2 | func_8014ed80 (0x8014ed80) | 0x8014f24c |
| 72 | 36 | 2 | func_8017eec0 (0x8017eec0) | 0x8017f024 |
| 70 | 14 | 5 | func_80161208 (0x80161208) | 0x80161418 0x80161450 0x801614e4 0x8016151c |
| 68 | 34 | 2 | func_801495c4 (0x801495c4) | 0x8014964c |
| 68 | 34 | 2 | func_8014d0a4 (0x8014d0a4) | 0x8014d438 |
| 60 | 20 | 3 | func_80172780 (0x80172780) | 0x80172894 0x80172c50 |
| 58 | 29 | 2 | func_80155e30 (0x80155e30) | 0x801576a8 |
| 57 | 19 | 3 | func_80134310 (0x80134310) | 0x80134a28 0x80134fb8 |
| 54 | 27 | 2 | func_801530e4 (0x801530e4) | 0x801533a4 |
| 54 | 27 | 2 | func_80157158 (0x80157158) | 0x80163664 |
| 52 | 13 | 4 | func_8015a1c8 (0x8015a1c8) | 0x8015ac90 0x8015cf24 0x8015f738 |
| 52 | 13 | 4 | func_8015a1fc (0x8015a1fc) | 0x8015a230 0x8016b3f4 0x80170b14 |
| 52 | 26 | 2 | func_8015db6c (0x8015db6c) | 0x8015decc |
| 52 | 26 | 2 | func_801657d8 (0x801657d8) | 0x80165874 |
| 50 | 10 | 5 | func_80146d90 (0x80146d90) | 0x80147a84 0x80147aac 0x80147f50 0x80163234 |
| 48 | 8 | 6 | func_8012d38c (0x8012d38c) | 0x801376c8 0x80150cc4 0x8016b428 0x8016ba48 0x80174c60 |
| 48 | 8 | 6 | func_80147928 (0x80147928) | 0x8014799c 0x80147a10 0x80162f60 0x80162f80 0x80162fa0 |
| 48 | 16 | 3 | func_801526d4 (0x801526d4) | 0x80152c40 0x80157880 |
| 46 | 23 | 2 | func_8014ca14 (0x8014ca14) | 0x8014ca88 |
| 44 | 22 | 2 | func_80147860 (0x80147860) | 0x80162f08 |
| 42 | 14 | 3 | func_80161240 (0x80161240) | 0x80161554 0x8016158c |
| 42 | 21 | 2 | func_8016edec (0x8016edec) | 0x8016ee40 |
| 42 | 21 | 2 | func_8017e668 (0x8017e668) | 0x8017e7dc |
| 40 | 20 | 2 | func_80170068 (0x80170068) | 0x80170100 |
| 40 | 20 | 2 | func_80172f9c (0x80172f9c) | 0x80172fec |
| 38 | 19 | 2 | func_8015773c (0x8015773c) | 0x801585ec |
| 36 | 18 | 2 | func_80146a6c (0x80146a6c) | 0x80146ab4 |
| 36 | 9 | 4 | func_8016f264 (0x8016f264) | 0x8016f2c8 0x8016f30c 0x8016f350 |
| 36 | 18 | 2 | func_80170b48 (0x80170b48) | 0x801730b4 |
| 36 | 12 | 3 | func_80172b14 (0x80172b14) | 0x801737b8 0x801738dc |
| 34 | 17 | 2 | func_8012a68c (0x8012a68c) | 0x8012a758 |
| 34 | 17 | 2 | func_80147ad4 (0x80147ad4) | 0x80147b18 |
| 34 | 17 | 2 | func_8015bd8c (0x8015bd8c) | 0x8015bf04 |
| 32 | 16 | 2 | func_8012b864 (0x8012b864) | 0x8012b8a4 |
| 32 | 16 | 2 | func_80149544 (0x80149544) | 0x80149584 |
| 32 | 16 | 2 | func_80154150 (0x80154150) | 0x801541d8 |
| 32 | 16 | 2 | func_80154a74 (0x80154a74) | 0x80154ae0 |
| 32 | 16 | 2 | func_80157788 (0x80157788) | 0x801577c8 |
| 32 | 16 | 2 | func_80169fe0 (0x80169fe0) | 0x8016dee0 |
| 32 | 8 | 4 | func_8016f288 (0x8016f288) | 0x8016f2a8 0x8016f2ec 0x8016f330 |
| 32 | 16 | 2 | func_8016fa44 (0x8016fa44) | 0x8016fc24 |
| 32 | 16 | 2 | func_8016fb10 (0x8016fb10) | 0x80172a8c |
| 32 | 16 | 2 | func_801743f0 (0x801743f0) | 0x801751d8 |
| 32 | 16 | 2 | func_801757a0 (0x801757a0) | 0x801757e0 |
| 30 | 15 | 2 | func_80170da4 (0x80170da4) | 0x80170e70 |
| 28 | 14 | 2 | func_801288b0 (0x801288b0) | 0x801289f0 |
| 28 | 14 | 2 | func_8012a828 (0x8012a828) | 0x8012a8b0 |
| 28 | 14 | 2 | func_8012e32c (0x8012e32c) | 0x8016f0ac |
| 28 | 14 | 2 | func_801746a4 (0x801746a4) | 0x801746dc |
| 26 | 13 | 2 | func_8012931c (0x8012931c) | 0x80162fc0 |
| 26 | 13 | 2 | func_80155518 (0x80155518) | 0x8015554c |
| 26 | 13 | 2 | func_801574dc (0x801574dc) | 0x80157510 |
| 26 | 13 | 2 | func_80159b08 (0x80159b08) | 0x80159b3c |
| 26 | 13 | 2 | func_8015bdd0 (0x8015bdd0) | 0x8015be04 |
| 26 | 13 | 2 | func_8015bf48 (0x8015bf48) | 0x8015bf7c |
| 26 | 13 | 2 | func_8015c6ac (0x8015c6ac) | 0x8015c6e0 |
| 26 | 13 | 2 | func_8015cc0c (0x8015cc0c) | 0x8015cc40 |
| 26 | 13 | 2 | func_8015cf58 (0x8015cf58) | 0x8015cf8c |
| 26 | 13 | 2 | func_8015d480 (0x8015d480) | 0x8015d4b4 |
| 26 | 13 | 2 | func_8015da90 (0x8015da90) | 0x8015dac4 |
| 26 | 13 | 2 | func_8015ddf0 (0x8015ddf0) | 0x8015de24 |
| 26 | 13 | 2 | func_8015e150 (0x8015e150) | 0x8015e184 |
| 26 | 13 | 2 | func_8015eda0 (0x8015eda0) | 0x8015edd4 |
| 26 | 13 | 2 | func_8015efa4 (0x8015efa4) | 0x8015efd8 |
| 26 | 13 | 2 | func_8015f2bc (0x8015f2bc) | 0x8015f2f0 |
| 26 | 13 | 2 | func_8015f76c (0x8015f76c) | 0x8015f7a0 |
| 26 | 13 | 2 | func_8015fa44 (0x8015fa44) | 0x8015fa78 |
| 26 | 13 | 2 | func_801600d0 (0x801600d0) | 0x80160104 |
| 26 | 13 | 2 | func_80160334 (0x80160334) | 0x80160368 |
| 26 | 13 | 2 | func_801607e4 (0x801607e4) | 0x80160818 |
| 26 | 13 | 2 | func_80160acc (0x80160acc) | 0x80160b00 |
| 26 | 13 | 2 | func_80160e3c (0x80160e3c) | 0x80160e70 |
| 26 | 13 | 2 | func_8016ffa8 (0x8016ffa8) | 0x801735b8 |
| 24 | 8 | 3 | func_80153c9c (0x80153c9c) | 0x80165958 0x80165988 |
| 24 | 12 | 2 | func_80154274 (0x80154274) | 0x801542dc |
| 24 | 12 | 2 | func_80154b4c (0x80154b4c) | 0x80154b98 |
| 24 | 8 | 3 | func_8015d524 (0x8015d524) | 0x8015fa24 0x80165c58 |
| 24 | 12 | 2 | func_8016ed8c (0x8016ed8c) | 0x8016edbc |
| 22 | 11 | 2 | func_8016fb50 (0x8016fb50) | 0x8016fc64 |
| 20 | 10 | 2 | func_8012bee8 (0x8012bee8) | 0x80146e98 |
| 20 | 10 | 2 | func_80174784 (0x80174784) | 0x80174824 |
| 18 | 9 | 2 | func_80146578 (0x80146578) | 0x8014659c |
| 18 | 9 | 2 | func_80149350 (0x80149350) | 0x8014942c |
| 18 | 9 | 2 | func_80155fb0 (0x80155fb0) | 0x80155fd4 |
| 18 | 9 | 2 | func_801598bc (0x801598bc) | 0x80162414 |
| 16 | 8 | 2 | func_80146534 (0x80146534) | 0x80165938 |
| 16 | 8 | 2 | func_80150150 (0x80150150) | 0x80150460 |
+29 -5
View File
@@ -1142,11 +1142,35 @@ worked-example templates). Measured on ov_SC01_077 tractable reach-134 residuals
which conflicts with your real def. FIX = reconcile that one line to the real sig (`void func_X(void);`).
(Proven: func_8012A418.) A standalone `match_one` MATCH that fails the whole-binary gate with
`conflicting types for func_X / previous declaration` is this class — grep the overlay `.c` for `func_X`.
3. **Implicit-int caller plumbing (deferred class).** If an EARLIER-positioned caller in the same `.c` calls
`func_X` with no visible decl, gcc-2.7.2 (K&R) creates an implicit `int func_X()` that conflicts with the
later real def — but there is NO sibling decl to grep. Adding a forward extern at the file top can itself
collide; the clean resolution is that `dedup_propagate` puts the def in `engine_core.h` (included first) →
the implicit-int never forms. (3 such fns deferred to Phase 19 — propagate-first, gate-after.)
3. **~~Implicit-int caller plumbing~~ → CORRECTED (Phase 19 / T2, R14): two distinct real classes, NOT
implicit-int, and propagate-first does NOT fix them.** The 3 "deferred" fns (func_80147514, func_80168F40,
func_8017209C) were reproduced through the gate to find the ACTUAL blocker (R14 — verify the framing against
the bytes). Neither is implicit-int; `dedup_propagate` (def → `engine_core.h`) would NOT have resolved
either (the def still lands at its address-order site, after any file-scope caller extern). The two classes:
- **(3a) Resident-callee LINK-miss** (func_8017209C). The draft calls a resident EXE/engine function by
`func_<ADDR>`, but that address carries a **curated name** in `config/symbols.us.txt` (e.g.
`0x8004CFEC = ratan2`). The linker resolves the curated name, not `func_<ADDR>` → the draft *compiles* but
fails to **link** (`undefined reference to func_8004CFEC`) → the gate (correctly) reverts. **FIX =
`tools/canon_resident_calls.py`** rewrites every `func_<ADDR>` whose address has a curated `// func` name to
that name (extern + call), a pure draft-text transform (body bytes unchanged) → **run it FIRST in the
recovery pipeline.** Proven: func_8017209C byte-identical after `func_8004CFEC`→`ratan2`.
- **(3b) Shared-caller ARITY conflict** (func_80147514 = `s32`, func_80168F40 = `void *`). An already-banked
**shared caller macro** in `engine_core.h` (e.g. `DEFINE_func_80147478`, instantiated at a *lower* address)
declares the callee **file-scope** as `extern void func_X(void);` (void = no args) then calls `func_X();` —
but func_X's real def takes an argument → `conflicting types for func_X / previous declaration` (NOT
implicit-int; it's an explicit `(void)` proto). **FIX = change that caller macro's extern to no-prototype
`extern void func_X();`** (K&R): byte-neutral for the caller (the empty call is identical), and a no-proto
decl is **compatible** with a def whose params are **default-promotion-safe** (`int`/`s32`/`long`/pointer —
NOT `char`/`short`/`float`; the narrow-param wall §3 of the toolkit still applies there). The macro lives in
the shared header, so **fleet-re-gate** (`make check-all`). Proven: func_80147514 + func_80168F40, all
136/136 byte-identical, byte-neutral on every overlay (only ov_SC01_077 carries the def; the other 133 keep
the stub, where a declaration-only change emits no code).
**The recovery pipeline is therefore: `draft → canon_resident_calls → sig_unify → harvest_verify --chunk 1`**
(canon_resident_calls first so link-miss names are fixed before any signature unification; sig_unify still
mandatory for def/callee-sig canonicalization). The 3b no-proto move is a separate, one-time edit per
caller/callee pair (it touches the shared header) — apply it when the gate reports `conflicting types … (void)`
from a shared-caller macro and the def's params are promotion-safe.
**Two NEW residual classes found at scale (beyond the §17 quirks):**
- **Per-file `-O0` class.** ~18 functions in ov_SC01_077 were built `-O0` (prologue sig `21F0A003` =
+4 -4
View File
@@ -3,11 +3,11 @@
# source-derived (committed src/*.c + config/dedup.us.yaml). Live byte gate: `make check-all`;
# cross-binary collapsible-byte leverage: docs/duplicates.cross.md.
FLEET REAL substantive : 193192 (of which dedup-shared 192702 via 1450 groups / 192746 instances)
FLEET REAL substantive : 193201 (of which dedup-shared 192702 via 1450 groups / 192746 instances)
FLEET LINKED PsyQ objs : 959
FLEET byte-identical : 194839 / 344010 = 56.64% (REAL+LINKED+empties)
FLEET byte-identical : 194848 / 344010 = 56.64% (REAL+LINKED+empties)
FLEET NON_MATCHING : 7 (0 in any default build — G4)
FLEET INCLUDE_ASM stubs : 149164
FLEET INCLUDE_ASM stubs : 149155
FLEET matchable : 344010
| binary | REAL | shared | LINKED | byte-ident | matchable | byte-ident % |
@@ -22,7 +22,7 @@ FLEET matchable : 344010
| ov_SC01_008 | 1434 | 1434 | 0 | 1436 | 2428 | 59.1% |
| ov_SC01_009 | 1434 | 1434 | 0 | 1435 | 2510 | 57.2% |
| ov_SC01_074 | 1434 | 1434 | 0 | 1436 | 2427 | 59.2% |
| ov_SC01_077 | 1717 | 1402 | 0 | 1719 | 2586 | 66.5% |
| ov_SC01_077 | 1726 | 1402 | 0 | 1728 | 2586 | 66.8% |
| ov_SC01_080 | 1438 | 1438 | 0 | 1438 | 2515 | 57.2% |
| ov_SC01_084 | 1438 | 1438 | 0 | 1443 | 2581 | 55.9% |
| ov_SC02_000 | 1442 | 1442 | 0 | 1449 | 2684 | 54.0% |
File diff suppressed because one or more lines are too long
+4 -3
View File
@@ -15,7 +15,7 @@
## Tasks
- [x] **T1 — Per-file -O0 split-file lever** — DONE (re-scoped by Drew: bank infra + 6, defer rest). The 3-object split works (`ov_SC01_077_a` before / `ov_SC01_077_o0` -O0 / `ov_SC01_077` after — a single object's .text can't be split around a middle object). **6/16 -O0 fns matched** byte-perfect (`func_8013B568/B7F4/BD34/C360/C938/C964`). **DEFERRED to Phase 20:** the 10 remaining -O0 fns hit an indexed-global `%lo`-folding codegen quirk (gcc-source research, R17 — our cc1 materializes the address, the original folds %lo); AND the ×134 per-overlay rollout (engine_core.h compiles -O2, can't carry -O0 fns → each overlay needs its own -O0 split). Two findings corrected the Phase-18 backlog's "afternoon, free ×134" premise (R14).
- [ ] **T2 — Recovery tooling.** `tools/cast_call_sites.py` (call-site fn-ptr casts) + implicit-int propagate-first. Build/validate on `.run/drafts-p18s1/` near-misses.
- [x] **T2 — Recovery tooling (light) — DONE.** R14 finding overturned the Phase-18 "implicit-int / propagate-first" framing: reproducing the 3 deferred near-misses through the gate showed **3 distinct real classes** (none implicit-int). (a) **Resident-callee link-miss** (func_8017209C calls `func_8004CFEC` = curated `ratan2`) → built **`tools/canon_resident_calls.py`** (rewrite `func_<ADDR>`→curated name; pipeline runs it FIRST). (b) **Shared-caller arity conflict** (func_80147514 `s32`, func_80168F40 `void*`): an engine_core.h caller macro declares the callee file-scope `extern void func_X(void)` → `conflicting types`; **FIX = caller extern → no-proto `extern void func_X();`** (byte-neutral, promotion-safe params). `cast_call_sites.py` NOT needed (the §17a "call-site cast = #1 miss" did not appear here; deferred to T3 if real near-misses need it). **3 matches banked** in ov_SC01_077 (byte-gated); 2 no-proto lines in engine_core.h; **`make check-all` 136/136 byte-identical** (R22); dedup-check 1450 validated/0 failed. Recovery pipeline = `draft → canon_resident_calls → sig_unify → harvest_verify --chunk 1` (cookbook §17a corrected, SETUP inventory, R16/R21).
- [ ] **T3 — Scale waves (2–3 batches of 50, Ultracode).** Regen Ghidra-C for fresh targets, `gen_harvest_targets.py` manifest, Step-1 wave prompt → recovery (T2) → gate → `dedup_propagate` ×134 → checkpoint → improve. Each batch = a progress report.
- [ ] **T4 — (CONDITIONAL) gcc-research spike.** Only on a blocking residual class (loop-guard order `func_8012C2D0`; §10 schedule `func_8014F2E0`).
- [ ] **PhaseEnd** — verify all checkboxes (P7), demonstrate milestone, write `PhaseEnd_Phase19.md` (+ `## Plain-English Recap`, R25; Phase-20 backlog), archive worklog (R19).
@@ -28,13 +28,14 @@
- 2026-06-20 — Phase started; plan approved (gate 1); task list built (R28); CURRENT_PHASE.md created. Beginning T1.
- 2026-06-20 — T1: built + proved the 3-object -O0 split infra; matched 6/16 -O0 fns (ov_SC01_077 d19c9580). Two consults with Drew on T1 scope: (1) full -O0 rollout chosen, then (2) on discovering the remaining fns are research-grade (the %lo quirk), Drew chose "bank 6 + infra, defer rest to Phase 20." Fleet unchanged (the 6 are ov_SC01_077-local until rollout). Verified main/resident/ov_SC01_077/+2 byte-identical. Committed (commit:0158 + cookbook §18 commit:0159). → T2.
- 2026-06-20 — T2 scoping finding (R14): examined Phase-18's actual near-misses (.run/drafts-p18s1-recover*/) — the recoveries were mostly **def-signature canonicalization** (ret→void, params→void*/int), which **`sig_unify` already does**, + a data-type reconcile (`struct Q16`→`BigCopy`) + a whitespace fix. The §17a "call-site casts = #1 miss" did NOT show up in these. So T2 is lighter than planned: confirm sig_unify is wired draft→`sig_unify`→gate, add the implicit-int **propagate-first** helper (3 fns: func_80147514/80168F40/8017209C → def into engine_core.h, gate after) + a small data-type-reconcile, and treat call-site-casts as a thin add only if T3's real near-misses need it. **SESSION CHECKPOINT here (Drew) — resume fresh.**
- 2026-06-20 — **T2 DONE.** Resumed fresh, rebuilt task list (R28), /effort max. Reproduced the 3 deferred near-misses through the gate (R14) → the "implicit-int / propagate-first" premise was WRONG: real classes are (a) resident-callee link-miss → new `tools/canon_resident_calls.py` (func_8017209C ✓), (b) shared-caller arity conflict → caller-extern no-proto fix (func_80147514 + func_80168F40 ✓). func_8012A418 isn't a stub in ov_SC01_077 (not a target; already Phase-18-reconciled). **3 matches banked**, 2 engine_core.h no-proto lines, **make check-all 136/136 byte-identical** (full extract + R22), dedup 1450/0, fleet 56.64% (194,848 — the 3 are ov_SC01_077-local, ×134 propagation rides T3/Phase-20: func_80147514/F40 inline named structs need engine_types.h lifting, func_8017209C propagatable). Cookbook §17a corrected, SETUP inventory updated. Pipeline now `draft → canon_resident_calls → sig_unify → harvest_verify`. → **T3 (the +3-5% lever).**
## ▶ RESUME HERE (fresh session)
1. Re-read load order + this file. Rebuild the harness task list (R28). `/effort max`.
2. **T2 (light):** wire/confirm the draft→`sig_unify`→`harvest_verify` recovery pipeline; build the implicit-int propagate-first helper + data-type-reconcile; validate on the `.run/drafts-p18s1-recover*` near-misses; commit. (cast_call_sites.py only if T3 near-misses actually need it.)
2. ~~T2~~ **DONE** (committed) — `canon_resident_calls.py` + the no-proto caller-extern fix; 3 matches banked; check-all 136/136. Recovery pipeline = `draft → canon_resident_calls → sig_unify → harvest_verify`.
3. **T3 (the main lever, +3-5%):** regen Ghidra-C for fresh tractable reach-134 fns (`DecompileFunctions.java`, headless — MCP stopped, R23/R29); `gen_harvest_targets.py` manifest; then **PROMPT Drew for `/effort ultracode` (R26/R27) and WAIT** before launching the wave. Run 2-3 batches of 50 (recover→gate→`dedup_propagate` ×134→checkpoint→improve between batches).
4. Then T4 (conditional) / PhaseEnd.
- State at checkpoint: 2 commits landed (commit:0158, commit:0159); tree clean; fleet 56.64% (T1's 6 are ov_SC01_077-local, not yet fleet-counted — they bank fleet-% only after the Phase-20 ×134 rollout).
- State after T2: commits commit:0158, commit:0159, commit:0160 (T1) + the T2 commit landed; fleet 56.64% (T1's 6 + T2's 3 are ov_SC01_077-local, not yet fleet-counted — they bank fleet-% only after the ×134 rollout). Next = T3.
## Blockers
*(none)*
+107 -3
View File
@@ -749,7 +749,34 @@ DEFINE_func_801474D8() /* dedup: shared engine-core @0x801474D8 (src/shared) */
DEFINE_func_801474EC() /* dedup: shared engine-core @0x801474EC (src/shared) */
INCLUDE_ASM("asm/ov_SC01_077/nonmatchings/ov_SC01_077", func_80147514);
#include "common.h"
struct V4s80147514 { s16 a, b, c, d; };
extern s32 func_80012C6C(s32 a0, s32 a1, s32 a2);
extern s32 func_800129CC(s32 a0, s32 a1);
void func_80147514(s32 arg0) {
s16 buf[8];
*(struct V4s80147514 *)buf = *(struct V4s80147514 *)(arg0 + 0x120);
if (((u16)buf[0] | (u16)buf[1] | (u16)buf[2]) == 0) {
buf[1] = -0xFFF;
}
if (*(s16 *)(arg0 + 0x12E) != 0) {
buf[0] = (u16)buf[0] + *(u16 *)(arg0 + 0x128);
buf[1] = (u16)buf[1] + *(u16 *)(arg0 + 0x12A);
buf[2] = (u16)buf[2] + *(u16 *)(arg0 + 0x12C);
}
*(s16 *)(arg0 + 0x118) = func_80012C6C(*(s16 *)(arg0 + 0x118), buf[0], 8);
*(s16 *)(arg0 + 0x11A) = func_80012C6C(*(s16 *)(arg0 + 0x11A), buf[1], 8);
*(s16 *)(arg0 + 0x11C) = func_80012C6C(*(s16 *)(arg0 + 0x11C), buf[2], 8);
buf[0] = *(u16 *)(arg0 + 0x118);
buf[1] = *(u16 *)(arg0 + 0x11A);
buf[2] = *(u16 *)(arg0 + 0x11C);
func_800129CC((s32)buf, arg0 + 0x100);
}
DEFINE_func_80147628() /* dedup: shared engine-core @0x80147628 (src/shared) */
@@ -3605,7 +3632,51 @@ INCLUDE_ASM("asm/ov_SC01_077/nonmatchings/ov_SC01_077", func_80168D94);
DEFINE_func_80168EC4() /* dedup: shared engine-core @0x80168EC4 (src/shared) */
INCLUDE_ASM("asm/ov_SC01_077/nonmatchings/ov_SC01_077", func_80168F40);
#include "common.h"
extern s32 func_80016A5C();
extern Blk20 D_800AE620;
/* First stack record: sp+0x10 .. sp+0x28 (struct-relative offsets). Mixed widths;
* offsets 0x06/0x0E/0x13/0x17 are never written (alignment gaps). */
struct A {
u16 unk00; u16 unk02; u16 unk04; /* 0x10 0x12 0x14 */
u16 unk06; /* 0x16 (gap) */
u16 unk08; u16 unk0A; u16 unk0C; /* 0x18 0x1A 0x1C */
u16 unk0E; /* 0x1E (gap) */
u8 unk10; u8 unk11; u8 unk12; /* 0x20 0x21 0x22 */
u8 unk13; /* 0x23 (gap) */
u8 unk14; u8 unk15; u8 unk16; /* 0x24 0x25 0x26 */
u8 unk17; /* 0x27 (gap) */
s32 unk18; /* 0x28 */
};
/* Second stack record at sp+0x30. 40 bytes reserved (the frame is 0x60); only the
* leading 8 words (0x30..0x4C) are populated from D_800AE620 via the Bv view. */
struct B { s32 w[8]; s32 tail[2]; };
struct Bv { s32 w[8]; };
void func_80168F40(void *arg0) {
struct A a;
struct B b;
a.unk00 = *(u16 *)((u8 *)arg0 + 0x10);
a.unk02 = *(u16 *)((u8 *)arg0 + 0x14);
a.unk04 = *(u16 *)((u8 *)arg0 + 0x18);
a.unk08 = *(u16 *)((u8 *)arg0 + 0x6);
a.unk0A = *(u16 *)((u8 *)arg0 + 0xA);
a.unk0C = *(u16 *)((u8 *)arg0 + 0xE);
a.unk10 = 8;
a.unk14 = 0xC0;
a.unk12 = 0;
a.unk11 = 0;
a.unk16 = 0x80;
a.unk15 = 0x80;
*(struct Bv *)&b = *(struct Bv *)&D_800AE620;
a.unk18 = 0x50000000;
func_80016A5C(&a, &b);
}
typedef int (*DispatchFn)();
@@ -4586,7 +4657,40 @@ DEFINE_func_80171EC8() /* dedup: shared engine-core @0x80171EC8 (src/shared) */
INCLUDE_ASM("asm/ov_SC01_077/nonmatchings/ov_SC01_077", func_80171FFC);
INCLUDE_ASM("asm/ov_SC01_077/nonmatchings/ov_SC01_077", func_8017209C);
extern s32 func_8017248C(s32 a0, s32 a1);
extern void func_80146D90(s32 a0);
extern s32 ratan2(s32 a0, s32 a1); /* ratan2 */
extern s32 func_80012DBC(s32 a0, s32 a1, s32 a2, s32 a3);
extern void func_80172170(s32 a0, s32 a1);
s32 func_8017209C(void *arg0, void *arg1, s32 arg2, s32 arg3) {
s32 ret;
register s32 ang __asm__("$3"); /* $v1 */
register s32 a3p __asm__("$19"); /* $s3 = arg3 */
register s32 a2p __asm__("$20"); /* $s4 = arg2 */
a3p = arg3;
a2p = arg2;
ret = func_8017248C((s32)arg0, (s32)arg1);
if (ret != 0) {
func_80146D90((s32)arg0);
return ret;
}
ang = (ratan2((s32)*(s16 *)((u8 *)arg1 + 0) - (s32)*(s16 *)((u8 *)arg0 + 6),
(s32)*(s16 *)((u8 *)arg1 + 4) - (s32)*(s16 *)((u8 *)arg0 + 0xE))
+ 0x800) & 0xFFF;
if (a3p != 0) {
ang = (s16)func_80012DBC((s32)*(s16 *)(*(s32 *)((u8 *)arg0 + 0x20) + 0x12),
ang, (s16)a3p, 1);
}
*(s16 *)(*(s32 *)((u8 *)arg0 + 0x20) + 0x12) = ang;
func_80172170((s32)arg0, a2p & 0xFF);
return 0;
}
DEFINE_func_80172170() /* dedup: shared engine-core @0x80172170 (src/shared) */
+2 -2
View File
@@ -6023,7 +6023,7 @@
}
#define DEFINE_func_80147478() \
extern void func_80147514(void); \
extern void func_80147514(); \
extern void func_80147628(s32 a0); \
void func_80147478(s32 a0) { \
if ((*(s32 *)(a0 + 0x44) & 0x40000000) == 0) { \
@@ -15525,7 +15525,7 @@
}
#define DEFINE_func_80168EC4() \
extern void func_80168F40(void); \
extern void func_80168F40(); \
extern void func_800D22E4(s32 a0); \
extern void func_80146C3C(void); \
void func_80168EC4(s32 a0) { \
+94
View File
@@ -0,0 +1,94 @@
#!/usr/bin/env python3
"""canon_resident_calls.py — rewrite `func_<ADDR>` references in a harvest draft to the
CURATED resident symbol name when that address has one (Phase 19 / T2 recovery).
The link-miss recovery class. Overlay drafts call resident EXE/engine functions by their
`func_<ADDR>` name, but ~927 resident functions carry a *curated* name in config/symbols.us.txt
(e.g. 0x8004CFEC = `ratan2`). The linker resolves the curated name, NOT `func_8004CFEC`, so a
draft that calls `func_8004CFEC(...)` compiles fine but fails to LINK
(`undefined reference to func_8004CFEC`) -> the whole-binary byte-gate (correctly) reverts it.
This pass maps every address that has a `// func` curated (non-`func_`) name in the stacked
symbol files (symbols.us + symbols.resident + symbols.<ov>) and rewrites each `func_<ADDR>`
token at such an address to that name, in both the extern declaration and the call. A pure
draft-text transform (like sig_unify): the body bytes are unchanged (same call target, same
address) -> the whole-binary `harvest_verify` byte-gate remains the sole arbiter (G3/P9).
Proven on func_8017209C (calls ratan2 @0x8004CFEC). Run BEFORE sig_unify in the recovery
pipeline: draft -> canon_resident_calls -> sig_unify -> harvest_verify --chunk 1
Usage:
tools/canon_resident_calls.py --overlay ov_SC01_077 --in .run/drafts-X --out .run/drafts-X-cn
tools/canon_resident_calls.py --symbols config/symbols.us.txt,... --in ... --out ...
"""
import argparse, os, re, glob
REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# `name = 0xADDR; // func` (curated function symbols; data is `// data` and uses D_ refs, not func_)
SYM_RE = re.compile(r'^\s*([A-Za-z_]\w*)\s*=\s*0x([0-9A-Fa-f]+)\s*;\s*//\s*func\b')
FUNC_TOK = re.compile(r'\bfunc_([0-9A-Fa-f]{8})\b')
def load_name_map(symbol_paths):
"""addr(int) -> curated name, for every `// func` symbol whose name is NOT func_<ADDR>.
Later files in the stack override earlier (overlay-local wins), mirroring splat's stacking."""
out = {}
for p in symbol_paths:
if not os.path.exists(p):
continue
for ln in open(p):
m = SYM_RE.match(ln)
if not m:
continue
name, addr = m.group(1), int(m.group(2), 16)
if name.lower() != f'func_{addr:08x}': # skip auto func_ names (no-op rewrites)
out[addr] = name
return out
def rewrite(text, name_map):
n = [0]
def repl(m):
addr = int(m.group(1), 16)
nm = name_map.get(addr)
if nm and nm != m.group(0):
n[0] += 1
return nm
return m.group(0)
return FUNC_TOK.sub(repl, text), n[0]
def main():
ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
ap.add_argument('--overlay', default='ov_SC01_077')
ap.add_argument('--symbols', help='comma-separated symbol files (default: us + resident + overlay)')
ap.add_argument('--in', dest='indir', required=True)
ap.add_argument('--out', dest='outdir', required=True)
a = ap.parse_args()
if a.symbols:
sym_paths = [os.path.join(REPO, p) for p in a.symbols.split(',')]
else:
sym_paths = [os.path.join(REPO, p) for p in (
'config/symbols.us.txt', 'config/symbols.resident.txt',
f'config/symbols.{a.overlay}.txt')]
name_map = load_name_map(sym_paths)
os.makedirs(os.path.join(REPO, a.outdir), exist_ok=True)
drafts = touched = total = 0
for p in sorted(glob.glob(os.path.join(REPO, a.indir, '*.c'))):
new, k = rewrite(open(p).read(), name_map)
open(os.path.join(REPO, a.outdir, os.path.basename(p)), 'w').write(new)
drafts += 1
if k:
touched += 1
total += k
print(f'curated func names: {len(name_map)}; drafts: {drafts}; '
f'rewritten: {touched} draft(s), {total} ref(s)')
if __name__ == '__main__':
main()