phase11: merge 26 — 545 bodies / 554 regions
Worker A's 0x8006B7C0 (420 B) and worker D's 0x800307FC (92 B).
This commit is contained in:
+889
-891
File diff suppressed because it is too large
Load Diff
@@ -136,6 +136,7 @@
|
||||
0x800301FC 0x8003022C src/func_800301FC.c
|
||||
0x80030284 0x800302DC src/func_80030284.c
|
||||
0x80030358 0x80030390 src/func_80030358.c
|
||||
0x800307FC 0x80030858 src/func_800307FC.c
|
||||
0x80030858 0x800308C4 src/func_80030858.c
|
||||
0x800308C4 0x800309CC src/func_800308C4.c
|
||||
0x800319F0 0x80031A48 src/func_800319F0.c
|
||||
@@ -265,6 +266,7 @@
|
||||
0x8006B66C 0x8006B6BC src/func_8006B66C.c
|
||||
0x8006B6BC 0x8006B778 src/func_8006B6BC.c
|
||||
0x8006B778 0x8006B7C0 src/func_8006B778.c
|
||||
0x8006B7C0 0x8006B964 src/func_8006B7C0.c
|
||||
0x8006B9E0 0x8006BA3C src/func_8006B9E0.c
|
||||
0x8006BC08 0x8006BC34 src/func_8006BC08.c
|
||||
0x8006BC34 0x8006BC74 src/func_8006BC34.c
|
||||
|
||||
|
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* func_80031EBC — 112 bytes at 0x80031EBC..0x80031F2C
|
||||
*
|
||||
* Goal B, Phase 11. **First attempt.** The SIBLING of 0x800320D8: same object at `*(a0 + 164)`,
|
||||
* same "flag ? one word : a 16-byte struct copy" idiom, same trailing-position call — and the
|
||||
* struct-assignment lever found on 0x800320D8 transferred unchanged.
|
||||
*
|
||||
* obj = *(int **)(a0 + 164);
|
||||
* if (*(int *)((char *)obj + 652) == 0)
|
||||
* v.a = *(int *)((char *)obj + 660);
|
||||
* else
|
||||
* v = *(V4 *)((char *)obj + 660); <- a 16-byte struct ASSIGNMENT, four loads then four stores
|
||||
* func_80031CC0(a0, (int *)&v, a0 + 4764);
|
||||
*
|
||||
* The observed instructions are:
|
||||
* addiu sp,sp,-0x28 frame, 40 bytes
|
||||
* move a3,a0
|
||||
* sw ra,0x20(sp) only ra is saved — no callee-saved data register
|
||||
* lw a2,0xa4(a3) a2 = *(int **)(a0 + 164)
|
||||
* nop
|
||||
* lw v0,0x28c(a2) the flag
|
||||
* nop
|
||||
* bnez v0,else if (flag != 0) take the 4-word path
|
||||
* nop
|
||||
* lw v0,0x294(a2) else: v.a = obj->f660
|
||||
* j join
|
||||
* sw v0,0x10(sp)
|
||||
* else:
|
||||
* lw v0,0x294(a2) / lw v1,0x298(a2) / lw a0,0x29c(a2) / lw a1,0x2a0(a2)
|
||||
* sw v0,0x10(sp) / sw v1,0x14(sp) / sw a0,0x18(sp) / sw a1,0x1c(sp) FOUR LOADS THEN FOUR STORES
|
||||
* join:
|
||||
* move a0,a3
|
||||
* addiu a1,sp,0x10
|
||||
* jal 0x80031CC0
|
||||
* addiu a2,a0,0x129c a2 = a0 + 4764 (delay slot; a0 is already a3)
|
||||
* lw ra / addiu sp,sp,0x28 / jr ra / nop
|
||||
*
|
||||
* THE LEVER — the same BATCH SHAPE as 0x800320D8. Four indexed element stores compile to load/store
|
||||
* pairs interleaved with load-delay nops; the original batches four loads then four stores, which is
|
||||
* a 16-byte struct assignment. That it transferred to a second row unchanged is the point: it is a
|
||||
* *shape* lever, not a row-specific trick.
|
||||
*
|
||||
* The single-word path leaves `v.b`/`v.c`/`v.d` uninitialised and the callee receives them — a real
|
||||
* property of the original (third instance this session), NOT a reconstruction error. Do not "fix" it.
|
||||
*
|
||||
* LIMITS: the function name, the callee, the meaning of the 164/652/660/4764 offsets and the claim
|
||||
* that the local is a 4-int scratch are hypotheses reconstructed from the disassembly; only the
|
||||
* compiled bytes are evidence. The member names of V4 are not recoverable; the 16-byte copy is.
|
||||
*/
|
||||
|
||||
typedef struct { int a, b, c, d; } V4;
|
||||
|
||||
extern void func_80031CC0(int a0, int *a1, int a2);
|
||||
|
||||
void func_80031EBC(int a0)
|
||||
{
|
||||
V4 v;
|
||||
int *obj;
|
||||
|
||||
obj = *(int **)(a0 + 164);
|
||||
if (*(int *)((char *)obj + 652) == 0) {
|
||||
v.a = *(int *)((char *)obj + 660);
|
||||
} else {
|
||||
v = *(V4 *)((char *)obj + 660);
|
||||
}
|
||||
|
||||
func_80031CC0(a0, (int *)&v, a0 + 4764);
|
||||
}
|
||||
Reference in New Issue
Block a user