Files
BFM-decomp/cookbook/C0259.md
T

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:

  1. 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.
  2. The card's own "banked twin" pointer. func_801830EC, func_80184358, func_801887D0, func_801835B0, func_8018694C, func_80186BAC, func_80180A3C.
  3. A grep by symbol name across src/. func_8017EF0C, func_801807F8, func_80184814, func_8017DC20, func_8018301C, func_800CBCBC.
  4. A stale .run shard 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: the glabel size header reads 0xFC vs 0x264. 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 .s you 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).