"""D3 Q12: close the last gap -- is FUN_1800e2a40 the thing FUN_18003e370 calls?
Its only 8-byte pointer slot is at +0xd0 of one table, not +0x40, so either the call
goes through a thunk or the attribution is wrong.  Print all callers, and print the
service constructor FUN_180018bd0 so the interface can be named.
CONTROL: the semantic anchor is independent of the vtable -- byte[2] of the output
array is computed as (isPlayer && squadHasRoom && !alreadyInSquad), which can only be
TO_ACTIVE_SQUAD, the 3rd of the eight names.  If callers show a thunk, both lines of
evidence agree; if not, the semantic anchor still stands alone."""
import traceback
try:
    print("### callers of FUN_1800e2a40")
    for c in callers(0x1800e2a40):
        print("  ", c)
    for frm, typ, fn, ent in xrefs_to(0x1800e2a40):
        print("   xref %#x %s in %s (%#x)" % (frm, typ, fn, ent))
    print()
    print("### FUN_180018bd0 (the service FUN_18003e370 asks for)")
    print(dec(0x180018bd0))
    print("### FUN_18003cbf0 (CARD_ID extraction, 2nd arg to slot 0x40)")
    print(dec(0x18003cbf0))
except Exception:
    traceback.print_exc()
