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