phase9: merge B 2 — 383 regions / 374 distinct bodies

Worker B: 28 new this cycle. 0x800B6C14's inverted-polarity guard
(if (test() == 0) — nonzero skips the work) recorded as the 3rd
same-count-wrong-reading this cycle. Two pure-allocation negatives
(0x8007374C 7B reg swap, 0x800A86B4 pointer roles). Gate MATCH
whole-binary SHA-1 e173426c157384ebf1b6caf8c6fea18a85a14af9.
This commit is contained in:
Christopher Williams
2026-09-24 02:18:56 -04:00
parent 57a9640fd2
commit 2c972af35e
3 changed files with 120 additions and 0 deletions
+6
View File
@@ -123,6 +123,7 @@
0x80038788 0x80038790 src/func_80038788.c
0x80038790 0x8003879C src/func_80038790.c
0x8003AAE8 0x8003AB20 src/func_8003AAE8.c
0x8003ABB4 0x8003AC00 src/func_8003ABB4.c
0x8003B2F0 0x8003B320 src/func_8003B2F0.c
0x8003B320 0x8003B34C src/func_8003B320.c
0x8003CB8C 0x8003CBE4 src/func_8003CB8C.c
@@ -202,6 +203,7 @@
0x80085B80 0x80085B90 src/func_80085B80.c
0x80089314 0x80089338 src/func_80089314.c
0x800893E8 0x80089434 src/func_800893E8.c
0x80089B30 0x80089B88 src/func_80089B30.c
0x80089C4C 0x80089C54 src/func_80042088.c
0x80089C54 0x80089C64 src/func_80089C54.c
0x80089C64 0x80089C74 src/func_80089C64.c
@@ -246,6 +248,7 @@
0x8009E8D0 0x8009E95C src/func_8009E8D0.c
0x8009F0E8 0x8009F120 src/func_8009F0E8.c
0x800A2F20 0x800A2F44 src/func_800A2F20.c
0x800A34E8 0x800A3540 src/func_800A34E8.c
0x800A45E0 0x800A466C src/func_8009E8D0.c
0x800A5CC8 0x800A5CEC src/func_800A5CC8.c
0x800A5CEC 0x800A5D24 src/func_800A5CEC.c
@@ -256,6 +259,7 @@
0x800A74BC 0x800A74D0 src/func_800A74BC.c
0x800A8B48 0x800A8B8C src/func_800A8B48.c
0x800A9D58 0x800A9D90 src/func_800A9D58.c
0x800A9F7C 0x800A9FD4 src/func_800A9F7C.c
0x800A9FD4 0x800AA01C src/func_800A9FD4.c
0x800AA2B4 0x800AA2F8 src/func_800AA2B4.c
0x800AA56C 0x800AA59C src/func_800AA56C.c
@@ -276,6 +280,7 @@
0x800B5AF0 0x800B5AF8 src/func_80042088.c
0x800B5CB4 0x800B5CF8 src/func_800B5CB4.c
0x800B6BDC 0x800B6C14 src/func_800B6BDC.c
0x800B6C14 0x800B6C60 src/func_800B6C14.c
0x800B7230 0x800B7264 src/func_800B7230.c
0x800B74D0 0x800B7524 src/func_800B74D0.c
0x800BBDEC 0x800BBDF8 src/func_800BBDEC.c
@@ -353,6 +358,7 @@
0x80103B54 0x80103B60 src/func_80103B54.c
0x80103B60 0x80103B6C src/func_80103B60.c
0x80103B6C 0x80103B8C src/func_80103B6C.c
0x80103B8C 0x80103BE4 src/func_80103B8C.c
0x80103C7C 0x80103CA0 src/func_800F7FB4.c
0x80103F84 0x80103FA8 src/func_800F7FB4.c
0x80103FCC 0x80103FDC src/func_80103FCC.c
1 # Code-region registry: one C region per matched function.
123 0x80038788
124 0x80038790
125 0x8003AAE8
126 0x8003ABB4
127 0x8003B2F0
128 0x8003B320
129 0x8003CB8C
203 0x80085B80
204 0x80089314
205 0x800893E8
206 0x80089B30
207 0x80089C4C
208 0x80089C54
209 0x80089C64
248 0x8009E8D0
249 0x8009F0E8
250 0x800A2F20
251 0x800A34E8
252 0x800A45E0
253 0x800A5CC8
254 0x800A5CEC
259 0x800A74BC
260 0x800A8B48
261 0x800A9D58
262 0x800A9F7C
263 0x800A9FD4
264 0x800AA2B4
265 0x800AA56C
280 0x800B5AF0
281 0x800B5CB4
282 0x800B6BDC
283 0x800B6C14
284 0x800B7230
285 0x800B74D0
286 0x800BBDEC
358 0x80103B54
359 0x80103B60
360 0x80103B6C
361 0x80103B8C
362 0x80103C7C
363 0x80103F84
364 0x80103FCC
+55
View File
@@ -0,0 +1,55 @@
/* func_8003ABB4 — 0x8003ABB4..0x8003AC00 (76 bytes).
*
* Original words:
* 27BDFFD8 addiu sp,sp,-40
* AFBF0024 sw ra,36(sp)
* AFB00020 sw s0,32(sp)
* 8C820008 lw v0,8(a0) v0 = obj->8
* 8C50000C lw s0,12(v0) s0 = v0->0xc
* 0C00EAC8 jal 0x8003AB20
* 27A60010 _addiu a2,sp,16 (delay slot) third argument = &local
* 00002821 move a1,zero
* 27A60010 addiu a2,sp,16
* 0C009635 jal 0x800258D4
* 02002021 _move a0,s0 (delay slot)
* 0C004421 jal 0x80011084
* 02002021 _move a0,s0 (delay slot)
* 8FBF0024 lw ra,36(sp)
* 8FB00020 lw s0,32(sp)
* 27BD0028 addiu sp,sp,40
* 03E00008 jr ra
* 00000000 nop
*
* A three-call sequence over a two-hop pointer walk, with one stack object shared
* between the first two calls.
*
* The first call receives the routine's own `a0` and `a1` unchanged (neither is set)
* plus the local's address, so `a1` is a **pass-through** — the routine must declare
* it or the register count is wrong. The second call supplies `s0` as its first
* argument and the zero as its second, and the third supplies `s0` alone.
*
* The `nop` after the first `lw` is the load-delay fill; the frame is 40 bytes with
* `ra` at 36 and `s0` at 32, leaving the local at 0x10 to extend to 0x1f, so the
* object is at most 16 bytes.
*
* LIMITS: the displacements 8 and 0xc are read from the bytes; the two hops are
* typed `int` here purely so the second hop can be dereferenced, and nothing
* establishes what either object is. The local's declared size (16) is chosen to
* make the frame come out and is not evidence — only the first two calls use it and
* neither call's required size is visible. The three callees are named for their
* addresses.
*/
int func_8003AB20(int a0, int a1, char *buf);
void func_800258D4(int a0, int a1, char *buf);
void func_80011084(int a0);
void func_8003ABB4(int obj, int arg)
{
char buf[16];
int inner = *(int *)(*(int *)(obj + 8) + 0xc);
func_8003AB20(obj, arg, buf);
func_800258D4(inner, 0, buf);
func_80011084(inner);
}
+59
View File
@@ -0,0 +1,59 @@
/* func_800B6C14 — 0x800B6C14..0x800B6C60 (76 bytes).
*
* Original words:
* 27BDFFE8 addiu sp,sp,-24
* AFB00010 sw s0,16(sp)
* AFBF0014 sw ra,20(sp)
* 0C02DAF7 jal 0x800B6BDC
* 00808021 _move s0,a0 (delay slot) keep the argument
* 14400008 bnez v0,0x800B6C4C
* 00000000 _nop (delay slot)
* 278406FC addiu a0,gp,1788 a0 = &D_80122034 (gp + 0x6FC)
* 0C009918 jal 0x80026460
* 02002821 _move a1,s0 (delay slot)
* 02002021 move a0,s0
* 24050001 li a1,1
* 0C02DA25 jal 0x800B6894
* 00003021 _move a2,zero (delay slot)
* 8FBF0014 lw ra,20(sp) <- 0x800B6C4C
* 8FB00010 lw s0,16(sp)
* 27BD0018 addiu sp,sp,24
* 03E00008 jr ra
* 00000000 nop
*
* A guard-with-a-report: if the test routine answers non-zero nothing happens,
* otherwise a message is emitted from a global descriptor and a second routine is
* called with a fixed middle argument.
*
* The guard's polarity is worth stating because it is the opposite of the usual
* shape: **`bnez` skips the work**, so non-zero means "handled, do nothing" and zero
* means "report". Writing the C as `if (!test())` is therefore required; an
* `if (test())` would invert the region.
*
* `addiu a0,gp,1788` takes the descriptor's address **gp-relatively** with no `lui`,
* so the symbol is within ±32K of `gp` (cookbook finding 10): `gp` is 0x80121938 and
* the address is **0x80122034**, which needs a `gp` marker row in the registry.
*
* The second call's third argument is cleared (`move a2,zero`) in the call's delay
* slot, and the first argument is the routine's own — so the signature of the callee
* here is (arg, 1, 0).
*
* LIMITS: the gp offset 0x6FC is read from the bytes; that the address is a message
* descriptor is inferred from its being passed to a routine alongside the object, not
* from anything in this body. The two callees are named for their addresses and the
* test routine's return type is inferred only from its use in a zero test.
*/
extern char D_80122034;
int func_800B6BDC(int arg);
void func_80026460(char *desc, int arg);
void func_800B6894(int arg, int one, int zero);
void func_800B6C14(int arg)
{
if (func_800B6BDC(arg) == 0) {
func_80026460(&D_80122034, arg);
func_800B6894(arg, 1, 0);
}
}