nmarshall commited on
Commit
3bc8c35
·
1 Parent(s): 3ae56cb

qvm: recover method counter updates

Browse files
docs/ASSET_PIPELINE_TODO.md CHANGED
@@ -910,3 +910,6 @@ Research progress: RE-748 [report](research/QVM_CLIENT_NOTIFICATIONS.md); origin
910
 
911
 
912
  Research progress: RE-749 [report](research/QVM_METHOD_STAT_SLOTS.md); original assets unchanged.
 
 
 
 
910
 
911
 
912
  Research progress: RE-749 [report](research/QVM_METHOD_STAT_SLOTS.md); original assets unchanged.
913
+
914
+
915
+ Research progress: RE-750 [report](research/QVM_METHOD_STAT_UPDATES.md); original assets unchanged.
docs/FINDINGS.md CHANGED
@@ -1256,3 +1256,6 @@ RE-725–734 batch: [health, contact and Rust impulse findings](research/QVM_HEA
1256
 
1257
 
1258
  **RE-749 — Complete method to statistic slot classification:** 278733 maps19 selected methods into statistic slots0..18 using the original jump table; all other tested methods return-1. [Evidence](research/QVM_METHOD_STAT_SLOTS.md).
 
 
 
 
1256
 
1257
 
1258
  **RE-749 — Complete method to statistic slot classification:** 278733 maps19 selected methods into statistic slots0..18 using the original jump table; all other tested methods return-1. [Evidence](research/QVM_METHOD_STAT_SLOTS.md).
1259
+
1260
+
1261
+ **RE-750 — Complete method counter mutation aliases and notifications:** 278834 updates per-method or fallback counters with wrapping increments, distinct self cases, and ordered aggregate/report requests. [Evidence](research/QVM_METHOD_STAT_UPDATES.md).
docs/PROVISIONAL_TODO.md CHANGED
@@ -1248,3 +1248,6 @@ Research progress: RE-748 [report](research/QVM_CLIENT_NOTIFICATIONS.md); full n
1248
 
1249
 
1250
  Research progress: RE-749 [report](research/QVM_METHOD_STAT_SLOTS.md); full native/platform/game scope remains open.
 
 
 
 
1248
 
1249
 
1250
  Research progress: RE-749 [report](research/QVM_METHOD_STAT_SLOTS.md); full native/platform/game scope remains open.
1251
+
1252
+
1253
+ Research progress: RE-750 [report](research/QVM_METHOD_STAT_UPDATES.md); full native/platform/game scope remains open.
docs/RESEARCH_LEDGER.md CHANGED
@@ -1395,3 +1395,8 @@ Exactly ten task commits follow baseline `e1f7eb5a`. Each task passed focused `c
1395
  ## 2026-10-21 — RE-749 Complete method to statistic slot classification
1396
 
1397
  278733 maps19 selected methods into statistic slots0..18 using the original jump table; all other tested methods return-1. Focused `cargo xtask test-group stat-slots` passes (3 Python tests); selected reports regenerate twice byte-identically, with storage, links and whitespace guards. New report: 19282 bytes. Full-suite validation is deferred to the tenth batch commit. No original assets, Rust runtime or shared VM evaluator changed.
 
 
 
 
 
 
1395
  ## 2026-10-21 — RE-749 Complete method to statistic slot classification
1396
 
1397
  278733 maps19 selected methods into statistic slots0..18 using the original jump table; all other tested methods return-1. Focused `cargo xtask test-group stat-slots` passes (3 Python tests); selected reports regenerate twice byte-identically, with storage, links and whitespace guards. New report: 19282 bytes. Full-suite validation is deferred to the tenth batch commit. No original assets, Rust runtime or shared VM evaluator changed.
1398
+
1399
+
1400
+ ## 2026-10-21 — RE-750 Complete method counter mutation aliases and notifications
1401
+
1402
+ 278834 updates per-method or fallback counters with wrapping increments, distinct self cases, and ordered aggregate/report requests. Focused `cargo xtask test-group stat-updates` passes (3 Python tests); selected reports regenerate twice byte-identically, with storage, links and whitespace guards. New report: 956970 bytes. Full-suite validation is deferred to the tenth batch commit. No original assets, Rust runtime or shared VM evaluator changed.
docs/REVERSE_ENGINEERING_TODO.md CHANGED
@@ -1291,3 +1291,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
1291
 
1292
 
1293
  - [x] RE-749 Complete method to statistic slot classification ([report](research/QVM_METHOD_STAT_SLOTS.md)).
 
 
 
 
1291
 
1292
 
1293
  - [x] RE-749 Complete method to statistic slot classification ([report](research/QVM_METHOD_STAT_SLOTS.md)).
1294
+
1295
+
1296
+ - [x] RE-750 Complete method counter mutation aliases and notifications ([report](research/QVM_METHOD_STAT_UPDATES.md)).
docs/research/QVM_METHOD_STAT_UPDATES.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Complete method counter mutation aliases and notifications
2
+
3
+ RE-750. Reproduce with `python3 scripts/analyze_qvm_method_stat_updates.py`; validate with `cargo xtask test-group stat-updates`. See the [machine report](qvm-method-stat-updates.json).
4
+
5
+ Recovered complete278834 across205 fixtures with actual278733, every method-1..49, self aliases, absent actor and zero/max counter values. Independent offset and callback oracles cover table/fallback dispatch.279720/279586/285227/283622 internals stay captured; invalid victim/null low-page accesses and semantic stat names remain open.
6
+
7
+ No original executable/full VM/native world collision or rendering runs. Supplied callback/native responses and fixture domains remain explicit; complete macOS/Linux Rust/Bevy/Solari gameplay remains open.
docs/research/README.md CHANGED
@@ -846,3 +846,6 @@ The extension collector adds five focused tests for native tail calls, command-r
846
 
847
 
848
  [RE-749: Complete method to statistic slot classification](QVM_METHOD_STAT_SLOTS.md).
 
 
 
 
846
 
847
 
848
  [RE-749: Complete method to statistic slot classification](QVM_METHOD_STAT_SLOTS.md).
849
+
850
+
851
+ [RE-750: Complete method counter mutation aliases and notifications](QVM_METHOD_STAT_UPDATES.md).
docs/research/qvm-method-stat-updates.json ADDED
The diff for this file is too large to render. See raw diff
 
scripts/analyze_qvm_method_stat_updates.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Complete278834 counter writes, aliasing and notification requests."""
3
+ import itertools
4
+ from pathlib import Path
5
+ from qvm_research_support import source
6
+ from qvm_stat_update_support import seed,update,OFFSETS
7
+ from analyze_qvm import write_json
8
+
9
+ def main():
10
+ q,raw,h,ins=source();rows=[]
11
+ cases=[dict(method=m,self=s,initial=v) for m,s,v in itertools.product([-1,*range(50)],[False,True],[0,0xffffffff])];cases += [dict(method=20,self=False,initial=0,actor_absent=True)]
12
+ for a in cases:
13
+ actor=-1 if a.get('actor_absent') else 1;victim=1 if a['self'] else 2
14
+ _,_,p=update(ins,seed(raw,h,**a),{8:actor,12:a['method'],16:victim});p['input']=a;rows.append(p)
15
+ write_json(Path('docs/research/qvm-method-stat-updates.json'),{'source':q['source'],'sha256':q['sha256'],'tracked_offsets':OFFSETS,'probes':rows,'limits':'Complete278834 finite methods-1..49, actor1/victim2 or self1, absent actor-1, zero/max counters. Actual278733;279720/279586/285227/283622 captured. Invalid victim/null low-page domains excluded; no aggregate/report/native effect execution.'})
16
+ if __name__=='__main__':main()
scripts/qvm_stat_update_support.py ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """278834 counters with actual278733; reporting/aggregate children captured."""
2
+ from qvm_health_effects_support import seed as health_seed,H,CLIENT,A_CLIENT
3
+ from qvm_research_support import constants
4
+ from qvm_trace_support import resume,captured
5
+ from qvm_method_stats_support import method_seed,classify
6
+ from qvm_notification_support import POOL
7
+ T=H+0xf0000
8
+ OFFSETS=sorted(set([856+76*j+k for j in range(19) for k in [60,64]]+list(range(2376,2516,4))))
9
+
10
+ def seed(raw,h,**a):
11
+ m=health_seed(raw,h);m.update(method_seed(raw,h));m.update(constants(raw,h,range(31532,31684,4)));m[POOL+880+520]=A_CLIENT;m[POOL+1760+520]=CLIENT
12
+ for c in [CLIENT,A_CLIENT]:
13
+ for o in OFFSETS:m[c+o]=a.get('initial',0)
14
+ return m
15
+
16
+ def update(ins,m,args):
17
+ for o,v in args.items():m[T+52+o]=v
18
+ addresses=sorted({c+o for c in [CLIENT,A_CLIENT] for o in OFFSETS});before={a:m[a]&0xffffffff for a in addresses};requests=[]
19
+ hs={c:captured(c,requests) for c in [279720,279586,285227,283622]};hs[278733]=classify
20
+ m,e=resume(ins,278835,279584,m,T,handlers=hs)
21
+ changes=[{'client':'actor' if a>=A_CLIENT and a<A_CLIENT+7000 else 'victim','offset':a-(A_CLIENT if a>=A_CLIENT and a<A_CLIENT+7000 else CLIENT),'before':before[a],'after':m[a]&0xffffffff} for a in addresses if before[a]!=(m[a]&0xffffffff)]
22
+ return m,0,{'arguments':args,'changes':changes,'requests':requests,'execution':e}
scripts/test_qvm_method_stat_updates.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json,unittest
2
+ from pathlib import Path
3
+ from test_qvm_method_stat_slots import SLOTS
4
+ from qvm_notification_support import POOL
5
+
6
+ def expected(a):
7
+ if a.get('actor_absent'):return [],[]
8
+ method=a['method'];slot=SLOTS.get(method,-1);items=[];pair=False;self_hit=a['self'];victim='actor' if self_hit else 'victim'
9
+ if slot>=0:items=[('actor',916+76*slot),(victim,920+76*slot)];pair=True
10
+ elif method in [0,1,2,3,4,5,8,9]:items=[(victim,2512)]
11
+ elif method in {6:2488,7:2492,31:2504,32:2508,33:2508,35:2508,47:2496}:items=[(victim,{6:2488,7:2492,31:2504,32:2508,33:2508,35:2508,47:2496}[method])]
12
+ elif method in [22,25] and self_hit:items=[(victim,2460 if method==22 else 2452)]
13
+ elif method in [12,13,22,23,24,25,34,37,48]:
14
+ x,y={12:(2396,2468),13:(2400,2472),22:(2384,2456),23:(2408,2480),24:(2404,2476),25:(2376,2448),34:(2428,2500),37:(2392,2464),48:(2412,2484)}[method];items=[('actor',x),(victim,y)];pair=method!=34
15
+ changes=[{'client':c,'offset':o,'before':a['initial'],'after':(a['initial']+1)&0xffffffff} for c,o in items];changes.sort(key=lambda r:(0 if r['client']=='victim' else 1,r['offset']))
16
+ return changes,([279720] if pair else [])+[279586,279586,285227,283622]
17
+ class MethodStatUpdateTests(unittest.TestCase):
18
+ @classmethod
19
+ def setUpClass(cls):cls.ps=json.loads(Path('docs/research/qvm-method-stat-updates.json').read_text())['probes']
20
+ def test_independent_counter_and_callback_oracle(self):
21
+ for p in self.ps:
22
+ changes,calls=expected(p['input']);self.assertEqual(p['changes'],changes,p['input']);self.assertEqual([c['target'] for c in p['requests']],calls,p['input'])
23
+ def test_self_alias_and_unsigned_wrap_coverage(self):
24
+ self.assertEqual(len(self.ps),205);self.assertTrue(any(p['input']['self'] and p['changes'] for p in self.ps));self.assertTrue(any(c['after']==0 for p in self.ps for c in p['changes']))
25
+ def test_complete_exit_and_identifier_notification_abi(self):
26
+ for p in self.ps:
27
+ self.assertEqual(p['execution']['stop'],279584)
28
+ for c in p['requests']:
29
+ if c['target']==285227:self.assertEqual(c['arguments'],{'8':1 if p['input']['self'] else 2,'12':1})
30
+ if __name__=='__main__':unittest.main()
xtask/checks.tsv CHANGED
@@ -1230,3 +1230,6 @@ group notifications scripts/analyze_qvm_client_notifications.py
1230
  report scripts/analyze_qvm_method_stat_slots.py docs/research/qvm-method-stat-slots.json
1231
  edge docs/research/qvm-method-stat-slots.json scripts/test_qvm_method_stat_slots.py
1232
  group stat-slots scripts/analyze_qvm_method_stat_slots.py
 
 
 
 
1230
  report scripts/analyze_qvm_method_stat_slots.py docs/research/qvm-method-stat-slots.json
1231
  edge docs/research/qvm-method-stat-slots.json scripts/test_qvm_method_stat_slots.py
1232
  group stat-slots scripts/analyze_qvm_method_stat_slots.py
1233
+ report scripts/analyze_qvm_method_stat_updates.py docs/research/qvm-method-stat-updates.json
1234
+ edge docs/research/qvm-method-stat-updates.json scripts/test_qvm_method_stat_updates.py
1235
+ group stat-updates scripts/analyze_qvm_method_stat_updates.py