Show the loader rewrites shrub packet headers into RAM pointers
Answering the "what is the tag byte" question needed an anchor. Searching live RAM from scratch was the wrong way to get one: 04 04 00 01 matches unrelated data at 0x1ac988 and there is no way to tell a real hit from a coincidental one. The savestates are the anchor -- slot 1 is level 0, and searching one gives candidates that can be checked rather than guessed at. Range measured: savestate slot 1, ~/.config/PCSX2/sstates/SCUS-97268 (38996035).01.p2s, records at 0x22a6b8 onward, read with gc-trace read --state. Result: 40+ records beginning 04 04 00 01 00 00 00 00 at 0x30 spacing -- the packet framing identified on disc -- with the second half of each header rewritten: disc: 04 04 00 01 | 00 00 00 00 | 00 00 00 05 | 00 80 0e 6c RAM: 04 04 00 01 | 00 00 00 00 | 13 00 00 30 | 70 6a 93 00 Bytes 0-7 unchanged; bytes 8-15 are not. On disc bytes 12-13 are the constant 00 80 and byte 15 the constant 6c; in RAM bytes 12-15 hold a pointer -- 0x00936a70, 0x009376f0, 0x00937850, 0x00939c50 in consecutive records, all inside EE RAM and ascending across the table as a walk of consecutive objects would be. Byte 11 becomes 0x30 in every record seen, against a constant 0x05 on disc, and bytes 8-9 hold a varying small value (0x13, 0x16, 0x24). So the packet table at +0x40 is what the loader walks: span-relative on disc, absolute in RAM. This was inferred from one class before; these 40+ records show it directly. Consequence for the tag bytes: the vocabularies at record bytes 7 and 15 are real, but byte 15 sits in a field the loader overwrites with a pointer. Its disc values are read as data by something rather than stored as a tag. Not settled: whether byte 7's vocabulary is also rewritten, and whether 0x6d marks payload the loader expands. That needs these records compared one by one against their disc spans, which is cheap now that the anchor exists.
This commit is contained in:
@@ -163,3 +163,51 @@ Advanced); the socket is `$XDG_RUNTIME_DIR/pcsx2.sock` on Linux.
|
|||||||
|
|
||||||
**Nothing here redistributes game data.** The disc, the BIOS and the
|
**Nothing here redistributes game data.** The disc, the BIOS and the
|
||||||
savestates are the user's own; the repository holds the tool and the numbers.
|
savestates are the user's own; the repository holds the tool and the numbers.
|
||||||
|
|
||||||
|
## Shrub packet headers are rewritten in RAM: the loader relocates them
|
||||||
|
|
||||||
|
Answering the "what is the tag byte" question needed an anchor, and searching
|
||||||
|
RAM from scratch was the wrong way to get one -- it finds coincidental matches
|
||||||
|
(`04 04 00 01` matches unrelated data at `0x1ac988`) and no way to tell them
|
||||||
|
apart. The savestates are the anchor: slot `.01` is level 0, and searching one
|
||||||
|
gives candidates that can be *checked* rather than guessed at.
|
||||||
|
|
||||||
|
**Range measured:** savestate slot 1,
|
||||||
|
`~/.config/PCSX2/sstates/SCUS-97268 (38996035).01.p2s`, records at `0x22a6b8`
|
||||||
|
onward, read with `gc-trace read --state`.
|
||||||
|
|
||||||
|
**Result: 40+ records beginning `04 04 00 01 00 00 00 00` at `0x30` spacing**,
|
||||||
|
which is the packet framing identified on disc, and the loader has rewritten
|
||||||
|
the second half of each header:
|
||||||
|
|
||||||
|
disc: 04 04 00 01 | 00 00 00 00 | 00 00 00 05 | 00 80 0e 6c
|
||||||
|
RAM: 04 04 00 01 | 00 00 00 00 | 13 00 00 30 | 70 6a 93 00
|
||||||
|
|
||||||
|
Bytes 0-7 are unchanged. Bytes 8-11 and 12-15 are not:
|
||||||
|
|
||||||
|
- on disc, bytes 12-13 are the constant `00 80` and byte 15 the constant `6c`;
|
||||||
|
- in RAM, bytes 12-15 hold what is plainly a pointer -- `0x00936a70`,
|
||||||
|
`0x009376f0`, `0x00937850`, `0x00939c50` in consecutive records, all inside
|
||||||
|
EE RAM, and ascending across the table exactly as a walk of consecutive
|
||||||
|
objects would be.
|
||||||
|
|
||||||
|
Byte 11 becomes `0x30` in every record seen, against a constant `0x05` on
|
||||||
|
disc, and bytes 8-9 hold a varying small value (`0x13`, `0x16`, `0x24`).
|
||||||
|
|
||||||
|
**What this means.** The packet table at `+0x40` is the thing the loader walks:
|
||||||
|
it holds span-relative offsets on disc and absolute RAM addresses after
|
||||||
|
loading, which is what the previous pass found and what these 40+ records show
|
||||||
|
directly. Any header field read past byte 8 on disc is describing something the
|
||||||
|
loader replaces.
|
||||||
|
|
||||||
|
**Consequence for the tag bytes.** The values at record bytes 7 and 15 measured
|
||||||
|
on disc are *not* stable identifiers -- at least byte 15 sits in a field the
|
||||||
|
loader overwrites with a pointer. The four-value and two-value vocabularies are
|
||||||
|
real (0x30, 0x6d, 0x80 and 0 appear against 1636 records of otherwise-uniform
|
||||||
|
bytes), but byte 15 being a pointer in RAM means its disc values are being read
|
||||||
|
as data by something, not stored as a tag.
|
||||||
|
|
||||||
|
**Not settled:** whether byte 7's vocabulary is also rewritten, and whether
|
||||||
|
`0x6d` marks a payload that the loader expands. That needs the same records
|
||||||
|
compared one by one against their disc spans, which is the next step and is
|
||||||
|
now cheap because the anchor exists.
|
||||||
|
|||||||
Reference in New Issue
Block a user