xref: /xnu-11215.1.10/tools/lldbmacros/exclaves.py (revision 8d741a5de7ff4191bf97d57b9f54c2f6d4a15585)
1""" Please make sure you read the README file COMPLETELY BEFORE reading anything below.
2    It is very critical that you read coding guidelines in Section E in README file.
3"""
4from process import GetProcFromTask
5from utils import Cast, GetEnumName
6from core.kernelcore import IterateLinkageChain
7from core.cvalue import addressof
8from core.standard import VT, ArgumentError
9from core.configuration import config, vHUMAN
10from xnu import kern, header, lldb_command, lldb_type_summary
11
12
13@header(f"{'Task': <20s} {'PID': <8s} {'Name': <30s} {'Conclave': <20s} {'Conclave name': <60s} {'State': <15s}")
14def GetAllConclavesSummary(t):
15    """ Summarizes the important fields regarding to conclaves.
16        params: task: value - value object representing a task in kernel
17        returns: str - summary of all conclaves
18    """
19    proc     = GetProcFromTask(t)
20    resource = Cast(t.conclave, 'exclaves_resource_t *')
21    state    = GetEnumName('conclave_state_t',    resource.r_conclave.c_state, 'CONCLAVE_S_')
22
23    out_str  = f"{t:<#20x} {proc.p_pid:<8} {proc.p_comm:<30s} {t.conclave:<#20x} {resource.r_name:<60s} {state:<15s}"
24
25    return out_str
26
27
28# Macro: showallconclaves
29@lldb_command('showallconclaves', fancy=True)
30def ShowAllConclaves(cmd_args=None, cmd_options={}, O=None):
31    """ Iterate over all the tasks and show the tasks that have conclaves attached to them.
32
33        Usage: showallconclaves
34    """
35
36    with O.table(GetAllConclavesSummary.header):
37        for t in kern.tasks:
38            if not hasattr(t, 'conclave'):
39                print("The system does not support exclaves")
40                return
41            if t.conclave:
42                print(GetAllConclavesSummary(t))
43# EndMacro: showallconclaves
44
45
46# Macro: showexclavesresourcetable
47@lldb_command('showexclavesresourcetable', "D:")
48def ShowExclavesResourceTable(cmd_args=None, cmd_options={}):
49    """ Print all resources in all domains the roottable contains
50
51        Usage: showexclavesresourcetable [-D <domain>]
52               -D domain  : the name of the domain. e.g. "com.apple.kernel"
53    """
54
55    domain_tbl = kern.GetGlobalVariable('root_table')
56    try:
57        domain_heads = Cast(domain_tbl.t_buckets, 'queue_chain_t *')
58    except AttributeError:
59        print("The system does not support exclaves")
60        return
61
62    for domain_idx in range(int(domain_tbl.t_buckets_count)):
63        for elem in IterateLinkageChain(addressof(domain_heads[domain_idx]), 'table_item_t *', 'i_chain'):
64            domain = Cast(elem.i_value, 'exclaves_resource_domain_t *')
65
66            if "-D" in cmd_options:
67                if str(domain.d_name) != cmd_options['-D']:
68                    continue
69
70            tbl_loc   = Cast(domain.d_table_name, 'queue_chain_t *')
71            entry_tbl = Cast(tbl_loc,             'table_t *')
72
73            d_name_ = f"{VT.Bold}{str(domain.d_name)}{VT.EndBold}"
74            out = (
75                f"domain:{domain:<#x} d_name:{d_name_} "
76                f"d_table_name:{domain.d_table_name:<#x} d_table_id:{domain.d_table_id:<#x}"
77            )
78
79            if config['verbosity'] > vHUMAN :
80                out = f"domain-{domain_idx} " + out
81            print(f"\n{out}")
82            print("---------------------------------------------------------------")
83
84            out = f"{'Entry':<5s} {'Resource': <20s} {'Name':<60s} {'Type':<25s} {'Id':<9s} {'Port':<20s} {'Connected':<10s}"
85            if config['verbosity'] > vHUMAN :
86                out += f"{'Elem': <19s} {'i_key': <19s} {'Len': <3s} {'i_value': <19s}"
87            print(out)
88
89            entry_heads = Cast(entry_tbl.t_buckets, 'queue_chain_t *')
90            for entry_idx in range(int(entry_tbl.t_buckets_count)):
91                for elem in IterateLinkageChain(entry_heads[entry_idx], 'table_item_t *', 'i_chain'):
92                    resource = Cast(elem.i_key, 'exclaves_resource_t *')
93
94                    state  = GetEnumName('conclave_state_t',        resource.r_conclave.c_state, 'CONCLAVE_S_')
95                    r_type = GetEnumName('xnuproxy_resourcetype_s', resource.r_type,             'XNUPROXY_RESOURCETYPE_')
96                    connected = "yes" if resource.r_connected else "no"
97
98                    out = (
99                        f"{entry_idx:<5} {resource:<#20x} {resource.r_name:<60s} {r_type:<25s} "
100                        f"{resource.r_id:<#9x} {resource.r_port:<#20x} {connected:<10s}"
101                    )
102                    if config['verbosity'] > vHUMAN :
103                        out += f"{elem:<#19x} {elem.i_key:<#19x} {elem.i_key_len:<3} {elem.i_value:<#19x}"
104                    print(out)
105# EndMacro: showexclavesresourcetable
106
107@lldb_type_summary(['esync_t'])
108@header("{0: <20s} {1: <10s} {2: <20s} {3: <20s}".format("esync_t", "id", "policy", "turnstile"))
109def GetEsyncSummary(esync):
110    """ Summarizes esync data structure
111        params: esync: value - value object representing esync structure
112        returns: str - summary of the esync object
113    """
114    format_string = "{0: <#020x} {1: <#010x} {2: <20s} {3: <#20x}"
115    return format_string.format(esync, esync.es_id, GetEnumName('esync_policy_t', esync.es_policy), esync.es_turnstile)
116
117@lldb_command('showesynctable', fancy=True)
118def ShowESyncTable(cmd_args=None, cmd_options={}, O=None):
119    """ Display info about the specified epoch sync table
120        Usage: showesynctable <ht_t>|<ht_t *>
121        Example: showesynctable &exclaves_queue_ht
122    """
123
124    if not cmd_args:
125        raise ArgumentError("No arguments passed.")
126
127    try:
128        table = kern.GetValueAsType(cmd_args[0], 'ht_t')
129        bucket = Cast(table.ht_bucket, 'ht_bucket_t *')
130    except:
131        table = kern.GetValueFromAddress(cmd_args[0], "ht_t *")
132        bucket = Cast(table.ht_bucket, 'ht_bucket_t *')
133
134    with O.table(GetEsyncSummary.header, indent=True):
135        for idx in range(int(table.ht_size)):
136            for elem in IterateLinkageChain(addressof(bucket[idx].htb_head), 'esync_t *', 'es_link'):
137                print(GetEsyncSummary(elem))
138
139    return
140