"""The raw `call [reg+0x270]` scan over-matched: most hits are a DIFFERENT class
(they pass a 0x38*0x17 buffer). The FutDataManagerImpl instance is always obtained
via FUN_1800d7170() -> FUN_180009c80(&obj, ...). So the true readers of the trading
gate are functions that call FUN_180009c80 AND contain call [reg+0x270] with no arg.
CONTROL: FUN_1801a7260 (TO_TRADE_PILE) and FUN_18006cc60 (the publisher) must both
survive the refinement; the squad functions FUN_180194b60 etc must all drop out.
Also: polarity of FUN_1801a7260 via its callers / the action-id table.
"""
import traceback, struct
try:
    tstart = None
    for b in mem.getBlocks():
        if b.getName() == ".text":
            tstart = int(b.getStart().getOffset())
            tb = read_bytes(tstart, int(b.getEnd().getOffset()) - tstart + 1)

    getters = {}
    for g, gname in [(0x180009c80, "FUN_180009c80 mgr-getter"),
                     (0x1800d7170, "FUN_1800d7170")]:
        s = set()
        for frm, typ, fn, ent in xrefs_to(g):
            if ent: s.add(ent)
        getters[gname] = s
        print("%s: %d callers" % (gname, len(s)))

    mgr = getters["FUN_180009c80 mgr-getter"]
    print("\n=== vt+0x270 call sites whose function ALSO calls the mgr getter ===")
    d = struct.pack("<i", 0x270)
    for modrm in (0x90, 0x91, 0x92, 0x93, 0x96, 0x97):
        pat = bytes([0xff, modrm]) + d
        i = tb.find(pat)
        while i != -1:
            a = tstart + i
            f = fm.getFunctionContaining(addr(a))
            ent = int(f.getEntryPoint().getOffset()) if f else 0
            mark = "MGR" if ent in mgr else "   "
            if ent in mgr:
                print("   %s %#x in %s" % (mark, a, f.getName()))
            i = tb.find(pat, i + 1)

    print("\n=== callers of FUN_1801a7260 (TO_TRADE_PILE) ===")
    for frm, typ, fn, ent in xrefs_to(0x1801a7260):
        print("   %#x %-12s %s ent=%#x" % (frm, typ, fn, ent))

    print("\n=== TO_TRADE_PILE / action-name literals ===")
    for pat in [b"TO_TRADE_PILE", b"FROM_TRADE_PILE", b"LIST_ITEM", b"AUCTION",
                b"TRANSFER", b"MARKET"]:
        for h in find_all(pat)[:12]:
            print("   %#x %r  xrefs=%s" % (h, rd_str(h, 60),
                  [(hex(x[0]), x[2]) for x in xrefs_to(h)][:4]))

    print("\n=== publisher FUN_18006cc60 ===")
    s = dec(0x18006cc60); print("len=%d" % len(s)); print(s)
except Exception:
    traceback.print_exc()
