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