re: entry_a is a code/data boundary, not an entry -- and the decoder was reading data as code

Disassembling the three Stage-02 entry_a targets shows opcodes 0x19 and 0x1A, and the
ISL dispatcher's table has 25 entries (cmplwi 0x18).  They are not instructions.  Each
phase region ENDS with a trailing data table of 8-byte typed records -- tag 0x19 = int,
tag 0x1A = IEEE float (0.0, 0.5, 1.0, 4.0) -- and entry_a is where it starts.

Confirmed across the disc: in 44 of 44 phases the first offset whose opcode exceeds
0x18 is exactly that phase's entry_a, with zero exceptions, and only two tags ever
appear (1394 x 0x19, 675 x 0x1A).  So the record is

    0x1883, base, size, 0, code_end, force_end_handler

one boundary and one entry, not two entries as the previous commit said.

That also retires this thread's own "82 of 88 land on a valid instruction = 93.2% vs a
38.6% control" as TOO WEAK a test: a data record has length 8 and passes "nonzero,
even".  The entry_b result stands on different evidence -- those targets were matched
against isl.call_sites(), an independent enumeration.

isl.linear_offsets was decoding all 2069 data records as instructions, 1.23% of the
stream.  Now each phase's walk stops at its boundary:

  decoded instructions   168251 -> 166182  (= 168251 - 2069, as predicted)
  opcode > 0x18               2069 -> 0
  call sites covered     25705/25705 -> 25705/25705
  exits unreachable                0 -> 0
  conditions unknown             400 -> 400

Recorded because the first attempt at the fix was worse than the bug: it destroyed 36%
of the stream (168251 -> 107596, exits 0 -> 74) because linear_offsets is ONE global
walk from the first phase base, so stopping at phase 1's table lost every later phase.
It has to skip the region and resume at the next base.  A count moving hard in the
wrong direction is the same signal as one that will not move.

Still open: the table's contents are undecoded -- its int values land on the
instruction stream 46/51 against a 29.5% chance rate, but 0 of them are unreached
run-starts, so this is not what starts the unreachable code either.
This commit is contained in:
Sylpheed RE agent
2026-08-27 06:59:58 +00:00
parent e897da3017
commit 7cd2370372
5 changed files with 127 additions and 38 deletions

View File

@@ -35,8 +35,22 @@ unknown, what evidence exists, and what the first step would be. Move an item in
which is what an engine-entered abort handler should look like.
⚠️ First seeding attempt moved NOTHING (85.0 %→85.0 %, 5→5) because
`dominating_conditions()` builds its own entry set — fix-the-instance again.
🟡 Still open: reach only 85.0 %→**85.2 %**, so what starts the other ~15 % is
unknown; `entry_a` is unidentified; 6 of 88 values do not land on an instruction.
**(2026-08-27) `entry_a` IDENTIFIED — and it is NOT an entry point.** It is the
offset where the phase's CODE ends and a trailing **DATA table** begins: 8-byte
typed records, tag `0x19` = int, tag `0x1A` = IEEE float, and the dispatcher only
has 25 opcodes (`cmplwi 0x18`). **44 of 44 phases: the first opcode > 0x18 is
exactly `entry_a`, zero exceptions**; only tags 0x19 (1394) and 0x1A (675) occur.
So the record is `0x1883, base, size, 0, code_end, force_end_handler`. ⚠️ This
also retires the earlier "93.2 % land on a valid instruction" test as TOO WEAK — a
data record has length 8 and passes "nonzero, even". 🔧 `isl.linear_offsets` was
decoding all **2069** data records as instructions (1.23 %); now stops per phase
at the boundary: **168251 → 166182**, op>0x18 **2069 → 0**, call-site coverage
held at **25705/25705**, exits still 0 unreachable, conditions unchanged at 400.
⚠️ The first attempt at that fix cost **36 %** of the stream (168251→107596,
exits 0→74) because the walk is global and stopped at phase 1's table — it must
SKIP and resume per phase. 🟡 Still open: the table's contents are undecoded (its
int values hit the stream 46/51 vs 29.5 % chance but **0 are unreached
run-starts**), and what starts the other ~15 % of code is still unknown.
## ✅✅ SOLVED — the mission freeze was a modal sign-in dialog (2026-08-26)

View File

@@ -7,7 +7,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 8256 of 9879 instructions (83.6%).
CFG reached 8083 of 9706 instructions (83.3%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -68,7 +68,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 15821 of 18739 instructions (84.4%).
CFG reached 15650 of 18568 instructions (84.3%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -174,7 +174,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 8482 of 11105 instructions (76.4%).
CFG reached 8272 of 10895 instructions (75.9%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -286,7 +286,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 3688 of 4377 instructions (84.3%).
CFG reached 3605 of 4294 instructions (84.0%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -358,7 +358,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 4316 of 5194 instructions (83.1%).
CFG reached 4230 of 5108 instructions (82.8%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -419,7 +419,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 8409 of 9514 instructions (88.4%).
CFG reached 8286 of 9391 instructions (88.2%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -520,7 +520,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 7254 of 8026 instructions (90.4%).
CFG reached 7195 of 7967 instructions (90.3%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -621,7 +621,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 6642 of 7610 instructions (87.3%).
CFG reached 6526 of 7494 instructions (87.1%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -684,7 +684,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 9008 of 10053 instructions (89.6%).
CFG reached 8894 of 9939 instructions (89.5%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -803,7 +803,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 2578 of 2749 instructions (93.8%).
CFG reached 2544 of 2715 instructions (93.7%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -839,7 +839,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 6805 of 7253 instructions (93.8%).
CFG reached 6728 of 7176 instructions (93.8%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -903,7 +903,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 6202 of 6628 instructions (93.6%).
CFG reached 6141 of 6567 instructions (93.5%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -939,7 +939,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 4302 of 5258 instructions (81.8%).
CFG reached 4217 of 5173 instructions (81.5%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -980,7 +980,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 3305 of 3709 instructions (89.1%).
CFG reached 3228 of 3632 instructions (88.9%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -1037,7 +1037,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 6767 of 8106 instructions (83.5%).
CFG reached 6624 of 7963 instructions (83.2%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -1089,7 +1089,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 836 of 1179 instructions (70.9%).
CFG reached 775 of 1118 instructions (69.3%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -1123,7 +1123,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 881 of 925 instructions (95.2%).
CFG reached 871 of 915 instructions (95.2%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -1144,7 +1144,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 528 of 560 instructions (94.3%).
CFG reached 518 of 550 instructions (94.2%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -1165,7 +1165,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 811 of 846 instructions (95.9%).
CFG reached 801 of 836 instructions (95.8%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -1186,7 +1186,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 378 of 411 instructions (92.0%).
CFG reached 368 of 401 instructions (91.8%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -1207,7 +1207,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 706 of 738 instructions (95.7%).
CFG reached 696 of 728 instructions (95.6%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -1228,7 +1228,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 374 of 406 instructions (92.1%).
CFG reached 364 of 396 instructions (91.9%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -1249,7 +1249,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 4027 of 4235 instructions (95.1%).
CFG reached 3984 of 4192 instructions (95.0%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -1306,7 +1306,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 9577 of 9936 instructions (96.4%).
CFG reached 9525 of 9884 instructions (96.4%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -1341,7 +1341,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 3896 of 5604 instructions (69.5%).
CFG reached 3820 of 5528 instructions (69.1%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -1382,7 +1382,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 2468 of 3031 instructions (81.4%).
CFG reached 2410 of 2973 instructions (81.1%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -1440,7 +1440,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 2193 of 2401 instructions (91.3%).
CFG reached 2168 of 2376 instructions (91.2%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.
@@ -1476,7 +1476,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 14840 of 19779 instructions (75.0%).
CFG reached 14758 of 19697 instructions (74.9%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.

View File

@@ -7,7 +7,7 @@ entry to that `END_PHASE` passes through it, so it is NECESSARY for the
phase to end that way. Reachability alone is the wrong query here —
in a poll loop both successors reach the exit.
CFG reached 15821 of 18739 instructions (84.4%).
CFG reached 15650 of 18568 instructions (84.3%).
`precond` = necessary: the exit cannot happen unless it holds.
`TRIGGER` = also SUFFICIENT: once it holds the exit is unavoidable.

View File

@@ -1,4 +1,4 @@
# ✅ The mission-level `0x1883` record carries two ENTRY POINTS — and they were the missing exits
# ✅ The mission-level `0x1883` record: one entry point and one code/data boundary
Every phase exit in all 28 stages is now reachable. `data/isl-phase-guards-all.txt`
went from **5 of 177 exits unreachable** to **0**.
@@ -33,9 +33,12 @@ one per phase, whose operand is the phase's code base, and notes they each end
0x1883, base_delta, size, 0, entry_a, entry_b ; entries PHASE-RELATIVE
```
**Measured over all 28 stages: 82 of 88 of those values land on a valid
instruction — 93.2 %, against a 38.6 % chance rate for a random 4-aligned
offset.**
~~**Measured over all 28 stages: 82 of 88 of those values land on a valid
instruction — 93.2 %, against a 38.6 % chance rate.**~~
⚠️ **That test was too weak** — see *What `entry_a` really is* below. A trailing
data record has length 8 and so passes "nonzero, even length"; the 93.2 % counted
data as code. The `entry_b` result stands on a different footing: those targets
were matched against `isl.call_sites()`, an independent enumeration.
And for Stage 02 the second entry of each record is the phase's force-end
handler:
@@ -72,3 +75,52 @@ own size earlier in this corpus. With both patched: exits **5 → 0**.
Stage-02 records; what the first entry of each pair is has not been checked.
* **6 of 88 values do not land on an instruction.** Not investigated — they may
be absent phases, a different record variant, or a decode edge.
## 🔴 What `entry_a` really is — NOT an entry point
Disassembling the three Stage-02 `entry_a` targets shows **opcodes 0x19 and
0x1A**, and the dispatcher's table has 25 entries (`cmplwi 0x18`). Those are not
instructions at all:
```
014848: 00000819 tag 19 00000019 int 25
014850: 00000819 tag 19 00002B20 int
014858: 0000081A tag 1A 00000000 float 0.0
014860: 00000819 tag 19 00000005 int 5
014868: 00000819 tag 19 00002B88 int
014870: 0000081A tag 1A 3F000000 float 0.5
```
Each phase region **ends with a trailing DATA table** of 8-byte typed records —
tag `0x19` = int, tag `0x1A` = IEEE float — and `entry_a` is where it starts.
**Confirmed across the disc: in 44 of 44 phases, the first offset whose opcode
exceeds 0x18 is exactly that phase's `entry_a`. Zero exceptions.** Only two tags
ever appear: 1 394 × `0x19` and 675 × `0x1A`.
So the record is `0x1883, base, size, 0, code_end, force_end_handler` — one
boundary and one entry.
🟡 The table's contents are **not decoded**. Its int values do land on the
instruction stream more often than chance (46/51 vs 29.5 %), but **0 of them are
unreached run-starts** — so this is not what starts the unreachable code either.
## ✅ And the decoder was reading that data as code
`isl.linear_offsets` was decoding all **2 069** of those records as instructions,
1.23 % of the stream. Fixed by stopping each phase's walk at its boundary:
| | before | after |
|---|---|---|
| decoded instructions | 168 251 | **166 182** = 168 251 2 069 |
| records with opcode > 0x18 | 2 069 | **0** |
| **call sites covered** | 25 705 / 25 705 | **25 705 / 25 705** |
| exits unreachable | 0 | 0 |
| conditions with unknown LHS | 400 | 400 |
⚠️ **The first attempt at that fix destroyed 36 % of the stream** — 168 251 →
107 596, exits 0 → 74 — because `linear_offsets` is one global walk from the
first phase base, so stopping at phase 1's table lost every later phase. It has
to *skip* the region and resume at the next base. A count moving hard in the
wrong direction is the same signal as one that will not move.

View File

@@ -254,13 +254,36 @@ def linear_offsets(b, start=None):
reaching a call site needs no control-flow reconstruction at all.
"""
end = struct.unpack_from('>I', b, 0x0C)[0] # symtab1 = end of code
if start is None:
start = phase_bases(b)[0]
# Walk EACH PHASE separately: a phase's code runs from its base up to that
# phase's trailing data table, and the next phase's code begins at its own
# base. A single global walk stops dead at phase 1's table and loses every
# later phase -- that mistake cost 36% of the instruction stream.
bases = phase_bases(b)
if start is None or start in bases:
out = []
limits = list(bases[1:]) + [end]
for base, hi in zip(bases, limits):
out.extend(_walk_one(b, base, hi))
return out
return _walk_one(b, start, end)
def _walk_one(b, start, end):
out = []
off = start
while off + 4 <= end:
w = struct.unpack_from('>I', b, off)[0]
# The dispatcher's table has 25 entries (`cmplwi 0x18`), so an opcode
# above 0x18 is NOT an instruction. Each phase region ends with a
# trailing DATA table of 8-byte typed records -- tag 0x19 = int,
# tag 0x1A = IEEE float -- and its start is the FIRST entry of that
# phase's mission-level `0x1883` record. Measured: in 44 of 44 phases
# across all 28 stages the first opcode > 0x18 is exactly that value.
# Decoding those 2069 records as instructions was 1.23% of the stream.
if (w & 0xFF) > 0x18:
break
out.append(off)
ln = (struct.unpack_from('>I', b, off)[0] >> 8) & 0xFF
ln = (w >> 8) & 0xFF
if ln == 0 or ln % 2:
break
off += ln