"""Trace the FUT-root constructor's third argument, inherited by every request at +8.

The category request lives at FUT root +0x4140 (qword index 0x828). Its base ctor
stores the root constructor's param_3 at request+8, making that object the receiver
of owner.vtable[+0x18](owner, parsed_response, 0).
"""
import traceback

try:
    root_ctor = 0x18010cdc0
    print("=== root ctor callers ===")
    for ent, name in callers(root_ctor):
        print("\n--- %#x %s ---" % (ent, name))
        print(dec(ent))

    print("\n=== root ctor xrefs ===")
    for frm, typ, name, ent in xrefs_to(root_ctor):
        print("  from=%#x type=%s fn=%s entry=%#x" % (frm, typ, name, ent))
        if ent:
            print(dec(ent))

    # Static singleton slot and root vtables provide adjacent factory/type metadata.
    for site in (0x1802e6398, 0x18021c2a0, 0x18021cda8, 0x18021cdb8):
        print("\n=== qwords around %#x ===" % site)
        for i in range(-8, 16):
            p = site + i * 8
            try:
                value = qword(p)
            except Exception:
                continue
            print("  [%#x] = %#x %s" % (p, value, fname(value)))

except Exception:
    traceback.print_exc()
