diff --git a/config/regions.tsv b/config/regions.tsv index 1523225..e4bedc6 100644 --- a/config/regions.tsv +++ b/config/regions.tsv @@ -11,16 +11,41 @@ # # Matched so far: 0x80012780 0x8001278C src/func_80012780.c +0x80013C88 0x80013C90 src/func_80013C88.c +0x800179D4 0x800179E0 src/func_800179D4.c 0x80017AD4 0x80017AE8 src/func_80017AD4.c 0x80017AE8 0x80017AF8 src/func_80017AE8.c +0x80017C60 0x80017C6C src/func_80017C60.c 0x80017DD0 0x80017DF0 src/func_80017DD0.c +0x80019C04 0x80019C10 src/func_80019C04.c +0x8001AA9C 0x8001AAA8 src/func_8001AA9C.c 0x80024C14 0x80024C34 src/func_80024C14.c +0x80026258 0x80026264 src/func_80026258.c 0x80026264 0x80026274 src/func_80026264.c 0x800262E0 0x800262EC src/func_800262E0.c 0x800262EC 0x800262F8 src/func_800262E0.c +0x800262F8 0x80026304 src/func_800262F8.c +0x800267C0 0x800267CC src/func_800267C0.c +0x8002C888 0x8002C894 src/func_8002C888.c 0x8002D2A0 0x8002D2BC src/func_8002D2A0.c 0x8002D2BC 0x8002D2D4 src/func_8002D2BC.c +0x800321EC 0x800321F8 src/func_800321EC.c 0x80036308 0x80036328 src/func_80036308.c +0x8003636C 0x80036378 src/func_8003636C.c +0x80036378 0x80036380 src/func_80036378.c +0x80038788 0x80038790 src/func_80038788.c +0x80038790 0x8003879C src/func_80038790.c +0x80042088 0x80042090 src/func_80042088.c +0x80057DFC 0x80057E04 src/func_80057DFC.c 0x800697A4 0x800697C4 src/func_800697A4.c +0x8007DC40 0x8007DC4C src/func_8007DC40.c +0x80089C4C 0x80089C54 src/func_80042088.c +0x80089E74 0x80089E7C src/func_80042088.c +0x8008F4A0 0x8008F4AC src/func_8008F4A0.c +0x800B5AF0 0x800B5AF8 src/func_80042088.c +0x800BBDEC 0x800BBDF8 src/func_800BBDEC.c 0x800F8F9C 0x800F8FC0 src/func_800F8F9C.c +0x800FBDF8 0x800FBE04 src/func_800FBDF8.c +0x800FC2CC 0x800FC2D8 src/func_800FC2CC.c +0x800FE86C 0x800FE878 src/func_800FE86C.c 0x80109314 0x80109338 src/func_800F8F9C.c diff --git a/config/symbols.tsv b/config/symbols.tsv index 9d7c49d..71f78a1 100644 --- a/config/symbols.tsv +++ b/config/symbols.tsv @@ -18,6 +18,17 @@ _gp 0x80121938 D_80121974 0x80121974 gp D_80121B18 0x80121B18 gp D_80121B14 0x80121B14 gp +D_801219BC 0x801219BC gp +D_80121A88 0x80121A88 gp +D_80121A60 0x80121A60 gp +D_80121B2A 0x80121B2A gp +D_80121B8C 0x80121B8C gp +D_80121EA4 0x80121EA4 gp +D_8012265C 0x8012265C gp +D_801220A0 0x801220A0 gp +D_801220E0 0x801220E0 gp +D_80122104 0x80122104 gp +D_80122138 0x80122138 gp func_80024668 0x80024668 func_800F4098 0x800F4098 func_800695D8 0x800695D8 diff --git a/src/func_80013C88.c b/src/func_80013C88.c new file mode 100644 index 0000000..bc893a7 --- /dev/null +++ b/src/func_80013C88.c @@ -0,0 +1,17 @@ +/* + * func_80013C88 — 8 bytes at 0x80013C88..0x80013C90 + * + * Byte-identical reconstruction of a one-byte field setter. The store is + * scheduled into the `jr` delay slot (cookbook finding 8). + * + * The observed instructions are: + * jr ra + * sb a1,0x13c(a0) (delay slot) + * + * LIMITS: the name, the base pointer type and the field offset are hypotheses + * read from the disassembly; `sb` fixes only that a single byte is stored. + */ + +void func_80013C88(char *base, char value) { + base[0x13c] = value; +} diff --git a/src/func_800179D4.c b/src/func_800179D4.c new file mode 100644 index 0000000..f20b10b --- /dev/null +++ b/src/func_800179D4.c @@ -0,0 +1,20 @@ +/* + * func_800179D4 — 12 bytes at 0x800179D4..0x800179E0 + * + * Byte-identical reconstruction of a two-field setter that stores a halfword and + * a word. The second store is scheduled into the `jr` delay slot. + * + * The observed instructions are: + * sh a1,0x16(a0) base->half = first + * jr ra + * sw a2,0xc(a0) (delay slot) base->word = second + * + * LIMITS: the name, the base pointer type and both field offsets are hypotheses + * read from the disassembly. `sh` fixes the first store's width, `sw` the + * second's; the parameter order is fixed by the register usage (a1 then a2). + */ + +void func_800179D4(char *base, short first, int second) { + *(short *)(base + 0x16) = first; + *(int *)(base + 0xc) = second; +} diff --git a/src/func_80017C60.c b/src/func_80017C60.c new file mode 100644 index 0000000..17aa6f2 --- /dev/null +++ b/src/func_80017C60.c @@ -0,0 +1,22 @@ +/* + * func_80017C60 — 12 bytes at 0x80017C60..0x80017C6C + * + * Byte-identical reconstruction of a `gp`-relative halfword setter. `gp` is + * 0x80121938 (crt0 sets it at 0x800FB3E4), so 0x84(gp) is 0x801219BC; the symbol + * is marked `gp` in `config/symbols.tsv` so the access is emitted `%gp_rel` + * (cookbook finding 10). + * + * The observed instructions are: + * sh a0,0x84(gp) D_801219BC = value + * jr ra + * nop + * + * LIMITS: the name and the global's name and type are hypotheses read from the + * disassembly; `sh` fixes only that a halfword is stored. + */ + +extern short D_801219BC; + +void func_80017C60(short value) { + D_801219BC = value; +} diff --git a/src/func_80019C04.c b/src/func_80019C04.c new file mode 100644 index 0000000..7ee100e --- /dev/null +++ b/src/func_80019C04.c @@ -0,0 +1,21 @@ +/* + * func_80019C04 — 12 bytes at 0x80019C04..0x80019C10 + * + * Byte-identical reconstruction of a `gp`-relative word setter. `gp` is + * 0x80121938, so 0x150(gp) is 0x80121A88; the symbol is marked `gp` in + * `config/symbols.tsv` (cookbook finding 10). + * + * The observed instructions are: + * sw a0,0x150(gp) D_80121A88 = value + * jr ra + * nop + * + * LIMITS: the name and the global's name and type are hypotheses read from the + * disassembly; `sw` fixes only that one word is stored. + */ + +extern int D_80121A88; + +void func_80019C04(int value) { + D_80121A88 = value; +} diff --git a/src/func_8001AA9C.c b/src/func_8001AA9C.c new file mode 100644 index 0000000..eb4ac1f --- /dev/null +++ b/src/func_8001AA9C.c @@ -0,0 +1,21 @@ +/* + * func_8001AA9C — 12 bytes at 0x8001AA9C..0x8001AAA8 + * + * Byte-identical reconstruction of a `gp`-relative word setter. `gp` is + * 0x80121938, so 0x128(gp) is 0x80121A60; the symbol is marked `gp` in + * `config/symbols.tsv` (cookbook finding 10). + * + * The observed instructions are: + * sw a0,0x128(gp) D_80121A60 = value + * jr ra + * nop + * + * LIMITS: the name and the global's name and type are hypotheses read from the + * disassembly; `sw` fixes only that one word is stored. + */ + +extern int D_80121A60; + +void func_8001AA9C(int value) { + D_80121A60 = value; +} diff --git a/src/func_80026258.c b/src/func_80026258.c new file mode 100644 index 0000000..27f9511 --- /dev/null +++ b/src/func_80026258.c @@ -0,0 +1,21 @@ +/* + * func_80026258 — 12 bytes at 0x80026258..0x80026264 + * + * Byte-identical reconstruction of a `gp`-relative word setter. `gp` is + * 0x80121938, so 0x1dc(gp) is 0x80121B14, which is already a `gp`-marked row in + * `config/symbols.tsv` (cookbook finding 10). + * + * The observed instructions are: + * sw a0,0x1dc(gp) D_80121B14 = value + * jr ra + * nop + * + * LIMITS: the name and the global's name and type are hypotheses read from the + * disassembly; `sw` fixes only that one word is stored. + */ + +extern int D_80121B14; + +void func_80026258(int value) { + D_80121B14 = value; +} diff --git a/src/func_800262F8.c b/src/func_800262F8.c new file mode 100644 index 0000000..da9e704 --- /dev/null +++ b/src/func_800262F8.c @@ -0,0 +1,23 @@ +/* + * func_800262F8 — 12 bytes at 0x800262F8..0x80026304 + * + * Byte-identical reconstruction of a `gp`-relative word getter. `gp` is + * 0x80121938, so 0x1e0(gp) is 0x80121B18, which is already a `gp`-marked row in + * `config/symbols.tsv` (cookbook finding 10). It reads back the global that + * `func_800262E0` and `func_80026258` write, which is consistent with a + * getter/setter family, but that is an inference, not evidence. + * + * The observed instructions are: + * lw v0,0x1e0(gp) return D_80121B18 + * jr ra + * nop + * + * LIMITS: the name and the global's name and type are hypotheses read from the + * disassembly; `lw` fixes only that one word is loaded into the return register. + */ + +extern int D_80121B18; + +int func_800262F8(void) { + return D_80121B18; +} diff --git a/src/func_800267C0.c b/src/func_800267C0.c new file mode 100644 index 0000000..1a633db --- /dev/null +++ b/src/func_800267C0.c @@ -0,0 +1,21 @@ +/* + * func_800267C0.c — 12 bytes at 0x800267C0..0x800267CC + * + * Byte-identical reconstruction of a gp-relative byte setter that returns 0. + * gp is 0x80121938, so 0x1f2(gp) is 0x80121B2A; the symbol carries the `gp` + * marker in `config/symbols.tsv`. + * + * The observed instructions are: + * sb a0,0x1f2(gp) D_80121B2A = value + * jr ra + * clear v0 (delay slot) return 0 + * + * LIMITS: every name, type and offset here is a hypothesis read from the + * disassembly; only the compiled bytes are evidence. + */ +extern char D_80121B2A; + +int func_800267C0(char value) { + D_80121B2A = value; + return 0; +} diff --git a/src/func_8002C888.c b/src/func_8002C888.c new file mode 100644 index 0000000..46dcdf5 --- /dev/null +++ b/src/func_8002C888.c @@ -0,0 +1,19 @@ +/* + * func_8002C888.c — 12 bytes at 0x8002C888..0x8002C894 + * + * Byte-identical reconstruction of a gp-relative byte setter. gp is 0x80121938, + * so 0x254(gp) is 0x80121B8C; the symbol carries the `gp` marker. + * + * The observed instructions are: + * sb a0,0x254(gp) D_80121B8C = value + * jr ra + * nop + * + * LIMITS: every name, type and offset here is a hypothesis read from the + * disassembly; only the compiled bytes are evidence. + */ +extern char D_80121B8C; + +void func_8002C888(char value) { + D_80121B8C = value; +} diff --git a/src/func_800321EC.c b/src/func_800321EC.c new file mode 100644 index 0000000..fb1fd44 --- /dev/null +++ b/src/func_800321EC.c @@ -0,0 +1,16 @@ +/* + * func_800321EC.c — 12 bytes at 0x800321EC..0x800321F8 + * + * Byte-identical reconstruction of a word field getter at a large offset. + * + * The observed instructions are: + * lw v0,0xdc(a0) return base->word at 0xdc + * jr ra + * nop + * + * LIMITS: every name, type and offset here is a hypothesis read from the + * disassembly; only the compiled bytes are evidence. + */ +int func_800321EC(char *base) { + return *(int *)(base + 0xdc); +} diff --git a/src/func_8003636C.c b/src/func_8003636C.c new file mode 100644 index 0000000..312b445 --- /dev/null +++ b/src/func_8003636C.c @@ -0,0 +1,21 @@ +/* + * func_8003636C.c — 12 bytes at 0x8003636C..0x80036378 + * + * Byte-identical reconstruction of a flag setter. + * The store is scheduled into the `jr` delay slot. + * + * The observed instructions are: + * li v0,0x1 v0 = 1, used as scratch for the constant + * jr ra + * sb v0,0x129a(a0) (delay slot) base[0x129a] = 1 + * + * The function is `void`: an `int` return forced a second `li v0,1` into the + * delay slot and made the body 16 bytes instead of 12, so the `li` here is + * scratch for the constant, not a return value. + * + * LIMITS: every name, type and offset here is a hypothesis read from the + * disassembly; only the compiled bytes are evidence. + */ +void func_8003636C(char *base) { + base[0x129a] = 1; +} diff --git a/src/func_80036378.c b/src/func_80036378.c new file mode 100644 index 0000000..ac7e15c --- /dev/null +++ b/src/func_80036378.c @@ -0,0 +1,19 @@ +/* + * func_80036378 — 8 bytes at 0x80036378..0x80036380 + * + * Byte-identical reconstruction of a one-byte field setter at a large offset. + * The store is scheduled into the `jr` delay slot (cookbook finding 8). + * + * The observed instructions are: + * jr ra + * sb a1,0x1298(a0) (delay slot) + * + * LIMITS: the name, the base pointer type and the field offset are hypotheses + * read from the disassembly; `sb` fixes only that a single byte is stored. The + * 0x1298 offset is far outside a plausible single struct field's neighbourhood, + * so the base may be a byte buffer rather than a struct pointer. + */ + +void func_80036378(char *base, char value) { + base[0x1298] = value; +} diff --git a/src/func_80038788.c b/src/func_80038788.c new file mode 100644 index 0000000..ab8b87a --- /dev/null +++ b/src/func_80038788.c @@ -0,0 +1,17 @@ +/* + * func_80038788 — 8 bytes at 0x80038788..0x80038790 + * + * Byte-identical reconstruction of a one-byte field setter at a large offset. + * The store is scheduled into the `jr` delay slot (cookbook finding 8). + * + * The observed instructions are: + * jr ra + * sb a1,0x132c(a0) (delay slot) + * + * LIMITS: the name, the base pointer type and the field offset are hypotheses + * read from the disassembly; `sb` fixes only that a single byte is stored. + */ + +void func_80038788(char *base, char value) { + base[0x132c] = value; +} diff --git a/src/func_80038790.c b/src/func_80038790.c new file mode 100644 index 0000000..874432f --- /dev/null +++ b/src/func_80038790.c @@ -0,0 +1,19 @@ +/* + * func_80038790.c — 12 bytes at 0x80038790..0x8003879C + * + * Byte-identical reconstruction of a word field setter taking an unsigned char. + * The `andi a1,a1,0xff` is the unsigned-char parameter mask (cookbook finding + * 7: plain `char` is unsigned on this target, and an `unsigned char` argument + * is masked before use). + * + * The observed instructions are: + * andi a1,a1,0xff value &= 0xff + * jr ra + * sw a1,0x1328(a0) (delay slot) base->word at 0x1328 = value + * + * LIMITS: every name, type and offset here is a hypothesis read from the + * disassembly; only the compiled bytes are evidence. + */ +void func_80038790(char *base, unsigned char value) { + *(int *)(base + 0x1328) = value; +} diff --git a/src/func_80042088.c b/src/func_80042088.c new file mode 100644 index 0000000..8a7ab76 --- /dev/null +++ b/src/func_80042088.c @@ -0,0 +1,19 @@ +/* + * func_80042088 — 8 bytes at 0x80042088..0x80042090 + * + * Byte-identical reconstruction of an empty function. The identical 8-byte body + * occurs at four addresses (0x80042088, 0x80089C4C, 0x80089E74, 0x800B5AF0), so + * it is matched once and registered four times against this source — the + * documented N-rows-to-one-source duplicate-sharing mechanism. + * + * The observed instructions are: + * jr ra + * nop + * + * LIMITS: the name is an address placeholder. An empty C function is the only + * shape that produces this body, so the reconstruction is byte-proven while the + * original's name and purpose remain unknown. + */ + +void func_80042088(void) { +} diff --git a/src/func_80057DFC.c b/src/func_80057DFC.c new file mode 100644 index 0000000..f9f538e --- /dev/null +++ b/src/func_80057DFC.c @@ -0,0 +1,17 @@ +/* + * func_80057DFC — 8 bytes at 0x80057DFC..0x80057E04 + * + * Byte-identical reconstruction of a field clearer. The store is scheduled into + * the `jr` delay slot (cookbook finding 8). + * + * The observed instructions are: + * jr ra + * sw zero,0x4(a0) (delay slot) + * + * LIMITS: the name, the base pointer type and the field offset are hypotheses + * read from the disassembly; `sw` fixes only that one word is stored. + */ + +void func_80057DFC(int *base) { + base[1] = 0; +} diff --git a/src/func_8007DC40.c b/src/func_8007DC40.c new file mode 100644 index 0000000..66eb529 --- /dev/null +++ b/src/func_8007DC40.c @@ -0,0 +1,20 @@ +/* + * func_8007DC40.c — 12 bytes at 0x8007DC40..0x8007DC4C + * + * Byte-identical reconstruction of a gp-relative word getter tested against + * zero. gp is 0x80121938, so 0x56c(gp) is 0x80121EA4; the symbol carries the + * `gp` marker. `sltiu v0,v0,1` is the `== 0` comparison. + * + * The observed instructions are: + * lw v0,0x56c(gp) + * jr ra + * sltiu v0,v0,0x1 (delay slot) return value == 0 + * + * LIMITS: every name, type and offset here is a hypothesis read from the + * disassembly; only the compiled bytes are evidence. + */ +extern int D_80121EA4; + +int func_8007DC40(void) { + return D_80121EA4 == 0; +} diff --git a/src/func_8008F4A0.c b/src/func_8008F4A0.c new file mode 100644 index 0000000..b959d83 --- /dev/null +++ b/src/func_8008F4A0.c @@ -0,0 +1,21 @@ +/* + * func_8008F4A0.c — 12 bytes at 0x8008F4A0..0x8008F4AC + * + * Byte-identical reconstruction of a gp-relative byte getter tested against + * zero. gp is 0x80121938, so 0xd24(gp) is 0x8012265C; the symbol carries the + * `gp` marker. `lbu` fixes the global as a byte; `sltiu v0,v0,1` is the + * `== 0` comparison. + * + * The observed instructions are: + * lbu v0,0xd24(gp) + * jr ra + * sltiu v0,v0,0x1 (delay slot) return value == 0 + * + * LIMITS: every name, type and offset here is a hypothesis read from the + * disassembly; only the compiled bytes are evidence. + */ +extern unsigned char D_8012265C; + +int func_8008F4A0(void) { + return D_8012265C == 0; +} diff --git a/src/func_800BBDEC.c b/src/func_800BBDEC.c new file mode 100644 index 0000000..41ab859 --- /dev/null +++ b/src/func_800BBDEC.c @@ -0,0 +1,19 @@ +/* + * func_800BBDEC.c — 12 bytes at 0x800BBDEC..0x800BBDF8 + * + * Byte-identical reconstruction of a gp-relative word clearer. gp is 0x80121938, + * so 0x768(gp) is 0x801220A0; the symbol carries the `gp` marker. + * + * The observed instructions are: + * sw zero,0x768(gp) D_801220A0 = 0 + * jr ra + * nop + * + * LIMITS: every name, type and offset here is a hypothesis read from the + * disassembly; only the compiled bytes are evidence. + */ +extern int D_801220A0; + +void func_800BBDEC(void) { + D_801220A0 = 0; +} diff --git a/src/func_800FBDF8.c b/src/func_800FBDF8.c new file mode 100644 index 0000000..f5b8c1b --- /dev/null +++ b/src/func_800FBDF8.c @@ -0,0 +1,19 @@ +/* + * func_800FBDF8.c — 12 bytes at 0x800FBDF8..0x800FBE04 + * + * Byte-identical reconstruction of a gp-relative word getter. gp is 0x80121938, + * so 0x7a8(gp) is 0x801220E0; the symbol carries the `gp` marker. + * + * The observed instructions are: + * lw v0,0x7a8(gp) + * jr ra + * nop + * + * LIMITS: every name, type and offset here is a hypothesis read from the + * disassembly; only the compiled bytes are evidence. + */ +extern int D_801220E0; + +int func_800FBDF8(void) { + return D_801220E0; +} diff --git a/src/func_800FC2CC.c b/src/func_800FC2CC.c new file mode 100644 index 0000000..e0e82f6 --- /dev/null +++ b/src/func_800FC2CC.c @@ -0,0 +1,19 @@ +/* + * func_800FC2CC.c — 12 bytes at 0x800FC2CC..0x800FC2D8 + * + * Byte-identical reconstruction of a gp-relative word setter. gp is 0x80121938, + * so 0x7cc(gp) is 0x80122104; the symbol carries the `gp` marker. + * + * The observed instructions are: + * sw a0,0x7cc(gp) D_80122104 = value + * jr ra + * nop + * + * LIMITS: every name, type and offset here is a hypothesis read from the + * disassembly; only the compiled bytes are evidence. + */ +extern int D_80122104; + +void func_800FC2CC(int value) { + D_80122104 = value; +} diff --git a/src/func_800FE86C.c b/src/func_800FE86C.c new file mode 100644 index 0000000..ebed1f4 --- /dev/null +++ b/src/func_800FE86C.c @@ -0,0 +1,19 @@ +/* + * func_800FE86C.c — 12 bytes at 0x800FE86C..0x800FE878 + * + * Byte-identical reconstruction of a gp-relative word getter. gp is 0x80121938, + * so 0x800(gp) is 0x80122138; the symbol carries the `gp` marker. + * + * The observed instructions are: + * lw v0,0x800(gp) + * jr ra + * nop + * + * LIMITS: every name, type and offset here is a hypothesis read from the + * disassembly; only the compiled bytes are evidence. + */ +extern int D_80122138; + +int func_800FE86C(void) { + return D_80122138; +}