re: the static route locates the reflective parser and reframes the defaults
sylpheed.db has the machinery named: IdxdLoad_Dispatch 0x824486c0, Idxd_Parse 0x82449640, Reflect_FindFieldIndex 0x8244a2f0, Reflect_SetField 0x8244a4b0. FindFieldIndex looks a field up by NAME at runtime (strlen + compare), which supports the reflective-read reading -- but Idxd_Parse is a text parser that calls SetField on a target object, so a parsed record does exist and the earlier 'no flat record' hypothesis is weakened. The useful consequence: Idxd_Parse only writes fields the text contains, so a DEFAULTED field keeps whatever the constructor stored. The defaults are therefore immediates in each definition class's constructor -- reachable by walking the call graph above IdxdLoad_Dispatch -- not values to be scanned for in RAM. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -196,3 +196,39 @@ one of the cached, every-frame fields.
|
|||||||
|
|
||||||
This is a hypothesis, not a finding: it explains three negative probes but has not
|
This is a hypothesis, not a finding: it explains three negative probes but has not
|
||||||
been confirmed by watching a read happen.
|
been confirmed by watching a read happen.
|
||||||
|
|
||||||
|
## The static route says where the defaults must be
|
||||||
|
|
||||||
|
The DuckDB image (`xenia-rs/sylpheed.db`, 12 156 functions / 1.87 M instructions)
|
||||||
|
has the reflective machinery under real names:
|
||||||
|
|
||||||
|
| address | name |
|
||||||
|
|---|---|
|
||||||
|
| `0x824486c0` | `IdxdLoad_Dispatch` |
|
||||||
|
| `0x82448d00` | `IdxdLoad_Variant2` |
|
||||||
|
| `0x82449640` | `Idxd_Parse` |
|
||||||
|
| `0x8244a2f0` | `Reflect_FindFieldIndex` |
|
||||||
|
| `0x8244a4b0` | `Reflect_SetField` |
|
||||||
|
|
||||||
|
`Reflect_FindFieldIndex` measures a C string, indexes a buffer and calls a
|
||||||
|
compare routine — it looks a field up **by name at runtime**, which is the
|
||||||
|
reflective read the hypothesis above predicted. But `Idxd_Parse` is a **text
|
||||||
|
parser** (it checks for a UTF-16 BOM, walks characters through a jump table at
|
||||||
|
`0x824497f8`) and it calls `Reflect_SetField` on a target object passed in `r3`.
|
||||||
|
|
||||||
|
That last point **weakens the "no parsed record" hypothesis**: parsing writes
|
||||||
|
values into a real object. So a parsed record does exist — my three RAM probes
|
||||||
|
simply did not find the right one — and, more usefully, it tells us where a
|
||||||
|
*defaulted* field's value comes from. `Idxd_Parse` only ever writes the fields the
|
||||||
|
text actually contains, so a defaulted field keeps **whatever the object had
|
||||||
|
before parsing** — i.e. the value its **constructor** stored.
|
||||||
|
|
||||||
|
So the defaults are neither in the disc data (by definition) nor in a table to be
|
||||||
|
scanned for: they are immediates in the constructor of each definition class.
|
||||||
|
Reading them is a disassembly job — find the allocation site above
|
||||||
|
`IdxdLoad_Dispatch`, then the constructor it calls, and read the stores. That is
|
||||||
|
the next step, and it would settle the whole `…Ratio` / `…Count` family at once
|
||||||
|
rather than one field per flight.
|
||||||
|
|
||||||
|
(The `vtables`, `classes` and `methods` tables are empty in this DB build, as
|
||||||
|
`CLAUDE.md` warns, so the class has to be reached through the call graph.)
|
||||||
|
|||||||
Reference in New Issue
Block a user