re: the ind_call damage is bounded - no corpus claim was contaminated
The protective sweep after last commit's refutation. The question was which existing claims the ind_call cross product voids. Answer: none of the ones the corpus makes. Every caller-count claim in the corpus verifies against call edges, with zero ind_call contamination: title-crash-stl-tree sub_82457780 "one caller" call=1 ind_call=0 isl-trigger-queue sub_8226EAB8 "16 callers" call=16 ind_call=0 isl-coroutine-spawner sub_822737C8 "seven callers" call=7 ind_call=0 challenge-mission-gate 0x82175110 "22 callers" call=22 ind_call=0 4 of 4 exact, and not one of the four carries a single ind_call edge. There is a structural reason for that rather than luck. Partitioning the two target populations: 1710 targets have ind_call edges, 12170 have call edges, 103 have BOTH, 1607 are ind_call-only, 12067 are call-only. And all 1710 ind_call targets are vtable entries - 1710 of 1710, zero partials - against a control where only 273 of the 12170 call targets are. So ind_call fires only on virtual methods, and 1607 of them have no direct caller at all, which is exactly why the two EX_ screens came back empty on call and flooded on ind_call. The residual risk is narrow and nameable: the 103 targets carrying both kinds, where a caller count taken without a kind filter would be inflated by about 633. Everywhere else the two populations are disjoint, so a call-based count is safe and an ind_call-based one is meaningless. Rule for future work: always filter kind='call'; and when a function has no call edges, that is a fact about it - it is a virtual method - not a gap to be filled from ind_call. All seventeen artefacts byte-identical.
This commit is contained in:
@@ -6941,3 +6941,28 @@ a structural difference, not a coincidence.
|
|||||||
|
|
||||||
🔴 **Blocked**: the `+184` writer. Next route with power = the RTTI behind those
|
🔴 **Blocked**: the `+184` writer. Next route with power = the RTTI behind those
|
||||||
two anonymous classes, or a runtime watch — **not** another static offset search.
|
two anonymous classes, or a runtime watch — **not** another static offset search.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ 2026-08-28 — the `ind_call` damage is bounded, and no corpus claim was contaminated
|
||||||
|
|
||||||
|
Item (a), the protective sweep after last iteration's refutation.
|
||||||
|
|
||||||
|
✅ **Every caller-count claim in the corpus verifies against `call`, with zero
|
||||||
|
`ind_call`**: `sub_82457780` "one caller" → 1; `sub_8226EAB8` "16 callers" → 16;
|
||||||
|
`sub_822737C8` "seven callers" → 7; `0x82175110` "22 callers" → 22. **4 of 4
|
||||||
|
exact, 0 `ind_call` edges among them.**
|
||||||
|
|
||||||
|
🔑 **And there is a structural reason, not luck.** Targets with `ind_call` edges:
|
||||||
|
**1 710**; with `call` edges: **12 170**; **both: 103**; `ind_call` only:
|
||||||
|
**1 607**; `call` only: 12 067. **All 1 710 `ind_call` targets are vtable
|
||||||
|
entries — 1 710 of 1 710, zero partials** (control: only 273 of the 12 170
|
||||||
|
`call` targets are). So `ind_call` fires *only* on virtual methods, and 1 607 of
|
||||||
|
them have no direct caller at all — exactly why the two `EX_` screens were empty
|
||||||
|
on `call`.
|
||||||
|
|
||||||
|
⚠️ **Residual risk, named**: the **103** targets with *both* kinds, where an
|
||||||
|
unfiltered count would inflate by ~633. Elsewhere the populations are disjoint.
|
||||||
|
|
||||||
|
**Rule**: always filter `kind='call'`; and a function with no `call` edges is a
|
||||||
|
**virtual method**, not a gap to fill from `ind_call`.
|
||||||
|
|||||||
@@ -184,3 +184,46 @@ structural difference rather than a coincidence.
|
|||||||
graph are exhausted for it. A route with actual power would be the RTTI class
|
graph are exhausted for it. A route with actual power would be the RTTI class
|
||||||
behind `ANON_Class_271D5F25` / `_CAA8AD62`, or a runtime watch on the field —
|
behind `ANON_Class_271D5F25` / `_CAA8AD62`, or a runtime watch on the field —
|
||||||
not another static offset search.
|
not another static offset search.
|
||||||
|
|
||||||
|
### ✅ How far the `ind_call` damage reaches — bounded, and the corpus is clean
|
||||||
|
|
||||||
|
The refutation above is corpus-wide in principle, so the next question is which
|
||||||
|
existing claims it voids. Answer: **none of the ones the corpus makes.**
|
||||||
|
|
||||||
|
**Every caller-count claim in the corpus checks out against `call` edges, with
|
||||||
|
zero `ind_call` contamination:**
|
||||||
|
|
||||||
|
| doc | claim | `call` | `ind_call` |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `title-crash-stl-tree` | `sub_82457780` "one caller" | **1** | 0 |
|
||||||
|
| `isl-trigger-queue` | `sub_8226EAB8` "16 callers" | **16** | 0 |
|
||||||
|
| `isl-coroutine-spawner` | `sub_822737C8` "seven callers" | **7** | 0 |
|
||||||
|
| `challenge-mission-gate` | `0x82175110` "22 callers" | **22** | 0 |
|
||||||
|
|
||||||
|
4 of 4 exact, and none of the four has a single `ind_call` edge.
|
||||||
|
|
||||||
|
**And there is a structural reason, not luck.** Partitioning the two target
|
||||||
|
populations:
|
||||||
|
|
||||||
|
| | count |
|
||||||
|
|---|---|
|
||||||
|
| targets with `ind_call` edges | 1 710 |
|
||||||
|
| targets with `call` edges | 12 170 |
|
||||||
|
| **both** | 103 |
|
||||||
|
| `ind_call` only | 1 607 |
|
||||||
|
| `call` only | 12 067 |
|
||||||
|
|
||||||
|
🔑 **All 1 710 `ind_call` targets are vtable entries — 1 710 of 1 710, zero
|
||||||
|
partials.** (Against a control: only 273 of the 12 170 `call` targets are.) So
|
||||||
|
`ind_call` fires *only* on virtual methods, and **1 607 of them have no direct
|
||||||
|
caller at all** — which is exactly why the two `EX_` screens came back empty on
|
||||||
|
`call` and flooded on `ind_call`.
|
||||||
|
|
||||||
|
⚠️ **The residual risk, named precisely:** the **103** targets carrying *both*
|
||||||
|
kinds. There a caller count taken without a `kind` filter would be inflated by
|
||||||
|
~633. Everywhere else the two populations are disjoint, so a `call`-based count
|
||||||
|
is safe and an `ind_call`-based one is meaningless.
|
||||||
|
|
||||||
|
**Rule for future work:** always filter `kind='call'`; and when a function has no
|
||||||
|
`call` edges, that is a *fact about it* — it is a virtual method — not a gap to
|
||||||
|
be filled from `ind_call`.
|
||||||
|
|||||||
Reference in New Issue
Block a user