import struct
exec(open('/tmp/claude-0/-root-ants/f0a0d69c-fbe4-4887-8c0d-a5302a0da398/scratchpad/x86bridge.py').read().split("print('\\n--- registration")[0])
CODEREG=0x1d3728c
mpCount=u32(CODEREG); mpPtr=u32(CODEREG+4)
MP=struct.unpack_from('<%dI'%mpCount,B,va2off(mpPtr))
sm=open(SYM,'rb').read(); n,=struct.unpack_from('<I',sm,0)
size={}
for i in range(n):
    a,s=struct.unpack_from('<QI',sm,4+i*12); size[a]=s
def maddr(mi): return MP[mi] if 0<=mi<mpCount else 0

LOGS={}; INFOS={}
for ti,t in enumerate(TYPES):
    if S(t[1])!='Gu3' or S(t[0])!='Debug': continue
    for k in range(t[20]):
        m=METHODS[t[13]+k]; mn=S(m[0]); a=maddr(m[6]); pc=m[15]
        if mn in ('Log','Logf') and size.get(a,0)<=2: LOGS[a]=(mn,pc)
        if mn in ('Info','Infof'): INFOS.setdefault((('Infof' if mn=='Infof' else 'Info'),pc),a)
    break
print('stubs:',len(LOGS),' info targets:',len(INFOS))

# scan .text for  E8 rel32  calls landing on a stub
o=TO; hits={}
end=TS-5
for k in range(end):
    if B[o+k]!=0xE8: continue
    rel,=struct.unpack_from('<i',B,o+k+1)
    tgt=(TA+k+5+rel)&0xFFFFFFFF
    if tgt in LOGS:
        hits.setdefault(tgt,[]).append(TA+k)
tot=sum(len(v) for v in hits.values())
print('call sites targeting stripped Log stubs: %d (across %d stubs)'%(tot,len(hits)))
for a,v in sorted(hits.items()):
    mn,pc=LOGS[a]
    want=INFOS.get(('Infof' if mn=='Logf' else 'Info',pc))
    print('  stub 0x%08x %-5s params=%d  sites=%-5d -> Info@%s'%(a,mn,pc,len(v),hex(want) if want else 'NONE'))
