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