From f35ec5607ef4ef75f194b246ecb72f09ca12f5b3 Mon Sep 17 00:00:00 2001 From: Christopher Williams Date: Thu, 24 Sep 2026 01:45:51 -0400 Subject: [PATCH] =?UTF-8?q?phase9:=20merge=20B=200x80034A80=20=E2=80=94=20?= =?UTF-8?q?352=20regions=20/=20343=20bodies?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Worker B's maspsx structural limitation recorded: a region needing addu-encoded moves (maspsx expands move->addu, GNU as expands move->or) AND an assembler-filled jr slot cannot be matched with any single maspsx= setting — this explains a family of epilogue residuals. B verified in .s files. Two negatives with mechanisms (0x800254B0 alloc, 0x800751E8 with negu — evidence FOR the toolchain, finding-26 route). B self-corrected an invented-address method error. Gate MATCH whole- binary SHA-1 e173426c157384ebf1b6caf8c6fea18a85a14af9. --- config/regions.tsv | 1 + src/func_80034A80.c | 58 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 src/func_80034A80.c diff --git a/config/regions.tsv b/config/regions.tsv index 36efdaf..aa14aea 100644 --- a/config/regions.tsv +++ b/config/regions.tsv @@ -99,6 +99,7 @@ 0x80030358 0x80030390 src/func_80030358.c 0x80031F78 0x80031FC4 src/func_80031F78.c 0x800321EC 0x800321F8 src/func_800321EC.c +0x80034A80 0x80034ABC src/func_80034A80.c 0x80036308 0x80036328 src/func_80036308.c 0x8003636C 0x80036378 src/func_8003636C.c 0x80036378 0x80036380 src/func_80036378.c diff --git a/src/func_80034A80.c b/src/func_80034A80.c new file mode 100644 index 0000000..c1be3e0 --- /dev/null +++ b/src/func_80034A80.c @@ -0,0 +1,58 @@ +/* func_80034A80 — 0x80034A80..0x80034ABC (60 bytes). + * + * Original words: + * 27BDFF90 addiu sp,sp,-112 + * 3C058011 lui a1,0x8011 + * 24A5C114 addiu a1,a1,-16108 a1 = 0x8010C114 + * 8CA20000 lw v0,0(a1) + * 8CA30004 lw v1,4(a1) + * 8CA40008 lw a0,8(a1) + * AFA20010 sw v0,16(sp) + * AFA30014 sw v1,20(sp) + * AFA40018 sw a0,24(sp) + * 8CA2000C lw v0,12(a1) + * AFA2001C sw v0,28(sp) + * 27BD0070 addiu sp,sp,112 + * 03E00008 jr ra + * 00000000 nop + * + * A 112-byte frame that exists only to receive a 16-byte copy from a global, which + * is then discarded: nothing reads the frame, nothing is returned, and the frame is + * torn down immediately. Four words are loaded and four are stored, the fourth load + * scheduled after the first three stores. + * + * **This is a compiler artefact, like `0x8002E3A8`'s bare frame, but one step + * further on.** The frame is 80 bytes larger than the object copied into it, and + * the copy lands at offset 16 rather than 0 — so the source declared a local + * aggregate of 112 bytes and assigned a 16-byte struct into a member 16 bytes in, + * after which the local is dead. cc1 did not eliminate the stores (GCC 2.7.2 does + * not do dead-store elimination on aggregate members), so the whole sequence + * survives. + * + * `lui a1,0x8011` + `addiu a1,a1,-16108` is the macro expansion of a **symbol** + * address (cookbook finding 1; a literal would give `ori`, finding 5), so the + * source is the global at **0x8010C114** — `0x80110000 - 16108` is 0x8010C114, and + * note the displacement is negative, so the `lui` immediate is *not* the top half + * of the address (the sign-adjusted `%lo` trap). + * + * LIMITS: the frame size 112, the copy offset 16 and the four-word width are read + * from the displacements; the *declaration* that produces them is a reconstruction + * of compiler behaviour, not of a statement — the sizes are chosen to make the + * frame and offsets come out, and any 16-byte aggregate at offset 16 of a 112-byte + * frame would produce the same bytes. Since the copied data is never used, no + * observable property of this routine depends on what the type was. + */ + +typedef struct { + int w[4]; +} Blk16; + +extern Blk16 D_8010C114; + +void func_80034A80(void) +{ + char frame[112]; + Blk16 *slot = (Blk16 *)(frame + 16); + + *slot = D_8010C114; +}