re: the timer message's consumer is a runtime registry, not a tag compare
The move I flagged last iteration -- "0xAB03E5BA is built once, so
nothing consumes it" -- is refuted by its own control: 25 of the 40
distinct 0xAB03xxxx tags in the image are built exactly once (62.5 %),
and no 4-aligned word anywhere in the image begins 0xAB03, so tags are
never stored statically.
What does stand:
* sub_82175C20(bus+4, &msg) is a ring-buffer PUSH, not a dispatch.
* The message class has a one-method vtable {scalar deleting dtor}
with an MSVC RTTI locator at vtable[-1] -- no handler of its own.
* The bus at [0x828F35DC] has a map at +8216, looked up via
sub_82254A08 from sub_823001E8, whose only caller is the per-frame
pump sub_8230C398.
So the item is NOT settled: the insert path into bus+8216 is unread,
and whether running out of time ends the mission is still unknown.
Docs only; ISL artefacts regenerate byte-identical.
This commit is contained in:
@@ -336,6 +336,34 @@ unknown, what evidence exists, and what the first step would be. Move an item in
|
||||
unread, as is what B reaching zero does, and whether all 170 `timer_stop` sites
|
||||
are phase teardown.
|
||||
|
||||
* 🔎🔴 **(2026-08-27) THE TIMER MESSAGE'S CONSUMER: LOCATED, NOT READ — and the
|
||||
argument I was about to make is REFUTED BY ITS OWN CONTROL.
|
||||
[structures/isl-mission-timer](structures/isl-mission-timer.md).**
|
||||
The tempting move was "`0xAB03E5BA` is built at exactly one site, so nothing
|
||||
consumes the timer message". **The control kills it: 25 of the 40 distinct
|
||||
`0xAB03xxxx` tags in the image are built exactly once (62.5 %)** — single-site
|
||||
construction is the *majority*, not an anomaly. And the tag appears **nowhere
|
||||
in the image as a 4-byte word** — in fact **no 4-aligned word anywhere begins
|
||||
`0xAB03`** — so there is no static table of subscribed tags to find either.
|
||||
✅ **Two structural reads that do stand.** (1) The post is a **queue push, not a
|
||||
dispatch**: `sub_82175C20(bus+4, &msg)` is a ring-buffer append (capacity `+8`,
|
||||
head `+12`, count `+16`, array `+4`, grown via `sub_8228E208`) and never looks
|
||||
at the message. (2) The message class has a **one-method vtable**:
|
||||
`0x820A8D18`–`0x820A8DA0` is a run of 2-word records
|
||||
`{ sub_82301C20, 0x8210Exxx }`; the timer message's vptr `0x820A8D68` gives
|
||||
`vtable[0] = sub_82301C20` (a scalar deleting destructor — stores `0x820A7014`
|
||||
over the vptr, conditionally frees) and `vtable[-1] = 0x8210E288`, an **MSVC
|
||||
RTTI locator** (`0,0,0, &typeDesc 0x8289D094, &classHierarchy 0x8210E29C`,
|
||||
`numBaseClasses = 3`) — data, not code, and below `sylpheed.db`'s `0x82150000`
|
||||
floor. **So the message carries no handler of its own**, and dispatch is neither
|
||||
a literal compare nor virtual on the message.
|
||||
🟡 **Located:** the bus at `[0x828F35DC]` carries a **map at `+8216`**, looked
|
||||
up through `sub_82254A08` from **`sub_823001E8`**, whose only caller is
|
||||
`sub_8230C398` — the per-frame message pump, called from the frame loop
|
||||
(`0x821A6544`) with the frame `dt`. So the question reduces to **what inserts
|
||||
into `bus+8216` and with which key**. That path is unread, so **the item is NOT
|
||||
settled**: whether running out of time ends the mission is still unknown.
|
||||
|
||||
## ✅✅ SOLVED — the mission freeze was a modal sign-in dialog (2026-08-26)
|
||||
|
||||
`XamShowSigninUI` opens a modal dialog and `xeXamDispatchDialog` blocks the
|
||||
|
||||
@@ -110,13 +110,52 @@ the same coroutine one instruction apart, which is why they read almost the same
|
||||
value and the conflation was invisible. **The 1200-second limit belongs to the
|
||||
mission timer; it is not stopwatch 0's limit.**
|
||||
|
||||
## 🔴 The message bus: what the "one occurrence" of the tag is worth — nothing
|
||||
|
||||
The obvious next move was to search for a second site building `0xAB03E5BA` and
|
||||
conclude from its absence that nothing consumes the timer message. **That
|
||||
reasoning is dead**, and the control kills it:
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| instructions building `0xAB03E5BA` (`addis 0xAB03` + `ori 0xE5BA`) | 1 — the producer |
|
||||
| `0xAB03E5BA` as a 4-byte word **anywhere** in the image | **0** |
|
||||
| *any* 4-aligned word beginning `0xAB03` anywhere in the image | **0** |
|
||||
| distinct `0xAB03xxxx` tags built by an `addis`/`ori` pair | 40 |
|
||||
| **of those, built exactly once** | **25 (62.5 %)** |
|
||||
|
||||
Single-site construction is the **majority** case, so it says nothing about this
|
||||
tag in particular. And because no tag is ever stored as a static word, there is
|
||||
no table of subscribed tags to find either.
|
||||
|
||||
### ✅ Two structural reasons it cannot be a compare or a virtual call
|
||||
|
||||
* **The post is a QUEUE PUSH, not a dispatch.** `sub_82175C20(bus+4, &msg)` is a
|
||||
ring-buffer append — capacity at `+8`, head at `+12`, count at `+16`, element
|
||||
array at `+4`, growing through `sub_8228E208`. It never looks at the message.
|
||||
* **The message class has a ONE-METHOD vtable.** `0x820A8D18`–`0x820A8DA0` is a
|
||||
run of 2-word records `{ sub_82301C20, 0x8210Exxx }`. The timer message's vptr
|
||||
is `0x820A8D68`, so `vtable[0] = sub_82301C20` — a scalar deleting destructor
|
||||
(it stores `0x820A7014` over the vptr and conditionally frees) — and
|
||||
`vtable[-1] = 0x8210E288`, an MSVC RTTI locator (`0,0,0, &typeDescriptor
|
||||
0x8289D094, &classHierarchy 0x8210E29C`, `numBaseClasses = 3`). Not code: that
|
||||
address is data, and the disassembly does not even reach it (`sylpheed.db`
|
||||
starts at `0x82150000`). **The message carries no handler of its own.**
|
||||
|
||||
### 🟡 Where the subscriber actually lives — located, not read
|
||||
|
||||
The bus object at `[0x828F35DC]` carries a **map at `+8216`**, looked up through
|
||||
`sub_82254A08` from **`sub_823001E8`** — whose only caller is `sub_8230C398`, the
|
||||
per-frame message pump (itself called from the frame loop `sub_821A6544` with the
|
||||
frame `dt`). So dispatch is a **runtime registry keyed by the tag**, and the
|
||||
question "does running out of time end the mission" reduces to: *what inserts into
|
||||
`bus+8216`, and with which key.* That insert path is not read here.
|
||||
|
||||
## 🟡 Not settled
|
||||
|
||||
* **Who subscribes to `0xAB03E5BA`.** The literal appears at exactly one site —
|
||||
the producer — but `0xAB03` is the high half of *many* message tags in this
|
||||
image and dispatch is not by literal compare, so a single occurrence is **not**
|
||||
evidence that nothing consumes it. Whether running out of time ends the mission
|
||||
is therefore unread.
|
||||
* **Who subscribes to `0xAB03E5BA`** — see above. Located to the registry at
|
||||
`bus+8216`; the registration path is unread, so whether running out of time
|
||||
ends the mission is still unknown.
|
||||
* What B counting to zero does. Nothing observed acts on it.
|
||||
* Whether `timer_stop`'s 170 sites are all phase teardown, or some are a real
|
||||
mid-mission stop.
|
||||
|
||||
Reference in New Issue
Block a user