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