diff --git a/docs/re/structures/isl-builtins.md b/docs/re/structures/isl-builtins.md index 1ab75a28..21d520f0 100644 --- a/docs/re/structures/isl-builtins.md +++ b/docs/re/structures/isl-builtins.md @@ -442,3 +442,39 @@ from the context block** at the moment of the write. Reading the right offset ou of `$rsi` would name the guest instruction. That needs Xenia's context layout — which is in the xenia-rs sources on this box — and is a separate, tractable piece of work rather than another blind run. + +## 🟡 `sub_8226E458` is a splice — but I have not shown it touches the trigger queue + +Chasing which of `sub_8226EAB8`'s 16 callers grows the trigger count, the +promising one is `sub_8226E458`: + +``` +8226e504 lwz r11, 8(r30) ; source count +8226e508 subi r11, r11, 1 +8226e50c stw r11, 8(r30) ; source -= 1 +8226e51c bl 0x8226EAB8 ; ... then insert into the destination (+1) +``` + +Remove from one list, insert into another — a **splice**. And it has exactly one +caller, `0x8226D780`, **inside `sub_8226D740`**, the per-frame engine→script +drain. That is a tidy story: the engine moves records into the phase's queue each +frame, and the count I watched rises as it does. + +🔴 **The tidy story is not supported by the call site.** At `0x8226D780` the +argument is `lwz r4, 324(r29)` — `[ScriptPhase+324]`, the **unit array**, not the +trigger container. So whatever `sub_8226E458` splices between, I have **not** +shown it is the trigger queue, and the "engine feeds triggers each frame" +reading is mine rather than the disassembly's. + +Recording it unresolved. The same over-reach — taking a function's shape as its +purpose — produced the "push" mislabel on `sub_8226E3B8` and the +`ADN110`-for-null pretty-print, both of which cost an iteration to undo. + +**What is solid** and does not depend on this: `sub_8226EAB8` increments a count +at `+8` of the container it is handed; the trigger container embeds its list at +`+12`; and the watched word at `phase+272+20` is therefore that inner list's +count. The guest was executing inside `sub_8226EAB8` at the moment of the write. + +**Next:** rather than guessing among 16 callers, set the watchpoint again and +read the **guest LR** out of the context (`%rsi`) at the hit — the same technique +that named `sub_8226EAB8` will name its caller.