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