2.8 KiB
§238 — SAME NAME, DIFFERENT FUNCTION: THE OVERLAY-HOMONYM TRAP (P31 S58b)
Thirty-plus cards in this harvest burned turns — several burned entire sessions — on a body that belonged to a different binary's function with the same symbol name and often the same VMA. §214's similarity warnings cover twins; this is the harder failure, because the artefact is not a twin at all.
THE FOUR SOURCES OF THE WRONG BODY, in descending cost:
- A replayed/carried "previous attempt".
func_80182CA0(matched ov_SC06_022's 26-ins namesake instead of ov_SC05_010's 118-ins target — and the discarded Ghidra leftover had been ~90% right for the real function).func_80181224,func_8017FA94,func_80180B1C,func_80186A00,func_80182F4C,func_801849E4,func_80180030,func_80182674,func_8017F15C. - The card's own "banked twin" pointer.
func_801830EC,func_80184358,func_801887D0,func_801835B0,func_8018694C,func_80186BAC,func_80180A3C. - A grep by symbol name across
src/.func_8017EF0C,func_801807F8,func_80184814,func_8017DC20,func_8018301C,func_800CBCBC. - A stale
.runshard body. Roughly forty cards; usually detectable in seconds (see below).
THE FOUR CHEAP TELLS.
- The card header's instruction count.
func_80180030: "36 instructions" vs the 90-ins namesake.func_8017F15C: theglabelsize header reads0xFCvs0x264. This is the single fastest check and it is free. - The symbol sets do not intersect.
func_80182EB0(ov_SC02_005 vs ov_SC01_001): zero overlap. Diff the shard's callee set against the target's own relocation lines before refining anything. - The file PATH on the card header. Several cards resolved the moment someone re-opened the exact path printed on the card instead of a name-based grep hit.
- A "phantom target" that matches no
.syou have read means you are reading the wrong.s, not that the harness drifted (func_801819D0, ov_SC01_084).
AND THE POSITIVE USE. func_80187050 (ov_SC03_090) found five byte-identical unbanked twins
across binaries by grepping asm/ for the literal encodings 7F010224|FF7F0224 — a search that
src-side grep for = 0x7FFF; could never find, because every sibling was still an INCLUDE_ASM stub.
func_800CBCBC and func_80183A70 did the same with a distinctive addiu immediate.
Grep asm/ by encoding, not src/ by name.
BOUNDARY. Address+name collision across binaries is not a twin signal. Never mine a same-named
function from another overlay directory for shape, literals, register roles, or return type — see
func_801887D0, where the same-VMA sibling's s32 return was evidence against (this target writes
no $v0, and an s32 definition length-drifted by hoisting jr $ra above the tail sh).