diff --git a/docs/plan/level-assets.md b/docs/plan/level-assets.md index 78e73db..e69fba5 100644 --- a/docs/plan/level-assets.md +++ b/docs/plan/level-assets.md @@ -2171,3 +2171,39 @@ float constant -- and only disassembly separates them. `0x3a8060` at 148 bytes with six immediates is the cheapest thing to disassemble and would settle it: if the `lui` at that site is paired with an `ori` it is a float, and if it feeds an `addiu` computing `base + 0xc0` it is the chunk. + +### Disassembled: it is an address, not a float + +Settled. At `0x3a8060`: + + 263200c0 addiu r17, r18, 0x00c0 r17 = r18 + 0xc0 + 263000d0 addiu r17, r16, 0x00d0 r17 = r16 + 0xd0 + 262400e0 addiu r17, r4, 0x00e0 r17 = r4 + 0xe0 + 3c013f80 lui r0, r1, 0x3f80 the actual float constant: 1.0f + +So `0xc0` is an **address offset**. The float constant is elsewhere in the same +function and is `0x3f80`, exactly where it should be. + +And the three offsets are `0xc0`, `0xd0`, `0xe0` -- **16 bytes apart**. The +function is walking a table of fixed-stride structures, indexing the field at +offset `0xc0`. That is what a class-table lookup looks like, and it is consistent +with `moby_classes` starting at `0xc0` in core_data: the chunk's field at its own +offset, or a struct whose first accessed member sits there. + +**What this settles:** `0xc0` is an address computation, not a float constant. The +ambiguity from 05d9bf6 is closed for this function, and by extension the reading +of `0xc0` as `moby_classes.offset` survives. + +**What it does not settle:** that `0x3a8060` is the moby class *loader*. It is a +function that indexes a 16-byte-stride table at offset `0xc0`. That is consistent +with many things -- a moby class walk, a different structure that also lives at +`0xc0`, or ordinary field access on an object passed in `r18`. Identifying which +needs the register provenance: where `r18` comes from, and whether it is +`core_data + moby_classes.offset`. + +The next step is therefore narrow and concrete: trace `r18` back to its +definition. If it is loaded as `core_data + 0xc0`, that is the chunk. The +preceding instruction at this function's entry sets up a 64-byte frame and saves +`r16`-`r20`, so the walk is over arguments rather than a global -- which is itself +informative, because a *loader* would more likely take the chunk as an argument +from its caller than re-derive it. diff --git a/docs/roadmap.md b/docs/roadmap.md index 39b2a88..868b2d0 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -746,8 +746,11 @@ lookup, and it is the main thing inherited from ReRAC. referenced by 13-72x more level-0 functions than any of its 16 adjacent constants, at every immediate-set size -- 72 of 1,082 functions with fewer than 16 distinct immediates, where the best neighbour appears once. The - ~300 candidates with 48 or fewer immediates are a real shortlist. Presence - of an immediate is not proof of a read. + ~300 candidates with 48 or fewer immediates are a real shortlist. + Disassembly of one (`0x3a8060`) shows `addiu r17, r18, 0xc0` alongside + `0xd0` and `0xe0` -- a 16-byte-stride table walk at an address offset, with + the float constant (`lui 0x3f80`) elsewhere. Whether `r18` is + `core_data + moby_classes.offset` is not yet traced. - [~] GIF/VIF packet stream interpretation. **The tie control region is not a VIF or GIF tag stream** -- measured uniform on both framings across 13,042 records, so