From a3868fab5be567ef487205474c4187bf299ad1b3 Mon Sep 17 00:00:00 2001 From: "Claude (auto-RE)" Date: Wed, 12 Aug 2026 21:21:21 +0000 Subject: [PATCH] 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) --- docs/re/live-unit-definitions.md | 36 ++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/docs/re/live-unit-definitions.md b/docs/re/live-unit-definitions.md index b64f040..fa206d9 100644 --- a/docs/re/live-unit-definitions.md +++ b/docs/re/live-unit-definitions.md @@ -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 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.)