From 633e385647ac356d2c81f359e16443b850997c72 Mon Sep 17 00:00:00 2001 From: = Date: Sun, 30 Aug 2026 12:11:52 -0500 Subject: [PATCH] config: repoint 12 stale legacy_source rows left behind by symbol renames Mechanism. `legacy_source` on a TU manifest function row names the per-function `src/` file that function is delinked from. When a `func_ovNNN_AAAAAAAA` symbol is later named, the delinks entry and the file are renamed together to the mangled spelling -- but the manifest row is not, so its `legacy_source` keeps pointing at a path that no longer exists. #2016 fixed the rows whose `.c` had become a `.cpp`; these are the residue where NEITHER extension exists because the stem itself changed. Derivation. Over the 89 entries in config/tu_manifest.d there are 1108 `legacy_source` rows (only `functions` rows carry the field; `data`/`bss` never do). On d773264f9: 0 stale (.c row / .cpp on disk), 0 inverse (.cpp row / .c on disk), 80 dangling (neither extension present). Resolution rule -- by address, never by name. For each dangling row, parse the module's config/arm9/overlays//delinks.txt (config/arm9/delinks.txt for arm9) and find the entry whose section range STARTS at the row's `address`. All 12 rows fixed here resolved to exactly one entry, and in every case the match was exact on both ends -- start == address and end == address + size -- and the entry is still marked `complete`. No range moved and none was handed back to the cartridge; this is stale bookkeeping only. Example: ov020/HauntedChair's `func_ov020_021129dc` (0x021129dc + 0x124) is owned by src/_ZN12HauntedChair6State3Ev.cpp, complete, 0x021129dc-0x02112b00. Promoted entries are deliberately left alone -- 68 of the 80. All six `promoted` entries in the manifest are 100% dangling; none is mixed, so leaving them is self-consistent per entry. Dangling there is the designed terminal state, not a defect: notes/translation-unit-reconstruction-plan.md section 6 lists the field as "legacy source paths to remove on promotion", and tools/tu_promote.py `git rm`s every `legacy_source` as part of promoting, collapsing the N per-function delinks entries into one spanning `complete` entry at `promoted_source`. Repointing them would also be actively harmful: tu_promote's rewrite_attribution keys one attribution override per absorbed symbol off the legacy path's STEM (`lineage.get("src/" + stem)`), so collapsing 25 distinct stems onto one TU path would destroy that 1:1 symbol->author mapping. Resolving them by address confirms the reading -- only the first function of each promoted TU resolves at all (its address is the promoted span's start, and it maps to `promoted_source`); the other 62 interior addresses are no longer entry starts, exactly as promotion intends. Counts: dangling 80 -> 68 (all 68 promoted, deliberate). stale 0 -> 0, inverse 0 -> 0. Every row on a non-promoted entry now resolves to a path that exists, with no duplicate `legacy_source` introduced inside any entry. Config only: 12 changed lines across 4 manifest files, patched in place so the 2-space indent, LF endings and trailing newline are byte-preserved. No delinks.txt, symbols.txt, relocs.txt, src/, src_tu/, include/ or tools/ change, so no gate input moves and no rebuild is implied. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01WdCK1xgrJdiJzPCh3bAJfQ --- config/tu_manifest.d/ov002/Enemy.json | 2 +- config/tu_manifest.d/ov010/PeachPainting.json | 2 +- config/tu_manifest.d/ov020/HauntedChair.json | 14 +++++++------- config/tu_manifest.d/ov029/WaterDiamond.json | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/config/tu_manifest.d/ov002/Enemy.json b/config/tu_manifest.d/ov002/Enemy.json index 27c8f0001b..c8b1ee53d6 100644 --- a/config/tu_manifest.d/ov002/Enemy.json +++ b/config/tu_manifest.d/ov002/Enemy.json @@ -31,7 +31,7 @@ "symbol": "func_ov002_020ada40", "address": "0x020ada40", "size": "0x00000100", - "legacy_source": "src/func_ov002_020ada40.cpp", + "legacy_source": "src/_ZN12dEnemyBase_c20KillByInvincibleCharERK10Vector3_16R6Player5Fix12IiE.cpp", "ordinal": 1 }, { diff --git a/config/tu_manifest.d/ov010/PeachPainting.json b/config/tu_manifest.d/ov010/PeachPainting.json index 717b753cac..e546c2ac1e 100644 --- a/config/tu_manifest.d/ov010/PeachPainting.json +++ b/config/tu_manifest.d/ov010/PeachPainting.json @@ -36,7 +36,7 @@ "symbol": "func_ov010_02111e84", "address": "0x02111e84", "size": "0x00000040", - "legacy_source": "src/func_ov010_02111e84.c", + "legacy_source": "src/_ZN13PeachPainting20UpdateModelTransformEv.cpp", "ordinal": 2 }, { diff --git a/config/tu_manifest.d/ov020/HauntedChair.json b/config/tu_manifest.d/ov020/HauntedChair.json index 2d26dcc666..a27cd49d8e 100644 --- a/config/tu_manifest.d/ov020/HauntedChair.json +++ b/config/tu_manifest.d/ov020/HauntedChair.json @@ -36,49 +36,49 @@ "symbol": "func_ov020_021129dc", "address": "0x021129dc", "size": "0x00000124", - "legacy_source": "src/func_ov020_021129dc.c", + "legacy_source": "src/_ZN12HauntedChair6State3Ev.cpp", "ordinal": 2 }, { "symbol": "func_ov020_02112b00", "address": "0x02112b00", "size": "0x00000394", - "legacy_source": "src/func_ov020_02112b00.c", + "legacy_source": "src/_ZN12HauntedChair6State2Ev.cpp", "ordinal": 3 }, { "symbol": "func_ov020_02112e94", "address": "0x02112e94", "size": "0x00000234", - "legacy_source": "src/func_ov020_02112e94.c", + "legacy_source": "src/_ZN12HauntedChair6State1Ev.cpp", "ordinal": 4 }, { "symbol": "func_ov020_021130c8", "address": "0x021130c8", "size": "0x00000080", - "legacy_source": "src/func_ov020_021130c8.c", + "legacy_source": "src/_ZN12HauntedChair6State0Ev.cpp", "ordinal": 5 }, { "symbol": "func_ov020_02113148", "address": "0x02113148", "size": "0x000000b0", - "legacy_source": "src/func_ov020_02113148.c", + "legacy_source": "src/_ZN12HauntedChair18ApproachStateValueEPsS0_isis.cpp", "ordinal": 6 }, { "symbol": "func_ov020_021131f8", "address": "0x021131f8", "size": "0x00000048", - "legacy_source": "src/func_ov020_021131f8.c", + "legacy_source": "src/_ZN12HauntedChair5BreakEv.cpp", "ordinal": 7 }, { "symbol": "func_ov020_02113240", "address": "0x02113240", "size": "0x00000098", - "legacy_source": "src/func_ov020_02113240.cpp", + "legacy_source": "src/_ZN12HauntedChair11UpdateModelEv.cpp", "ordinal": 8 }, { diff --git a/config/tu_manifest.d/ov029/WaterDiamond.json b/config/tu_manifest.d/ov029/WaterDiamond.json index 0872a23a44..76d8388524 100644 --- a/config/tu_manifest.d/ov029/WaterDiamond.json +++ b/config/tu_manifest.d/ov029/WaterDiamond.json @@ -36,21 +36,21 @@ "symbol": "func_ov029_021117ac", "address": "0x021117ac", "size": "0x000000a4", - "legacy_source": "src/func_ov029_021117ac.cpp", + "legacy_source": "src/_ZN12WaterDiamond19CheckClsnWithPlayerEv.cpp", "ordinal": 2 }, { "symbol": "func_ov029_02111850", "address": "0x02111850", "size": "0x00000078", - "legacy_source": "src/func_ov029_02111850.cpp", + "legacy_source": "src/_ZN12WaterDiamond10SetWaterIDEv.cpp", "ordinal": 3 }, { "symbol": "func_ov029_021118c8", "address": "0x021118c8", "size": "0x00000040", - "legacy_source": "src/func_ov029_021118c8.c", + "legacy_source": "src/_ZN12WaterDiamond20UpdateModelTransformEv.cpp", "ordinal": 4 }, {