1#!/usr/bin/env python3 2import sys 3import struct 4import mmap 5import json 6import copy 7import re 8import base64 9import argparse 10import logging 11import contextlib 12import zlib 13from operator import itemgetter 14 15long = int 16 17class Globals(object): 18 pass 19G = Globals() 20G.accept_incomplete_data = False 21G.data_was_incomplete = False 22 23kcdata_type_def = { 24 'KCDATA_TYPE_INVALID': 0x0, 25 'KCDATA_TYPE_STRING_DESC': 0x1, 26 'KCDATA_TYPE_UINT32_DESC': 0x2, 27 'KCDATA_TYPE_UINT64_DESC': 0x3, 28 'KCDATA_TYPE_INT32_DESC': 0x4, 29 'KCDATA_TYPE_INT64_DESC': 0x5, 30 'KCDATA_TYPE_BINDATA_DESC': 0x6, 31 'KCDATA_TYPE_ARRAY': 0x11, 32 'KCDATA_TYPE_TYPEDEFINITION': 0x12, 33 'KCDATA_TYPE_CONTAINER_BEGIN': 0x13, 34 'KCDATA_TYPE_CONTAINER_END': 0x14, 35 36 'KCDATA_TYPE_ARRAY_PAD0': 0x20, 37 'KCDATA_TYPE_ARRAY_PAD1': 0x21, 38 'KCDATA_TYPE_ARRAY_PAD2': 0x22, 39 'KCDATA_TYPE_ARRAY_PAD3': 0x23, 40 'KCDATA_TYPE_ARRAY_PAD4': 0x24, 41 'KCDATA_TYPE_ARRAY_PAD5': 0x25, 42 'KCDATA_TYPE_ARRAY_PAD6': 0x26, 43 'KCDATA_TYPE_ARRAY_PAD7': 0x27, 44 'KCDATA_TYPE_ARRAY_PAD8': 0x28, 45 'KCDATA_TYPE_ARRAY_PAD9': 0x29, 46 'KCDATA_TYPE_ARRAY_PADa': 0x2a, 47 'KCDATA_TYPE_ARRAY_PADb': 0x2b, 48 'KCDATA_TYPE_ARRAY_PADc': 0x2c, 49 'KCDATA_TYPE_ARRAY_PADd': 0x2d, 50 'KCDATA_TYPE_ARRAY_PADe': 0x2e, 51 'KCDATA_TYPE_ARRAY_PADf': 0x2f, 52 53 'KCDATA_TYPE_LIBRARY_LOADINFO': 0x30, 54 'KCDATA_TYPE_LIBRARY_LOADINFO64': 0x31, 55 'KCDATA_TYPE_TIMEBASE': 0x32, 56 'KCDATA_TYPE_MACH_ABSOLUTE_TIME': 0x33, 57 'KCDATA_TYPE_TIMEVAL': 0x34, 58 'KCDATA_TYPE_USECS_SINCE_EPOCH': 0x35, 59 'KCDATA_TYPE_PID': 0x36, 60 'KCDATA_TYPE_PROCNAME': 0x37, 61 'KCDATA_TYPE_NESTED_KCDATA': 0x38, 62 'KCDATA_TYPE_LIBRARY_AOTINFO': 0x39, 63 64 'STACKSHOT_KCCONTAINER_TASK': 0x903, 65 'STACKSHOT_KCCONTAINER_THREAD': 0x904, 66 'STACKSHOT_KCTYPE_DONATING_PIDS': 0x907, 67 'STACKSHOT_KCTYPE_SHAREDCACHE_LOADINFO': 0x908, 68 'STACKSHOT_KCTYPE_THREAD_NAME': 0x909, 69 'STACKSHOT_KCTYPE_KERN_STACKFRAME': 0x90A, 70 'STACKSHOT_KCTYPE_KERN_STACKFRAME64': 0x90B, 71 'STACKSHOT_KCTYPE_USER_STACKFRAME': 0x90C, 72 'STACKSHOT_KCTYPE_USER_STACKFRAME64': 0x90D, 73 'STACKSHOT_KCTYPE_BOOTARGS': 0x90E, 74 'STACKSHOT_KCTYPE_OSVERSION': 0x90F, 75 'STACKSHOT_KCTYPE_KERN_PAGE_SIZE': 0x910, 76 'STACKSHOT_KCTYPE_JETSAM_LEVEL': 0x911, 77 'STACKSHOT_KCTYPE_DELTA_SINCE_TIMESTAMP': 0x912, 78 'STACKSHOT_KCTYPE_KERN_STACKLR': 0x913, 79 'STACKSHOT_KCTYPE_KERN_STACKLR64': 0x914, 80 'STACKSHOT_KCTYPE_USER_STACKLR': 0x915, 81 'STACKSHOT_KCTYPE_USER_STACKLR64': 0x916, 82 'STACKSHOT_KCTYPE_NONRUNNABLE_TIDS': 0x917, 83 'STACKSHOT_KCTYPE_NONRUNNABLE_TASKS': 0x918, 84 'STACKSHOT_KCTYPE_CPU_TIMES': 0x919, 85 'STACKSHOT_KCTYPE_STACKSHOT_DURATION': 0x91a, 86 'STACKSHOT_KCTYPE_STACKSHOT_FAULT_STATS': 0x91b, 87 'STACKSHOT_KCTYPE_KERNELCACHE_LOADINFO': 0x91c, 88 'STACKSHOT_KCTYPE_THREAD_WAITINFO' : 0x91d, 89 'STACKSHOT_KCTYPE_THREAD_GROUP_SNAPSHOT' : 0x91e, 90 'STACKSHOT_KCTYPE_THREAD_GROUP' : 0x91f, 91 'STACKSHOT_KCTYPE_JETSAM_COALITION_SNAPSHOT' : 0x920, 92 'STACKSHOT_KCTYPE_JETSAM_COALITION' : 0x921, 93 'STACKSHOT_KCTYPE_THREAD_POLICY_VERSION': 0x922, 94 'STACKSHOT_KCTYPE_INSTRS_CYCLES' : 0x923, 95 'STACKSHOT_KCTYPE_USER_STACKTOP' : 0x924, 96 'STACKSHOT_KCTYPE_ASID' : 0x925, 97 'STACKSHOT_KCTYPE_PAGE_TABLES' : 0x926, 98 'STACKSHOT_KCTYPE_SYS_SHAREDCACHE_LAYOUT' : 0x927, 99 'STACKSHOT_KCTYPE_THREAD_DISPATCH_QUEUE_LABEL' : 0x928, 100 'STACKSHOT_KCTYPE_THREAD_TURNSTILEINFO' : 0x929, 101 'STACKSHOT_KCTYPE_TASK_CPU_ARCHITECTURE' : 0x92a, 102 'STACKSHOT_KCTYPE_LATENCY_INFO' : 0x92b, 103 'STACKSHOT_KCTYPE_LATENCY_INFO_TASK' : 0x92c, 104 'STACKSHOT_KCTYPE_LATENCY_INFO_THREAD' : 0x92d, 105 'STACKSHOT_KCTYPE_LOADINFO64_TEXT_EXEC' : 0x92e, 106 'STACKSHOT_KCTYPE_AOTCACHE_LOADINFO' : 0x92f, 107 'STACKSHOT_KCTYPE_TRANSITIONING_TASK_SNAPSHOT' : 0x930, 108 'STACKSHOT_KCCONTAINER_TRANSITIONING_TASK' : 0x931, 109 'STACKSHOT_KCTYPE_USER_ASYNC_START_INDEX' : 0x932, 110 'STACKSHOT_KCTYPE_USER_ASYNC_STACKLR64' : 0x933, 111 'STACKSHOT_KCCONTAINER_PORTLABEL' : 0x934, 112 'STACKSHOT_KCTYPE_PORTLABEL' : 0x935, 113 'STACKSHOT_KCTYPE_PORTLABEL_NAME' : 0x936, 114 'STACKSHOT_KCTYPE_DYLD_COMPACTINFO' : 0x937, 115 'STACKSHOT_KCTYPE_SUSPENSION_INFO' : 0x938, 116 'STACKSHOT_KCTYPE_SUSPENSION_SOURCE' : 0x939, 117 'STACKSHOT_KCTYPE_TASK_DELTA_SNAPSHOT': 0x940, 118 'STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT': 0x941, 119 'STACKSHOT_KCCONTAINER_SHAREDCACHE' : 0x942, 120 'STACKSHOT_KCTYPE_SHAREDCACHE_INFO' : 0x943, 121 'STACKSHOT_KCTYPE_SHAREDCACHE_AOTINFO' : 0x944, 122 'STACKSHOT_KCTYPE_SHAREDCACHE_ID' : 0x945, 123 'STACKSHOT_KCTYPE_CODESIGNING_INFO' : 0x946, 124 'STACKSHOT_KCTYPE_OS_BUILD_VERSION' : 0x947, 125 'STACKSHOT_KCTYPE_KERN_EXCLAVES_THREADINFO' : 0x948, 126 'STACKSHOT_KCCONTAINER_EXCLAVES' : 0x949, 127 'STACKSHOT_KCCONTAINER_EXCLAVE_SCRESULT' : 0x94a, 128 'STACKSHOT_KCTYPE_EXCLAVE_SCRESULT_INFO' : 0x94b, 129 'STACKSHOT_KCCONTAINER_EXCLAVE_IPCSTACKENTRY' : 0x94c, 130 'STACKSHOT_KCTYPE_EXCLAVE_IPCSTACKENTRY_INFO' : 0x94d, 131 'STACKSHOT_KCTYPE_EXCLAVE_IPCSTACKENTRY_ECSTACK' : 0x94e, 132 'STACKSHOT_KCCONTAINER_EXCLAVE_ADDRESSSPACE' : 0x94f, 133 'STACKSHOT_KCTYPE_EXCLAVE_ADDRESSSPACE_INFO' : 0x950, 134 'STACKSHOT_KCTYPE_EXCLAVE_ADDRESSSPACE_NAME' : 0x951, 135 'STACKSHOT_KCCONTAINER_EXCLAVE_TEXTLAYOUT' : 0x952, 136 'STACKSHOT_KCTYPE_EXCLAVE_TEXTLAYOUT_INFO' : 0x953, 137 'STACKSHOT_KCTYPE_EXCLAVE_TEXTLAYOUT_SEGMENTS' : 0x954, 138 'STACKSHOT_KCTYPE_KERN_EXCLAVES_CRASH_THREADINFO' : 0x955, 139 'STACKSHOT_KCTYPE_LATENCY_INFO_CPU': 0x956, 140 'STACKSHOT_KCTYPE_TASK_EXEC_META': 0x957, 141 'STACKSHOT_KCTYPE_TASK_MEMORYSTATUS': 0x958, 142 'STACKSHOT_KCTYPE_MTEINFO_CELL': 0x959, 143 'STACKSHOT_KCTYPE_LATENCY_INFO_BUFFER': 0x95a, 144 'KCDATA_TYPE_BUFFER_END': 0xF19158ED, 145 146 'TASK_CRASHINFO_EXTMODINFO': 0x801, 147 'TASK_CRASHINFO_BSDINFOWITHUNIQID': 0x802, 148 'TASK_CRASHINFO_TASKDYLD_INFO': 0x803, 149 'TASK_CRASHINFO_UUID': 0x804, 150 'TASK_CRASHINFO_PID': 0x805, 151 'TASK_CRASHINFO_PPID': 0x806, 152 153 # Don't want anyone using this. It's struct rusage from whatever machine generated the data 154 #'TASK_CRASHINFO_RUSAGE': 0x807, 155 'Type_0x807': 0x807, 156 157 'TASK_CRASHINFO_RUSAGE_INFO': 0x808, 158 'TASK_CRASHINFO_PROC_NAME': 0x809, 159 'TASK_CRASHINFO_PROC_STARTTIME': 0x80B, 160 'TASK_CRASHINFO_USERSTACK': 0x80C, 161 'TASK_CRASHINFO_ARGSLEN': 0x80D, 162 'TASK_CRASHINFO_EXCEPTION_CODES': 0x80E, 163 'TASK_CRASHINFO_PROC_PATH': 0x80F, 164 'TASK_CRASHINFO_PROC_CSFLAGS': 0x810, 165 'TASK_CRASHINFO_PROC_STATUS': 0x811, 166 'TASK_CRASHINFO_UID': 0x812, 167 'TASK_CRASHINFO_GID': 0x813, 168 'TASK_CRASHINFO_PROC_ARGC': 0x814, 169 'TASK_CRASHINFO_PROC_FLAGS': 0x815, 170 'TASK_CRASHINFO_CPUTYPE': 0x816, 171 'TASK_CRASHINFO_WORKQUEUEINFO': 0x817, 172 'TASK_CRASHINFO_RESPONSIBLE_PID': 0x818, 173 'TASK_CRASHINFO_DIRTY_FLAGS': 0x819, 174 'TASK_CRASHINFO_CRASHED_THREADID': 0x81A, 175 'TASK_CRASHINFO_COALITION_ID': 0x81B, 176 'TASK_CRASHINFO_JIT_ADDRESS_RANGE': 0x840, 177 'TASK_CRASHINFO_MB': 0x841, 178 'TASK_CRASHINFO_CS_AUXILIARY_INFO': 0x842, 179 'EXIT_REASON_SNAPSHOT': 0x1001, 180 'EXIT_REASON_USER_DESC': 0x1002, 181 'EXIT_REASON_USER_PAYLOAD': 0x1003, 182 'EXIT_REASON_CODESIGNING_INFO': 0x1004, 183 'EXIT_REASON_WORKLOOP_ID': 0x1005, 184 'EXIT_REASON_DISPATCH_QUEUE_NO': 0x1006, 185 'KCDATA_BUFFER_BEGIN_CRASHINFO': 0xDEADF157, 186 'KCDATA_BUFFER_BEGIN_DELTA_STACKSHOT': 0xDE17A59A, 187 'KCDATA_BUFFER_BEGIN_STACKSHOT': 0x59a25807, 188 'KCDATA_BUFFER_BEGIN_COMPRESSED': 0x434f4d50, 189 'KCDATA_BUFFER_BEGIN_OS_REASON': 0x53A20900, 190 'KCDATA_BUFFER_BEGIN_XNUPOST_CONFIG': 0x1E21C09F 191} 192kcdata_type_def_rev = dict((v, k) for k, v in iter(kcdata_type_def.items())) 193 194KNOWN_TYPES_COLLECTION = {} 195 196KNOWN_TOPLEVEL_CONTAINER_TYPES = () 197 198def enum(**args): 199 return type('enum', (), args) 200 201# 202# Decode bytes as UTF-8, using surrogateescape if there are invalid UTF-8 203# sequences; see PEP-383 204# 205def BytesToString(b): 206 if isinstance(b, str): 207 return b 208 return b.decode('utf-8', errors="surrogateescape") 209 210# important keys 211SC_SLID_FIRSTMAPPING_KEY = 'sharedCacheSlidFirstMapping' 212 213# important builtin types 214KCSUBTYPE_TYPE = enum(KC_ST_CHAR=1, KC_ST_INT8=2, KC_ST_UINT8=3, KC_ST_INT16=4, KC_ST_UINT16=5, KC_ST_INT32=6, KC_ST_UINT32=7, KC_ST_INT64=8, KC_ST_UINT64=9) 215 216 217LEGAL_OLD_STYLE_ARRAY_TYPE_NAMES = ['KCDATA_TYPE_LIBRARY_LOADINFO', 218 'KCDATA_TYPE_LIBRARY_LOADINFO64', 219 'STACKSHOT_KCTYPE_KERN_STACKFRAME', 220 'STACKSHOT_KCTYPE_USER_STACKFRAME', 221 'STACKSHOT_KCTYPE_KERN_STACKFRAME64', 222 'STACKSHOT_KCTYPE_USER_STACKFRAME64', 223 'STACKSHOT_KCTYPE_DONATING_PIDS', 224 'STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT'] 225 226KCDATA_FLAGS_STRUCT_PADDING_MASK = 0xf 227KCDATA_FLAGS_STRUCT_HAS_PADDING = 0x80 228 229class KCSubTypeElement(object): 230 """convert kcdata_subtype_descriptor to """ 231 _unpack_formats = (None, 'c', 'b', 'B', 'h', 'H', 'i', 'I', 'q', 'Q') 232 _ctypes = ('Unknown', 'char', 'int8_t', 'uint8_t', 'int16_t', 'uint16_t', 'int32_t', 'uint32_t', 'int64_t', 'uint64_t') 233 234 def __init__(self, st_name, st_type, st_size, st_offset=0, st_flag=0, custom_repr=None): 235 self.name = st_name 236 self.offset = st_offset 237 self.type_id = st_type 238 if st_type <= 0 or st_type > KCSUBTYPE_TYPE.KC_ST_UINT64: 239 raise ValueError("Invalid type passed %d" % st_type) 240 self.unpack_fmt = KCSubTypeElement._unpack_formats[self.type_id] 241 self.size = st_size 242 self.totalsize = st_size 243 self.count = 1 244 self.is_array_type = False 245 self.custom_JsonRepr = custom_repr 246 if (st_flag & 0x1) == 0x1: 247 self.is_array_type = True 248 self.size = st_size & 0xffff 249 self.count = (st_size >> 16) & 0xffff 250 self.totalsize = self.size * self.count 251 252 @staticmethod 253 def GetSizeForArray(el_count, el_size): 254 return ((el_count & 0xffff) << 16) | (el_size & 0xffff) 255 256 @staticmethod 257 def FromBinaryTypeData(byte_data): 258 (st_flag, st_type, st_offset, st_size, st_name) = struct.unpack_from('=BBHI32s', byte_data) 259 st_name = BytesToString(st_name).rstrip('\0') 260 return KCSubTypeElement(st_name, st_type, st_size, st_offset, st_flag) 261 262 @staticmethod 263 def FromBasicCtype(st_name, st_type, st_offset=0, legacy_size=None): 264 if st_type <= 0 or st_type > KCSUBTYPE_TYPE.KC_ST_UINT64: 265 raise ValueError("Invalid type passed %d" % st_type) 266 st_size = struct.calcsize(KCSubTypeElement._unpack_formats[st_type]) 267 st_flag = 0 268 retval = KCSubTypeElement(st_name, st_type, st_size, st_offset, st_flag, KCSubTypeElement._get_naked_element_value) 269 if legacy_size: 270 retval.legacy_size = legacy_size 271 return retval 272 273 @staticmethod 274 def FromKCSubTypeElement(other, name_override=''): 275 _copy = copy.copy(other) 276 if name_override: 277 _copy.name = name_override 278 return copy 279 280 def GetName(self): 281 return self.name 282 283 def GetTotalSize(self): 284 return self.totalsize 285 286 def GetValueAsString(self, base_data, array_pos=0): 287 v = self.GetValue(base_data, array_pos) 288 if isinstance(v, bytes): 289 return BytesToString(v) 290 return str(v) 291 292 def GetValue(self, base_data, array_pos=0): 293 return struct.unpack_from(self.unpack_fmt, base_data[self.offset + (array_pos * self.size):])[0] 294 295 @staticmethod 296 def _get_naked_element_value(elementValue, elementName): 297 return json.dumps(elementValue) 298 299 def __str__(self): 300 if self.is_array_type: 301 return '[%d,%d] %s %s[%d];' % (self.offset, self.totalsize, self.GetCTypeDesc(), self.name, self.count) 302 return '[%d,%d] %s %s;' % (self.offset, self.totalsize, self.GetCTypeDesc(), self.name) 303 304 def __repr__(self): 305 return str(self) 306 307 def GetCTypeDesc(self): 308 return KCSubTypeElement._ctypes[self.type_id] 309 310 def GetStringRepr(self, base_data): 311 if not self.is_array_type: 312 return self.GetValueAsString(base_data) 313 if self.type_id == KCSUBTYPE_TYPE.KC_ST_CHAR: 314 str_len = self.count 315 if len(base_data) < str_len: 316 str_len = len(base_data) 317 str_arr = [] 318 for i in range(str_len): 319 _v = self.GetValue(base_data, i) 320 if ord(_v) == 0: 321 break 322 str_arr.append(self.GetValueAsString(base_data, i)) 323 return json.dumps(''.join(str_arr)) 324 325 count = self.count 326 if count > len(base_data)//self.size: 327 count = len(base_data)//self.size 328 329 o = '[' + ','.join([self.GetValueAsString(base_data, i) for i in range(count)]) + ']' 330 331 return o 332 333 def GetJsonRepr(self, base_data, flags=0): 334 if (flags & (KCDATA_FLAGS_STRUCT_HAS_PADDING | KCDATA_FLAGS_STRUCT_PADDING_MASK)) != 0: 335 padding = (flags & KCDATA_FLAGS_STRUCT_PADDING_MASK) 336 if padding: 337 base_data = base_data[:-padding] 338 if self.custom_JsonRepr: 339 if self.is_array_type: 340 e_data = [self.GetValue(base_data, i) for i in range(self.count)] 341 else: 342 e_data = self.GetValue(base_data) 343 return self.custom_JsonRepr(e_data, self.name) 344 return self.GetStringRepr(base_data) 345 346 def sizeof(self): 347 return self.totalsize 348 349 def ShouldSkip(self, data): 350 return len(data) < self.offset + self.totalsize 351 352 def ShouldMerge(self): 353 return False 354 355 356class KCTypeDescription(object): 357 def __init__(self, t_type_id, t_elements=[], t_name='anon', custom_repr=None, legacy_size=None, merge=False, naked=False): 358 self.type_id = t_type_id 359 self.elements = t_elements 360 self.name = t_name 361 self.totalsize = 0 362 self.custom_JsonRepr = custom_repr 363 if legacy_size: 364 self.legacy_size = legacy_size 365 self.merge = merge 366 self.naked = naked 367 for e in self.elements: 368 self.totalsize += e.GetTotalSize() 369 370 def ValidateData(self, base_data): 371 if len(base_data) >= self.totalsize: 372 return True 373 return False 374 375 def GetTypeID(self): 376 return self.type_id 377 378 def GetName(self): 379 return self.name 380 381 def __str__(self): 382 o = '%s {\n\t' % self.name + "\n\t".join([str(e) for e in self.elements]) + '\n};' 383 return o 384 385 @staticmethod 386 def FromKCTypeDescription(other, t_type_id, t_name): 387 retval = KCTypeDescription(t_type_id, other.elements, t_name, other.custom_JsonRepr, 388 legacy_size=getattr(other, 'legacy_size', None)) 389 return retval 390 391 def ShouldMerge(self): 392 return self.merge 393 394 def GetJsonRepr(self, base_data, flags): 395 if (flags & (KCDATA_FLAGS_STRUCT_HAS_PADDING | KCDATA_FLAGS_STRUCT_PADDING_MASK)) != 0: 396 padding = (flags & KCDATA_FLAGS_STRUCT_PADDING_MASK) 397 if padding: 398 base_data = base_data[:-padding] 399 elif hasattr(self, 'legacy_size') and len(base_data) == self.legacy_size + ((-self.legacy_size) & 0xf): 400 base_data = base_data[:self.legacy_size] 401 if self.custom_JsonRepr: 402 return self.custom_JsonRepr([e.GetValue(base_data) for e in self.elements]) 403 if self.naked: 404 o = ", ".join([e.GetJsonRepr(base_data) for e in self.elements if not e.ShouldSkip(base_data)]) 405 else: 406 o = ", ".join(['"%s": %s' % (e.GetName(), e.GetJsonRepr(base_data)) for e in self.elements if not e.ShouldSkip(base_data)]) 407 if not self.merge: 408 o = '{' + o + '}' 409 return o 410 411 def sizeof(self): 412 return max(st.totalsize + st.offset for st in self.elements) 413 414 415def GetTypeNameForKey(k): 416 retval = "0x%x" % k 417 if k in KNOWN_TYPES_COLLECTION: 418 retval = KNOWN_TYPES_COLLECTION[k].GetName() 419 elif k in kcdata_type_def_rev: 420 retval = kcdata_type_def_rev[k] 421 return retval 422 423 424def GetTypeForName(n): 425 ret = 0 426 if n in kcdata_type_def: 427 ret = kcdata_type_def[n] 428 return ret 429 430 431LEGAL_OLD_STYLE_ARRAY_TYPES = list(map(GetTypeForName, LEGAL_OLD_STYLE_ARRAY_TYPE_NAMES)) 432 433kcdata_type_def_rev[GetTypeForName('KCDATA_BUFFER_BEGIN_STACKSHOT')] = 'kcdata_stackshot' 434kcdata_type_def_rev[GetTypeForName('KCDATA_BUFFER_BEGIN_DELTA_STACKSHOT')] = 'kcdata_delta_stackshot' 435kcdata_type_def_rev[GetTypeForName('KCDATA_BUFFER_BEGIN_CRASHINFO')] = 'kcdata_crashinfo' 436kcdata_type_def_rev[GetTypeForName('KCDATA_BUFFER_BEGIN_OS_REASON')] = 'kcdata_reason' 437kcdata_type_def_rev[GetTypeForName('STACKSHOT_KCCONTAINER_TASK')] = 'task_snapshots' 438kcdata_type_def_rev[GetTypeForName('STACKSHOT_KCCONTAINER_TRANSITIONING_TASK')] = 'transitioning_task_snapshots' 439kcdata_type_def_rev[GetTypeForName('STACKSHOT_KCCONTAINER_THREAD')] = 'thread_snapshots' 440kcdata_type_def_rev[GetTypeForName('STACKSHOT_KCCONTAINER_PORTLABEL')] = 'portlabels' 441kcdata_type_def_rev[GetTypeForName('STACKSHOT_KCCONTAINER_SHAREDCACHE')] = 'shared_caches' 442kcdata_type_def_rev[GetTypeForName('KCDATA_BUFFER_BEGIN_XNUPOST_CONFIG')] = 'xnupost_testconfig' 443kcdata_type_def_rev[GetTypeForName('STACKSHOT_KCCONTAINER_EXCLAVES')] = 'threads_exclave' 444kcdata_type_def_rev[GetTypeForName('STACKSHOT_KCCONTAINER_EXCLAVE_SCRESULT')] = 'thread_exclave' 445kcdata_type_def_rev[GetTypeForName('STACKSHOT_KCCONTAINER_EXCLAVE_IPCSTACKENTRY')] = 'exclave_ipcstackentry' 446kcdata_type_def_rev[GetTypeForName('STACKSHOT_KCCONTAINER_EXCLAVE_ADDRESSSPACE')] = 'exclave_addressspace' 447kcdata_type_def_rev[GetTypeForName('STACKSHOT_KCCONTAINER_EXCLAVE_TEXTLAYOUT')] = 'exclave_textlayout' 448 449class Indent(object): 450 def __init__(self): 451 self.n = 0 452 def __call__(self, end=False): 453 if end: 454 return " " * (self.n-4) 455 else: 456 return " " * self.n 457 @contextlib.contextmanager 458 def indent(self): 459 self.n += 4 460 try: 461 yield 462 finally: 463 self.n -= 4 464 465INDENT = Indent() 466 467class KCObject(object): 468 469 def __init__(self, type_code, data, offset, flags=0): 470 471 self.i_type = type_code 472 self.i_data = data 473 self.offset = offset 474 self.i_size = len(data) 475 self.i_flags = flags 476 self.obj_collection = [] 477 self.obj = {} 478 self.is_container_type = False 479 self.is_array_type = False 480 self.is_naked_type = False 481 self.nested_kcdata = None 482 self.i_name = GetTypeNameForKey(type_code) 483 484 self.ParseData() 485 486 if self.i_type == GetTypeForName('KCDATA_TYPE_CONTAINER_BEGIN'): 487 self.__class__ = KCContainerObject 488 elif self.i_type == GetTypeForName('KCDATA_BUFFER_BEGIN_COMPRESSED'): 489 self.__class__ = KCCompressedBufferObject 490 elif self.i_type in KNOWN_TOPLEVEL_CONTAINER_TYPES: 491 self.__class__ = KCBufferObject 492 493 self.InitAfterParse() 494 495 def __str__(self): 496 return "<KCObject at 0x%x>" % self.offset 497 498 def InitAfterParse(self): 499 pass 500 501 @staticmethod 502 def FromKCItem(kcitem): 503 return KCObject(kcitem.i_type, kcitem.i_data, kcitem.i_offset, kcitem.i_flags) 504 505 def IsContainerEnd(self): 506 return self.i_type == GetTypeForName('KCDATA_TYPE_CONTAINER_END') 507 508 def IsBufferEnd(self): 509 return self.i_type == GetTypeForName('KCDATA_TYPE_BUFFER_END') 510 511 def IsArray(self): 512 return self.is_array_type 513 514 def ShouldMerge(self): 515 if self.nested_kcdata: 516 return True 517 elif not self.is_array_type and self.i_type in KNOWN_TYPES_COLLECTION: 518 return KNOWN_TYPES_COLLECTION[self.i_type].ShouldMerge() 519 else: 520 return False 521 522 def GetJsonRepr(self): 523 if self.is_array_type: 524 return '[' + ', '.join([i.GetJsonRepr() for i in self.obj_collection]) + ']' 525 if self.i_type in KNOWN_TYPES_COLLECTION: 526 return KNOWN_TYPES_COLLECTION[self.i_type].GetJsonRepr(self.i_data, self.i_flags) 527 if self.is_naked_type: 528 return json.dumps(self.obj) 529 if self.nested_kcdata: 530 return self.nested_kcdata.GetJsonRepr() 531 532 raise NotImplementedError("Broken GetJsonRepr implementation") 533 534 def ParseData(self): 535 536 logging.info(self.i_type) 537 if self.i_type == GetTypeForName('KCDATA_TYPE_CONTAINER_BEGIN'): 538 self.obj['uniqID'] = self.i_flags 539 self.i_name = str(self.obj['uniqID']) 540 self.obj['typeID'] = struct.unpack_from('I', self.i_data)[0] 541 logging.info("0x%08x: %sCONTAINER: %s(%x)" % (self.offset, INDENT(), GetTypeNameForKey(self.obj['typeID']), self.i_flags)) 542 543 elif self.i_type in (KNOWN_TOPLEVEL_CONTAINER_TYPES): 544 self.obj['uniqID'] = self.i_name 545 self.obj['typeID'] = self.i_type 546 logging.info("0x%08x: %s%s" % (self.offset, INDENT(), self.i_name)) 547 548 elif self.i_type == GetTypeForName('KCDATA_TYPE_CONTAINER_END'): 549 self.obj['uniqID'] = self.i_flags 550 logging.info("0x%08x: %sEND" % (self.offset, INDENT(end=True))) 551 552 elif self.i_type == GetTypeForName('KCDATA_TYPE_BUFFER_END'): 553 self.obj = '' 554 logging.info("0x%08x: %sEND_BUFFER" % (self.offset, INDENT(end=True))) 555 556 elif self.i_type == GetTypeForName('KCDATA_TYPE_UINT32_DESC'): 557 self.is_naked_type = True 558 u_d = struct.unpack_from('32sI', self.i_data) 559 self.i_name = BytesToString(u_d[0]).rstrip('\0') 560 self.obj = u_d[1] 561 logging.info("0x%08x: %s%s" % (self.offset, INDENT(), self.i_name)) 562 563 elif self.i_type == GetTypeForName('KCDATA_TYPE_UINT64_DESC'): 564 self.is_naked_type = True 565 u_d = struct.unpack_from('32sQ', self.i_data) 566 self.i_name = BytesToString(u_d[0]).rstrip('\0') 567 self.obj = u_d[1] 568 logging.info("0x%08x: %s%s" % (self.offset, INDENT(), self.i_name)) 569 570 elif self.i_type == GetTypeForName('KCDATA_TYPE_TYPEDEFINITION'): 571 self.is_naked_type = True 572 u_d = struct.unpack_from('II32s', self.i_data) 573 self.obj['name'] = BytesToString(u_d[2]).split(chr(0))[0] 574 self.i_name = "typedef[%s]" % self.obj['name'] 575 self.obj['typeID'] = u_d[0] 576 self.obj['numOfFields'] = u_d[1] 577 element_arr = [] 578 for i in range(u_d[1]): 579 e = KCSubTypeElement.FromBinaryTypeData(self.i_data[40+(i*40):]) 580 element_arr.append(e) 581 type_desc = KCTypeDescription(u_d[0], element_arr, self.obj['name']) 582 self.obj['fields'] = [str(e) for e in element_arr] 583 KNOWN_TYPES_COLLECTION[type_desc.GetTypeID()] = type_desc 584 logging.info("0x%08x: %s%s" % (self.offset, INDENT(), self.i_name)) 585 586 elif self.i_type == GetTypeForName('KCDATA_TYPE_ARRAY'): 587 self.is_array_type = True 588 e_t = (self.i_flags >> 32) & 0xffffffff 589 if e_t not in LEGAL_OLD_STYLE_ARRAY_TYPES: 590 raise Exception("illegal old-style array type: %s (0x%x)" % (GetTypeNameForKey(e_t), e_t)) 591 e_c = self.i_flags & 0xffffffff 592 e_s = KNOWN_TYPES_COLLECTION[e_t].legacy_size 593 if e_s * e_c > self.i_size: 594 raise Exception("array too small for its count") 595 self.obj['typeID'] = e_t 596 self.i_name = GetTypeNameForKey(e_t) 597 self.i_type = e_t 598 self.obj['numOfElements'] = e_c 599 self.obj['sizeOfElement'] = e_s 600 logging.info("0x%08x: %sARRAY: %s" % (self.offset, INDENT(), self.i_name)) 601 #populate the array here by recursive creation of KCObject 602 with INDENT.indent(): 603 for _i in range(e_c): 604 _o = KCObject(e_t, self.i_data[(_i * e_s):(_i * e_s) + e_s], self.offset + _i*e_s) 605 self.obj_collection.append(_o) 606 607 elif self.i_type >= GetTypeForName('KCDATA_TYPE_ARRAY_PAD0') and self.i_type <= GetTypeForName('KCDATA_TYPE_ARRAY_PADf'): 608 self.is_array_type = True 609 e_t = (self.i_flags >> 32) & 0xffffffff 610 e_c = self.i_flags & 0xffffffff 611 e_s = (self.i_size - (self.i_type & 0xf)) // e_c if e_c != 0 else None 612 self.obj['typeID'] = e_t 613 self.i_name = GetTypeNameForKey(e_t) 614 self.i_type = e_t 615 self.obj['numOfElements'] = e_c 616 self.obj['sizeOfElement'] = e_s 617 logging.info("0x%08x: %sARRAY: %s" % (self.offset, INDENT(), self.i_name)) 618 #populate the array here by recursive creation of KCObject 619 with INDENT.indent(): 620 for _i in range(e_c): 621 _o = KCObject(e_t, self.i_data[(_i * e_s):(_i * e_s) + e_s], self.offset + _i*e_s) 622 self.obj_collection.append(_o) 623 624 elif self.i_type == GetTypeForName('KCDATA_TYPE_NESTED_KCDATA'): 625 logging.info("0x%08x: %sNESTED_KCDATA" % (self.offset, INDENT())) 626 with INDENT.indent(): 627 nested_iterator = kcdata_item_iterator(self.i_data[:self.i_size]) 628 nested_buffer = KCObject.FromKCItem(next(nested_iterator)) 629 if not isinstance(nested_buffer, KCBufferObject): 630 raise Exception("nested buffer isn't a KCBufferObject") 631 nested_buffer.ReadItems(nested_iterator) 632 self.nested_kcdata = nested_buffer 633 634 elif self.i_type in KNOWN_TYPES_COLLECTION: 635 self.i_name = KNOWN_TYPES_COLLECTION[self.i_type].GetName() 636 self.is_naked_type = True 637 logging.info("0x%08x: %s%s" % (self.offset, INDENT(), self.i_name)) 638 else: 639 self.is_naked_type = True 640 #self.obj = "data of len %d" % len(self.i_data) 641 #self.obj = ''.join(["%x" % ki for ki in struct.unpack('%dB' % len(self.i_data), self.i_data)]) 642 if isinstance(self.i_data, str): 643 self.obj = list(map(ord, BytesToString(self.i_data))) 644 else: 645 self.obj = [i for i in self.i_data] 646 logging.info("0x%08x: %s%s" % (self.offset, INDENT(), self.i_name)) 647 648 649class KCContainerObject(KCObject): 650 def __init__(self, *args, **kwargs): 651 assert False 652 653 def InitAfterParse(self): 654 self.obj_container_dict = {} 655 self.obj_nested_objs = {} 656 657 def ShouldMerge(self): 658 return True 659 660 def GetJsonRepr(self): 661 # o = '"%s"' % self.obj['uniqID'] + ' : { "typeID" : %d ,' % self.obj['typeID'] 662 o = '"%s"' % self.obj['uniqID'] + ' : { ' 663 for (k, v) in self.obj_container_dict.items(): 664 if v.ShouldMerge(): 665 o += v.GetJsonRepr() + "," 666 else: 667 o += ' "%s" : ' % k + v.GetJsonRepr() + "," 668 669 for (k, v) in self.obj_nested_objs.items(): 670 o += '"%s" : {' % k + ",".join([vi.GetJsonRepr() for vi in v.values()]) + "} ," 671 672 o = o.rstrip(',') + "}" 673 674 return o 675 676 def AddObject(self, kco): 677 assert not kco.IsContainerEnd() 678 if isinstance(kco, KCContainerObject): 679 type_name = GetTypeNameForKey(kco.obj['typeID']) 680 if type_name not in self.obj_nested_objs: 681 self.obj_nested_objs[type_name] = {} 682 self.obj_nested_objs[type_name][kco.i_name] = kco 683 return 684 if kco.i_name in self.obj_container_dict: 685 if kco.IsArray() and self.obj_container_dict[kco.i_name].IsArray(): 686 self.obj_container_dict[kco.i_name].obj_collection.extend( kco.obj_collection ) 687 else: 688 self.obj_container_dict[kco.i_name] = kco 689 690 def IsEndMarker(self, o): 691 if not o.IsContainerEnd(): 692 return False 693 if o.i_flags != self.i_flags: 694 raise Exception("container end marker doesn't match") 695 return True 696 697 no_end_message = "could not find container end marker" 698 699 def ReadItems(self, iterator): 700 found_end = False 701 with INDENT.indent(): 702 for i in iterator: 703 o = KCObject.FromKCItem(i) 704 if self.IsEndMarker(o): 705 found_end = True 706 break 707 if o.IsBufferEnd(): 708 break 709 if isinstance(o, KCContainerObject): 710 o.ReadItems(iterator) 711 self.AddObject(o) 712 if not found_end: 713 if G.accept_incomplete_data: 714 if not G.data_was_incomplete: 715 print("kcdata.py WARNING: data is incomplete!", file=sys.stderr) 716 G.data_was_incomplete = True 717 else: 718 raise Exception(self.no_end_message) 719 720 721 722class KCBufferObject(KCContainerObject): 723 724 def IsEndMarker(self,o): 725 if o.IsContainerEnd(): 726 raise Exception("container end marker at the toplevel") 727 return o.IsBufferEnd() 728 729 no_end_message = "could not find buffer end marker" 730 731class KCCompressedBufferObject(KCContainerObject): 732 733 def ReadItems(self, iterator): 734 self.header = dict() 735 with INDENT.indent(): 736 for i in iterator: 737 o = KCObject.FromKCItem(i) 738 if self.IsEndMarker(o): 739 self.compressed_type = o.i_type 740 self.blob_start = o.offset + 16 741 break 742 o.ParseData() 743 self.header[o.i_name] = o.obj 744 745 def IsEndMarker(self, o): 746 return o.i_type in KNOWN_TOPLEVEL_CONTAINER_TYPES 747 748 def GetCompressedBlob(self, data): 749 if self.header['kcd_c_type'] != 1: 750 raise NotImplementedError 751 blob = data[self.blob_start:self.blob_start+self.header['kcd_c_totalout']] 752 if len(blob) != self.header['kcd_c_totalout']: 753 raise ValueError 754 return blob 755 756 def Decompress(self, data): 757 start_marker = struct.pack('<IIII', self.compressed_type, 0, 0, 0) 758 end_marker = struct.pack('<IIII', GetTypeForName('KCDATA_TYPE_BUFFER_END'), 0, 0, 0) 759 decompressed = zlib.decompress(self.GetCompressedBlob(data)) 760 if len(decompressed) != self.header['kcd_c_totalin']: 761 raise ValueError("length of decompressed: %d vs expected %d" % (len(decompressed), self.header['kcd_c_totalin'])) 762 alignbytes = b'\x00' * (-len(decompressed) % 16) 763 return start_marker + decompressed + alignbytes + end_marker 764 765 766class KCData_item: 767 """ a basic kcdata_item type object. 768 """ 769 header_size = 16 # (uint32_t + uint32_t + uint64_t) 770 771 def __init__(self, barray, pos=0): 772 """ create an object by parsing data from bytes array 773 returns : obj - if data is readable 774 raises ValueError if something is not ok. 775 """ 776 self.i_type = struct.unpack('I', barray[pos:pos+4])[0] # int.from_bytes(barray[pos:pos+4]) 777 self.i_size = struct.unpack('I', barray[pos+4:pos+8])[0] # int.from_bytes(barray[pos+4:pos+8]) 778 self.i_flags = struct.unpack('Q', barray[pos+8:pos+16])[0] # int.from_bytes(barray[pos+8:pos+16]) 779 self.i_data = barray[pos+16: (pos + 16 + self.i_size)] 780 self.i_offset = pos 781 782 def __len__(self): 783 return self.i_size + KCData_item.header_size 784 785 def GetHeaderDescription(self): 786 outs = "type: 0x%x size: 0x%x flags: 0x%x (%s)" % (self.i_type, self.i_size, self.i_flags, GetTypeNameForKey(self.i_type)) 787 if self.i_offset is not None: 788 outs = "pos: 0x%x" % self.i_offset + outs 789 return outs 790 791 def __str__(self): 792 return self.GetHeaderDescription() 793 794def kcdata_item_iterator(data): 795 file_len = len(data) 796 curpos = 0 797 while curpos < file_len: 798 item = KCData_item(data, curpos) 799 yield item 800 curpos += len(item) 801 802def _get_data_element(elementValues): 803 return json.dumps(elementValues[-1]) 804 805KNOWN_TOPLEVEL_CONTAINER_TYPES = list(map(GetTypeForName, ('KCDATA_BUFFER_BEGIN_COMPRESSED', 'KCDATA_BUFFER_BEGIN_CRASHINFO', 'KCDATA_BUFFER_BEGIN_STACKSHOT', 'KCDATA_BUFFER_BEGIN_DELTA_STACKSHOT', 'KCDATA_BUFFER_BEGIN_OS_REASON','KCDATA_BUFFER_BEGIN_XNUPOST_CONFIG'))) 806 807KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_UINT32_DESC')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_UINT32_DESC'), ( 808 KCSubTypeElement('desc', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(32, 1), 0, 1), 809 KCSubTypeElement('data', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 32, 0) 810), 811 'KCDATA_TYPE_UINT32_DESC', 812 _get_data_element 813) 814 815KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_UINT64_DESC')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_UINT64_DESC'), ( 816 KCSubTypeElement('desc', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(32, 1), 0, 1), 817 KCSubTypeElement('data', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 32, 0) 818), 819 'KCDATA_TYPE_UINT64_DESC', 820 _get_data_element 821) 822 823KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_TIMEBASE')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_TIMEBASE'), ( 824 KCSubTypeElement('numer', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0), 825 KCSubTypeElement('denom', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4, 0) 826), 827 'mach_timebase_info' 828) 829 830 831STACKSHOT_IO_NUM_PRIORITIES = 4 832KNOWN_TYPES_COLLECTION[0x901] = KCTypeDescription(0x901, ( 833 KCSubTypeElement.FromBasicCtype('ss_disk_reads_count', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 834 KCSubTypeElement.FromBasicCtype('ss_disk_reads_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 835 KCSubTypeElement.FromBasicCtype('ss_disk_writes_count', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 836 KCSubTypeElement.FromBasicCtype('ss_disk_writes_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 837 KCSubTypeElement('ss_io_priority_count', KCSUBTYPE_TYPE.KC_ST_UINT64, KCSubTypeElement.GetSizeForArray(STACKSHOT_IO_NUM_PRIORITIES, 8), 32, 1), 838 KCSubTypeElement('ss_io_priority_size', KCSUBTYPE_TYPE.KC_ST_UINT64, KCSubTypeElement.GetSizeForArray(STACKSHOT_IO_NUM_PRIORITIES, 8), 32 + (STACKSHOT_IO_NUM_PRIORITIES * 8), 1), 839 KCSubTypeElement.FromBasicCtype('ss_paging_count', KCSUBTYPE_TYPE.KC_ST_UINT64, 32 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)), 840 KCSubTypeElement.FromBasicCtype('ss_paging_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 40 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)), 841 KCSubTypeElement.FromBasicCtype('ss_non_paging_count', KCSUBTYPE_TYPE.KC_ST_UINT64, 48 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)), 842 KCSubTypeElement.FromBasicCtype('ss_non_paging_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 56 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)), 843 KCSubTypeElement.FromBasicCtype('ss_data_count', KCSUBTYPE_TYPE.KC_ST_UINT64, 64 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)), 844 KCSubTypeElement.FromBasicCtype('ss_data_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 72 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)), 845 KCSubTypeElement.FromBasicCtype('ss_metadata_count', KCSUBTYPE_TYPE.KC_ST_UINT64, 80 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)), 846 KCSubTypeElement.FromBasicCtype('ss_metadata_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 88 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)) 847), 848 'io_statistics' 849) 850 851KNOWN_TYPES_COLLECTION[0x902] = KCTypeDescription(0x902, ( 852 KCSubTypeElement('snapshot_magic', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 0, 0), 853 KCSubTypeElement('free_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 1, 0), 854 KCSubTypeElement('active_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 2, 0), 855 KCSubTypeElement('inactive_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 3, 0), 856 KCSubTypeElement('purgeable_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 4, 0), 857 KCSubTypeElement('wired_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 5, 0), 858 KCSubTypeElement('speculative_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 6, 0), 859 KCSubTypeElement('throttled_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 7, 0), 860 KCSubTypeElement('filebacked_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 8, 0), 861 KCSubTypeElement('compressions', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 9, 0), 862 KCSubTypeElement('decompressions', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 10, 0), 863 KCSubTypeElement('compressor_size', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 11, 0), 864 KCSubTypeElement('busy_buffer_count', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 4 * 12, 0), 865 KCSubTypeElement('pages_wanted', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 13, 0), 866 KCSubTypeElement('pages_reclaimed', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 14, 0), 867 KCSubTypeElement('pages_wanted_reclaimed_valid', KCSUBTYPE_TYPE.KC_ST_UINT8, 1, 4 * 15, 0) 868), 869 'mem_and_io_snapshot' 870) 871 872 873KNOWN_TYPES_COLLECTION[0x930] = KCTypeDescription(0x930, ( 874 KCSubTypeElement.FromBasicCtype('tts_unique_pid', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 875 KCSubTypeElement.FromBasicCtype('tts_ss_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 876 KCSubTypeElement.FromBasicCtype('tts_transition_type', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 877 KCSubTypeElement.FromBasicCtype('tts_pid', KCSUBTYPE_TYPE.KC_ST_INT32, 24), 878 KCSubTypeElement('tts_p_comm', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(32, 1), 28, 1) 879), 880 'transitioning_task_snapshot' 881) 882 883KNOWN_TYPES_COLLECTION[0x905] = KCTypeDescription(0x905, ( 884 KCSubTypeElement.FromBasicCtype('ts_unique_pid', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 885 KCSubTypeElement.FromBasicCtype('ts_ss_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 886 KCSubTypeElement.FromBasicCtype('ts_user_time_in_terminated_thre', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 887 KCSubTypeElement.FromBasicCtype('ts_system_time_in_terminated_th', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 888 KCSubTypeElement.FromBasicCtype('ts_p_start_sec', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 889 KCSubTypeElement.FromBasicCtype('ts_task_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 890 KCSubTypeElement.FromBasicCtype('ts_max_resident_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 891 KCSubTypeElement.FromBasicCtype('ts_suspend_count', KCSUBTYPE_TYPE.KC_ST_UINT32, 56), 892 KCSubTypeElement.FromBasicCtype('ts_faults', KCSUBTYPE_TYPE.KC_ST_UINT32, 60), 893 KCSubTypeElement.FromBasicCtype('ts_pageins', KCSUBTYPE_TYPE.KC_ST_UINT32, 64), 894 KCSubTypeElement.FromBasicCtype('ts_cow_faults', KCSUBTYPE_TYPE.KC_ST_UINT32, 68), 895 KCSubTypeElement.FromBasicCtype('ts_was_throttled', KCSUBTYPE_TYPE.KC_ST_UINT32, 72), 896 KCSubTypeElement.FromBasicCtype('ts_did_throttle', KCSUBTYPE_TYPE.KC_ST_UINT32, 76), 897 KCSubTypeElement.FromBasicCtype('ts_latency_qos', KCSUBTYPE_TYPE.KC_ST_UINT32, 80), 898 KCSubTypeElement.FromBasicCtype('ts_pid', KCSUBTYPE_TYPE.KC_ST_INT32, 84), 899 KCSubTypeElement('ts_p_comm', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(32, 1), 88, 1), 900 KCSubTypeElement.FromBasicCtype('ts_uid', KCSUBTYPE_TYPE.KC_ST_UINT32, 120), 901 KCSubTypeElement.FromBasicCtype('ts_gid', KCSUBTYPE_TYPE.KC_ST_UINT32, 124) 902), 903 'task_snapshot' 904) 905 906 907KNOWN_TYPES_COLLECTION[0x946] = KCTypeDescription(0x946, ( 908 KCSubTypeElement.FromBasicCtype('csflags', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 909 KCSubTypeElement.FromBasicCtype('cs_trust_level', KCSUBTYPE_TYPE.KC_ST_UINT32, 8), 910 ), 911 'stackshot_task_codesigning_info' 912) 913KNOWN_TYPES_COLLECTION[0x906] = KCTypeDescription(0x906, ( 914 KCSubTypeElement.FromBasicCtype('ths_thread_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 915 KCSubTypeElement.FromBasicCtype('ths_wait_event', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 916 KCSubTypeElement.FromBasicCtype('ths_continuation', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 917 KCSubTypeElement.FromBasicCtype('ths_total_syscalls', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 918 KCSubTypeElement.FromBasicCtype('ths_voucher_identifier', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 919 KCSubTypeElement.FromBasicCtype('ths_dqserialnum', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 920 KCSubTypeElement.FromBasicCtype('ths_user_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 921 KCSubTypeElement.FromBasicCtype('ths_sys_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 56), 922 KCSubTypeElement.FromBasicCtype('ths_ss_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 64), 923 KCSubTypeElement.FromBasicCtype('ths_last_run_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 72), 924 KCSubTypeElement.FromBasicCtype('ths_last_made_runnable_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 80), 925 KCSubTypeElement.FromBasicCtype('ths_state', KCSUBTYPE_TYPE.KC_ST_UINT32, 88), 926 KCSubTypeElement.FromBasicCtype('ths_sched_flags', KCSUBTYPE_TYPE.KC_ST_UINT32, 92), 927 KCSubTypeElement.FromBasicCtype('ths_base_priority', KCSUBTYPE_TYPE.KC_ST_INT16, 96), 928 KCSubTypeElement.FromBasicCtype('ths_sched_priority', KCSUBTYPE_TYPE.KC_ST_INT16, 98), 929 KCSubTypeElement.FromBasicCtype('ths_eqos', KCSUBTYPE_TYPE.KC_ST_UINT8, 100), 930 KCSubTypeElement.FromBasicCtype('ths_rqos', KCSUBTYPE_TYPE.KC_ST_UINT8, 101), 931 KCSubTypeElement.FromBasicCtype('ths_rqos_override', KCSUBTYPE_TYPE.KC_ST_UINT8, 102), 932 KCSubTypeElement.FromBasicCtype('ths_io_tier', KCSUBTYPE_TYPE.KC_ST_UINT8, 103), 933 KCSubTypeElement.FromBasicCtype('ths_thread_t', KCSUBTYPE_TYPE.KC_ST_UINT64, 104), 934 KCSubTypeElement.FromBasicCtype('ths_requested_policy', KCSUBTYPE_TYPE.KC_ST_UINT64, 112), 935 KCSubTypeElement.FromBasicCtype('ths_effective_policy', KCSUBTYPE_TYPE.KC_ST_UINT64, 120), 936), 937 'thread_snapshot', 938 legacy_size = 0x68 939) 940 941KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_DISPATCH_QUEUE_LABEL')] = KCSubTypeElement('dispatch_queue_label', KCSUBTYPE_TYPE.KC_ST_CHAR, 942 KCSubTypeElement.GetSizeForArray(64, 1), 0, 1) 943 944KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT'), ( 945 KCSubTypeElement.FromBasicCtype('tds_thread_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 946 KCSubTypeElement.FromBasicCtype('tds_voucher_identifier', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 947 KCSubTypeElement.FromBasicCtype('tds_ss_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 948 KCSubTypeElement.FromBasicCtype('tds_last_made_runnable_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 949 KCSubTypeElement.FromBasicCtype('tds_state', KCSUBTYPE_TYPE.KC_ST_UINT32, 32), 950 KCSubTypeElement.FromBasicCtype('tds_sched_flags', KCSUBTYPE_TYPE.KC_ST_UINT32, 36), 951 KCSubTypeElement.FromBasicCtype('tds_base_priority', KCSUBTYPE_TYPE.KC_ST_INT16, 40), 952 KCSubTypeElement.FromBasicCtype('tds_sched_priority', KCSUBTYPE_TYPE.KC_ST_INT16, 42), 953 KCSubTypeElement.FromBasicCtype('tds_eqos', KCSUBTYPE_TYPE.KC_ST_UINT8, 44), 954 KCSubTypeElement.FromBasicCtype('tds_rqos', KCSUBTYPE_TYPE.KC_ST_UINT8, 45), 955 KCSubTypeElement.FromBasicCtype('tds_rqos_override', KCSUBTYPE_TYPE.KC_ST_UINT8, 46), 956 KCSubTypeElement.FromBasicCtype('tds_io_tier', KCSUBTYPE_TYPE.KC_ST_UINT8, 47), 957 KCSubTypeElement.FromBasicCtype('tds_requested_policy', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 958 KCSubTypeElement.FromBasicCtype('tds_effective_policy', KCSUBTYPE_TYPE.KC_ST_UINT64, 56), 959), 960 'thread_delta_snapshot', 961 legacy_size = 48 962) 963 964KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_TASK_DELTA_SNAPSHOT')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_TASK_DELTA_SNAPSHOT'), ( 965 KCSubTypeElement.FromBasicCtype('tds_unique_pid', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 966 KCSubTypeElement.FromBasicCtype('tds_ss_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 967 KCSubTypeElement.FromBasicCtype('tds_user_time_in_terminated_thr', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 968 KCSubTypeElement.FromBasicCtype('tds_system_time_in_terminated_t', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 969 KCSubTypeElement.FromBasicCtype('tds_task_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 970 KCSubTypeElement.FromBasicCtype('tds_max_resident_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 971 KCSubTypeElement.FromBasicCtype('tds_suspend_count', KCSUBTYPE_TYPE.KC_ST_UINT32, 48), 972 KCSubTypeElement.FromBasicCtype('tds_faults', KCSUBTYPE_TYPE.KC_ST_UINT32, 52), 973 KCSubTypeElement.FromBasicCtype('tds_pageins', KCSUBTYPE_TYPE.KC_ST_UINT32, 56), 974 KCSubTypeElement.FromBasicCtype('tds_cow_faults', KCSUBTYPE_TYPE.KC_ST_UINT32, 60), 975 KCSubTypeElement.FromBasicCtype('tds_was_throttled', KCSUBTYPE_TYPE.KC_ST_UINT32, 64), 976 KCSubTypeElement.FromBasicCtype('tds_did_throttle', KCSUBTYPE_TYPE.KC_ST_UINT32, 68), 977 KCSubTypeElement.FromBasicCtype('tds_latency_qos', KCSUBTYPE_TYPE.KC_ST_UINT32, 72), 978), 979 'task_delta_snapshot' 980) 981 982KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_TASK_EXEC_META')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_TASK_EXEC_META'), ( 983 KCSubTypeElement.FromBasicCtype('tem_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 984), 985 'task_exec_meta' 986) 987 988KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_NAME')] = KCSubTypeElement('pth_name', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(64, 1), 0, 1) 989 990KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_SYS_SHAREDCACHE_LAYOUT')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_SYS_SHAREDCACHE_LAYOUT'), ( 991 KCSubTypeElement('imageLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 992 KCSubTypeElement('imageUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 8, 1) 993), 994 'system_shared_cache_layout' 995) 996 997KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_LIBRARY_LOADINFO64')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_LIBRARY_LOADINFO64'), ( 998 KCSubTypeElement('imageLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 999 KCSubTypeElement('imageUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 8, 1) 1000), 1001 'dyld_load_info', 1002 legacy_size = 24 1003) 1004 1005KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_LIBRARY_LOADINFO')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_LIBRARY_LOADINFO'), ( 1006 KCSubTypeElement('imageLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0), 1007 KCSubTypeElement('imageUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 4, 1) 1008), 1009 'dyld_load_info', 1010 legacy_size = 20 1011) 1012 1013KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_LOADINFO64_TEXT_EXEC')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_LOADINFO64_TEXT_EXEC'), ( 1014 KCSubTypeElement('imageLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 1015 KCSubTypeElement('imageUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 8, 1), 1016), 1017 'dyld_load_info_text_exec' 1018) 1019 1020KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_AOTCACHE_LOADINFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_AOTCACHE_LOADINFO'), ( 1021 KCSubTypeElement('x86SlidBaseAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 1022 KCSubTypeElement('x86UUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 8, 1), 1023 KCSubTypeElement('aotSlidBaseAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 24, 0), 1024 KCSubTypeElement('aotUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 32, 1), 1025), 1026 'dyld_aot_cache_uuid_info' 1027) 1028KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_SHAREDCACHE_AOTINFO')] = KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_AOTCACHE_LOADINFO')] 1029 1030KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_SHAREDCACHE_LOADINFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_SHAREDCACHE_LOADINFO'), ( 1031 KCSubTypeElement('imageLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 1032 KCSubTypeElement('imageUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 8, 1), 1033 KCSubTypeElement('imageSlidBaseAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 24, 0), 1034 KCSubTypeElement('sharedCacheSlidFirstMapping', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 32, 0), 1035), 1036 'shared_cache_dyld_load_info', 1037 legacy_size = 0x18 1038) 1039 1040KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_SHAREDCACHE_INFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_SHAREDCACHE_INFO'), ( 1041 KCSubTypeElement('sharedCacheSlide', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 1042 KCSubTypeElement('sharedCacheUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 8, 1), 1043 KCSubTypeElement('sharedCacheUnreliableSlidBaseAd', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 24, 0), 1044 KCSubTypeElement('sharedCacheSlidFirstMapping', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 32, 0), 1045 KCSubTypeElement('sharedCacheID', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 40, 0), 1046 KCSubTypeElement('sharedCacheFlags', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 44, 0), 1047), 1048 'shared_cache_dyld_load_info', 1049) 1050 1051KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERNELCACHE_LOADINFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_KERNELCACHE_LOADINFO'), ( 1052 KCSubTypeElement('imageLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 1053 KCSubTypeElement('imageUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 8, 1), 1054), 1055 'kernelcache_load_info' 1056) 1057 1058KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_SHAREDCACHE_ID')] = KCSubTypeElement('sharedCacheID', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0, KCSubTypeElement._get_naked_element_value) 1059 1060KNOWN_TYPES_COLLECTION[0x33] = KCSubTypeElement('mach_absolute_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value) 1061KNOWN_TYPES_COLLECTION[0x907] = KCSubTypeElement.FromBasicCtype('donating_pids', KCSUBTYPE_TYPE.KC_ST_INT32, legacy_size=4) 1062 1063KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_USECS_SINCE_EPOCH')] = KCSubTypeElement('usecs_since_epoch', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value) 1064 1065KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME'), ( 1066 KCSubTypeElement.FromBasicCtype('lr', KCSUBTYPE_TYPE.KC_ST_UINT32), 1067 KCSubTypeElement.FromBasicCtype('sp', KCSUBTYPE_TYPE.KC_ST_UINT32, 4) 1068), 1069 'kernel_stack_frames', 1070 legacy_size = 8 1071) 1072 1073KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR'), ( 1074 KCSubTypeElement.FromBasicCtype('lr', KCSUBTYPE_TYPE.KC_ST_UINT32), 1075), 1076 'kernel_stack_frames' 1077) 1078 1079 1080KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_USER_STACKFRAME')] = KCTypeDescription.FromKCTypeDescription( 1081 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME')], 1082 GetTypeForName('STACKSHOT_KCTYPE_USER_STACKFRAME'), 1083 'user_stack_frames' 1084) 1085 1086KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_USER_STACKLR')] = KCTypeDescription.FromKCTypeDescription( 1087 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR')], 1088 GetTypeForName('STACKSHOT_KCTYPE_USER_STACKLR'), 1089 'user_stack_frames' 1090) 1091 1092KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME64')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME64'), ( 1093 KCSubTypeElement.FromBasicCtype('lr', KCSUBTYPE_TYPE.KC_ST_UINT64), 1094 KCSubTypeElement.FromBasicCtype('sp', KCSUBTYPE_TYPE.KC_ST_UINT64, 8) 1095), 1096 'kernel_stack_frames', 1097 legacy_size = 16 1098) 1099 1100KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_USER_STACKFRAME64')] = KCTypeDescription.FromKCTypeDescription( 1101 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME64')], 1102 GetTypeForName('STACKSHOT_KCTYPE_USER_STACKFRAME64'), 1103 'user_stack_frames' 1104) 1105 1106 1107KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR64')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR64'), ( 1108 KCSubTypeElement.FromBasicCtype('lr', KCSUBTYPE_TYPE.KC_ST_UINT64), 1109), 1110 'kernel_stack_frames' 1111) 1112 1113KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_USER_STACKLR64')] = KCTypeDescription.FromKCTypeDescription( 1114 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR64')], 1115 GetTypeForName('STACKSHOT_KCTYPE_USER_STACKLR64'), 1116 'user_stack_frames' 1117) 1118 1119KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_USER_ASYNC_START_INDEX')] = KCSubTypeElement.FromBasicCtype('user_async_start_index', KCSUBTYPE_TYPE.KC_ST_UINT32) 1120 1121KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_USER_ASYNC_STACKLR64')] = KCTypeDescription.FromKCTypeDescription( 1122 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR64')], 1123 GetTypeForName('STACKSHOT_KCTYPE_USER_ASYNC_STACKLR64'), 1124 'user_async_stack_frames' 1125) 1126 1127KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_NONRUNNABLE_TIDS')] = KCSubTypeElement.FromBasicCtype('nonrunnable_threads', KCSUBTYPE_TYPE.KC_ST_INT64) 1128 1129KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_NONRUNNABLE_TASKS')] = KCSubTypeElement.FromBasicCtype('nonrunnable_tasks', KCSUBTYPE_TYPE.KC_ST_INT64) 1130 1131KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_OSVERSION')] = KCSubTypeElement('osversion', KCSUBTYPE_TYPE.KC_ST_CHAR, 1132 KCSubTypeElement.GetSizeForArray(256, 1), 0, 1) 1133 1134KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_BOOTARGS')] = KCSubTypeElement('boot_args', KCSUBTYPE_TYPE.KC_ST_CHAR, 1135 KCSubTypeElement.GetSizeForArray(256, 1), 0, 1) 1136 1137KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_PAGE_SIZE')] = KCSubTypeElement('kernel_page_size', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0, KCSubTypeElement._get_naked_element_value) 1138 1139KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_POLICY_VERSION')] = KCSubTypeElement('thread_policy_version', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0, KCSubTypeElement._get_naked_element_value) 1140 1141KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_JETSAM_LEVEL')] = KCSubTypeElement('jetsam_level', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0, KCSubTypeElement._get_naked_element_value) 1142 1143KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_DELTA_SINCE_TIMESTAMP')] = KCSubTypeElement("stackshot_delta_since_timestamp", KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value) 1144 1145KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_STACKSHOT_FAULT_STATS')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_STACKSHOT_FAULT_STATS'), 1146 ( 1147 KCSubTypeElement.FromBasicCtype('sfs_pages_faulted_in', KCSUBTYPE_TYPE.KC_ST_UINT32, 0), 1148 KCSubTypeElement.FromBasicCtype('sfs_time_spent_faulting', KCSUBTYPE_TYPE.KC_ST_UINT64, 4), 1149 KCSubTypeElement.FromBasicCtype('sfs_system_max_fault_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 12), 1150 KCSubTypeElement.FromBasicCtype('sfs_stopped_faulting', KCSUBTYPE_TYPE.KC_ST_UINT8, 20) 1151 ), 1152 'stackshot_fault_stats') 1153 1154KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_WAITINFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_THREAD_WAITINFO'), 1155 ( 1156 KCSubTypeElement.FromBasicCtype('owner', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1157 KCSubTypeElement.FromBasicCtype('waiter', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1158 KCSubTypeElement.FromBasicCtype('context', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1159 KCSubTypeElement.FromBasicCtype('wait_type', KCSUBTYPE_TYPE.KC_ST_UINT8, 24), 1160 KCSubTypeElement.FromBasicCtype('portlabel_id', KCSUBTYPE_TYPE.KC_ST_INT16, 25), 1161 KCSubTypeElement.FromBasicCtype('wait_flags', KCSUBTYPE_TYPE.KC_ST_INT32, 27) 1162 ), 1163 'thread_waitinfo') 1164 1165KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_TURNSTILEINFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_THREAD_TURNSTILEINFO'), 1166 ( 1167 KCSubTypeElement.FromBasicCtype('waiter', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1168 KCSubTypeElement.FromBasicCtype('turnstile_context', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1169 KCSubTypeElement.FromBasicCtype('turnstile_priority', KCSUBTYPE_TYPE.KC_ST_UINT8, 16), 1170 KCSubTypeElement.FromBasicCtype('number_of_hops', KCSUBTYPE_TYPE.KC_ST_UINT8, 17), 1171 KCSubTypeElement.FromBasicCtype('turnstile_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 18), 1172 KCSubTypeElement.FromBasicCtype('portlabel_id', KCSUBTYPE_TYPE.KC_ST_INT16, 26), 1173 ), 1174 'thread_turnstileinfo') 1175 1176KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_PORTLABEL')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_PORTLABEL'), 1177 ( 1178 KCSubTypeElement.FromBasicCtype('portlabel_id', KCSUBTYPE_TYPE.KC_ST_INT16, 0), 1179 KCSubTypeElement.FromBasicCtype('portlabel_flags', KCSUBTYPE_TYPE.KC_ST_UINT16, 2), 1180 KCSubTypeElement.FromBasicCtype('portlabel_domain', KCSUBTYPE_TYPE.KC_ST_UINT8, 4), 1181 ), 1182 'portlabel_info', merge=True) 1183 1184KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_PORTLABEL_NAME')] = ( 1185 KCSubTypeElement("portlabel_name", KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(-1, 1), 0, 1)) 1186 1187KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_GROUP_SNAPSHOT')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_THREAD_GROUP'), 1188 ( 1189 KCSubTypeElement.FromBasicCtype('tgs_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1190 KCSubTypeElement('tgs_name', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(16, 1), 1191 8, 1), 1192 KCSubTypeElement.FromBasicCtype('tgs_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1193 ), 1194 'thread_group_snapshot') 1195 1196 1197KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_GROUP')] = KCSubTypeElement('thread_group', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value) 1198 1199KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_JETSAM_COALITION_SNAPSHOT')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_JETSAM_COALITION_SNAPSHOT'), 1200 ( 1201 KCSubTypeElement.FromBasicCtype('jcs_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1202 KCSubTypeElement.FromBasicCtype('jcs_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1203 KCSubTypeElement.FromBasicCtype('jcs_thread_group', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1204 KCSubTypeElement.FromBasicCtype('jcs_leader_task_uniqueid', KCSUBTYPE_TYPE.KC_ST_UINT64, 24) 1205 ), 1206 'jetsam_coalition_snapshot') 1207 1208KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_JETSAM_COALITION')] = KCSubTypeElement('jetsam_coalition', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value) 1209 1210KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_INSTRS_CYCLES')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_INSTRS_CYCLES'), 1211 ( 1212 KCSubTypeElement.FromBasicCtype('ics_instructions', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1213 KCSubTypeElement.FromBasicCtype('ics_cycles', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1214 KCSubTypeElement.FromBasicCtype('ics_p_instructions', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1215 KCSubTypeElement.FromBasicCtype('ics_p_cycles', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1216 ), 1217 'instrs_cycles_snapshot') 1218 1219KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_TASK_CPU_ARCHITECTURE')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_TASK_CPU_ARCHITECTURE'), 1220 ( 1221 KCSubTypeElement.FromBasicCtype('cputype', KCSUBTYPE_TYPE.KC_ST_INT32, 0), 1222 KCSubTypeElement.FromBasicCtype('cpusubtype', KCSUBTYPE_TYPE.KC_ST_INT32, 4) 1223 ), 1224 'task_cpu_architecture') 1225 1226KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO'), 1227 ( 1228 KCSubTypeElement.FromBasicCtype('latency_version', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1229 KCSubTypeElement.FromBasicCtype('setup_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1230 KCSubTypeElement.FromBasicCtype('total_task_iteration_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1231 KCSubTypeElement.FromBasicCtype('total_terminated_task_iteration', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1232 KCSubTypeElement.FromBasicCtype('task_queue_building_latency_mt', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 1233 KCSubTypeElement.FromBasicCtype('terminated_task_queue_building_latency_mt', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 1234 KCSubTypeElement.FromBasicCtype('cpu_wait_latency_mt', KCSUBTYPE_TYPE.KC_ST_INT32, 48), 1235 KCSubTypeElement.FromBasicCtype('calling_cpu_number', KCSUBTYPE_TYPE.KC_ST_INT32, 56), 1236 ), 1237 'stackshot_latency_collection') 1238 1239KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO_CPU')] = KCTypeDescription(GetTypeForName('STACKSHOT_LATENCY_INFO_CPU'), 1240 ( 1241 KCSubTypeElement.FromBasicCtype('cpu_number', KCSUBTYPE_TYPE.KC_ST_INT32, 0), 1242 KCSubTypeElement.FromBasicCtype('cluster_type', KCSUBTYPE_TYPE.KC_ST_INT32, 4), 1243 KCSubTypeElement.FromBasicCtype('init_latency_mt', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1244 KCSubTypeElement.FromBasicCtype('workqueue_latency_mt', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1245 KCSubTypeElement.FromBasicCtype('total_latency_mt', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1246 KCSubTypeElement.FromBasicCtype('total_cycles', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 1247 KCSubTypeElement.FromBasicCtype('total_instrs', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 1248 KCSubTypeElement.FromBasicCtype('tasks_processed', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 1249 KCSubTypeElement.FromBasicCtype('threads_processed', KCSUBTYPE_TYPE.KC_ST_UINT64, 56), 1250 KCSubTypeElement.FromBasicCtype('faulting_time_mt', KCSUBTYPE_TYPE.KC_ST_UINT64, 64), 1251 KCSubTypeElement.FromBasicCtype('total_buf', KCSUBTYPE_TYPE.KC_ST_UINT64, 72), 1252 KCSubTypeElement.FromBasicCtype('intercluster_buf_used', KCSUBTYPE_TYPE.KC_ST_UINT64, 80), 1253 ), 1254 'stackshot_latency_cpu') 1255 1256KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO_BUFFER')] = KCTypeDescription(GetTypeForName('STACKSHOT_LATENCY_INFO_BUFFER'), 1257 ( 1258 KCSubTypeElement.FromBasicCtype('cluster_type', KCSUBTYPE_TYPE.KC_ST_INT32, 0), 1259 KCSubTypeElement.FromBasicCtype('size', KCSUBTYPE_TYPE.KC_ST_UINT64, 4), 1260 KCSubTypeElement.FromBasicCtype('used', KCSUBTYPE_TYPE.KC_ST_UINT64, 12), 1261 KCSubTypeElement.FromBasicCtype('overhead', KCSUBTYPE_TYPE.KC_ST_UINT64, 20), 1262 ), 1263 'stackshot_latency_buffer') 1264 1265KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO_TASK')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO_TASK'), 1266 ( 1267 KCSubTypeElement.FromBasicCtype('task_uniqueid', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1268 KCSubTypeElement.FromBasicCtype('setup_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1269 KCSubTypeElement.FromBasicCtype('task_thread_count_loop_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1270 KCSubTypeElement.FromBasicCtype('task_thread_data_loop_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1271 KCSubTypeElement.FromBasicCtype('cur_tsnap_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 1272 KCSubTypeElement.FromBasicCtype('pmap_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 1273 KCSubTypeElement.FromBasicCtype('bsd_proc_ids_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 1274 KCSubTypeElement.FromBasicCtype('misc_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 56), 1275 KCSubTypeElement.FromBasicCtype('misc2_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 64), 1276 KCSubTypeElement.FromBasicCtype('end_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 72) 1277 ), 1278 'stackshot_latency_task') 1279 1280KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO_THREAD')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO_THREAD'), 1281 ( 1282 KCSubTypeElement.FromBasicCtype('thread_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1283 KCSubTypeElement.FromBasicCtype('cur_thsnap1_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1284 KCSubTypeElement.FromBasicCtype('dispatch_serial_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1285 KCSubTypeElement.FromBasicCtype('dispatch_label_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1286 KCSubTypeElement.FromBasicCtype('cur_thsnap2_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 1287 KCSubTypeElement.FromBasicCtype('thread_name_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 1288 KCSubTypeElement.FromBasicCtype('sur_times_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 1289 KCSubTypeElement.FromBasicCtype('user_stack_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 56), 1290 KCSubTypeElement.FromBasicCtype('kernel_stack_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 64), 1291 KCSubTypeElement.FromBasicCtype('misc_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 72), 1292 ), 1293 'stackshot_latency_thread') 1294 1295KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_NAME')] = KCSubTypeElement('pth_name', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(64, 1), 0, 1) 1296 1297def set_type(name, *args): 1298 typ = GetTypeForName(name) 1299 KNOWN_TYPES_COLLECTION[typ] = KCTypeDescription(GetTypeForName(typ), *args) 1300 1301 1302set_type('STACKSHOT_KCTYPE_USER_STACKTOP', 1303 ( 1304 KCSubTypeElement.FromBasicCtype('sp', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1305 KCSubTypeElement('stack_contents', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(8, 1), 8, 1), 1306 ), 1307 'user_stacktop') 1308 1309#KNOWN_TYPES_COLLECTION[0x907] = KCSubTypeElement('donating_pids', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0, KCSubTypeElement._get_naked_element_value) 1310KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PID')] = KCSubTypeElement('pid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1311KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PPID')] = KCSubTypeElement('ppid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1312KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_NAME')] = KCSubTypeElement('p_comm', KCSUBTYPE_TYPE.KC_ST_CHAR, 1313 KCSubTypeElement.GetSizeForArray(32, 1), 0, 1) 1314KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_USERSTACK')] = KCSubTypeElement('userstack_ptr', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0) 1315KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_ARGSLEN')] = KCSubTypeElement('p_argslen', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1316 1317KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_PATH')] = KCSubTypeElement('p_path', KCSUBTYPE_TYPE.KC_ST_CHAR, 1318 KCSubTypeElement.GetSizeForArray(1024, 1), 0, 1) 1319KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_CSFLAGS')] = KCSubTypeElement('p_csflags', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1320KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_UID')] = KCSubTypeElement('uid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1321KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_GID')] = KCSubTypeElement('gid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1322KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_ARGC')] = KCSubTypeElement('argc', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1323KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_FLAGS')] = KCSubTypeElement('p_flags', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1324KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_CPUTYPE')] = KCSubTypeElement('cputype', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1325KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_RESPONSIBLE_PID')] = KCSubTypeElement('responsible_pid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1326KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_DIRTY_FLAGS')] = KCSubTypeElement('dirty_flags', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1327KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_CRASHED_THREADID')] = KCSubTypeElement('crashed_threadid', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0) 1328KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_COALITION_ID')] = KCSubTypeElement('coalition_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0) 1329 1330KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_STATUS')] = KCSubTypeElement('p_status', KCSUBTYPE_TYPE.KC_ST_UINT8, 1, 0, 0) 1331 1332KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_BSDINFOWITHUNIQID')] = KCTypeDescription(GetTypeForName('TASK_CRASHINFO_BSDINFOWITHUNIQID'), 1333 ( KCSubTypeElement('p_uuid', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 0, 1), 1334 KCSubTypeElement.FromBasicCtype('p_uniqueid', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1335 KCSubTypeElement.FromBasicCtype('p_puniqueid', KCSUBTYPE_TYPE.KC_ST_UINT64, 24) 1336 ), 1337 'proc_uniqidentifierinfo') 1338 1339KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_EXCEPTION_CODES')] = ( 1340 KCTypeDescription(GetTypeForName('TASK_CRASHINFO_EXCEPTION_CODES'), 1341 (KCSubTypeElement.FromBasicCtype('code_0', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1342 KCSubTypeElement.FromBasicCtype('code_1', KCSUBTYPE_TYPE.KC_ST_UINT64, 8)), 1343 'mach_exception_data_t')) 1344 1345 1346KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_STARTTIME')] = ( 1347 KCTypeDescription(GetTypeForName('TASK_CRASHINFO_PROC_STARTTIME'), 1348 (KCSubTypeElement.FromBasicCtype('tv_sec', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1349 KCSubTypeElement.FromBasicCtype('tv_usec', KCSUBTYPE_TYPE.KC_ST_UINT64, 8)), 1350 'proc_starttime')) 1351 1352 1353KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_RUSAGE_INFO')] = KCTypeDescription(GetTypeForName('TASK_CRASHINFO_RUSAGE_INFO'), 1354 ( 1355 KCSubTypeElement('ri_uuid', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 0, 1), 1356 KCSubTypeElement.FromBasicCtype('ri_user_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1357 KCSubTypeElement.FromBasicCtype('ri_system_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1358 KCSubTypeElement.FromBasicCtype('ri_pkg_idle_wkups', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 1359 KCSubTypeElement.FromBasicCtype('ri_interrupt_wkups', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 1360 KCSubTypeElement.FromBasicCtype('ri_pageins', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 1361 KCSubTypeElement.FromBasicCtype('ri_wired_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 56), 1362 KCSubTypeElement.FromBasicCtype('ri_resident_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 64), 1363 KCSubTypeElement.FromBasicCtype('ri_phys_footprint', KCSUBTYPE_TYPE.KC_ST_UINT64, 72), 1364 KCSubTypeElement.FromBasicCtype('ri_proc_start_abstime', KCSUBTYPE_TYPE.KC_ST_UINT64, 80), 1365 KCSubTypeElement.FromBasicCtype('ri_proc_exit_abstime', KCSUBTYPE_TYPE.KC_ST_UINT64, 88), 1366 KCSubTypeElement.FromBasicCtype('ri_child_user_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 96), 1367 KCSubTypeElement.FromBasicCtype('ri_child_system_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 104), 1368 KCSubTypeElement.FromBasicCtype('ri_child_pkg_idle_wkups', KCSUBTYPE_TYPE.KC_ST_UINT64, 112), 1369 KCSubTypeElement.FromBasicCtype('ri_child_interrupt_wkups', KCSUBTYPE_TYPE.KC_ST_UINT64, 120), 1370 KCSubTypeElement.FromBasicCtype('ri_child_pageins', KCSUBTYPE_TYPE.KC_ST_UINT64, 128), 1371 KCSubTypeElement.FromBasicCtype('ri_child_elapsed_abstime', KCSUBTYPE_TYPE.KC_ST_UINT64, 136), 1372 KCSubTypeElement.FromBasicCtype('ri_diskio_bytesread', KCSUBTYPE_TYPE.KC_ST_UINT64, 144), 1373 KCSubTypeElement.FromBasicCtype('ri_diskio_byteswritten', KCSUBTYPE_TYPE.KC_ST_UINT64, 152), 1374 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_default', KCSUBTYPE_TYPE.KC_ST_UINT64, 160), 1375 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_maintenance', KCSUBTYPE_TYPE.KC_ST_UINT64, 168), 1376 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_background', KCSUBTYPE_TYPE.KC_ST_UINT64, 176), 1377 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_utility', KCSUBTYPE_TYPE.KC_ST_UINT64, 184), 1378 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_legacy', KCSUBTYPE_TYPE.KC_ST_UINT64, 192), 1379 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_user_initiated', KCSUBTYPE_TYPE.KC_ST_UINT64, 200), 1380 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_user_interactiv', KCSUBTYPE_TYPE.KC_ST_UINT64, 208), 1381 KCSubTypeElement.FromBasicCtype('ri_billed_system_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 216), 1382 KCSubTypeElement.FromBasicCtype('ri_serviced_system_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 224) 1383 ), 1384 'rusage_info') 1385 1386#The sizes for these need to be kept in sync with 1387#MAX_CRASHINFO_SIGNING_ID_LEN, MAX_CRASHINFO_TEAM_ID_LEN 1388KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_CS_SIGNING_ID')] = KCSubTypeElement('cs_signing_id', KCSUBTYPE_TYPE.KC_ST_CHAR, 1389 KCSubTypeElement.GetSizeForArray(64, 1), 0, 1) 1390KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_CS_TEAM_ID')] = KCSubTypeElement('cs_team_id', KCSUBTYPE_TYPE.KC_ST_CHAR, 1391 KCSubTypeElement.GetSizeForArray(32, 1), 0, 1) 1392 1393KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_CS_VALIDATION_CATEGORY')] = KCSubTypeElement('cs_validation_category', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0) 1394 1395KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_CS_TRUST_LEVEL')] = KCSubTypeElement('cs_trust_level', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0) 1396 1397KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_JIT_ADDRESS_RANGE')] = KCTypeDescription(GetTypeForName('TASK_CRASHINFO_JIT_ADDRESS_RANGE'), 1398 ( 1399 KCSubTypeElement.FromBasicCtype('start_address', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1400 KCSubTypeElement.FromBasicCtype('end_address', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1401 ), 'jit_address_range') 1402 1403KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_MB')] = KCTypeDescription(GetTypeForName('TASK_CRASHINFO_MB'), 1404 ( 1405 KCSubTypeElement.FromBasicCtype('start_address', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1406 KCSubTypeElement('data', KCSUBTYPE_TYPE.KC_ST_UINT64, KCSubTypeElement.GetSizeForArray(64, 64), 8, 0), 1407 ) 1408) 1409 1410KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_CS_AUXILIARY_INFO')] = KCSubTypeElement('cs_auxiliary_info', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0) 1411 1412KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_CPU_TIMES')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_CPU_TIMES'), 1413 ( 1414 KCSubTypeElement.FromBasicCtype('user_usec', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1415 KCSubTypeElement.FromBasicCtype('system_usec', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1416 KCSubTypeElement.FromBasicCtype('runnable_usec', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1417 ), 'cpu_times') 1418 1419KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_STACKSHOT_DURATION')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_STACKSHOT_DURATION'), 1420 ( 1421 KCSubTypeElement.FromBasicCtype('stackshot_duration', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1422 KCSubTypeElement.FromBasicCtype('stackshot_duration_outer', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1423 KCSubTypeElement.FromBasicCtype('stackshot_duration_prior', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1424 ), 'stackshot_duration', merge=True 1425) 1426 1427KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_PROCNAME')] = ( 1428 KCSubTypeElement("proc_name", KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(-1, 1), 0, 1)) 1429 1430KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_PID')] = ( 1431 KCSubTypeElement('pid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0)) 1432 1433KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_LIBRARY_AOTINFO')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_LIBRARY_AOTINFO'), 1434 ( 1435 KCSubTypeElement('x86LoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 1436 KCSubTypeElement('aotLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 8, 0), 1437 KCSubTypeElement('aotImageSize', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 16, 0), 1438 KCSubTypeElement('aotImageKey', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(32, 1), 24, 1), 1439 ), 'dyld_aot_info') 1440 1441KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_SNAPSHOT')] = KCTypeDescription(GetTypeForName('EXIT_REASON_SNAPSHOT'), 1442 ( 1443 KCSubTypeElement.FromBasicCtype('ers_namespace', KCSUBTYPE_TYPE.KC_ST_UINT32, 0), 1444 KCSubTypeElement.FromBasicCtype('ers_code', KCSUBTYPE_TYPE.KC_ST_UINT64, 4), 1445 KCSubTypeElement.FromBasicCtype('ers_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 12), 1446 ), 'exit_reason_basic_info') 1447 1448KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_USER_DESC')] = ( 1449 KCSubTypeElement("exit_reason_user_description", KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(-1, 1), 0, 1)) 1450 1451KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_USER_PAYLOAD')] = KCSubTypeElement('exit_reason_user_payload', 1452 KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(-1, 1), 0, 1) 1453 1454KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_CODESIGNING_INFO')] = KCTypeDescription(GetTypeForName('EXIT_REASON_CODESIGNING_INFO'), 1455 ( 1456 KCSubTypeElement.FromBasicCtype('ceri_virt_addr', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1457 KCSubTypeElement.FromBasicCtype('ceri_file_offset', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1458 KCSubTypeElement("ceri_pathname", KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(1024, 1), 16, 1), 1459 KCSubTypeElement("ceri_filename", KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(1024, 1), 1040, 1), 1460 KCSubTypeElement.FromBasicCtype('ceri_codesig_modtime_secs', KCSUBTYPE_TYPE.KC_ST_UINT64, 2064), 1461 KCSubTypeElement.FromBasicCtype('ceri_codesig_modtime_nsecs', KCSUBTYPE_TYPE.KC_ST_UINT64, 2072), 1462 KCSubTypeElement.FromBasicCtype('ceri_page_modtime_secs', KCSUBTYPE_TYPE.KC_ST_UINT64, 2080), 1463 KCSubTypeElement.FromBasicCtype('ceri_page_modtime_nsecs', KCSUBTYPE_TYPE.KC_ST_UINT64, 2088), 1464 KCSubTypeElement.FromBasicCtype('ceri_path_truncated', KCSUBTYPE_TYPE.KC_ST_UINT8, 2096), 1465 KCSubTypeElement.FromBasicCtype('ceri_object_codesigned', KCSUBTYPE_TYPE.KC_ST_UINT8, 2097), 1466 KCSubTypeElement.FromBasicCtype('ceri_page_codesig_validated', KCSUBTYPE_TYPE.KC_ST_UINT8, 2098), 1467 KCSubTypeElement.FromBasicCtype('ceri_page_codesig_tainted', KCSUBTYPE_TYPE.KC_ST_UINT8, 2099), 1468 KCSubTypeElement.FromBasicCtype('ceri_page_codesig_nx', KCSUBTYPE_TYPE.KC_ST_UINT8, 2100), 1469 KCSubTypeElement.FromBasicCtype('ceri_page_wpmapped', KCSUBTYPE_TYPE.KC_ST_UINT8, 2101), 1470 KCSubTypeElement.FromBasicCtype('ceri_page_slid', KCSUBTYPE_TYPE.KC_ST_UINT8, 2102), 1471 KCSubTypeElement.FromBasicCtype('ceri_page_dirty', KCSUBTYPE_TYPE.KC_ST_UINT8, 2103), 1472 KCSubTypeElement.FromBasicCtype('ceri_page_shadow_depth', KCSUBTYPE_TYPE.KC_ST_UINT32, 2104), 1473 ), 'exit_reason_codesigning_info') 1474 1475KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_WORKLOOP_ID')] = ( 1476 KCSubTypeElement('exit_reason_workloop_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value)) 1477 1478KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_DISPATCH_QUEUE_NO')] = ( 1479 KCSubTypeElement('exit_reason_dispatch_queue_no', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value)) 1480 1481KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_ASID')] = ( 1482 KCSubTypeElement('ts_asid', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0)) 1483 1484KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_PAGE_TABLES')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_PAGE_TABLES'), ( 1485 KCSubTypeElement(None, KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value), ), 1486 'ts_pagetable', 1487 merge=True, 1488 naked=True 1489) 1490 1491KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_SUSPENSION_INFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_SUSPENSION_INFO'), ( 1492 KCSubTypeElement.FromBasicCtype('tss_last_start', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1493 KCSubTypeElement.FromBasicCtype('tss_last_end', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1494 KCSubTypeElement.FromBasicCtype('tss_count', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1495 KCSubTypeElement.FromBasicCtype('tss_duration', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1496), 'suspension_info') 1497 1498KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_SUSPENSION_SOURCE')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_SUSPENSION_SOURCE'), ( 1499 KCSubTypeElement.FromBasicCtype('tss_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1500 KCSubTypeElement.FromBasicCtype('tss_tid', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1501 KCSubTypeElement.FromBasicCtype('tss_pid', KCSUBTYPE_TYPE.KC_ST_INT32, 16), 1502 KCSubTypeElement('tss_procname', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(65, 1), 20, 1) 1503), 'suspension_source') 1504 1505KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_OS_BUILD_VERSION')] = KCSubTypeElement('os_build_version', KCSUBTYPE_TYPE.KC_ST_CHAR, 1506 KCSubTypeElement.GetSizeForArray(256, 1), 0, 1) 1507 1508KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_EXCLAVES_THREADINFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_KERN_EXCLAVES_THREADINFO'), 1509 ( 1510 KCSubTypeElement.FromBasicCtype('tei_scid', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1511 KCSubTypeElement.FromBasicCtype('tei_thread_offset', KCSUBTYPE_TYPE.KC_ST_UINT32, 8), 1512 KCSubTypeElement.FromBasicCtype('tei_flags', KCSUBTYPE_TYPE.KC_ST_UINT32, 12), 1513 ), 'exclaves_thread_info') 1514 1515KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_SCRESULT_INFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_SCRESULT_INFO'), 1516 ( 1517 KCSubTypeElement.FromBasicCtype('esc_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1518 KCSubTypeElement.FromBasicCtype('esc_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1519 ), 'exclave_scresult_info') 1520 1521KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_IPCSTACKENTRY_INFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_IPCSTACKENTRY_INFO'), 1522 ( 1523 KCSubTypeElement.FromBasicCtype('eise_asid', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1524 KCSubTypeElement.FromBasicCtype('eise_tnid', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1525 KCSubTypeElement.FromBasicCtype('eise_invocationid', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1526 KCSubTypeElement.FromBasicCtype('eise_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1527 ), 'exclave_ipcstackentry_info') 1528 1529KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_IPCSTACKENTRY_ECSTACK')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_IPCSTACKENTRY_ECSTACK'), 1530 ( 1531 KCSubTypeElement.FromBasicCtype('lr', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1532 ), 'secure_ecstack_entry') 1533 1534KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_ADDRESSSPACE_INFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_ADDRESSSPACE_INFO'), 1535 ( 1536 KCSubTypeElement.FromBasicCtype('eas_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1537 KCSubTypeElement.FromBasicCtype('eas_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1538 KCSubTypeElement.FromBasicCtype('eas_layoutid', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1539 KCSubTypeElement.FromBasicCtype('eas_slide', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1540 KCSubTypeElement.FromBasicCtype('eas_asroot', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 1541 ), 'exclave_addressspace_info') 1542 1543KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_ADDRESSSPACE_NAME')] = KCSubTypeElement('exclave_addressspace_name', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(64, 1), 0, 1) 1544 1545KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_TEXTLAYOUT_INFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_TEXTLAYOUT_INFO'), 1546 ( 1547 KCSubTypeElement.FromBasicCtype('layout_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1548 KCSubTypeElement.FromBasicCtype('etl_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1549 KCSubTypeElement.FromBasicCtype('sharedcache_index', KCSUBTYPE_TYPE.KC_ST_UINT32, 16), 1550 ), 'exclave_textlayout_info') 1551 1552KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_TEXTLAYOUT_SEGMENTS')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_TEXTLAYOUT_SEGMENTS'), 1553 ( 1554 KCSubTypeElement('layoutSegment_uuid', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 0, 1), 1555 KCSubTypeElement.FromBasicCtype('layoutSegment_loadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1556 KCSubTypeElement.FromBasicCtype('layoutSegment_rawLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1557 ), 'exclave_textlayout_segments') 1558 1559KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_TASK_MEMORYSTATUS')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_TASK_MEMORYSTATUS'), 1560 ( 1561 KCSubTypeElement.FromBasicCtype('tms_current_memlimit', KCSUBTYPE_TYPE.KC_ST_INT32, 0), 1562 KCSubTypeElement.FromBasicCtype('tms_effectivepriority', KCSUBTYPE_TYPE.KC_ST_INT32, 4), 1563 KCSubTypeElement.FromBasicCtype('tms_requestedpriority', KCSUBTYPE_TYPE.KC_ST_INT32, 8), 1564 KCSubTypeElement.FromBasicCtype('tms_assertionpriority', KCSUBTYPE_TYPE.KC_ST_INT32, 12), 1565 ), 'task_memorystatus') 1566 1567KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_MTEINFO_CELL')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_MTEINFO_CELL'), 1568 ( 1569 KCSubTypeElement.FromBasicCtype('mic_state', KCSUBTYPE_TYPE.KC_ST_UINT8, 0), 1570 KCSubTypeElement.FromBasicCtype('mic_tagged_count', KCSUBTYPE_TYPE.KC_ST_UINT8, 1), 1571 KCSubTypeElement.FromBasicCtype('mic_free_count', KCSUBTYPE_TYPE.KC_ST_UINT8, 2), 1572 KCSubTypeElement.FromBasicCtype('mic_wired_count', KCSUBTYPE_TYPE.KC_ST_UINT8, 3), 1573 KCSubTypeElement.FromBasicCtype('mic_wired_tagged_count', KCSUBTYPE_TYPE.KC_ST_UINT8, 4), 1574 KCSubTypeElement.FromBasicCtype('mic_kernel_wired_tagged_count', KCSUBTYPE_TYPE.KC_ST_UINT8, 5), 1575 ), 'mte_info_cell') 1576 1577def GetSecondsFromMATime(mat, tb): 1578 return (float(long(mat) * tb['numer']) / tb['denom']) / 1e9 1579 1580def GetLongForAddress(address): 1581 if isinstance(address, str): 1582 if '0x' in address.lower(): 1583 address = long(address, 16) 1584 else: 1585 address = long(address) 1586 return address 1587 1588def FindLibraryForAddress(liblist, address): 1589 current_lib = None 1590 for l in liblist: 1591 l_addr = GetLongForAddress(l[1]) 1592 if address >= l_addr: 1593 current_lib = l 1594 return current_lib 1595 1596def FindIndexOfLibInCatalog(catalog, lib): 1597 index = None 1598 i = 0 1599 for l in catalog: 1600 if l[0] == lib[0] and l[1] == lib[1]: 1601 index = i 1602 break 1603 i += 1 1604 1605 if index is None: 1606 catalog.append(lib) 1607 index = len(catalog) - 1 1608 1609 return index 1610 1611def GetOffsetOfAddressForLib(lib, address): 1612 return (address - GetLongForAddress(lib[1])) 1613 1614def GetSymbolInfoForFrame(catalog, liblist, address): 1615 address = GetLongForAddress(address) 1616 lib = FindLibraryForAddress(liblist, address) 1617 if not lib: 1618 lib = ["00000000000000000000000000000000",0,"A"] 1619 offset = GetOffsetOfAddressForLib(lib, address) 1620 index = FindIndexOfLibInCatalog(catalog, lib) 1621 return [index, offset] 1622 1623def GetStateDescription(s): 1624 retval = [] 1625 TH_WAIT = 0x01 1626 TH_SUSP = 0x02 1627 TH_RUN = 0x04 1628 TH_UNINT = 0x08 1629 TH_TERMINATE = 0x10 1630 TH_TERMINATE2 = 0x20 1631 TH_WAIT_REPORT = 0x40 1632 TH_IDLE = 0x80 1633 TH_WAKING = 0x100 1634 if (s & TH_WAIT): 1635 retval.append("TH_WAIT") 1636 if (s & TH_SUSP): 1637 retval.append("TH_SUSP") 1638 if (s & TH_RUN): 1639 retval.append("TH_RUN") 1640 if (s & TH_UNINT): 1641 retval.append("TH_UNINT") 1642 if (s & TH_TERMINATE): 1643 retval.append("TH_TERMINATE") 1644 if (s & TH_TERMINATE2): 1645 retval.append("TH_TERMINATE2") 1646 if (s & TH_WAIT_REPORT): 1647 retval.append("TH_WAIT_REPORT") 1648 if (s & TH_IDLE): 1649 retval.append("TH_IDLE") 1650 if (s & TH_WAKING): 1651 retval.append("TH_WAKING") 1652 return retval 1653 1654 1655def format_uuid(elementValues): 1656 # sometimes we get string like "25A926D8-F742-3E5E..." 1657 if isinstance(elementValues, str): 1658 return elementValues 1659 return ''.join("%02x" % i for i in elementValues) 1660 1661kThreadWaitNone = 0x00 1662kThreadWaitKernelMutex = 0x01 1663kThreadWaitPortReceive = 0x02 1664kThreadWaitPortSetReceive = 0x03 1665kThreadWaitPortSend = 0x04 1666kThreadWaitPortSendInTransit = 0x05 1667kThreadWaitSemaphore = 0x06 1668kThreadWaitKernelRWLockRead = 0x07 1669kThreadWaitKernelRWLockWrite = 0x08 1670kThreadWaitKernelRWLockUpgrade = 0x09 1671kThreadWaitUserLock = 0x0a 1672kThreadWaitPThreadMutex = 0x0b 1673kThreadWaitPThreadRWLockRead = 0x0c 1674kThreadWaitPThreadRWLockWrite = 0x0d 1675kThreadWaitPThreadCondVar = 0x0e 1676kThreadWaitParkedWorkQueue = 0x0f 1677kThreadWaitWorkloopSyncWait = 0x10 1678kThreadWaitOnProcess = 0x11 1679kThreadWaitSleepWithInheritor = 0x12 1680kThreadWaitEventlink = 0x13 1681kThreadWaitCompressor = 0x14 1682kThreadWaitParkedBoundWorkQueue = 0x15 1683kThreadWaitPageBusy = 0x16 1684kThreadWaitPagerInit = 0x17 1685kThreadWaitPagerReady = 0x18 1686kThreadWaitPagingActivity = 0x19 1687kThreadWaitMappingInProgress = 0x1a 1688kThreadWaitMemoryBlocked = 0x1b 1689kThreadWaitPagingInProgress = 0x1c 1690kThreadWaitPageInThrottle = 0x1d 1691kThreadWaitExclaveCore = 0x1e 1692kThreadWaitExclaveKit = 0x1f 1693 1694 1695UINT64_MAX = 0xffffffffffffffff 1696STACKSHOT_WAITOWNER_KERNEL = (UINT64_MAX - 1) 1697STACKSHOT_WAITOWNER_PORT_LOCKED = (UINT64_MAX - 2) 1698STACKSHOT_WAITOWNER_PSET_LOCKED = (UINT64_MAX - 3) 1699STACKSHOT_WAITOWNER_INTRANSIT = (UINT64_MAX - 4) 1700STACKSHOT_WAITOWNER_MTXSPIN = (UINT64_MAX - 5) 1701STACKSHOT_WAITOWNER_THREQUESTED = (UINT64_MAX - 6) 1702STACKSHOT_WAITOWNER_SUSPENDED = (UINT64_MAX - 7) 1703 1704STACKSHOT_TURNSTILE_STATUS_UNKNOWN = 0x01 1705STACKSHOT_TURNSTILE_STATUS_LOCKED_WAITQ = 0x02 1706STACKSHOT_TURNSTILE_STATUS_WORKQUEUE = 0x04 1707STACKSHOT_TURNSTILE_STATUS_THREAD = 0x08 1708STACKSHOT_TURNSTILE_STATUS_BLOCKED_ON_TASK = 0x10 1709STACKSHOT_TURNSTILE_STATUS_HELD_IPLOCK = 0x20 1710STACKSHOT_TURNSTILE_STATUS_SENDPORT = 0x40 1711STACKSHOT_TURNSTILE_STATUS_RECEIVEPORT = 0x80 1712 1713# 1714# These come from xpc_domain_type_t in <xpc/launch_private.h> 1715PORTLABEL_DOMAINS = { 1716 1: 'system', # XPC_DOMAIN_SYSTEM 1717 2: 'user', # XPC_DOMAIN_USER 1718 5: 'pid', # XPC_DOMAIN_PID 1719 7: 'port', # XPC_DOMAIN_PORT 1720} 1721def portlabel_domain(x): 1722 if x is None: 1723 return "unknown" 1724 return PORTLABEL_DOMAINS.get(x, "unknown.{}".format(x)) 1725 1726STACKSHOT_WAITINFO_FLAGS_SPECIALREPLY = 0x1 1727STACKSHOT_PORTLABEL_THROTTLED = 0x2 1728 1729def portThrottledSuffix(portlabel_flags): 1730 if (portlabel_flags & STACKSHOT_PORTLABEL_THROTTLED): 1731 return " (service port throttled by launchd)" 1732 else: 1733 return "" 1734 1735def formatPortLabelID(portlabel_id, portlabels): 1736 portlabel = {} 1737 if portlabel_id > 0: 1738 if portlabels is not None: 1739 portlabel = portlabels.get(str(portlabel_id), {}) 1740 portlabel_name = portlabel_domain(portlabel.get('portlabel_domain')) + " " 1741 portlabel_name += portlabel.get("portlabel_name", "!!!unknown, ID {} !!!".format(portlabel_id)) 1742 return " {" + portlabel_name + portThrottledSuffix(portlabel.get('portlabel_flags', 0)) + "}" 1743 if portlabel_id < 0: 1744 return " {labeled, info truncated" + portThrottledSuffix(portlabel.get('portlabel_flags', 0)) + "}" 1745 return "" 1746 1747def formatWaitInfo(info, wantHex, portlabels): 1748 base='#x' if wantHex else 'd' 1749 s = 'thread {0:{base}}: '.format(info['waiter'], base=base) 1750 type = info['wait_type'] 1751 context = info['context'] 1752 owner = info['owner'] 1753 ownerThread = "{0:{base}}".format(owner, base=base) 1754 portlabel_id = info.get('portlabel_id', 0) 1755 flags = info.get('wait_flags', 0) 1756 1757 if type == kThreadWaitKernelMutex: 1758 s += 'kernel mutex %x' % context 1759 if owner == STACKSHOT_WAITOWNER_MTXSPIN: 1760 s += " in spin mode" 1761 elif owner: 1762 s += " owned by thread %s" % ownerThread 1763 else: 1764 s += "with unknown owner" 1765 elif type == kThreadWaitPortReceive: 1766 s += "mach_msg receive on " 1767 if flags & STACKSHOT_WAITINFO_FLAGS_SPECIALREPLY: 1768 s += "REPLY " 1769 flags = flags - STACKSHOT_WAITINFO_FLAGS_SPECIALREPLY 1770 if owner == STACKSHOT_WAITOWNER_PORT_LOCKED: 1771 s += "locked port %x" % context 1772 elif owner == STACKSHOT_WAITOWNER_INTRANSIT: 1773 s += "intransit port %x" % context 1774 elif owner: 1775 s += "port %x name %x" % (context, owner) 1776 else: 1777 s += "port %x" % context 1778 elif type == kThreadWaitPortSetReceive: 1779 if owner == STACKSHOT_WAITOWNER_PSET_LOCKED: 1780 s += "mach_msg receive on locked port set %x" % context 1781 else: 1782 s += "mach_msg receive on port set %x" % context 1783 elif type == kThreadWaitPortSend: 1784 s += "mach_msg send on " 1785 if owner == STACKSHOT_WAITOWNER_PORT_LOCKED: 1786 s += "locked port %x" % context 1787 elif owner == STACKSHOT_WAITOWNER_INTRANSIT: 1788 s += "intransit port %x" % context 1789 elif owner == STACKSHOT_WAITOWNER_KERNEL: 1790 s += "port %x owned by kernel" % context 1791 elif owner: 1792 s += "port %x owned by pid %d" % (context, owner) 1793 else: 1794 s += "port %x with unknown owner" % context 1795 elif type == kThreadWaitPortSendInTransit: 1796 s += "mach_msg send on port %x in transit to " % context 1797 if owner: 1798 s += "port %x" % owner 1799 else: 1800 s += "unknown port" 1801 elif type == kThreadWaitSemaphore: 1802 s += "semaphore port %x " % context 1803 if owner: 1804 s += "owned by pid %d" % owner 1805 else: 1806 s += "with unknown owner" 1807 elif type == kThreadWaitKernelRWLockRead: 1808 s += "krwlock %x for reading" % context 1809 if owner: 1810 s += " owned by thread %s" % ownerThread 1811 elif type == kThreadWaitKernelRWLockWrite: 1812 s += "krwlock %x for writing" % context 1813 if owner: 1814 s += " owned by thread %s" % ownerThread 1815 elif type == kThreadWaitKernelRWLockUpgrade: 1816 s += "krwlock %x for upgrading" % context 1817 if owner: 1818 s += " owned by thread %s" % ownerThread 1819 elif type == kThreadWaitUserLock: 1820 if owner: 1821 s += "unfair lock %x owned by thread %s" % (context, ownerThread) 1822 else: 1823 s += "spin lock %x" % context 1824 elif type == kThreadWaitPThreadMutex: 1825 s += "pthread mutex %x" % context 1826 if owner: 1827 s += " owned by thread %s" % ownerThread 1828 else: 1829 s += " with unknown owner" 1830 elif type == kThreadWaitPThreadRWLockRead: 1831 s += "pthread rwlock %x for reading" % context 1832 elif type == kThreadWaitPThreadRWLockWrite: 1833 s += "pthread rwlock %x for writing" % context 1834 elif type == kThreadWaitPThreadCondVar: 1835 s += "pthread condvar %x" % context 1836 elif type == kThreadWaitWorkloopSyncWait: 1837 s += "workloop sync wait" 1838 if owner == STACKSHOT_WAITOWNER_SUSPENDED: 1839 s += ", suspended" 1840 elif owner == STACKSHOT_WAITOWNER_THREQUESTED: 1841 s += ", thread requested" 1842 elif owner != 0: 1843 s += ", owned by thread %s" % ownerThread 1844 else: 1845 s += ", unknown owner" 1846 s += ", workloop id %x" % context 1847 elif type == kThreadWaitOnProcess: 1848 if owner == 2**64-1: 1849 s += "waitpid, for any children" 1850 elif 2**32 <= owner and owner < 2**64-1: 1851 s += "waitpid, for process group %d" % abs(owner - 2**64) 1852 else: 1853 s += "waitpid, for pid %d" % owner 1854 elif type == kThreadWaitSleepWithInheritor: 1855 if owner == 0: 1856 s += "turnstile, held waitq" 1857 else: 1858 s += "turnstile, pushing thread %s" % ownerThread 1859 elif type == kThreadWaitEventlink: 1860 if owner == 0: 1861 s += "eventlink, held waitq" 1862 else: 1863 s += "eventlink, signaled by thread %s" % ownerThread 1864 elif type == kThreadWaitCompressor: 1865 s += "in compressor segment %x, busy for thread %s" % (context, ownerThread) 1866 elif type == kThreadWaitExclaveCore: 1867 if owner == 0: 1868 s += "exclavecore wait, id 0x%x" % context 1869 else: 1870 s += "exclavecore wait, id 0x%x, owner thread %s" % (context, ownerThread) 1871 elif type == kThreadWaitExclaveKit: 1872 if owner == 0: 1873 s += "exclavekit wait, id 0x%x" % context 1874 else: 1875 s += "exclavekit wait, id 0x%x, owner thread %s" % (context, ownerThread) 1876 elif type == kThreadWaitPageBusy: 1877 s += f"busy page 0x{context:x}" 1878 elif type == kThreadWaitPagerInit: 1879 s += f"pager initialization for vm object 0x{context:x}" 1880 elif type == kThreadWaitPagerReady: 1881 s += f"pager ready for vm object 0x{context:x}" 1882 elif type == kThreadWaitPagingActivity: 1883 s += f"paging/activity in progress for vm object 0x{context:x}" 1884 elif type == kThreadWaitMappingInProgress: 1885 s += f"mapping in progress for vm object 0x{context:x}" 1886 elif type == kThreadWaitMemoryBlocked: 1887 s += f"blocked vm object 0x{context:x}" 1888 elif type == kThreadWaitPagingInProgress: 1889 s += f"paging in progress for vm object 0x{context:x}" 1890 elif type == kThreadWaitPageInThrottle: 1891 s += f"throttled vm object 0x{context:x}" 1892 else: 1893 s += "unknown type %d (owner %s, context %x)" % (type, ownerThread, context) 1894 1895 s += formatPortLabelID(portlabel_id, portlabels) 1896 1897 if flags != 0: 1898 s += "flags {}".format(hex(flags)) 1899 return s 1900 1901def formatTurnstileInfo(ti, wi_portlabel_id, portlabels): 1902 if ti is None: 1903 return " [no turnstile]" 1904 1905 ts_flags = int(ti['turnstile_flags']) 1906 ctx = int(ti['turnstile_context']) 1907 hop = int(ti['number_of_hops']) 1908 prio = int(ti['turnstile_priority']) 1909 portlabel_id = ti.get("portlabel_id", 0) 1910 1911 portlabel_summary = "" 1912 if portlabel_id != 0 and portlabel_id != wi_portlabel_id: 1913 portlabel_summary += formatPortLabelID(portlabel_id, portlabels) 1914 1915 if ts_flags & STACKSHOT_TURNSTILE_STATUS_HELD_IPLOCK: 1916 return " [turnstile blocked on task, but ip_lock was held]" + portlabel_summary 1917 if ts_flags & STACKSHOT_TURNSTILE_STATUS_BLOCKED_ON_TASK: 1918 return " [turnstile blocked on task pid %d, hops: %d, priority: %d]%s" % (ctx, hop, prio, portlabel_summary) 1919 if ts_flags & STACKSHOT_TURNSTILE_STATUS_LOCKED_WAITQ: 1920 return " [turnstile was in process of being updated]" + portlabel_summary 1921 if ts_flags & STACKSHOT_TURNSTILE_STATUS_WORKQUEUE: 1922 return " [blocked on workqueue: 0x%x, hops: %x, priority: %d]%s" % (ctx, hop, prio, portlabel_summary) 1923 if ts_flags & STACKSHOT_TURNSTILE_STATUS_THREAD: 1924 return " [blocked on: %d, hops: %x, priority: %d]%s" % (ctx, hop, prio, portlabel_summary) 1925 if ts_flags & STACKSHOT_TURNSTILE_STATUS_UNKNOWN: 1926 return " [turnstile with unknown inheritor]" + portlabel_summary 1927 1928 return " [unknown turnstile status!]" + portlabel_summary 1929 1930def formatWaitInfoWithTurnstiles(waitinfos, tsinfos, portlabels): 1931 wis_tis = [] 1932 for w in waitinfos: 1933 found_pair = False 1934 for t in tsinfos: 1935 if int(w['waiter']) == int(t['waiter']): 1936 wis_tis.append((w, t)) 1937 found_pair = True 1938 break 1939 if not found_pair: 1940 wis_tis.append((w, None)) 1941 1942 return [formatWaitInfo(wi, False, portlabels) + formatTurnstileInfo(ti, wi.get('portlabel_id', 0), portlabels) for (wi, ti) in wis_tis] 1943 1944 1945def FindTextLayout(text_layouts, text_layout_id): 1946 for layout in text_layouts.values(): 1947 if layout['exclave_textlayout_info']['layout_id'] == text_layout_id: 1948 return layout 1949 return None 1950 1951def BinaryImagesFromExclavesLayout(textlayout): 1952 flags = textlayout['exclave_textlayout_info']['etl_flags'] 1953 sharedCacheIndex = textlayout['exclave_textlayout_info'].get('sharedcache_index', 0xffffffff) 1954 layouts = [ [format_uuid(layout['layoutSegment_uuid']), layout['layoutSegment_loadAddress'], 'P'] for layout in textlayout['exclave_textlayout_segments'] ] 1955 # 0x4 == kExclaveTextLayoutHasSharedCache 1956 if ((flags & 0x4) != 0 and sharedCacheIndex < len(layouts)): 1957 layouts[sharedCacheIndex][2] = "S" 1958 layouts.sort(key=itemgetter(1)) 1959 return layouts 1960 1961def GetExclaveLibs(text_layouts, text_layout_id): 1962 textlayout = text_layouts.get(str(text_layout_id)) 1963 1964 # This fallback is needed to preserve compatibility with kcdata generated before rdar://123838752 1965 # FindTextLayout function should be removed in future 1966 if not textlayout or textlayout['exclave_textlayout_info']['layout_id'] != text_layout_id: 1967 textlayout = FindTextLayout(text_layouts, text_layout_id) 1968 1969 return BinaryImagesFromExclavesLayout(textlayout) 1970 1971# kcdata is json at path 'kcdata_stackshot/threads_exclave/0' 1972def GetEASFrames(AllImageCatalog, kcdata, ipc_entry, notes, scid): 1973 info = ipc_entry['exclave_ipcstackentry_info'] 1974 asid = info['eise_asid'] 1975 1976 address_spaces = kcdata.get('exclave_addressspace') 1977 if not address_spaces: 1978 notes.warn("PID ${PID} TID ${TID} SCID %d Missing address spaces info" % scid) 1979 return [] 1980 as_info = address_spaces.get(str(asid)) 1981 if not as_info: 1982 notes.warn("PID ${PID} TID ${TID} SCID %d Missing address space info for ASID 0x%x" % (scid, asid)) 1983 return [] 1984 text_layout_id = as_info['exclave_addressspace_info']['eas_layoutid'] 1985 addr_space_name = as_info['exclave_addressspace_name'] 1986 1987 exclave_libs = GetExclaveLibs(kcdata['exclave_textlayout'], text_layout_id) 1988 1989 frames = [] 1990 stack = ipc_entry.get('secure_ecstack_entry', []) 1991 for stack_item in stack: 1992 lr = GetLongForAddress(stack_item['lr']) 1993 # this is a buggy value of unknown origin 1994 # rdar://123508690 (Some Exclave Stackshot frames ends with invalid value 0xFFFF000000000000) 1995 if lr == 0xFFFF000000000000: 1996 continue 1997 frames.append(GetSymbolInfoForFrame(AllImageCatalog, exclave_libs, lr)) 1998 1999 if frames: 2000 frame_info = "frames %d to %d" % (notes.offset, notes.offset + len(frames) - 1) 2001 else: 2002 frame_info = "no frames" 2003 notes.info("PID ${PID} TID ${TID} SCID %d ASID 0x%x has address space name '%s' (%s)" % (scid, asid, addr_space_name, frame_info)) 2004 notes.addToOffset(len(frames)) 2005 return frames 2006 2007 2008def GetExclavesFrames(AllImageCatalog, json, scid, notes): 2009 kcdata = json['kcdata_stackshot'] 2010 threads_exclave = kcdata.get('threads_exclave') 2011 if not threads_exclave: 2012 notes.warn("PID ${PID} TID ${TID} no threads_exclave info found, skipping exclaves frames") 2013 return [] 2014 2015 exclaves_content = threads_exclave.get('0') 2016 if not exclaves_content: 2017 notes.warn("PID ${PID} TID ${TID} threads_exclave data not found, skipping exclaves frames") 2018 return [] 2019 2020 threads_info = exclaves_content.get('thread_exclave') 2021 if not threads_info: 2022 notes.warn("PID ${PID} TID ${TID} no thread_exclave info found, skipping exclaves frames") 2023 return [] 2024 2025 scid_info = threads_info.get(str(scid)) 2026 if not scid_info: 2027 notes.warn("PID ${PID} TID ${TID} no exclaves info available for SCID %d, skipping exclaves frames" % scid) 2028 return [] 2029 2030 frames = [] 2031 2032 ipc_stack = scid_info.get("exclave_ipcstackentry") 2033 if not ipc_stack: 2034 notes.info("\nPID ${PID} TID ${TID} SCID %d IPC chain is missing" % scid) 2035 return [] 2036 notes.info("\nPID ${PID} TID ${TID} SCID %d has IPC chain with %d items:" % (scid, len(ipc_stack))) 2037 for i in reversed(range(len(ipc_stack))): 2038 ipc_entry = ipc_stack[str(i)] 2039 entry_frames = GetEASFrames(AllImageCatalog, exclaves_content, ipc_entry, notes, scid) 2040 frames.extend(entry_frames) 2041 2042 return frames 2043 2044 2045def InsertExclavesFrames(AllImageCatalog, json, thdata, notes, kernel_frames): 2046 thread_info = thdata.get('exclaves_thread_info') 2047 if not thread_info: 2048 # this is not exclave thread 2049 return 2050 2051 scid = thread_info["tei_scid"] 2052 offset = thread_info["tei_thread_offset"] 2053 notes.offset = offset 2054 2055 exclaves_frames = GetExclavesFrames(AllImageCatalog, json, scid, notes) 2056 2057 # insert exclaves frames to offset 2058 for i in range(len(exclaves_frames)): 2059 kernel_frames.insert(offset + i, exclaves_frames[i]) 2060 2061class NotesBuilder: 2062 2063 notes = [] 2064 pid = None 2065 tis = None 2066 offset = 0 2067 2068 def __init__(self, pid, tid): 2069 self.pid = pid 2070 self.tid = tid 2071 self.notes = [] 2072 self.offset = 0 # offset of next IPC stack in kernel stack 2073 2074 # Replace ${PID} with a PID and ${TID} with TID and add newline 2075 def format(self, note): 2076 note = note.replace('${PID}', str(self.pid)) 2077 note = note.replace('${TID}', str(self.tid)) 2078 return note + '\n' 2079 2080 def warn(self, note): 2081 note = self.format(note) 2082 sys.stdout.write(note) 2083 self.notes.append(note) 2084 2085 def info(self, note): 2086 note = self.format(note) 2087 self.notes.append(note) 2088 2089 def isEmpty(self): 2090 return len(self.notes) == 0 2091 2092 def text(self): 2093 return ''.join(self.notes) 2094 2095 def addToOffset(self, frame_count): 2096 self.offset += frame_count 2097 2098def SaveStackshotReport(j, outfile_name, incomplete): 2099 import time 2100 ss = j.get('kcdata_stackshot') 2101 if not ss: 2102 print("No KCDATA_BUFFER_BEGIN_STACKSHOT object found. Skipping writing report.") 2103 return 2104 2105 timestamp = ss.get('usecs_since_epoch') 2106 try: 2107 timestamp = time.strftime("%Y-%m-%d %H:%M:%S +0000",time.gmtime(timestamp // 1000000 if timestamp else None)) 2108 except ValueError as e: 2109 print("couldn't convert timestamp:", str(e)) 2110 timestamp = None 2111 2112 os_version = ss.get('osversion', 'Unknown') 2113 timebase = ss.get('mach_timebase_info', {"denom": 1, "numer": 1}) 2114 2115 sc_note = None 2116 extra_note = None 2117 dsc_common = None 2118 shared_cache_info = ss.get('shared_cache_dyld_load_info') 2119 if shared_cache_info: 2120 shared_cache_base_addr = shared_cache_info['imageSlidBaseAddress'] 2121 # If we have a slidFirstMapping and it's >= base_address, use that. 2122 # 2123 # Otherwise we're processing a stackshot from before the slidFirstMapping 2124 # field was introduced and corrected. On ARM the SlidBaseAddress is the 2125 # same, but on x86 it's off by 0x20000000. We use 'X86_64' in the 2126 # kernel version string plus checking kern_page_size == 4k' as 2127 # proxy for x86_64, and only adjust SlidBaseAddress if the unslid 2128 # address is precisely the expected incorrect value. 2129 # 2130 is_intel = ('X86_64' in ss.get('osversion', "") and 2131 ss.get('kernel_page_size', 0) == 4096) 2132 slidFirstMapping = shared_cache_info.get(SC_SLID_FIRSTMAPPING_KEY, -1) 2133 if slidFirstMapping >= shared_cache_base_addr: 2134 shared_cache_base_addr = slidFirstMapping 2135 sc_note = "base-accurate" 2136 2137 elif is_intel: 2138 sc_slide = shared_cache_info['imageLoadAddress'] 2139 if (shared_cache_base_addr - sc_slide) == 0x7fff00000000: 2140 shared_cache_base_addr += 0x20000000 2141 sc_note = "base-x86-adjusted" 2142 extra_note = "Shared cache base adjusted for x86. " 2143 else: 2144 sc_note = "base-x86-unknown" 2145 2146 dsc_common = [format_uuid(shared_cache_info['imageUUID']), 2147 shared_cache_base_addr, "S" ] 2148 print("Shared cache UUID found from the binary data is <%s> " % str(dsc_common[0])) 2149 2150 dsc_layout = ss.get('system_shared_cache_layout') 2151 2152 dsc_libs = [] 2153 if dsc_layout: 2154 print("Found in memory system shared cache layout with {} images".format(len(dsc_layout))) 2155 slide = ss.get('shared_cache_dyld_load_info')['imageLoadAddress'] 2156 2157 for image in dsc_layout: 2158 dsc_libs.append([format_uuid(image['imageUUID']), image['imageLoadAddress'] + slide, "C"]) 2159 2160 AllImageCatalog = [] 2161 obj = {} 2162 obj["kernel"] = os_version 2163 if timestamp is not None: 2164 obj["date"] = timestamp 2165 obj["reason"] = "kernel panic stackshot" 2166 obj["incident"] = "ABCDEFGH-1234-56IJ-789K-0LMNOPQRSTUV" 2167 obj["crashReporterKey"] = "12ab34cd45aabbccdd6712ab34cd45aabbccdd67" 2168 obj["bootArgs"] = ss.get('boot_args','') 2169 obj["frontmostPids"] = [0] 2170 obj["exception"] = "0xDEADF157" 2171 obj["processByPid"] = {} 2172 if sc_note is not None: 2173 obj["sharedCacheNote"] = sc_note 2174 2175 if incomplete: 2176 obj["reason"] = "!!!INCOMPLETE!!! kernel panic stackshot" 2177 obj["notes"] = "Generated by xnu kcdata.py from incomplete data! Some information is missing! " 2178 else: 2179 obj["notes"] = "Generated by xnu kcdata.py. " 2180 2181 if extra_note is not None: 2182 obj["notes"] = obj["notes"] + extra_note 2183 2184 processByPid = obj["processByPid"] 2185 ssplist = ss.get('task_snapshots', {}) 2186 ssplist.update(ss.get('transitioning_task_snapshots', {})) 2187 kern_load_info = [] 2188 if "0" in ssplist: 2189 kc_uuid = ssplist["0"].get('kernelcache_load_info', None) 2190 if kc_uuid: 2191 kernelcache_uuid = [format_uuid(kc_uuid['imageUUID']), kc_uuid['imageLoadAddress'], "U" ] 2192 kern_load_info.append(kernelcache_uuid) 2193 2194 kl_infos = ssplist["0"].get("dyld_load_info", []) 2195 for dlinfo in kl_infos: 2196 kern_load_info.append([format_uuid(dlinfo['imageUUID']), dlinfo['imageLoadAddress'], "K"]) 2197 2198 kl_infos_text_exec = ssplist["0"].get("dyld_load_info_text_exec", []) 2199 for dlinfo in kl_infos_text_exec: 2200 kern_load_info.append([format_uuid(dlinfo['imageUUID']), dlinfo['imageLoadAddress'], "T"]) 2201 2202 for pid,piddata in sorted(ssplist.items()): 2203 processByPid[str(pid)] = {} 2204 tsnap = processByPid[str(pid)] 2205 pr_lib_dsc = dsc_common 2206 2207 # see if there's an alternate shared cache 2208 scd = piddata.get('shared_cache_dyld_load_info') 2209 if scd is not None: 2210 if 'imageSlidBaseAddress' not in scd: 2211 print("Specific task shared cache format does not include slid shared cache base address. Skipping writing report.") 2212 return 2213 2214 scd_uuid = format_uuid(scd['imageUUID']) 2215 scd_base_addr = scd['imageSlidBaseAddress'] 2216 pr_lib_dsc = [scd_uuid, scd_base_addr, "S"] 2217 2218 pr_libs = [] 2219 if len(dsc_libs) == 0 and pr_lib_dsc: 2220 pr_libs.append(pr_lib_dsc) 2221 _lib_type = "P" 2222 if int(pid) == 0: 2223 _lib_type = "K" 2224 pr_libs = [] 2225 else: 2226 for dlinfo in piddata.get('dyld_load_info',[]): 2227 pr_libs.append([format_uuid(dlinfo['imageUUID']), dlinfo['imageLoadAddress'], _lib_type]) 2228 2229 pr_libs.extend(kern_load_info) 2230 pr_libs.extend(dsc_libs) 2231 2232 if 'jit_address_range' in piddata: 2233 address_range = piddata.get('jit_address_range', {}) 2234 tsnap['jitStartAddress'] = address_range['start_address'] 2235 tsnap['jitEndAddress'] = address_range['end_address'] 2236 pr_libs.append([format_uuid("00000000000000000000000000000000"), tsnap['jitStartAddress'] , "J"]) 2237 pr_libs.sort(key=itemgetter(1)) 2238 ttsnap = piddata.get('transitioning_task_snapshot', None) 2239 if ttsnap is not None: 2240 # Transitioning task snapshots have "tts_" prefixes; change them to 2241 # "ts_". 2242 ttsnap = { key[1:] : value for key,value in ttsnap.items() } 2243 # Add a note to let people know 2244 obj["notes"] = obj["notes"] + "PID {} is a transitioning (exiting) task. ".format(pid) 2245 tasksnap = piddata.get('task_snapshot', ttsnap) 2246 if tasksnap is None: 2247 continue 2248 tsnap["pid"] = tasksnap["ts_pid"] 2249 if 'ts_asid' in piddata: 2250 tsnap["asid"] = piddata["ts_asid"] 2251 2252 if 'ts_pagetable' in piddata: 2253 pagetables = [] 2254 for tte in piddata["ts_pagetable"]: 2255 pagetables.append(tte) 2256 tsnap["pageTables"] = pagetables 2257 2258 # Some fields are missing from transitioning_task snapshots. 2259 if ttsnap is None: 2260 tsnap["residentMemoryBytes"] = tasksnap["ts_task_size"] 2261 tsnap["timesDidThrottle"] = tasksnap["ts_did_throttle"] 2262 tsnap["systemTimeTask"] = GetSecondsFromMATime(tasksnap["ts_system_time_in_terminated_th"], timebase) 2263 tsnap["pageIns"] = tasksnap["ts_pageins"] 2264 tsnap["pageFaults"] = tasksnap["ts_faults"] 2265 tsnap["userTimeTask"] = GetSecondsFromMATime(tasksnap["ts_user_time_in_terminated_thre"], timebase) 2266 tsnap["procname"] = tasksnap["ts_p_comm"] 2267 if ttsnap is None: 2268 tsnap["copyOnWriteFaults"] = tasksnap["ts_cow_faults"] 2269 tsnap["timesThrottled"] = tasksnap["ts_was_throttled"] 2270 tsnap["threadById"] = {} 2271 threadByID = tsnap["threadById"] 2272 thlist = piddata.get('thread_snapshots', {}) 2273 for tid,thdata in sorted(thlist.items()): 2274 threadByID[str(tid)] = {} 2275 thsnap = threadByID[str(tid)] 2276 if "thread_snapshot" not in thdata: 2277 print("Found broken thread state for thread ID: %s." % tid) 2278 break 2279 threadsnap = thdata["thread_snapshot"] 2280 thsnap["userTime"] = GetSecondsFromMATime(threadsnap["ths_user_time"], timebase) 2281 thsnap["id"] = threadsnap["ths_thread_id"] 2282 thsnap["basePriority"] = threadsnap["ths_base_priority"] 2283 thsnap["systemTime"] = GetSecondsFromMATime(threadsnap["ths_sys_time"], timebase) 2284 thsnap["schedPriority"] = threadsnap["ths_sched_priority"] 2285 thsnap["state"] = GetStateDescription(threadsnap['ths_state']) 2286 thsnap["qosEffective"] = threadsnap["ths_eqos"] 2287 thsnap["qosRequested"] = threadsnap["ths_rqos"] 2288 2289 if "pth_name" in thdata: 2290 thsnap["name"] = thdata["pth_name"] 2291 2292 if threadsnap['ths_continuation']: 2293 thsnap["continuation"] = GetSymbolInfoForFrame(AllImageCatalog, pr_libs, threadsnap['ths_continuation']) 2294 if "kernel_stack_frames" in thdata: 2295 kuserframes = [] 2296 for f in thdata["kernel_stack_frames"]: 2297 kuserframes.append(GetSymbolInfoForFrame(AllImageCatalog, pr_libs, f['lr'])) 2298 notesBuilder = NotesBuilder(tsnap['pid'], tid) 2299 InsertExclavesFrames(AllImageCatalog, j, thdata, notesBuilder, kuserframes) 2300 if not notesBuilder.isEmpty(): 2301 obj['notes'] += notesBuilder.text() 2302 thsnap["kernelFrames"] = kuserframes 2303 2304 if "user_stack_frames" in thdata: 2305 uframes = [] 2306 for f in thdata["user_stack_frames"]: 2307 uframes.append(GetSymbolInfoForFrame(AllImageCatalog, pr_libs, f['lr'])) 2308 thsnap["userFrames"] = uframes 2309 2310 if "user_stacktop" in thdata: 2311 (address,) = struct.unpack("<Q", struct.pack("B"*8, *thdata["user_stacktop"]["stack_contents"])) 2312 thsnap["userStacktop"] = GetSymbolInfoForFrame(AllImageCatalog, pr_libs, address) 2313 2314 if threadsnap['ths_wait_event']: 2315 thsnap["waitEvent"] = GetSymbolInfoForFrame(AllImageCatalog, pr_libs, threadsnap['ths_wait_event']) 2316 2317 if 'thread_waitinfo' in piddata and 'thread_turnstileinfo' in piddata: 2318 tsnap['waitInfo'] = formatWaitInfoWithTurnstiles(piddata['thread_waitinfo'], piddata['thread_turnstileinfo'], piddata.get('portlabels', None)) 2319 elif 'thread_waitinfo' in piddata: 2320 portlabels = ss.get('portlabels', None) 2321 tsnap['waitInfo'] = [formatWaitInfo(x, False, portlabels) for x in piddata['thread_waitinfo']] 2322 if 'stackshot_task_codesigning_info' in piddata: 2323 csinfo = piddata.get('stackshot_task_codesigning_info', {}) 2324 tsnap['csFlags'] = csinfo['csflags'] 2325 tsnap['csTrustLevel'] = csinfo['cs_trust_level'] 2326 if 'suspension_info' in piddata: 2327 suspinfo = piddata.get('suspension_info', {}) 2328 tsnap['suspension_count'] = suspinfo['tss_count'] 2329 tsnap['suspension_duration_secs'] = GetSecondsFromMATime(suspinfo['tss_duration'], timebase) 2330 tsnap['suspension_last_start'] = GetSecondsFromMATime(suspinfo['tss_last_start'], timebase) 2331 tsnap['suspension_last_end'] = GetSecondsFromMATime(suspinfo['tss_last_end'], timebase) 2332 2333 suspsources = piddata.get('suspension_source', []) 2334 suspension_sources = [] 2335 for source in filter(lambda x: x['tss_time'] != 0, suspsources): 2336 suspension_sources.append({ 2337 'suspension_time': GetSecondsFromMATime(source['tss_time'], timebase), 2338 'suspension_tid': source['tss_tid'], 2339 'suspension_pid': source['tss_pid'], 2340 'suspension_procname': source['tss_procname'], 2341 }) 2342 2343 tsnap['suspension_sources'] = suspension_sources 2344 # check if process is currently suspended 2345 if tsnap['suspension_last_start'] > tsnap['suspension_last_end']: 2346 obj['notes'] += "\nPID {} ({}) is currently suspended (count: {}, total duration: {:.4f}s, last_start: {:.4f}, last_end: {:.4f}) - recent suspensions are:\n".format(pid, tsnap['procname'], tsnap['suspension_count'], tsnap['suspension_duration_secs'], tsnap['suspension_last_start'], tsnap['suspension_last_end']) 2347 for source in suspension_sources: 2348 obj['notes'] += "From PID {} TID {} ({}) - at {}\n".format(source['suspension_pid'], source['suspension_tid'], source['suspension_procname'], source['suspension_time']) 2349 2350 obj['binaryImages'] = AllImageCatalog 2351 if outfile_name == '-': 2352 fh = sys.stdout 2353 else: 2354 fh = open(outfile_name, "w") 2355 2356 header = {} 2357 header['bug_type'] = 288 2358 if timestamp is not None: 2359 header['timestamp'] = timestamp 2360 header['os_version'] = os_version 2361 fh.write(json.dumps(header, sort_keys=True)) 2362 fh.write("\n") 2363 2364 fh.write(json.dumps(obj, sort_keys=True, indent=2, separators=(',', ': '))) 2365 fh.close() 2366 2367 2368@contextlib.contextmanager 2369def data_from_stream(stream): 2370 try: 2371 fmap = mmap.mmap(stream.fileno(), 0, mmap.MAP_SHARED, mmap.PROT_READ) 2372 except Exception: 2373 yield stream.buffer.read() 2374 else: 2375 try: 2376 yield fmap 2377 finally: 2378 fmap.close() 2379 2380def iterate_kcdatas(kcdata_file): 2381 with data_from_stream(kcdata_file) as data: 2382 iterator = kcdata_item_iterator(data) 2383 kcdata_buffer = KCObject.FromKCItem(next(iterator)) 2384 2385 if isinstance(kcdata_buffer, KCCompressedBufferObject): 2386 kcdata_buffer.ReadItems(iterator) 2387 decompressed = kcdata_buffer.Decompress(data) 2388 iterator = kcdata_item_iterator(decompressed) 2389 kcdata_buffer = KCObject.FromKCItem(next(iterator)) 2390 2391 if not isinstance(kcdata_buffer, KCBufferObject): 2392 # ktrace stackshot chunk 2393 iterator = kcdata_item_iterator(data[16:]) 2394 kcdata_buffer = KCObject.FromKCItem(next(iterator)) 2395 2396 if not isinstance(kcdata_buffer, KCBufferObject): 2397 try: 2398 decoded = base64.b64decode(data) 2399 except Exception: 2400 pass 2401 else: 2402 iterator = kcdata_item_iterator(decoded) 2403 kcdata_buffer = KCObject.FromKCItem(next(iterator)) 2404 if not isinstance(kcdata_buffer, KCBufferObject): 2405 import gzip 2406 from io import BytesIO 2407 try: 2408 decompressed = gzip.GzipFile(fileobj=BytesIO(data[:])).read() 2409 except Exception: 2410 pass 2411 else: 2412 iterator = kcdata_item_iterator(decompressed) 2413 kcdata_buffer = KCObject.FromKCItem(next(iterator)) 2414 2415 if not isinstance(kcdata_buffer, KCBufferObject): 2416 raise Exception("unknown file type") 2417 2418 2419 kcdata_buffer.ReadItems(iterator) 2420 yield kcdata_buffer 2421 2422 for magic in iterator: 2423 kcdata_buffer = KCObject.FromKCItem(magic) 2424 if kcdata_buffer.i_type == 0: 2425 continue 2426 if not isinstance(kcdata_buffer, KCBufferObject): 2427 raise Exception("unknown file type") 2428 kcdata_buffer.ReadItems(iterator) 2429 yield kcdata_buffer 2430 2431# 2432# Values for various flag fields. Each entry's key is the key seen in the 2433# processed kcdata, the value is an array of bits, from low (0x1) to high, with 2434# either a string flag name or None for unused holes. 2435# 2436# Only put flags in here which are stable - this is run against stackshots 2437# of all different versions. For anything unstable, we'll need a decoder ring 2438# added to the stackshot. 2439# 2440PRETTIFY_FLAGS = { 2441 'jcs_flags': [ 2442 'kCoalitionTermRequested', 2443 'kCoalitionTerminated', 2444 'kCoalitionReaped', 2445 'kCoalitionPrivileged', 2446 ], 2447 'sharedCacheFlags': [ 2448 'kSharedCacheSystemPrimary', 2449 'kSharedCacheDriverkit' 2450 'kSharedCacheAOT', 2451 ], 2452 'stackshot_in_flags': [ # STACKSHOT_*, also stackshot_out_flags 2453 'get_dq', 2454 'save_loadinfo', 2455 'get_global_mem_stats', 2456 'save_kext_loadinfo', 2457 None, 2458 None, 2459 None, 2460 None, 2461 'active_kernel_threads_only', 2462 'get_boot_profile', 2463 'do_compress', 2464 None, 2465 None, 2466 'save_imp_donation_pids', 2467 'save_in_kernel_buffer', 2468 'retrieve_existing_buffer', 2469 'kcdata_format', 2470 'enable_bt_faulting', 2471 'collect_delta_snapshot', 2472 'collect_sharedcache_layout', 2473 'trylock', 2474 'enable_uuid_faulting', 2475 'from_panic', 2476 'no_io_stats', 2477 'thread_waitinfo', 2478 'thread_group', 2479 'save_jetsam_coalitions', 2480 'instrs_cycles', 2481 'asid', 2482 'page_tables', 2483 'disable_latency_info', 2484 'save_dyld_compactinfo', 2485 'include_driver_threads_in_kernel', 2486 'exclaves', 2487 ], 2488 'system_state_flags': [ 2489 'kUser64_p', 2490 'kKern64_p', 2491 ], 2492 'tgs_flags': [ 2493 'kThreadGroupEfficient', 2494 'kThreadGroupApplication', 2495 'kThreadGroupCritical', 2496 'kThreadGroupBestEffort', 2497 None, 2498 None, 2499 None, 2500 None, 2501 'kThreadGroupUIApplication', 2502 'kThreadGroupManaged', 2503 'kThreadGroupStrictTimers', 2504 ], 2505 'ths_ss_flags': [ 2506 'kUser64_p', 2507 'kKern64_p', 2508 'kHasDispatchSerial', 2509 'kStacksPCOnly', 2510 'kThreadDarwinBG', 2511 'kThreadIOPassive', 2512 'kThreadSuspended', 2513 'kThreadTruncatedBT', 2514 'kGlobalForcedIdle', 2515 'kThreadFaultedBT', 2516 'kThreadTriedFaultBT', 2517 'kThreadOnCore', 2518 'kThreadIdleWorker', 2519 'kThreadMain', 2520 'kThreadTruncKernBT', 2521 'kThreadTruncUserBT', 2522 'kThreadTruncUserAsyncBT', 2523 'kThreadExclaveRPCActive', 2524 'kThreadExclaveUpcallActive', 2525 'kThreadExclaveSchedulerRequest', 2526 ], 2527 'ths_state': [ 2528 'TH_WAIT', 2529 'TH_SUSP', 2530 'TH_RUN', 2531 'TH_UNINT', 2532 'TH_TERMINATE', 2533 'TH_TERMINATE2', 2534 'TH_WAIT_REPORT', 2535 'TH_IDLE', 2536 'TH_WAKING', 2537 ], 2538 'ts_ss_flags': [ 2539 'kUser64_p', 2540 'kKern64_p', 2541 'kTaskRsrcFlagged', 2542 'kTerminatedSnapshot', 2543 'kPidSuspended', 2544 'kFrozen', 2545 'kTaskDarwinBG', 2546 'kTaskExtDarwinBG', 2547 'kTaskVisVisible', 2548 'kTaskVisNonvisible', 2549 'kTaskIsForeground', 2550 'kTaskIsBoosted', 2551 'kTaskIsSuppressed', 2552 'kTaskIsTimerThrottled', 2553 'kTaskIsImpDonor', 2554 'kTaskIsLiveImpDonor', 2555 'kTaskIsDirty', 2556 'kTaskWqExceededConstrainedThreadLimit', 2557 'kTaskWqExceededTotalThreadLimit', 2558 'kTaskWqFlagsAvailable', 2559 'kTaskUUIDInfoFaultedIn', 2560 'kTaskUUIDInfoMissing', 2561 'kTaskUUIDInfoTriedFault', 2562 'kTaskSharedRegionInfoUnavailable', 2563 'kTaskTALEngaged', 2564 None, 2565 'kTaskIsDirtyTracked', 2566 'kTaskAllowIdleExit', 2567 'kTaskIsTranslated', 2568 'kTaskSharedRegionNone', 2569 'kTaskSharedRegionSystem', 2570 'kTaskSharedRegionOther', 2571 'kTaskDyldCompactInfoNone', 2572 'kTaskDyldCompactInfoTooBig', 2573 'kTaskDyldCompactInfoFaultedIn', 2574 'kTaskDyldCompactInfoMissing', 2575 'kTaskDyldCompactInfoTriedFault', 2576 'kTaskWqExceededCooperativeThreadLimit', 2577 'kTaskWqExceededActiveConstrainedThreadLimit', 2578 'kTaskRunawayMitigated', 2579 'kTaskIsActive', 2580 'kTaskIsManaged', 2581 'kTaskHasAssertion', 2582 ], 2583 'turnstile_flags': [ 2584 'turnstile_status_unknown', 2585 'turnstile_status_locked_waitq', 2586 'turnstile_status_workqueue', 2587 'turnstile_status_thread', 2588 'turnstile_status_blocked_on_task', 2589 'turnstile_status_held_iplock', 2590 ], 2591 'portlabel_flags': [ 2592 'label_read_failed', 2593 'service_throttled', 2594 ], 2595 'esc_flags': [ 2596 'kExclaveScresultHaveIPCStack', 2597 ], 2598 'eise_flags': [ 2599 'kExclaveIpcStackEntryHaveInvocationID', 2600 'kExclaveIpcStackEntryHaveStack', 2601 ], 2602 'eas_flags': [ 2603 'kExclaveAddressSpaceHaveSlide', 2604 ], 2605 'etl_flags': [ 2606 'kExclaveTextLayoutLoadAddressesSynthetic', 2607 'kExclaveTextLayoutLoadAddressesUnslid', 2608 'kExclaveTextLayoutHasSharedCache', 2609 ], 2610} 2611PRETTIFY_FLAGS['stackshot_out_flags'] = PRETTIFY_FLAGS['stackshot_in_flags'] 2612PRETTIFY_FLAGS['tts_ss_flags'] = PRETTIFY_FLAGS['ts_ss_flags'] 2613 2614# Fields which should never be hexified 2615PRETTIFY_DONTHEX = { 2616 'stackshot_in_pid': True, 2617 'tts_pid': True, 2618 'ts_pid': True, 2619 'donating_pids': True, 2620 'ppid': True, 2621} 2622 2623# Only hex() the value if it is multiple digits 2624def prettify_hex(v): 2625 if v < -9 or v > 9: 2626 return hex(v) 2627 return str(v) 2628 2629def prettify_flags(v, flags): 2630 output="" 2631 seen = 0 2632 if v == 0: 2633 return "0" 2634 for (s, n) in zip(range(len(flags)),flags): 2635 if n is None: 2636 continue 2637 if (v & (2 ** s)): 2638 output += "|" + n 2639 seen |= 2 ** s 2640 if output == "": 2641 return prettify_hex(v) 2642 rest = (v & ~seen) 2643 if (rest != 0): 2644 output += "|" + prettify_hex(rest) 2645 return prettify_hex(v) + " (" + output[1:] + ")" 2646 2647def prettify_core(data, mosthex, key, portlabels): 2648 if key == 'stack_contents': 2649 (address,) = struct.unpack("<Q", struct.pack("B"*8, *data)) 2650 return '0x%X' % address 2651 2652 elif isinstance(data, list): 2653 if 'uuid' in key.lower() and len(data) == 16: 2654 return '%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X' % tuple(data) 2655 2656 return [prettify_core(x, mosthex, key, portlabels) for x in data] 2657 2658 elif key == 'thread_waitinfo': 2659 return formatWaitInfo(data, mosthex, portlabels) 2660 2661 elif isinstance(data, dict): 2662 if 'portlabels' in data: 2663 portlabels = data['portlabels'] 2664 newdata = dict() 2665 for key, value in data.items(): 2666 if mosthex and key != 'task_snapshots' and len(key) > 0 and key.isnumeric(): 2667 key = prettify_hex(int(key)) 2668 newdata[key] = prettify_core(value, mosthex, key, portlabels) 2669 return newdata 2670 2671 elif 'address' in key.lower() and isinstance(data, (int, long)): 2672 return '0x%X' % data 2673 elif key == 'lr' or key == SC_SLID_FIRSTMAPPING_KEY: 2674 return '0x%X' % data 2675 elif key in PRETTIFY_FLAGS and isinstance(data, (int, long)): 2676 return prettify_flags(data, PRETTIFY_FLAGS[key]) 2677 elif key.endswith('_flags') and isinstance(data, (int, long)): 2678 return prettify_hex(data) 2679 2680 elif mosthex and not PRETTIFY_DONTHEX.get(key, False): 2681 if isinstance(data, (int, long)): 2682 return prettify_hex(data) 2683 elif isinstance(data, str) and len(data) > 0 and data.isnumeric(): 2684 return prettify_hex(int(data)) 2685 return data 2686 2687 else: 2688 return data 2689 2690def prettify(data, mosthex): 2691 return prettify_core(data, mosthex, "", None) 2692 2693# N.B.: This is called directly from `xnu.py` for `panicdata -S XXX.ips`'s implementation. 2694def decode_kcdata_file(kcdata_file, stackshot_file, multiple=False, prettyhex=False, pretty=False, output_as_plist=False): 2695 for i,kcdata_buffer in enumerate(iterate_kcdatas(kcdata_file)): 2696 if i > 0 and not multiple: 2697 break 2698 2699 str_data = "{" + kcdata_buffer.GetJsonRepr() + "}" 2700 str_data = str_data.replace("\t", " ") 2701 2702 try: 2703 json_obj = json.loads(str_data) 2704 except Exception: 2705 print("JSON reparsing failed! Printing string data!\n", file=sys.stderr) 2706 import textwrap 2707 print(textwrap.fill(str_data, 100)) 2708 raise 2709 2710 if prettyhex: 2711 json_obj = prettify(json_obj, True) 2712 elif pretty: 2713 json_obj = prettify(json_obj, False) 2714 2715 if stackshot_file: 2716 SaveStackshotReport(json_obj, stackshot_file, G.data_was_incomplete) 2717 elif output_as_plist: 2718 import Foundation 2719 plist = Foundation.NSPropertyListSerialization.dataWithPropertyList_format_options_error_( 2720 json_obj, Foundation.NSPropertyListXMLFormat_v1_0, 0, None)[0].bytes().tobytes() 2721 #sigh. on some pythons long integers are getting output with L's in the plist. 2722 plist = re.sub(r'^(\s*<integer>\d+)L(</integer>\s*)$', r"\1\2", BytesToString(plist), flags=re.MULTILINE) 2723 print(plist,) 2724 else: 2725 print(json.dumps(json_obj, sort_keys=True, indent=4, separators=(',', ': '))) 2726 2727if __name__ == '__main__': 2728 parser = argparse.ArgumentParser(description="Decode a kcdata binary file.") 2729 parser.add_argument("-l", "--listtypes", action="store_true", required=False, default=False, 2730 help="List all known types", 2731 dest="list_known_types") 2732 2733 parser.add_argument("-s", "--stackshot", required=False, default=False, 2734 help="Generate a stackshot report file", 2735 dest="stackshot_file") 2736 2737 parser.add_argument("--multiple", help="look for multiple stackshots in a single file", action='store_true') 2738 2739 parser.add_argument("-p", "--plist", required=False, default=False, 2740 help="output as plist", action="store_true") 2741 2742 parser.add_argument("-S", "--sdk", required=False, default="", help="sdk property passed to xcrun command to find the required tools. Default is empty string.", dest="sdk") 2743 parser.add_argument("-P", "--pretty", default=False, action='store_true', help="make the output a little more human readable") 2744 parser.add_argument("-X", "--prettyhex", default=False, action='store_true', help="make the output a little more human readable, and print most things as hex") 2745 parser.add_argument("--incomplete", action='store_true', help="accept incomplete data") 2746 parser.add_argument("kcdata_file", type=argparse.FileType('r'), help="Path to a kcdata binary file.") 2747 2748 class VerboseAction(argparse.Action): 2749 def __call__(self, parser, namespace, values, option_string=None): 2750 logging.basicConfig(level=logging.INFO, stream=sys.stderr, format='%(message)s') 2751 parser.add_argument('-v', "--verbose", action=VerboseAction, nargs=0) 2752 2753 args = parser.parse_args() 2754 2755 if args.multiple and args.stackshot_file: 2756 raise NotImplementedError 2757 2758 if args.pretty and args.stackshot_file: 2759 raise NotImplementedError 2760 2761 if args.list_known_types: 2762 for (n, t) in KNOWN_TYPES_COLLECTION.items(): 2763 print("%d : %s " % (n, str(t))) 2764 sys.exit(1) 2765 2766 if args.incomplete or args.stackshot_file: 2767 G.accept_incomplete_data = True 2768 2769 decode_kcdata_file(args.kcdata_file, args.stackshot_file, args.multiple, args.prettyhex, args.pretty, args.plist) 2770