wine_ptrace_trace: add chain breakpoints + live-dump chain I/O (DIV confirmed: input is VLAW output 0-17.6, tmp6f8 ~0.8)
This commit is contained in:
@@ -125,6 +125,13 @@ err = db(ta(out,1000)/ta(ref,1000)) # err в dB, цель <0.1
|
|||||||
|
|
||||||
**Статус:** chain отключен, используется VLAW path (`RT_VLAW=1`). Target `0.314→<0.05` требует **live-dump chain I/O** или полной транскрипции data flow из decompilation.
|
**Статус:** chain отключен, используется VLAW path (`RT_VLAW=1`). Target `0.314→<0.05` требует **live-dump chain I/O** или полной транскрипции data flow из decompilation.
|
||||||
|
|
||||||
|
**Live-dump chain (ptrace):** chain вызывается в рантайме (DIV#0-7 на `0x1803a06a0`):
|
||||||
|
- Input: `a` = bands_curve (VLAW output, min=0, max=17.6, mean=0.048)
|
||||||
|
- `b` = tmp6f8 (step 9b accumulation, min=0, max=0.8, mean=0.8)
|
||||||
|
- 8 DIV hits на одном кадре (dual-band: 2 bands × 4 iterations?)
|
||||||
|
|
||||||
|
**Для полного live-dump нужно:** breakpoints на всех шагах 9-19 (LOG#1, DIVIDE, dc40, FMA, EXP#1, array-mul, kWarp, LOG#2, IIR4×2, EXP#2).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Чистая работа
|
## Чистая работа
|
||||||
|
|||||||
@@ -37,6 +37,11 @@ BP_CIN = 0x180529c60
|
|||||||
BP_COUT = 0x180529ee1
|
BP_COUT = 0x180529ee1
|
||||||
BP_AIN = 0x180016140
|
BP_AIN = 0x180016140
|
||||||
BP_AOUT = 0x18000332c
|
BP_AOUT = 0x18000332c
|
||||||
|
# Chain 9-19 breakpoints (BLOCKMAP:620-644)
|
||||||
|
BP_CHAIN_START = 0x18052a580 # band loop start (52a580)
|
||||||
|
BP_CHAIN_LOG1 = 0x18052a63a # LOG#1 in chain (52a63a)
|
||||||
|
BP_CHAIN_LOG2 = 0x18052aefd # LOG#2 in chain (52aefd)
|
||||||
|
BP_CHAIN_END = 0x18052b3cd # chain end / FIR start (52b3cd)
|
||||||
CTX_SLOTS = {'scr': 0x540628, 'trk': 0x540688, 'cur': 0x540678,
|
CTX_SLOTS = {'scr': 0x540628, 'trk': 0x540688, 'cur': 0x540678,
|
||||||
'fir_ptr': 0x540668}
|
'fir_ptr': 0x540668}
|
||||||
|
|
||||||
@@ -281,7 +286,12 @@ def main():
|
|||||||
('DIV', BP_DIV), ('DC40', BP_DC40),
|
('DIV', BP_DIV), ('DC40', BP_DC40),
|
||||||
('EXPVAR', BP_EXPVAR), ('FN', BP_FN),
|
('EXPVAR', BP_EXPVAR), ('FN', BP_FN),
|
||||||
('CIN', BP_CIN), ('COUT', BP_COUT),
|
('CIN', BP_CIN), ('COUT', BP_COUT),
|
||||||
('AIN', BP_AIN), ('AOUT', BP_AOUT)):
|
('AIN', BP_AIN), ('AOUT', BP_AOUT),
|
||||||
|
# Chain 9-19 breakpoints
|
||||||
|
('CHAIN_START', BP_CHAIN_START),
|
||||||
|
('CHAIN_LOG1', BP_CHAIN_LOG1),
|
||||||
|
('CHAIN_LOG2', BP_CHAIN_LOG2),
|
||||||
|
('CHAIN_END', BP_CHAIN_END)):
|
||||||
if not mapped(addr):
|
if not mapped(addr):
|
||||||
print('!! %s@%#x не смапплен — пропуск' % (nm_ := name, addr), flush=True)
|
print('!! %s@%#x не смапплен — пропуск' % (nm_ := name, addr), flush=True)
|
||||||
continue
|
continue
|
||||||
@@ -299,9 +309,11 @@ def main():
|
|||||||
samples = []
|
samples = []
|
||||||
hits = {'COPY': 0, 'EXP': 0, 'DF0': 0, 'DF0RET': 0, 'TRACKSAVE': 0,
|
hits = {'COPY': 0, 'EXP': 0, 'DF0': 0, 'DF0RET': 0, 'TRACKSAVE': 0,
|
||||||
'DIV': 0, 'DC40': 0, 'EXPVAR': 0, 'FN': 0,
|
'DIV': 0, 'DC40': 0, 'EXPVAR': 0, 'FN': 0,
|
||||||
'CIN': 0, 'COUT': 0, 'AIN': 0, 'AOUT': 0}
|
'CIN': 0, 'COUT': 0, 'AIN': 0, 'AOUT': 0,
|
||||||
|
'CHAIN_START': 0, 'CHAIN_LOG1': 0, 'CHAIN_LOG2': 0, 'CHAIN_END': 0}
|
||||||
track_by_tid = {}
|
track_by_tid = {}
|
||||||
track_dumps = []
|
track_dumps = []
|
||||||
|
chain_dumps = []
|
||||||
regs_by_tid = {}
|
regs_by_tid = {}
|
||||||
t_start = time.time()
|
t_start = time.time()
|
||||||
|
|
||||||
@@ -410,8 +422,35 @@ def main():
|
|||||||
continue
|
continue
|
||||||
if kind == 'DF0':
|
if kind == 'DF0':
|
||||||
track_by_tid[pid] = regs.rdx
|
track_by_tid[pid] = regs.rdx
|
||||||
|
# Chain 9-19: dump buffers at key points
|
||||||
|
if kind in ('CHAIN_START', 'CHAIN_LOG1', 'CHAIN_LOG2', 'CHAIN_END'):
|
||||||
|
rec_c = {'kind': kind, 'tid': pid,
|
||||||
|
't': round(time.time()-t_start, 4),
|
||||||
|
'rcx': regs.rcx, 'rdx': regs.rdx,
|
||||||
|
'r8': regs.r8, 'r9': regs.r9,
|
||||||
|
'rsp': regs.rsp}
|
||||||
|
try:
|
||||||
|
# chain input: [678i] = rcx (bands_curve), [6f8] = rdx (tmp6f8)
|
||||||
|
if regs.rcx > 0x10000 and regs.rdx > 0x10000:
|
||||||
|
rec_c['bands_in'] = rd_f32(regs.rcx, min(2050, 512)) # first 512 vals
|
||||||
|
rec_c['tmp6f8_in'] = rd_f32(regs.rdx, min(2050, 512))
|
||||||
|
rec_c['acc_ptr'] = regs.r8 if regs.r8 > 0x10000 else 0
|
||||||
|
if rec_c['acc_ptr']:
|
||||||
|
rec_c['acc_in'] = rd_f32(rec_c['acc_ptr'], min(2050, 512))
|
||||||
|
except OSError as e:
|
||||||
|
rec_c['err'] = str(e)
|
||||||
|
chain_dumps.append(rec_c)
|
||||||
|
hits[kind] += 1
|
||||||
|
# standard int3 handling
|
||||||
|
poke(pid, site, (peek(pid, site) & ~0xFF) | obyte)
|
||||||
|
regs.rip = site
|
||||||
|
setregs(pid, regs)
|
||||||
|
pt(PTRACE_SINGLESTEP, pid, 0, 0)
|
||||||
|
os.waitpid(pid, __WALL)
|
||||||
|
poke(pid, site, (peek(pid, site) & ~0xFF) | 0xCC)
|
||||||
|
pt(PTRACE_CONT, pid, 0, 0)
|
||||||
|
continue
|
||||||
if kind in ('CIN','COUT'):
|
if kind in ('CIN','COUT'):
|
||||||
key='cin_%d'%pid if kind=='CIN' else 'cout_%d'%pid
|
|
||||||
if kind=='CIN':
|
if kind=='CIN':
|
||||||
regs_by_tid[pid]=dict(rdx=regs.rdx,r12=regs.r12,
|
regs_by_tid[pid]=dict(rdx=regs.rdx,r12=regs.r12,
|
||||||
rcx=regs.rcx)
|
rcx=regs.rcx)
|
||||||
@@ -632,7 +671,7 @@ def main():
|
|||||||
snap_ptrs[nm] = p
|
snap_ptrs[nm] = p
|
||||||
snap_arr[nm] = rd_f32(p, 4100)
|
snap_arr[nm] = rd_f32(p, 4100)
|
||||||
with open(os.path.join(outdir, 'chain_samples.pkl'), 'wb') as f:
|
with open(os.path.join(outdir, 'chain_samples.pkl'), 'wb') as f:
|
||||||
pickle.dump({'samples': samples, 'snap_ptrs': snap_ptrs, 'ctx': ctx}, f)
|
pickle.dump({'samples': samples, 'chain_dumps': chain_dumps, 'snap_ptrs': snap_ptrs, 'ctx': ctx}, f)
|
||||||
np.savez_compressed(os.path.join(outdir, 'ctx_snap.npz'), **snap_arr)
|
np.savez_compressed(os.path.join(outdir, 'ctx_snap.npz'), **snap_arr)
|
||||||
print('saved %d -> %s' % (len(samples), outdir), flush=True)
|
print('saved %d -> %s' % (len(samples), outdir), flush=True)
|
||||||
for _ in range(600):
|
for _ in range(600):
|
||||||
|
|||||||
Reference in New Issue
Block a user