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 base64 13import zlib 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 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, item_type, item_size, item_flags, item_data): 769 self.i_type = item_type 770 self.i_size = item_size 771 self.i_flags = item_flags 772 self.i_data = item_data 773 self.i_offset = None 774 775 def __init__(self, barray, pos=0): 776 """ create an object by parsing data from bytes array 777 returns : obj - if data is readable 778 raises ValueError if something is not ok. 779 """ 780 self.i_type = struct.unpack('I', barray[pos:pos+4])[0] # int.from_bytes(barray[pos:pos+4]) 781 self.i_size = struct.unpack('I', barray[pos+4:pos+8])[0] # int.from_bytes(barray[pos+4:pos+8]) 782 self.i_flags = struct.unpack('Q', barray[pos+8:pos+16])[0] # int.from_bytes(barray[pos+8:pos+16]) 783 self.i_data = barray[pos+16: (pos + 16 + self.i_size)] 784 self.i_offset = pos 785 786 def __len__(self): 787 return self.i_size + KCData_item.header_size 788 789 def GetHeaderDescription(self): 790 outs = "type: 0x%x size: 0x%x flags: 0x%x (%s)" % (self.i_type, self.i_size, self.i_flags, GetTypeNameForKey(self.i_type)) 791 if not self.i_offset is None: 792 outs = "pos: 0x%x" % self.i_offset + outs 793 return outs 794 795 def __str__(self): 796 return self.GetHeaderDescription() 797 798def kcdata_item_iterator(data): 799 file_len = len(data) 800 curpos = 0 801 while curpos < file_len: 802 item = KCData_item(data, curpos) 803 yield item 804 curpos += len(item) 805 806def _get_data_element(elementValues): 807 return json.dumps(elementValues[-1]) 808 809KNOWN_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'))) 810 811KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_UINT32_DESC')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_UINT32_DESC'), ( 812 KCSubTypeElement('desc', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(32, 1), 0, 1), 813 KCSubTypeElement('data', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 32, 0) 814), 815 'KCDATA_TYPE_UINT32_DESC', 816 _get_data_element 817) 818 819KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_UINT64_DESC')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_UINT64_DESC'), ( 820 KCSubTypeElement('desc', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(32, 1), 0, 1), 821 KCSubTypeElement('data', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 32, 0) 822), 823 'KCDATA_TYPE_UINT64_DESC', 824 _get_data_element 825) 826 827KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_TIMEBASE')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_TIMEBASE'), ( 828 KCSubTypeElement('numer', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0), 829 KCSubTypeElement('denom', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4, 0) 830), 831 'mach_timebase_info' 832) 833 834 835STACKSHOT_IO_NUM_PRIORITIES = 4 836KNOWN_TYPES_COLLECTION[0x901] = KCTypeDescription(0x901, ( 837 KCSubTypeElement.FromBasicCtype('ss_disk_reads_count', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 838 KCSubTypeElement.FromBasicCtype('ss_disk_reads_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 839 KCSubTypeElement.FromBasicCtype('ss_disk_writes_count', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 840 KCSubTypeElement.FromBasicCtype('ss_disk_writes_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 841 KCSubTypeElement('ss_io_priority_count', KCSUBTYPE_TYPE.KC_ST_UINT64, KCSubTypeElement.GetSizeForArray(STACKSHOT_IO_NUM_PRIORITIES, 8), 32, 1), 842 KCSubTypeElement('ss_io_priority_size', KCSUBTYPE_TYPE.KC_ST_UINT64, KCSubTypeElement.GetSizeForArray(STACKSHOT_IO_NUM_PRIORITIES, 8), 32 + (STACKSHOT_IO_NUM_PRIORITIES * 8), 1), 843 KCSubTypeElement.FromBasicCtype('ss_paging_count', KCSUBTYPE_TYPE.KC_ST_UINT64, 32 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)), 844 KCSubTypeElement.FromBasicCtype('ss_paging_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 40 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)), 845 KCSubTypeElement.FromBasicCtype('ss_non_paging_count', KCSUBTYPE_TYPE.KC_ST_UINT64, 48 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)), 846 KCSubTypeElement.FromBasicCtype('ss_non_paging_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 56 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)), 847 KCSubTypeElement.FromBasicCtype('ss_data_count', KCSUBTYPE_TYPE.KC_ST_UINT64, 64 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)), 848 KCSubTypeElement.FromBasicCtype('ss_data_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 72 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)), 849 KCSubTypeElement.FromBasicCtype('ss_metadata_count', KCSUBTYPE_TYPE.KC_ST_UINT64, 80 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)), 850 KCSubTypeElement.FromBasicCtype('ss_metadata_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 88 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)) 851), 852 'io_statistics' 853) 854 855KNOWN_TYPES_COLLECTION[0x902] = KCTypeDescription(0x902, ( 856 KCSubTypeElement('snapshot_magic', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 0, 0), 857 KCSubTypeElement('free_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 1, 0), 858 KCSubTypeElement('active_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 2, 0), 859 KCSubTypeElement('inactive_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 3, 0), 860 KCSubTypeElement('purgeable_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 4, 0), 861 KCSubTypeElement('wired_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 5, 0), 862 KCSubTypeElement('speculative_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 6, 0), 863 KCSubTypeElement('throttled_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 7, 0), 864 KCSubTypeElement('filebacked_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 8, 0), 865 KCSubTypeElement('compressions', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 9, 0), 866 KCSubTypeElement('decompressions', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 10, 0), 867 KCSubTypeElement('compressor_size', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 11, 0), 868 KCSubTypeElement('busy_buffer_count', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 4 * 12, 0), 869 KCSubTypeElement('pages_wanted', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 13, 0), 870 KCSubTypeElement('pages_reclaimed', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 14, 0), 871 KCSubTypeElement('pages_wanted_reclaimed_valid', KCSUBTYPE_TYPE.KC_ST_UINT8, 1, 4 * 15, 0) 872), 873 'mem_and_io_snapshot' 874) 875 876 877KNOWN_TYPES_COLLECTION[0x930] = KCTypeDescription(0x930, ( 878 KCSubTypeElement.FromBasicCtype('tts_unique_pid', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 879 KCSubTypeElement.FromBasicCtype('tts_ss_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 880 KCSubTypeElement.FromBasicCtype('tts_transition_type', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 881 KCSubTypeElement.FromBasicCtype('tts_pid', KCSUBTYPE_TYPE.KC_ST_INT32, 24), 882 KCSubTypeElement('tts_p_comm', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(32, 1), 28, 1) 883), 884 'transitioning_task_snapshot' 885) 886 887KNOWN_TYPES_COLLECTION[0x905] = KCTypeDescription(0x905, ( 888 KCSubTypeElement.FromBasicCtype('ts_unique_pid', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 889 KCSubTypeElement.FromBasicCtype('ts_ss_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 890 KCSubTypeElement.FromBasicCtype('ts_user_time_in_terminated_thre', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 891 KCSubTypeElement.FromBasicCtype('ts_system_time_in_terminated_th', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 892 KCSubTypeElement.FromBasicCtype('ts_p_start_sec', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 893 KCSubTypeElement.FromBasicCtype('ts_task_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 894 KCSubTypeElement.FromBasicCtype('ts_max_resident_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 895 KCSubTypeElement.FromBasicCtype('ts_suspend_count', KCSUBTYPE_TYPE.KC_ST_UINT32, 56), 896 KCSubTypeElement.FromBasicCtype('ts_faults', KCSUBTYPE_TYPE.KC_ST_UINT32, 60), 897 KCSubTypeElement.FromBasicCtype('ts_pageins', KCSUBTYPE_TYPE.KC_ST_UINT32, 64), 898 KCSubTypeElement.FromBasicCtype('ts_cow_faults', KCSUBTYPE_TYPE.KC_ST_UINT32, 68), 899 KCSubTypeElement.FromBasicCtype('ts_was_throttled', KCSUBTYPE_TYPE.KC_ST_UINT32, 72), 900 KCSubTypeElement.FromBasicCtype('ts_did_throttle', KCSUBTYPE_TYPE.KC_ST_UINT32, 76), 901 KCSubTypeElement.FromBasicCtype('ts_latency_qos', KCSUBTYPE_TYPE.KC_ST_UINT32, 80), 902 KCSubTypeElement.FromBasicCtype('ts_pid', KCSUBTYPE_TYPE.KC_ST_INT32, 84), 903 KCSubTypeElement('ts_p_comm', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(32, 1), 88, 1) 904), 905 'task_snapshot' 906) 907 908 909KNOWN_TYPES_COLLECTION[0x946] = KCTypeDescription(0x946, ( 910 KCSubTypeElement.FromBasicCtype('csflags', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 911 KCSubTypeElement.FromBasicCtype('cs_trust_level', KCSUBTYPE_TYPE.KC_ST_UINT32, 8), 912 ), 913 'stackshot_task_codesigning_info' 914) 915KNOWN_TYPES_COLLECTION[0x906] = KCTypeDescription(0x906, ( 916 KCSubTypeElement.FromBasicCtype('ths_thread_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 917 KCSubTypeElement.FromBasicCtype('ths_wait_event', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 918 KCSubTypeElement.FromBasicCtype('ths_continuation', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 919 KCSubTypeElement.FromBasicCtype('ths_total_syscalls', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 920 KCSubTypeElement.FromBasicCtype('ths_voucher_identifier', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 921 KCSubTypeElement.FromBasicCtype('ths_dqserialnum', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 922 KCSubTypeElement.FromBasicCtype('ths_user_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 923 KCSubTypeElement.FromBasicCtype('ths_sys_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 56), 924 KCSubTypeElement.FromBasicCtype('ths_ss_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 64), 925 KCSubTypeElement.FromBasicCtype('ths_last_run_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 72), 926 KCSubTypeElement.FromBasicCtype('ths_last_made_runnable_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 80), 927 KCSubTypeElement.FromBasicCtype('ths_state', KCSUBTYPE_TYPE.KC_ST_UINT32, 88), 928 KCSubTypeElement.FromBasicCtype('ths_sched_flags', KCSUBTYPE_TYPE.KC_ST_UINT32, 92), 929 KCSubTypeElement.FromBasicCtype('ths_base_priority', KCSUBTYPE_TYPE.KC_ST_INT16, 96), 930 KCSubTypeElement.FromBasicCtype('ths_sched_priority', KCSUBTYPE_TYPE.KC_ST_INT16, 98), 931 KCSubTypeElement.FromBasicCtype('ths_eqos', KCSUBTYPE_TYPE.KC_ST_UINT8, 100), 932 KCSubTypeElement.FromBasicCtype('ths_rqos', KCSUBTYPE_TYPE.KC_ST_UINT8, 101), 933 KCSubTypeElement.FromBasicCtype('ths_rqos_override', KCSUBTYPE_TYPE.KC_ST_UINT8, 102), 934 KCSubTypeElement.FromBasicCtype('ths_io_tier', KCSUBTYPE_TYPE.KC_ST_UINT8, 103), 935 KCSubTypeElement.FromBasicCtype('ths_thread_t', KCSUBTYPE_TYPE.KC_ST_UINT64, 104), 936 KCSubTypeElement.FromBasicCtype('ths_requested_policy', KCSUBTYPE_TYPE.KC_ST_UINT64, 112), 937 KCSubTypeElement.FromBasicCtype('ths_effective_policy', KCSUBTYPE_TYPE.KC_ST_UINT64, 120), 938), 939 'thread_snapshot', 940 legacy_size = 0x68 941) 942 943KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_DISPATCH_QUEUE_LABEL')] = KCSubTypeElement('dispatch_queue_label', KCSUBTYPE_TYPE.KC_ST_CHAR, 944 KCSubTypeElement.GetSizeForArray(64, 1), 0, 1) 945 946KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT'), ( 947 KCSubTypeElement.FromBasicCtype('tds_thread_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 948 KCSubTypeElement.FromBasicCtype('tds_voucher_identifier', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 949 KCSubTypeElement.FromBasicCtype('tds_ss_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 950 KCSubTypeElement.FromBasicCtype('tds_last_made_runnable_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 951 KCSubTypeElement.FromBasicCtype('tds_state', KCSUBTYPE_TYPE.KC_ST_UINT32, 32), 952 KCSubTypeElement.FromBasicCtype('tds_sched_flags', KCSUBTYPE_TYPE.KC_ST_UINT32, 36), 953 KCSubTypeElement.FromBasicCtype('tds_base_priority', KCSUBTYPE_TYPE.KC_ST_INT16, 40), 954 KCSubTypeElement.FromBasicCtype('tds_sched_priority', KCSUBTYPE_TYPE.KC_ST_INT16, 42), 955 KCSubTypeElement.FromBasicCtype('tds_eqos', KCSUBTYPE_TYPE.KC_ST_UINT8, 44), 956 KCSubTypeElement.FromBasicCtype('tds_rqos', KCSUBTYPE_TYPE.KC_ST_UINT8, 45), 957 KCSubTypeElement.FromBasicCtype('tds_rqos_override', KCSUBTYPE_TYPE.KC_ST_UINT8, 46), 958 KCSubTypeElement.FromBasicCtype('tds_io_tier', KCSUBTYPE_TYPE.KC_ST_UINT8, 47), 959 KCSubTypeElement.FromBasicCtype('tds_requested_policy', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 960 KCSubTypeElement.FromBasicCtype('tds_effective_policy', KCSUBTYPE_TYPE.KC_ST_UINT64, 56), 961), 962 'thread_delta_snapshot', 963 legacy_size = 48 964) 965 966KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_TASK_DELTA_SNAPSHOT')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_TASK_DELTA_SNAPSHOT'), ( 967 KCSubTypeElement.FromBasicCtype('tds_unique_pid', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 968 KCSubTypeElement.FromBasicCtype('tds_ss_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 969 KCSubTypeElement.FromBasicCtype('tds_user_time_in_terminated_thr', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 970 KCSubTypeElement.FromBasicCtype('tds_system_time_in_terminated_t', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 971 KCSubTypeElement.FromBasicCtype('tds_task_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 972 KCSubTypeElement.FromBasicCtype('tds_max_resident_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 973 KCSubTypeElement.FromBasicCtype('tds_suspend_count', KCSUBTYPE_TYPE.KC_ST_UINT32, 48), 974 KCSubTypeElement.FromBasicCtype('tds_faults', KCSUBTYPE_TYPE.KC_ST_UINT32, 52), 975 KCSubTypeElement.FromBasicCtype('tds_pageins', KCSUBTYPE_TYPE.KC_ST_UINT32, 56), 976 KCSubTypeElement.FromBasicCtype('tds_cow_faults', KCSUBTYPE_TYPE.KC_ST_UINT32, 60), 977 KCSubTypeElement.FromBasicCtype('tds_was_throttled', KCSUBTYPE_TYPE.KC_ST_UINT32, 64), 978 KCSubTypeElement.FromBasicCtype('tds_did_throttle', KCSUBTYPE_TYPE.KC_ST_UINT32, 68), 979 KCSubTypeElement.FromBasicCtype('tds_latency_qos', KCSUBTYPE_TYPE.KC_ST_UINT32, 72), 980), 981 'task_delta_snapshot' 982) 983 984 985KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_NAME')] = KCSubTypeElement('pth_name', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(64, 1), 0, 1) 986 987KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_SYS_SHAREDCACHE_LAYOUT')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_SYS_SHAREDCACHE_LAYOUT'), ( 988 KCSubTypeElement('imageLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 989 KCSubTypeElement('imageUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 8, 1) 990), 991 'system_shared_cache_layout' 992) 993 994KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_LIBRARY_LOADINFO64')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_LIBRARY_LOADINFO64'), ( 995 KCSubTypeElement('imageLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 996 KCSubTypeElement('imageUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 8, 1) 997), 998 'dyld_load_info', 999 legacy_size = 24 1000) 1001 1002KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_LIBRARY_LOADINFO')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_LIBRARY_LOADINFO'), ( 1003 KCSubTypeElement('imageLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0), 1004 KCSubTypeElement('imageUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 4, 1) 1005), 1006 'dyld_load_info', 1007 legacy_size = 20 1008) 1009 1010KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_LOADINFO64_TEXT_EXEC')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_LOADINFO64_TEXT_EXEC'), ( 1011 KCSubTypeElement('imageLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 1012 KCSubTypeElement('imageUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 8, 1), 1013), 1014 'dyld_load_info_text_exec' 1015) 1016 1017KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_AOTCACHE_LOADINFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_AOTCACHE_LOADINFO'), ( 1018 KCSubTypeElement('x86SlidBaseAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 1019 KCSubTypeElement('x86UUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 8, 1), 1020 KCSubTypeElement('aotSlidBaseAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 24, 0), 1021 KCSubTypeElement('aotUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 32, 1), 1022), 1023 'dyld_aot_cache_uuid_info' 1024) 1025KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_SHAREDCACHE_AOTINFO')] = KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_AOTCACHE_LOADINFO')] 1026 1027KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_SHAREDCACHE_LOADINFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_SHAREDCACHE_LOADINFO'), ( 1028 KCSubTypeElement('imageLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 1029 KCSubTypeElement('imageUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 8, 1), 1030 KCSubTypeElement('imageSlidBaseAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 24, 0), 1031 KCSubTypeElement('sharedCacheSlidFirstMapping', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 32, 0), 1032), 1033 'shared_cache_dyld_load_info', 1034 legacy_size = 0x18 1035) 1036 1037KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_SHAREDCACHE_INFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_SHAREDCACHE_INFO'), ( 1038 KCSubTypeElement('sharedCacheSlide', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 1039 KCSubTypeElement('sharedCacheUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 8, 1), 1040 KCSubTypeElement('sharedCacheUnreliableSlidBaseAd', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 24, 0), 1041 KCSubTypeElement('sharedCacheSlidFirstMapping', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 32, 0), 1042 KCSubTypeElement('sharedCacheID', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 40, 0), 1043 KCSubTypeElement('sharedCacheFlags', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 44, 0), 1044), 1045 'shared_cache_dyld_load_info', 1046) 1047 1048KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERNELCACHE_LOADINFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_KERNELCACHE_LOADINFO'), ( 1049 KCSubTypeElement('imageLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 1050 KCSubTypeElement('imageUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 8, 1), 1051), 1052 'kernelcache_load_info' 1053) 1054 1055KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_SHAREDCACHE_ID')] = KCSubTypeElement('sharedCacheID', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0, KCSubTypeElement._get_naked_element_value) 1056 1057KNOWN_TYPES_COLLECTION[0x33] = KCSubTypeElement('mach_absolute_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value) 1058KNOWN_TYPES_COLLECTION[0x907] = KCSubTypeElement.FromBasicCtype('donating_pids', KCSUBTYPE_TYPE.KC_ST_INT32, legacy_size=4) 1059 1060KNOWN_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) 1061 1062KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME'), ( 1063 KCSubTypeElement.FromBasicCtype('lr', KCSUBTYPE_TYPE.KC_ST_UINT32), 1064 KCSubTypeElement.FromBasicCtype('sp', KCSUBTYPE_TYPE.KC_ST_UINT32, 4) 1065), 1066 'kernel_stack_frames', 1067 legacy_size = 8 1068) 1069 1070KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR'), ( 1071 KCSubTypeElement.FromBasicCtype('lr', KCSUBTYPE_TYPE.KC_ST_UINT32), 1072), 1073 'kernel_stack_frames' 1074) 1075 1076 1077KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_USER_STACKFRAME')] = KCTypeDescription.FromKCTypeDescription( 1078 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME')], 1079 GetTypeForName('STACKSHOT_KCTYPE_USER_STACKFRAME'), 1080 'user_stack_frames' 1081) 1082 1083KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_USER_STACKLR')] = KCTypeDescription.FromKCTypeDescription( 1084 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR')], 1085 GetTypeForName('STACKSHOT_KCTYPE_USER_STACKLR'), 1086 'user_stack_frames' 1087) 1088 1089KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME64')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME64'), ( 1090 KCSubTypeElement.FromBasicCtype('lr', KCSUBTYPE_TYPE.KC_ST_UINT64), 1091 KCSubTypeElement.FromBasicCtype('sp', KCSUBTYPE_TYPE.KC_ST_UINT64, 8) 1092), 1093 'kernel_stack_frames', 1094 legacy_size = 16 1095) 1096 1097KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_USER_STACKFRAME64')] = KCTypeDescription.FromKCTypeDescription( 1098 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME64')], 1099 GetTypeForName('STACKSHOT_KCTYPE_USER_STACKFRAME64'), 1100 'user_stack_frames' 1101) 1102 1103 1104KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR64')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR64'), ( 1105 KCSubTypeElement.FromBasicCtype('lr', KCSUBTYPE_TYPE.KC_ST_UINT64), 1106), 1107 'kernel_stack_frames' 1108) 1109 1110KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_USER_STACKLR64')] = KCTypeDescription.FromKCTypeDescription( 1111 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR64')], 1112 GetTypeForName('STACKSHOT_KCTYPE_USER_STACKLR64'), 1113 'user_stack_frames' 1114) 1115 1116KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_USER_ASYNC_START_INDEX')] = KCSubTypeElement.FromBasicCtype('user_async_start_index', KCSUBTYPE_TYPE.KC_ST_UINT32) 1117 1118KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_USER_ASYNC_STACKLR64')] = KCTypeDescription.FromKCTypeDescription( 1119 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR64')], 1120 GetTypeForName('STACKSHOT_KCTYPE_USER_ASYNC_STACKLR64'), 1121 'user_async_stack_frames' 1122) 1123 1124KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_NONRUNNABLE_TIDS')] = KCSubTypeElement.FromBasicCtype('nonrunnable_threads', KCSUBTYPE_TYPE.KC_ST_INT64) 1125 1126KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_NONRUNNABLE_TASKS')] = KCSubTypeElement.FromBasicCtype('nonrunnable_tasks', KCSUBTYPE_TYPE.KC_ST_INT64) 1127 1128KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_OSVERSION')] = KCSubTypeElement('osversion', KCSUBTYPE_TYPE.KC_ST_CHAR, 1129 KCSubTypeElement.GetSizeForArray(256, 1), 0, 1) 1130 1131KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_BOOTARGS')] = KCSubTypeElement('boot_args', KCSUBTYPE_TYPE.KC_ST_CHAR, 1132 KCSubTypeElement.GetSizeForArray(256, 1), 0, 1) 1133 1134KNOWN_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) 1135 1136KNOWN_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) 1137 1138KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_JETSAM_LEVEL')] = KCSubTypeElement('jetsam_level', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0, KCSubTypeElement._get_naked_element_value) 1139 1140KNOWN_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) 1141 1142KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_STACKSHOT_FAULT_STATS')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_STACKSHOT_FAULT_STATS'), 1143 ( 1144 KCSubTypeElement.FromBasicCtype('sfs_pages_faulted_in', KCSUBTYPE_TYPE.KC_ST_UINT32, 0), 1145 KCSubTypeElement.FromBasicCtype('sfs_time_spent_faulting', KCSUBTYPE_TYPE.KC_ST_UINT64, 4), 1146 KCSubTypeElement.FromBasicCtype('sfs_system_max_fault_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 12), 1147 KCSubTypeElement.FromBasicCtype('sfs_stopped_faulting', KCSUBTYPE_TYPE.KC_ST_UINT8, 20) 1148 ), 1149 'stackshot_fault_stats') 1150 1151KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_WAITINFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_THREAD_WAITINFO'), 1152 ( 1153 KCSubTypeElement.FromBasicCtype('owner', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1154 KCSubTypeElement.FromBasicCtype('waiter', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1155 KCSubTypeElement.FromBasicCtype('context', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1156 KCSubTypeElement.FromBasicCtype('wait_type', KCSUBTYPE_TYPE.KC_ST_UINT8, 24), 1157 KCSubTypeElement.FromBasicCtype('portlabel_id', KCSUBTYPE_TYPE.KC_ST_INT16, 25), 1158 KCSubTypeElement.FromBasicCtype('wait_flags', KCSUBTYPE_TYPE.KC_ST_INT32, 27) 1159 ), 1160 'thread_waitinfo') 1161 1162KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_TURNSTILEINFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_THREAD_TURNSTILEINFO'), 1163 ( 1164 KCSubTypeElement.FromBasicCtype('waiter', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1165 KCSubTypeElement.FromBasicCtype('turnstile_context', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1166 KCSubTypeElement.FromBasicCtype('turnstile_priority', KCSUBTYPE_TYPE.KC_ST_UINT8, 16), 1167 KCSubTypeElement.FromBasicCtype('number_of_hops', KCSUBTYPE_TYPE.KC_ST_UINT8, 17), 1168 KCSubTypeElement.FromBasicCtype('turnstile_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 18), 1169 KCSubTypeElement.FromBasicCtype('portlabel_id', KCSUBTYPE_TYPE.KC_ST_INT16, 26), 1170 ), 1171 'thread_turnstileinfo') 1172 1173KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_PORTLABEL')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_PORTLABEL'), 1174 ( 1175 KCSubTypeElement.FromBasicCtype('portlabel_id', KCSUBTYPE_TYPE.KC_ST_INT16, 0), 1176 KCSubTypeElement.FromBasicCtype('portlabel_flags', KCSUBTYPE_TYPE.KC_ST_UINT16, 2), 1177 KCSubTypeElement.FromBasicCtype('portlabel_domain', KCSUBTYPE_TYPE.KC_ST_UINT8, 4), 1178 ), 1179 'portlabel_info', merge=True) 1180 1181KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_PORTLABEL_NAME')] = ( 1182 KCSubTypeElement("portlabel_name", KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(-1, 1), 0, 1)) 1183 1184KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_GROUP_SNAPSHOT')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_THREAD_GROUP'), 1185 ( 1186 KCSubTypeElement.FromBasicCtype('tgs_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1187 KCSubTypeElement('tgs_name', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(16, 1), 1188 8, 1), 1189 KCSubTypeElement.FromBasicCtype('tgs_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1190 ), 1191 'thread_group_snapshot') 1192 1193 1194KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_GROUP')] = KCSubTypeElement('thread_group', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value) 1195 1196KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_JETSAM_COALITION_SNAPSHOT')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_JETSAM_COALITION_SNAPSHOT'), 1197 ( 1198 KCSubTypeElement.FromBasicCtype('jcs_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1199 KCSubTypeElement.FromBasicCtype('jcs_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1200 KCSubTypeElement.FromBasicCtype('jcs_thread_group', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1201 KCSubTypeElement.FromBasicCtype('jcs_leader_task_uniqueid', KCSUBTYPE_TYPE.KC_ST_UINT64, 24) 1202 ), 1203 'jetsam_coalition_snapshot') 1204 1205KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_JETSAM_COALITION')] = KCSubTypeElement('jetsam_coalition', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value) 1206 1207KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_INSTRS_CYCLES')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_INSTRS_CYCLES'), 1208 ( 1209 KCSubTypeElement.FromBasicCtype('ics_instructions', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1210 KCSubTypeElement.FromBasicCtype('ics_cycles', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1211 KCSubTypeElement.FromBasicCtype('ics_p_instructions', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1212 KCSubTypeElement.FromBasicCtype('ics_p_cycles', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1213 ), 1214 'instrs_cycles_snapshot') 1215 1216KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_TASK_CPU_ARCHITECTURE')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_TASK_CPU_ARCHITECTURE'), 1217 ( 1218 KCSubTypeElement.FromBasicCtype('cputype', KCSUBTYPE_TYPE.KC_ST_INT32, 0), 1219 KCSubTypeElement.FromBasicCtype('cpusubtype', KCSUBTYPE_TYPE.KC_ST_INT32, 4) 1220 ), 1221 'task_cpu_architecture') 1222 1223KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO'), 1224 ( 1225 KCSubTypeElement.FromBasicCtype('latency_version', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1226 KCSubTypeElement.FromBasicCtype('setup_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1227 KCSubTypeElement.FromBasicCtype('total_task_iteration_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1228 KCSubTypeElement.FromBasicCtype('total_terminated_task_iteration', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1229 KCSubTypeElement.FromBasicCtype('task_queue_building_latency_mt', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 1230 KCSubTypeElement.FromBasicCtype('terminated_task_queue_building_latency_mt', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 1231 KCSubTypeElement.FromBasicCtype('cpu_wait_latency_mt', KCSUBTYPE_TYPE.KC_ST_INT32, 48), 1232 KCSubTypeElement.FromBasicCtype('calling_cpu_number', KCSUBTYPE_TYPE.KC_ST_INT32, 56), 1233 ), 1234 'stackshot_latency_collection') 1235 1236KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO_CPU')] = KCTypeDescription(GetTypeForName('STACKSHOT_LATENCY_INFO_CPU'), 1237 ( 1238 KCSubTypeElement.FromBasicCtype('cpu_number', KCSUBTYPE_TYPE.KC_ST_INT32, 0), 1239 KCSubTypeElement.FromBasicCtype('cluster_type', KCSUBTYPE_TYPE.KC_ST_INT32, 4), 1240 KCSubTypeElement.FromBasicCtype('init_latency_mt', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1241 KCSubTypeElement.FromBasicCtype('workqueue_latency_mt', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1242 KCSubTypeElement.FromBasicCtype('total_latency_mt', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1243 KCSubTypeElement.FromBasicCtype('total_cycles', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 1244 KCSubTypeElement.FromBasicCtype('total_instrs', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 1245 KCSubTypeElement.FromBasicCtype('tasks_processed', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 1246 KCSubTypeElement.FromBasicCtype('threads_processed', KCSUBTYPE_TYPE.KC_ST_UINT64, 56), 1247 KCSubTypeElement.FromBasicCtype('faulting_time_mt', KCSUBTYPE_TYPE.KC_ST_UINT64, 64), 1248 KCSubTypeElement.FromBasicCtype('total_buf', KCSUBTYPE_TYPE.KC_ST_UINT64, 72), 1249 KCSubTypeElement.FromBasicCtype('intercluster_buf_used', KCSUBTYPE_TYPE.KC_ST_UINT64, 80), 1250 ), 1251 'stackshot_latency_cpu') 1252 1253KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO_TASK')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO_TASK'), 1254 ( 1255 KCSubTypeElement.FromBasicCtype('task_uniqueid', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1256 KCSubTypeElement.FromBasicCtype('setup_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1257 KCSubTypeElement.FromBasicCtype('task_thread_count_loop_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1258 KCSubTypeElement.FromBasicCtype('task_thread_data_loop_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1259 KCSubTypeElement.FromBasicCtype('cur_tsnap_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 1260 KCSubTypeElement.FromBasicCtype('pmap_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 1261 KCSubTypeElement.FromBasicCtype('bsd_proc_ids_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 1262 KCSubTypeElement.FromBasicCtype('misc_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 56), 1263 KCSubTypeElement.FromBasicCtype('misc2_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 64), 1264 KCSubTypeElement.FromBasicCtype('end_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 72) 1265 ), 1266 'stackshot_latency_task') 1267 1268KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO_THREAD')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO_THREAD'), 1269 ( 1270 KCSubTypeElement.FromBasicCtype('thread_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1271 KCSubTypeElement.FromBasicCtype('cur_thsnap1_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1272 KCSubTypeElement.FromBasicCtype('dispatch_serial_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1273 KCSubTypeElement.FromBasicCtype('dispatch_label_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1274 KCSubTypeElement.FromBasicCtype('cur_thsnap2_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 1275 KCSubTypeElement.FromBasicCtype('thread_name_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 1276 KCSubTypeElement.FromBasicCtype('sur_times_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 1277 KCSubTypeElement.FromBasicCtype('user_stack_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 56), 1278 KCSubTypeElement.FromBasicCtype('kernel_stack_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 64), 1279 KCSubTypeElement.FromBasicCtype('misc_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 72), 1280 ), 1281 'stackshot_latency_thread') 1282 1283KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_NAME')] = KCSubTypeElement('pth_name', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(64, 1), 0, 1) 1284 1285def set_type(name, *args): 1286 typ = GetTypeForName(name) 1287 KNOWN_TYPES_COLLECTION[typ] = KCTypeDescription(GetTypeForName(typ), *args) 1288 1289 1290set_type('STACKSHOT_KCTYPE_USER_STACKTOP', 1291 ( 1292 KCSubTypeElement.FromBasicCtype('sp', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1293 KCSubTypeElement('stack_contents', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(8, 1), 8, 1), 1294 ), 1295 'user_stacktop') 1296 1297#KNOWN_TYPES_COLLECTION[0x907] = KCSubTypeElement('donating_pids', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0, KCSubTypeElement._get_naked_element_value) 1298KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PID')] = KCSubTypeElement('pid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1299KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PPID')] = KCSubTypeElement('ppid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1300KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_NAME')] = KCSubTypeElement('p_comm', KCSUBTYPE_TYPE.KC_ST_CHAR, 1301 KCSubTypeElement.GetSizeForArray(32, 1), 0, 1) 1302KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_USERSTACK')] = KCSubTypeElement('userstack_ptr', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0) 1303KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_ARGSLEN')] = KCSubTypeElement('p_argslen', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1304 1305KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_PATH')] = KCSubTypeElement('p_path', KCSUBTYPE_TYPE.KC_ST_CHAR, 1306 KCSubTypeElement.GetSizeForArray(1024, 1), 0, 1) 1307KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_CSFLAGS')] = KCSubTypeElement('p_csflags', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1308KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_UID')] = KCSubTypeElement('uid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1309KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_GID')] = KCSubTypeElement('gid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1310KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_ARGC')] = KCSubTypeElement('argc', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1311KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_FLAGS')] = KCSubTypeElement('p_flags', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1312KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_CPUTYPE')] = KCSubTypeElement('cputype', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1313KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_RESPONSIBLE_PID')] = KCSubTypeElement('responsible_pid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1314KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_DIRTY_FLAGS')] = KCSubTypeElement('dirty_flags', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1315KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_CRASHED_THREADID')] = KCSubTypeElement('crashed_threadid', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0) 1316KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_COALITION_ID')] = KCSubTypeElement('coalition_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0) 1317 1318KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_STATUS')] = KCSubTypeElement('p_status', KCSUBTYPE_TYPE.KC_ST_UINT8, 1, 0, 0) 1319 1320KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_BSDINFOWITHUNIQID')] = KCTypeDescription(GetTypeForName('TASK_CRASHINFO_BSDINFOWITHUNIQID'), 1321 ( KCSubTypeElement('p_uuid', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 0, 1), 1322 KCSubTypeElement.FromBasicCtype('p_uniqueid', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1323 KCSubTypeElement.FromBasicCtype('p_puniqueid', KCSUBTYPE_TYPE.KC_ST_UINT64, 24) 1324 ), 1325 'proc_uniqidentifierinfo') 1326 1327KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_EXCEPTION_CODES')] = ( 1328 KCTypeDescription(GetTypeForName('TASK_CRASHINFO_EXCEPTION_CODES'), 1329 (KCSubTypeElement.FromBasicCtype('code_0', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1330 KCSubTypeElement.FromBasicCtype('code_1', KCSUBTYPE_TYPE.KC_ST_UINT64, 8)), 1331 'mach_exception_data_t')) 1332 1333 1334KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_STARTTIME')] = ( 1335 KCTypeDescription(GetTypeForName('TASK_CRASHINFO_PROC_STARTTIME'), 1336 (KCSubTypeElement.FromBasicCtype('tv_sec', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1337 KCSubTypeElement.FromBasicCtype('tv_usec', KCSUBTYPE_TYPE.KC_ST_UINT64, 8)), 1338 'proc_starttime')) 1339 1340 1341KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_RUSAGE_INFO')] = KCTypeDescription(GetTypeForName('TASK_CRASHINFO_RUSAGE_INFO'), 1342 ( 1343 KCSubTypeElement('ri_uuid', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 0, 1), 1344 KCSubTypeElement.FromBasicCtype('ri_user_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1345 KCSubTypeElement.FromBasicCtype('ri_system_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1346 KCSubTypeElement.FromBasicCtype('ri_pkg_idle_wkups', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 1347 KCSubTypeElement.FromBasicCtype('ri_interrupt_wkups', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 1348 KCSubTypeElement.FromBasicCtype('ri_pageins', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 1349 KCSubTypeElement.FromBasicCtype('ri_wired_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 56), 1350 KCSubTypeElement.FromBasicCtype('ri_resident_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 64), 1351 KCSubTypeElement.FromBasicCtype('ri_phys_footprint', KCSUBTYPE_TYPE.KC_ST_UINT64, 72), 1352 KCSubTypeElement.FromBasicCtype('ri_proc_start_abstime', KCSUBTYPE_TYPE.KC_ST_UINT64, 80), 1353 KCSubTypeElement.FromBasicCtype('ri_proc_exit_abstime', KCSUBTYPE_TYPE.KC_ST_UINT64, 88), 1354 KCSubTypeElement.FromBasicCtype('ri_child_user_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 96), 1355 KCSubTypeElement.FromBasicCtype('ri_child_system_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 104), 1356 KCSubTypeElement.FromBasicCtype('ri_child_pkg_idle_wkups', KCSUBTYPE_TYPE.KC_ST_UINT64, 112), 1357 KCSubTypeElement.FromBasicCtype('ri_child_interrupt_wkups', KCSUBTYPE_TYPE.KC_ST_UINT64, 120), 1358 KCSubTypeElement.FromBasicCtype('ri_child_pageins', KCSUBTYPE_TYPE.KC_ST_UINT64, 128), 1359 KCSubTypeElement.FromBasicCtype('ri_child_elapsed_abstime', KCSUBTYPE_TYPE.KC_ST_UINT64, 136), 1360 KCSubTypeElement.FromBasicCtype('ri_diskio_bytesread', KCSUBTYPE_TYPE.KC_ST_UINT64, 144), 1361 KCSubTypeElement.FromBasicCtype('ri_diskio_byteswritten', KCSUBTYPE_TYPE.KC_ST_UINT64, 152), 1362 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_default', KCSUBTYPE_TYPE.KC_ST_UINT64, 160), 1363 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_maintenance', KCSUBTYPE_TYPE.KC_ST_UINT64, 168), 1364 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_background', KCSUBTYPE_TYPE.KC_ST_UINT64, 176), 1365 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_utility', KCSUBTYPE_TYPE.KC_ST_UINT64, 184), 1366 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_legacy', KCSUBTYPE_TYPE.KC_ST_UINT64, 192), 1367 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_user_initiated', KCSUBTYPE_TYPE.KC_ST_UINT64, 200), 1368 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_user_interactiv', KCSUBTYPE_TYPE.KC_ST_UINT64, 208), 1369 KCSubTypeElement.FromBasicCtype('ri_billed_system_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 216), 1370 KCSubTypeElement.FromBasicCtype('ri_serviced_system_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 224) 1371 ), 1372 'rusage_info') 1373 1374#The sizes for these need to be kept in sync with 1375#MAX_CRASHINFO_SIGNING_ID_LEN, MAX_CRASHINFO_TEAM_ID_LEN 1376KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_CS_SIGNING_ID')] = KCSubTypeElement('cs_signing_id', KCSUBTYPE_TYPE.KC_ST_CHAR, 1377 KCSubTypeElement.GetSizeForArray(64, 1), 0, 1) 1378KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_CS_TEAM_ID')] = KCSubTypeElement('cs_team_id', KCSUBTYPE_TYPE.KC_ST_CHAR, 1379 KCSubTypeElement.GetSizeForArray(32, 1), 0, 1) 1380 1381KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_CS_VALIDATION_CATEGORY')] = KCSubTypeElement('cs_validation_category', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0) 1382 1383KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_CS_TRUST_LEVEL')] = KCSubTypeElement('cs_trust_level', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0) 1384 1385KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_JIT_ADDRESS_RANGE')] = KCTypeDescription(GetTypeForName('TASK_CRASHINFO_JIT_ADDRESS_RANGE'), 1386 ( 1387 KCSubTypeElement.FromBasicCtype('start_address', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1388 KCSubTypeElement.FromBasicCtype('end_address', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1389 ), 'jit_address_range') 1390 1391KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_MB')] = KCTypeDescription(GetTypeForName('TASK_CRASHINFO_MB'), 1392 ( 1393 KCSubTypeElement.FromBasicCtype('start_address', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1394 KCSubTypeElement('data', KCSUBTYPE_TYPE.KC_ST_UINT64, KCSubTypeElement.GetSizeForArray(64, 64), 8, 0), 1395 ) 1396) 1397 1398KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_CS_AUXILIARY_INFO')] = KCSubTypeElement('cs_auxiliary_info', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0) 1399 1400KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_CPU_TIMES')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_CPU_TIMES'), 1401 ( 1402 KCSubTypeElement.FromBasicCtype('user_usec', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1403 KCSubTypeElement.FromBasicCtype('system_usec', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1404 KCSubTypeElement.FromBasicCtype('runnable_usec', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1405 ), 'cpu_times') 1406 1407KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_STACKSHOT_DURATION')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_STACKSHOT_DURATION'), 1408 ( 1409 KCSubTypeElement.FromBasicCtype('stackshot_duration', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1410 KCSubTypeElement.FromBasicCtype('stackshot_duration_outer', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1411 KCSubTypeElement.FromBasicCtype('stackshot_duration_prior', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1412 ), 'stackshot_duration', merge=True 1413) 1414 1415KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_PROCNAME')] = ( 1416 KCSubTypeElement("proc_name", KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(-1, 1), 0, 1)) 1417 1418KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_PID')] = ( 1419 KCSubTypeElement('pid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0)) 1420 1421KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_LIBRARY_AOTINFO')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_LIBRARY_AOTINFO'), 1422 ( 1423 KCSubTypeElement('x86LoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 1424 KCSubTypeElement('aotLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 8, 0), 1425 KCSubTypeElement('aotImageSize', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 16, 0), 1426 KCSubTypeElement('aotImageKey', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(32, 1), 24, 1), 1427 ), 'dyld_aot_info') 1428 1429KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_SNAPSHOT')] = KCTypeDescription(GetTypeForName('EXIT_REASON_SNAPSHOT'), 1430 ( 1431 KCSubTypeElement.FromBasicCtype('ers_namespace', KCSUBTYPE_TYPE.KC_ST_UINT32, 0), 1432 KCSubTypeElement.FromBasicCtype('ers_code', KCSUBTYPE_TYPE.KC_ST_UINT64, 4), 1433 KCSubTypeElement.FromBasicCtype('ers_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 12), 1434 ), 'exit_reason_basic_info') 1435 1436KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_USER_DESC')] = ( 1437 KCSubTypeElement("exit_reason_user_description", KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(-1, 1), 0, 1)) 1438 1439KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_USER_PAYLOAD')] = KCSubTypeElement('exit_reason_user_payload', 1440 KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(-1, 1), 0, 1) 1441 1442KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_CODESIGNING_INFO')] = KCTypeDescription(GetTypeForName('EXIT_REASON_CODESIGNING_INFO'), 1443 ( 1444 KCSubTypeElement.FromBasicCtype('ceri_virt_addr', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1445 KCSubTypeElement.FromBasicCtype('ceri_file_offset', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1446 KCSubTypeElement("ceri_pathname", KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(1024, 1), 16, 1), 1447 KCSubTypeElement("ceri_filename", KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(1024, 1), 1040, 1), 1448 KCSubTypeElement.FromBasicCtype('ceri_codesig_modtime_secs', KCSUBTYPE_TYPE.KC_ST_UINT64, 2064), 1449 KCSubTypeElement.FromBasicCtype('ceri_codesig_modtime_nsecs', KCSUBTYPE_TYPE.KC_ST_UINT64, 2072), 1450 KCSubTypeElement.FromBasicCtype('ceri_page_modtime_secs', KCSUBTYPE_TYPE.KC_ST_UINT64, 2080), 1451 KCSubTypeElement.FromBasicCtype('ceri_page_modtime_nsecs', KCSUBTYPE_TYPE.KC_ST_UINT64, 2088), 1452 KCSubTypeElement.FromBasicCtype('ceri_path_truncated', KCSUBTYPE_TYPE.KC_ST_UINT8, 2096), 1453 KCSubTypeElement.FromBasicCtype('ceri_object_codesigned', KCSUBTYPE_TYPE.KC_ST_UINT8, 2097), 1454 KCSubTypeElement.FromBasicCtype('ceri_page_codesig_validated', KCSUBTYPE_TYPE.KC_ST_UINT8, 2098), 1455 KCSubTypeElement.FromBasicCtype('ceri_page_codesig_tainted', KCSUBTYPE_TYPE.KC_ST_UINT8, 2099), 1456 KCSubTypeElement.FromBasicCtype('ceri_page_codesig_nx', KCSUBTYPE_TYPE.KC_ST_UINT8, 2100), 1457 KCSubTypeElement.FromBasicCtype('ceri_page_wpmapped', KCSUBTYPE_TYPE.KC_ST_UINT8, 2101), 1458 KCSubTypeElement.FromBasicCtype('ceri_page_slid', KCSUBTYPE_TYPE.KC_ST_UINT8, 2102), 1459 KCSubTypeElement.FromBasicCtype('ceri_page_dirty', KCSUBTYPE_TYPE.KC_ST_UINT8, 2103), 1460 KCSubTypeElement.FromBasicCtype('ceri_page_shadow_depth', KCSUBTYPE_TYPE.KC_ST_UINT32, 2104), 1461 ), 'exit_reason_codesigning_info') 1462 1463KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_WORKLOOP_ID')] = ( 1464 KCSubTypeElement('exit_reason_workloop_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value)) 1465 1466KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_DISPATCH_QUEUE_NO')] = ( 1467 KCSubTypeElement('exit_reason_dispatch_queue_no', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value)) 1468 1469KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_ASID')] = ( 1470 KCSubTypeElement('ts_asid', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0)) 1471 1472KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_PAGE_TABLES')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_PAGE_TABLES'), ( 1473 KCSubTypeElement(None, KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value), ), 1474 'ts_pagetable', 1475 merge=True, 1476 naked=True 1477) 1478 1479KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_SUSPENSION_INFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_SUSPENSION_INFO'), ( 1480 KCSubTypeElement.FromBasicCtype('tss_last_start', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1481 KCSubTypeElement.FromBasicCtype('tss_last_end', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1482 KCSubTypeElement.FromBasicCtype('tss_count', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1483 KCSubTypeElement.FromBasicCtype('tss_duration', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1484), 'suspension_info') 1485 1486KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_SUSPENSION_SOURCE')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_SUSPENSION_SOURCE'), ( 1487 KCSubTypeElement.FromBasicCtype('tss_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1488 KCSubTypeElement.FromBasicCtype('tss_tid', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1489 KCSubTypeElement.FromBasicCtype('tss_pid', KCSUBTYPE_TYPE.KC_ST_INT32, 16), 1490 KCSubTypeElement('tss_procname', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(65, 1), 20, 1) 1491), 'suspension_source') 1492 1493KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_OS_BUILD_VERSION')] = KCSubTypeElement('os_build_version', KCSUBTYPE_TYPE.KC_ST_CHAR, 1494 KCSubTypeElement.GetSizeForArray(256, 1), 0, 1) 1495 1496KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_EXCLAVES_THREADINFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_KERN_EXCLAVES_THREADINFO'), 1497 ( 1498 KCSubTypeElement.FromBasicCtype('tei_scid', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1499 KCSubTypeElement.FromBasicCtype('tei_thread_offset', KCSUBTYPE_TYPE.KC_ST_UINT32, 8), 1500 KCSubTypeElement.FromBasicCtype('tei_flags', KCSUBTYPE_TYPE.KC_ST_UINT32, 12), 1501 ), 'exclaves_thread_info') 1502 1503KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_SCRESULT_INFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_SCRESULT_INFO'), 1504 ( 1505 KCSubTypeElement.FromBasicCtype('esc_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1506 KCSubTypeElement.FromBasicCtype('esc_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1507 ), 'exclave_scresult_info') 1508 1509KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_IPCSTACKENTRY_INFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_IPCSTACKENTRY_INFO'), 1510 ( 1511 KCSubTypeElement.FromBasicCtype('eise_asid', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1512 KCSubTypeElement.FromBasicCtype('eise_tnid', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1513 KCSubTypeElement.FromBasicCtype('eise_invocationid', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1514 KCSubTypeElement.FromBasicCtype('eise_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1515 ), 'exclave_ipcstackentry_info') 1516 1517KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_IPCSTACKENTRY_ECSTACK')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_IPCSTACKENTRY_ECSTACK'), 1518 ( 1519 KCSubTypeElement.FromBasicCtype('lr', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1520 ), 'secure_ecstack_entry') 1521 1522KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_ADDRESSSPACE_INFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_ADDRESSSPACE_INFO'), 1523 ( 1524 KCSubTypeElement.FromBasicCtype('eas_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1525 KCSubTypeElement.FromBasicCtype('eas_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1526 KCSubTypeElement.FromBasicCtype('eas_layoutid', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1527 KCSubTypeElement.FromBasicCtype('eas_slide', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1528 KCSubTypeElement.FromBasicCtype('eas_asroot', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 1529 ), 'exclave_addressspace_info') 1530 1531KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_ADDRESSSPACE_NAME')] = KCSubTypeElement('exclave_addressspace_name', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(64, 1), 0, 1) 1532 1533KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_TEXTLAYOUT_INFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_TEXTLAYOUT_INFO'), 1534 ( 1535 KCSubTypeElement.FromBasicCtype('layout_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1536 KCSubTypeElement.FromBasicCtype('etl_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1537 KCSubTypeElement.FromBasicCtype('sharedcache_index', KCSUBTYPE_TYPE.KC_ST_UINT32, 16), 1538 ), 'exclave_textlayout_info') 1539 1540KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_TEXTLAYOUT_SEGMENTS')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_TEXTLAYOUT_SEGMENTS'), 1541 ( 1542 KCSubTypeElement('layoutSegment_uuid', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 0, 1), 1543 KCSubTypeElement.FromBasicCtype('layoutSegment_loadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1544 KCSubTypeElement.FromBasicCtype('layoutSegment_rawLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1545 ), 'exclave_textlayout_segments') 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(layout): 1919 flags = layout['exclave_textlayout_info']['etl_flags'] 1920 sharedCacheIndex = layout['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 < length(layouts)): 1924 layouts[sharedCacheIndex][2] = "S" 1925 layouts.sort(key=itemgetter(1)) 1926 return layouts 1927 1928def GetExclaveLibs(text_layouts, text_layout_id): 1929 from operator import itemgetter 1930 textlayout = text_layouts.get(str(text_layout_id)) 1931 1932 # This fallback is needed to preserve compatibility with kcdata generated before rdar://123838752 1933 # FindTextLayout function should be removed in future 1934 if not textlayout or textlayout['exclave_textlayout_info']['layout_id'] != text_layout_id: 1935 textlayout = FindTextLayout(text_layouts, text_layout_id) 1936 1937 return BinaryImagesFromExclavesLayout(layout) 1938 1939 1940# kcdata is json at path 'kcdata_stackshot/threads_exclave/0' 1941def GetEASFrames(AllImageCatalog, kcdata, ipc_entry, notes, scid): 1942 info = ipc_entry['exclave_ipcstackentry_info'] 1943 asid = info['eise_asid'] 1944 1945 address_spaces = kcdata.get('exclave_addressspace') 1946 if not address_spaces: 1947 notes.warn("PID ${PID} TID ${TID} SCID %d Missing address spaces info" % scid) 1948 return [] 1949 as_info = address_spaces.get(str(asid)) 1950 if not as_info: 1951 notes.warn("PID ${PID} TID ${TID} SCID %d Missing address space info for ASID 0x%x" % (scid, asid)) 1952 return [] 1953 text_layout_id = as_info['exclave_addressspace_info']['eas_layoutid'] 1954 addr_space_name = as_info['exclave_addressspace_name'] 1955 1956 exclave_libs = GetExclaveLibs(kcdata['exclave_textlayout'], text_layout_id) 1957 1958 frames = [] 1959 stack = ipc_entry.get('secure_ecstack_entry', []) 1960 for stack_item in stack: 1961 lr = GetLongForAddress(stack_item['lr']) 1962 # this is a buggy value of unknown origin 1963 # rdar://123508690 (Some Exclave Stackshot frames ends with invalid value 0xFFFF000000000000) 1964 if lr == 0xFFFF000000000000: 1965 continue 1966 frames.append(GetSymbolInfoForFrame(AllImageCatalog, exclave_libs, lr)) 1967 1968 if frames: 1969 frame_info = "frames %d to %d" % (notes.offset, notes.offset + len(frames) - 1) 1970 else: 1971 frame_info = "no frames" 1972 notes.info("PID ${PID} TID ${TID} SCID %d ASID 0x%x has address space name '%s' (%s)" % (scid, asid, addr_space_name, frame_info)) 1973 notes.addToOffset(len(frames)) 1974 return frames 1975 1976 1977def GetExclavesFrames(AllImageCatalog, json, scid, notes): 1978 kcdata = json['kcdata_stackshot'] 1979 threads_exclave = kcdata.get('threads_exclave') 1980 if not threads_exclave: 1981 notes.warn("PID ${PID} TID ${TID} no threads_exclave info found, skipping exclaves frames") 1982 return [] 1983 1984 exclaves_content = threads_exclave.get('0') 1985 if not exclaves_content: 1986 notes.warn("PID ${PID} TID ${TID} threads_exclave data not found, skipping exclaves frames") 1987 return [] 1988 1989 threads_info = exclaves_content.get('thread_exclave') 1990 if not threads_info: 1991 notes.warn("PID ${PID} TID ${TID} no thread_exclave info found, skipping exclaves frames") 1992 return [] 1993 1994 scid_info = threads_info.get(str(scid)) 1995 if not scid_info: 1996 notes.warn("PID ${PID} TID ${TID} no exclaves info available for SCID %d, skipping exclaves frames" % scid) 1997 return [] 1998 1999 frames = [] 2000 2001 ipc_stack = scid_info.get("exclave_ipcstackentry") 2002 if not ipc_stack: 2003 notes.info("\nPID ${PID} TID ${TID} SCID %d IPC chain is missing" % scid) 2004 return [] 2005 notes.info("\nPID ${PID} TID ${TID} SCID %d has IPC chain with %d items:" % (scid, len(ipc_stack))) 2006 for i in reversed(range(len(ipc_stack))): 2007 ipc_entry = ipc_stack[str(i)] 2008 entry_frames = GetEASFrames(AllImageCatalog, exclaves_content, ipc_entry, notes, scid) 2009 frames.extend(entry_frames) 2010 2011 return frames 2012 2013 2014def InsertExclavesFrames(AllImageCatalog, json, thdata, notes, kernel_frames): 2015 thread_info = thdata.get('exclaves_thread_info') 2016 if not thread_info: 2017 # this is not exclave thread 2018 return 2019 2020 scid = thread_info["tei_scid"] 2021 offset = thread_info["tei_thread_offset"] 2022 notes.offset = offset 2023 2024 exclaves_frames = GetExclavesFrames(AllImageCatalog, json, scid, notes) 2025 2026 # insert exclaves frames to offset 2027 for i in range(len(exclaves_frames)): 2028 kernel_frames.insert(offset + i, exclaves_frames[i]) 2029 2030class NotesBuilder: 2031 2032 notes = [] 2033 pid = None 2034 tis = None 2035 offset = 0 2036 2037 def __init__(self, pid, tid): 2038 self.pid = pid 2039 self.tid = tid 2040 self.notes = [] 2041 self.offset = 0 # offset of next IPC stack in kernel stack 2042 2043 # Replace ${PID} with a PID and ${TID} with TID and add newline 2044 def format(self, note): 2045 note = note.replace('${PID}', str(self.pid)) 2046 note = note.replace('${TID}', str(self.tid)) 2047 return note + '\n' 2048 2049 def warn(self, note): 2050 note = self.format(note) 2051 sys.stdout.write(note) 2052 self.notes.append(note) 2053 2054 def info(self, note): 2055 note = self.format(note) 2056 self.notes.append(note) 2057 2058 def isEmpty(self): 2059 return len(self.notes) == 0 2060 2061 def text(self): 2062 return ''.join(self.notes) 2063 2064 def addToOffset(self, frame_count): 2065 self.offset += frame_count 2066 2067def SaveStackshotReport(j, outfile_name, incomplete): 2068 import time 2069 from operator import itemgetter, attrgetter 2070 ss = j.get('kcdata_stackshot') 2071 if not ss: 2072 print("No KCDATA_BUFFER_BEGIN_STACKSHOT object found. Skipping writing report.") 2073 return 2074 2075 timestamp = ss.get('usecs_since_epoch') 2076 try: 2077 timestamp = time.strftime("%Y-%m-%d %H:%M:%S +0000",time.gmtime(timestamp // 1000000 if timestamp else None)) 2078 except ValueError as e: 2079 print("couldn't convert timestamp:", str(e)) 2080 timestamp = None 2081 2082 os_version = ss.get('osversion', 'Unknown') 2083 timebase = ss.get('mach_timebase_info', {"denom": 1, "numer": 1}) 2084 2085 sc_note = None 2086 extra_note = None 2087 dsc_common = None 2088 shared_cache_info = ss.get('shared_cache_dyld_load_info') 2089 if shared_cache_info: 2090 shared_cache_base_addr = shared_cache_info['imageSlidBaseAddress'] 2091 # If we have a slidFirstMapping and it's >= base_address, use that. 2092 # 2093 # Otherwise we're processing a stackshot from before the slidFirstMapping 2094 # field was introduced and corrected. On ARM the SlidBaseAddress is the 2095 # same, but on x86 it's off by 0x20000000. We use 'X86_64' in the 2096 # kernel version string plus checking kern_page_size == 4k' as 2097 # proxy for x86_64, and only adjust SlidBaseAddress if the unslid 2098 # address is precisely the expected incorrect value. 2099 # 2100 is_intel = ('X86_64' in ss.get('osversion', "") and 2101 ss.get('kernel_page_size', 0) == 4096) 2102 slidFirstMapping = shared_cache_info.get(SC_SLID_FIRSTMAPPING_KEY, -1); 2103 if slidFirstMapping >= shared_cache_base_addr: 2104 shared_cache_base_addr = slidFirstMapping 2105 sc_note = "base-accurate" 2106 2107 elif is_intel: 2108 sc_slide = shared_cache_info['imageLoadAddress'] 2109 if (shared_cache_base_addr - sc_slide) == 0x7fff00000000: 2110 shared_cache_base_addr += 0x20000000 2111 sc_note = "base-x86-adjusted" 2112 extra_note = "Shared cache base adjusted for x86. " 2113 else: 2114 sc_note = "base-x86-unknown" 2115 2116 dsc_common = [format_uuid(shared_cache_info['imageUUID']), 2117 shared_cache_base_addr, "S" ] 2118 print("Shared cache UUID found from the binary data is <%s> " % str(dsc_common[0])) 2119 2120 dsc_layout = ss.get('system_shared_cache_layout') 2121 2122 dsc_libs = [] 2123 if dsc_layout: 2124 print("Found in memory system shared cache layout with {} images".format(len(dsc_layout))) 2125 slide = ss.get('shared_cache_dyld_load_info')['imageLoadAddress'] 2126 2127 for image in dsc_layout: 2128 dsc_libs.append([format_uuid(image['imageUUID']), image['imageLoadAddress'] + slide, "C"]) 2129 2130 AllImageCatalog = [] 2131 obj = {} 2132 obj["kernel"] = os_version 2133 if timestamp is not None: 2134 obj["date"] = timestamp 2135 obj["reason"] = "kernel panic stackshot" 2136 obj["incident"] = "ABCDEFGH-1234-56IJ-789K-0LMNOPQRSTUV" 2137 obj["crashReporterKey"] = "12ab34cd45aabbccdd6712ab34cd45aabbccdd67" 2138 obj["bootArgs"] = ss.get('boot_args','') 2139 obj["frontmostPids"] = [0] 2140 obj["exception"] = "0xDEADF157" 2141 obj["processByPid"] = {} 2142 if sc_note is not None: 2143 obj["sharedCacheNote"] = sc_note 2144 2145 if incomplete: 2146 obj["reason"] = "!!!INCOMPLETE!!! kernel panic stackshot" 2147 obj["notes"] = "Generated by xnu kcdata.py from incomplete data! Some information is missing! " 2148 else: 2149 obj["notes"] = "Generated by xnu kcdata.py. " 2150 2151 if extra_note is not None: 2152 obj["notes"] = obj["notes"] + extra_note 2153 2154 processByPid = obj["processByPid"] 2155 ssplist = ss.get('task_snapshots', {}) 2156 ssplist.update(ss.get('transitioning_task_snapshots', {})) 2157 kern_load_info = [] 2158 if "0" in ssplist: 2159 kc_uuid = ssplist["0"].get('kernelcache_load_info', None) 2160 if kc_uuid: 2161 kernelcache_uuid = [format_uuid(kc_uuid['imageUUID']), kc_uuid['imageLoadAddress'], "U" ] 2162 kern_load_info.append(kernelcache_uuid) 2163 2164 kl_infos = ssplist["0"].get("dyld_load_info", []) 2165 for dlinfo in kl_infos: 2166 kern_load_info.append([format_uuid(dlinfo['imageUUID']), dlinfo['imageLoadAddress'], "K"]) 2167 2168 kl_infos_text_exec = ssplist["0"].get("dyld_load_info_text_exec", []) 2169 for dlinfo in kl_infos_text_exec: 2170 kern_load_info.append([format_uuid(dlinfo['imageUUID']), dlinfo['imageLoadAddress'], "T"]) 2171 2172 for pid,piddata in sorted(ssplist.items()): 2173 processByPid[str(pid)] = {} 2174 tsnap = processByPid[str(pid)] 2175 pr_lib_dsc = dsc_common 2176 2177 # see if there's an alternate shared cache 2178 scd = piddata.get('shared_cache_dyld_load_info') 2179 if scd is not None: 2180 if 'imageSlidBaseAddress' not in scd: 2181 print("Specific task shared cache format does not include slid shared cache base address. Skipping writing report.") 2182 return 2183 2184 scd_uuid = format_uuid(scd['imageUUID']) 2185 scd_base_addr = scd['imageSlidBaseAddress'] 2186 pr_lib_dsc = [scd_uuid, scd_base_addr, "S"] 2187 2188 pr_libs = [] 2189 if len(dsc_libs) == 0 and pr_lib_dsc: 2190 pr_libs.append(pr_lib_dsc) 2191 _lib_type = "P" 2192 if int(pid) == 0: 2193 _lib_type = "K" 2194 pr_libs = [] 2195 else: 2196 for dlinfo in piddata.get('dyld_load_info',[]): 2197 pr_libs.append([format_uuid(dlinfo['imageUUID']), dlinfo['imageLoadAddress'], _lib_type]) 2198 2199 pr_libs.extend(kern_load_info) 2200 pr_libs.extend(dsc_libs) 2201 2202 if 'jit_address_range' in piddata: 2203 address_range = piddata.get('jit_address_range', {}) 2204 tsnap['jitStartAddress'] = address_range['start_address'] 2205 tsnap['jitEndAddress'] = address_range['end_address'] 2206 pr_libs.append([format_uuid("00000000000000000000000000000000"), tsnap['jitStartAddress'] , "J"]) 2207 pr_libs.sort(key=itemgetter(1)) 2208 ttsnap = piddata.get('transitioning_task_snapshot', None) 2209 if ttsnap is not None: 2210 # Transitioning task snapshots have "tts_" prefixes; change them to 2211 # "ts_". 2212 ttsnap = { key[1:] : value for key,value in ttsnap.items() } 2213 # Add a note to let people know 2214 obj["notes"] = obj["notes"] + "PID {} is a transitioning (exiting) task. ".format(pid) 2215 tasksnap = piddata.get('task_snapshot', ttsnap); 2216 if tasksnap is None: 2217 continue; 2218 tsnap["pid"] = tasksnap["ts_pid"] 2219 if 'ts_asid' in piddata: 2220 tsnap["asid"] = piddata["ts_asid"] 2221 2222 if 'ts_pagetable' in piddata: 2223 pagetables = [] 2224 for tte in piddata["ts_pagetable"]: 2225 pagetables.append(tte) 2226 tsnap["pageTables"] = pagetables 2227 2228 # Some fields are missing from transitioning_task snapshots. 2229 if ttsnap is None: 2230 tsnap["residentMemoryBytes"] = tasksnap["ts_task_size"] 2231 tsnap["timesDidThrottle"] = tasksnap["ts_did_throttle"] 2232 tsnap["systemTimeTask"] = GetSecondsFromMATime(tasksnap["ts_system_time_in_terminated_th"], timebase) 2233 tsnap["pageIns"] = tasksnap["ts_pageins"] 2234 tsnap["pageFaults"] = tasksnap["ts_faults"] 2235 tsnap["userTimeTask"] = GetSecondsFromMATime(tasksnap["ts_user_time_in_terminated_thre"], timebase) 2236 tsnap["procname"] = tasksnap["ts_p_comm"] 2237 if ttsnap is None: 2238 tsnap["copyOnWriteFaults"] = tasksnap["ts_cow_faults"] 2239 tsnap["timesThrottled"] = tasksnap["ts_was_throttled"] 2240 tsnap["threadById"] = {} 2241 threadByID = tsnap["threadById"] 2242 thlist = piddata.get('thread_snapshots', {}) 2243 for tid,thdata in sorted(thlist.items()): 2244 threadByID[str(tid)] = {} 2245 thsnap = threadByID[str(tid)] 2246 if "thread_snapshot" not in thdata: 2247 print("Found broken thread state for thread ID: %s." % tid) 2248 break 2249 threadsnap = thdata["thread_snapshot"] 2250 thsnap["userTime"] = GetSecondsFromMATime(threadsnap["ths_user_time"], timebase) 2251 thsnap["id"] = threadsnap["ths_thread_id"] 2252 thsnap["basePriority"] = threadsnap["ths_base_priority"] 2253 thsnap["systemTime"] = GetSecondsFromMATime(threadsnap["ths_sys_time"], timebase) 2254 thsnap["schedPriority"] = threadsnap["ths_sched_priority"] 2255 thsnap["state"] = GetStateDescription(threadsnap['ths_state']) 2256 thsnap["qosEffective"] = threadsnap["ths_eqos"] 2257 thsnap["qosRequested"] = threadsnap["ths_rqos"] 2258 2259 if "pth_name" in thdata: 2260 thsnap["name"] = thdata["pth_name"]; 2261 2262 if threadsnap['ths_continuation']: 2263 thsnap["continuation"] = GetSymbolInfoForFrame(AllImageCatalog, pr_libs, threadsnap['ths_continuation']) 2264 if "kernel_stack_frames" in thdata: 2265 kuserframes = [] 2266 for f in thdata["kernel_stack_frames"]: 2267 kuserframes.append(GetSymbolInfoForFrame(AllImageCatalog, pr_libs, f['lr'])) 2268 notesBuilder = NotesBuilder(tsnap['pid'], tid) 2269 InsertExclavesFrames(AllImageCatalog, j, thdata, notesBuilder, kuserframes) 2270 if not notesBuilder.isEmpty(): 2271 obj['notes'] += notesBuilder.text() 2272 thsnap["kernelFrames"] = kuserframes 2273 2274 if "user_stack_frames" in thdata: 2275 uframes = [] 2276 for f in thdata["user_stack_frames"]: 2277 uframes.append(GetSymbolInfoForFrame(AllImageCatalog, pr_libs, f['lr'])) 2278 thsnap["userFrames"] = uframes 2279 2280 if "user_stacktop" in thdata: 2281 (address,) = struct.unpack("<Q", struct.pack("B"*8, *thdata["user_stacktop"]["stack_contents"])) 2282 thsnap["userStacktop"] = GetSymbolInfoForFrame(AllImageCatalog, pr_libs, address) 2283 2284 if threadsnap['ths_wait_event']: 2285 thsnap["waitEvent"] = GetSymbolInfoForFrame(AllImageCatalog, pr_libs, threadsnap['ths_wait_event']) 2286 2287 if 'thread_waitinfo' in piddata and 'thread_turnstileinfo' in piddata: 2288 tsnap['waitInfo'] = formatWaitInfoWithTurnstiles(piddata['thread_waitinfo'], piddata['thread_turnstileinfo'], piddata.get('portlabels', None)) 2289 elif 'thread_waitinfo' in piddata: 2290 portlabels = ss.get('portlabels', None) 2291 tsnap['waitInfo'] = [formatWaitInfo(x, False, portlabels) for x in piddata['thread_waitinfo']] 2292 if 'stackshot_task_codesigning_info' in piddata: 2293 csinfo = piddata.get('stackshot_task_codesigning_info', {}) 2294 tsnap['csFlags'] = csinfo['csflags'] 2295 tsnap['csTrustLevel'] = csinfo['cs_trust_level'] 2296 if 'suspension_info' in piddata: 2297 suspinfo = piddata.get('suspension_info', {}) 2298 tsnap['suspension_count'] = suspinfo['tss_count'] 2299 tsnap['suspension_duration_secs'] = GetSecondsFromMATime(suspinfo['tss_duration'], timebase) 2300 tsnap['suspension_last_start'] = GetSecondsFromMATime(suspinfo['tss_last_start'], timebase) 2301 tsnap['suspension_last_end'] = GetSecondsFromMATime(suspinfo['tss_last_end'], timebase) 2302 2303 suspsources = piddata.get('suspension_source', []) 2304 suspension_sources = [] 2305 for source in filter(lambda x: x['tss_time'] != 0, suspsources): 2306 suspension_sources.append({ 2307 'suspension_time': GetSecondsFromMATime(source['tss_time'], timebase), 2308 'suspension_tid': source['tss_tid'], 2309 'suspension_pid': source['tss_pid'], 2310 'suspension_procname': source['tss_procname'], 2311 }) 2312 2313 tsnap['suspension_sources'] = suspension_sources 2314 # check if process is currently suspended 2315 if tsnap['suspension_last_start'] > tsnap['suspension_last_end']: 2316 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']) 2317 for source in suspension_sources: 2318 obj['notes'] += "From PID {} TID {} ({}) - at {}\n".format(source['suspension_pid'], source['suspension_tid'], source['suspension_procname'], source['suspension_time']) 2319 2320 obj['binaryImages'] = AllImageCatalog 2321 if outfile_name == '-': 2322 fh = sys.stdout 2323 else: 2324 fh = open(outfile_name, "w") 2325 2326 header = {} 2327 header['bug_type'] = 288 2328 if timestamp is not None: 2329 header['timestamp'] = timestamp 2330 header['os_version'] = os_version 2331 fh.write(json.dumps(header, sort_keys=True)) 2332 fh.write("\n") 2333 2334 fh.write(json.dumps(obj, sort_keys=True, indent=2, separators=(',', ': '))) 2335 fh.close() 2336 2337 2338@contextlib.contextmanager 2339def data_from_stream(stream): 2340 try: 2341 fmap = mmap.mmap(stream.fileno(), 0, mmap.MAP_SHARED, mmap.PROT_READ) 2342 except: 2343 yield stream.buffer.read() 2344 else: 2345 try: 2346 yield fmap 2347 finally: 2348 fmap.close() 2349 2350def iterate_kcdatas(kcdata_file): 2351 with data_from_stream(kcdata_file) as data: 2352 iterator = kcdata_item_iterator(data) 2353 kcdata_buffer = KCObject.FromKCItem(next(iterator)) 2354 2355 if isinstance(kcdata_buffer, KCCompressedBufferObject): 2356 kcdata_buffer.ReadItems(iterator) 2357 decompressed = kcdata_buffer.Decompress(data) 2358 iterator = kcdata_item_iterator(decompressed) 2359 kcdata_buffer = KCObject.FromKCItem(next(iterator)) 2360 2361 if not isinstance(kcdata_buffer, KCBufferObject): 2362 # ktrace stackshot chunk 2363 iterator = kcdata_item_iterator(data[16:]) 2364 kcdata_buffer = KCObject.FromKCItem(next(iterator)) 2365 2366 if not isinstance(kcdata_buffer, KCBufferObject): 2367 try: 2368 decoded = base64.b64decode(data) 2369 except: 2370 pass 2371 else: 2372 iterator = kcdata_item_iterator(decoded) 2373 kcdata_buffer = KCObject.FromKCItem(next(iterator)) 2374 if not isinstance(kcdata_buffer, KCBufferObject): 2375 import gzip 2376 from io import BytesIO 2377 try: 2378 decompressed = gzip.GzipFile(fileobj=BytesIO(data[:])).read() 2379 except: 2380 pass 2381 else: 2382 iterator = kcdata_item_iterator(decompressed) 2383 kcdata_buffer = KCObject.FromKCItem(next(iterator)) 2384 2385 if not isinstance(kcdata_buffer, KCBufferObject): 2386 raise Exception("unknown file type") 2387 2388 2389 kcdata_buffer.ReadItems(iterator) 2390 yield kcdata_buffer 2391 2392 for magic in iterator: 2393 kcdata_buffer = KCObject.FromKCItem(magic) 2394 if kcdata_buffer.i_type == 0: 2395 continue 2396 if not isinstance(kcdata_buffer, KCBufferObject): 2397 raise Exception("unknown file type") 2398 kcdata_buffer.ReadItems(iterator) 2399 yield kcdata_buffer 2400 2401# 2402# Values for various flag fields. Each entry's key is the key seen in the 2403# processed kcdata, the value is an array of bits, from low (0x1) to high, with 2404# either a string flag name or None for unused holes. 2405# 2406# Only put flags in here which are stable - this is run against stackshots 2407# of all different versions. For anything unstable, we'll need a decoder ring 2408# added to the stackshot. 2409# 2410PRETTIFY_FLAGS = { 2411 'jcs_flags': [ 2412 'kCoalitionTermRequested', 2413 'kCoalitionTerminated', 2414 'kCoalitionReaped', 2415 'kCoalitionPrivileged', 2416 ], 2417 'sharedCacheFlags': [ 2418 'kSharedCacheSystemPrimary', 2419 'kSharedCacheDriverkit' 2420 'kSharedCacheAOT', 2421 ], 2422 'stackshot_in_flags': [ # STACKSHOT_*, also stackshot_out_flags 2423 'get_dq', 2424 'save_loadinfo', 2425 'get_global_mem_stats', 2426 'save_kext_loadinfo', 2427 None, 2428 None, 2429 None, 2430 None, 2431 'active_kernel_threads_only', 2432 'get_boot_profile', 2433 'do_compress', 2434 None, 2435 None, 2436 'save_imp_donation_pids', 2437 'save_in_kernel_buffer', 2438 'retrieve_existing_buffer', 2439 'kcdata_format', 2440 'enable_bt_faulting', 2441 'collect_delta_snapshot', 2442 'collect_sharedcache_layout', 2443 'trylock', 2444 'enable_uuid_faulting', 2445 'from_panic', 2446 'no_io_stats', 2447 'thread_waitinfo', 2448 'thread_group', 2449 'save_jetsam_coalitions', 2450 'instrs_cycles', 2451 'asid', 2452 'page_tables', 2453 'disable_latency_info', 2454 'save_dyld_compactinfo', 2455 'include_driver_threads_in_kernel', 2456 'exclaves', 2457 ], 2458 'system_state_flags': [ 2459 'kUser64_p', 2460 'kKern64_p', 2461 ], 2462 'tgs_flags': [ 2463 'kThreadGroupEfficient', 2464 'kThreadGroupApplication', 2465 'kThreadGroupCritical', 2466 'kThreadGroupBestEffort', 2467 None, 2468 None, 2469 None, 2470 None, 2471 'kThreadGroupUIApplication', 2472 'kThreadGroupManaged', 2473 'kThreadGroupStrictTimers', 2474 ], 2475 'ths_ss_flags': [ 2476 'kUser64_p', 2477 'kKern64_p', 2478 'kHasDispatchSerial', 2479 'kStacksPCOnly', 2480 'kThreadDarwinBG', 2481 'kThreadIOPassive', 2482 'kThreadSuspended', 2483 'kThreadTruncatedBT', 2484 'kGlobalForcedIdle', 2485 'kThreadFaultedBT', 2486 'kThreadTriedFaultBT', 2487 'kThreadOnCore', 2488 'kThreadIdleWorker', 2489 'kThreadMain', 2490 'kThreadTruncKernBT', 2491 'kThreadTruncUserBT', 2492 'kThreadTruncUserAsyncBT', 2493 'kThreadExclaveRPCActive', 2494 'kThreadExclaveUpcallActive', 2495 'kThreadExclaveSchedulerRequest', 2496 ], 2497 'ths_state': [ 2498 'TH_WAIT', 2499 'TH_SUSP', 2500 'TH_RUN', 2501 'TH_UNINT', 2502 'TH_TERMINATE', 2503 'TH_TERMINATE2', 2504 'TH_WAIT_REPORT', 2505 'TH_IDLE', 2506 ], 2507 'ts_ss_flags': [ 2508 'kUser64_p', 2509 'kKern64_p', 2510 'kTaskRsrcFlagged', 2511 'kTerminatedSnapshot', 2512 'kPidSuspended', 2513 'kFrozen', 2514 'kTaskDarwinBG', 2515 'kTaskExtDarwinBG', 2516 'kTaskVisVisible', 2517 'kTaskVisNonvisible', 2518 'kTaskIsForeground', 2519 'kTaskIsBoosted', 2520 'kTaskIsSuppressed', 2521 'kTaskIsTimerThrottled', 2522 'kTaskIsImpDonor', 2523 'kTaskIsLiveImpDonor', 2524 'kTaskIsDirty', 2525 'kTaskWqExceededConstrainedThreadLimit', 2526 'kTaskWqExceededTotalThreadLimit', 2527 'kTaskWqFlagsAvailable', 2528 'kTaskUUIDInfoFaultedIn', 2529 'kTaskUUIDInfoMissing', 2530 'kTaskUUIDInfoTriedFault', 2531 'kTaskSharedRegionInfoUnavailable', 2532 'kTaskTALEngaged', 2533 None, 2534 'kTaskIsDirtyTracked', 2535 'kTaskAllowIdleExit', 2536 'kTaskIsTranslated', 2537 'kTaskSharedRegionNone', 2538 'kTaskSharedRegionSystem', 2539 'kTaskSharedRegionOther', 2540 'kTaskDyldCompactInfoNone', 2541 'kTaskDyldCompactInfoTooBig', 2542 'kTaskDyldCompactInfoFaultedIn', 2543 'kTaskDyldCompactInfoMissing', 2544 'kTaskDyldCompactInfoTriedFault', 2545 'kTaskWqExceededCooperativeThreadLimit', 2546 'kTaskWqExceededActiveConstrainedThreadLimit', 2547 ], 2548 'turnstile_flags': [ 2549 'turnstile_status_unknown', 2550 'turnstile_status_locked_waitq', 2551 'turnstile_status_workqueue', 2552 'turnstile_status_thread', 2553 'turnstile_status_blocked_on_task', 2554 'turnstile_status_held_iplock', 2555 ], 2556 'portlabel_flags': [ 2557 'label_read_failed', 2558 'service_throttled', 2559 ], 2560 'esc_flags': [ 2561 'kExclaveScresultHaveIPCStack', 2562 ], 2563 'eise_flags': [ 2564 'kExclaveIpcStackEntryHaveInvocationID', 2565 'kExclaveIpcStackEntryHaveStack', 2566 ], 2567 'eas_flags': [ 2568 'kExclaveAddressSpaceHaveSlide', 2569 ], 2570 'etl_flags': [ 2571 'kExclaveTextLayoutLoadAddressesSynthetic', 2572 'kExclaveTextLayoutLoadAddressesUnslid', 2573 'kExclaveTextLayoutHasSharedCache', 2574 ], 2575} 2576PRETTIFY_FLAGS['stackshot_out_flags'] = PRETTIFY_FLAGS['stackshot_in_flags'] 2577PRETTIFY_FLAGS['tts_ss_flags'] = PRETTIFY_FLAGS['ts_ss_flags'] 2578 2579# Fields which should never be hexified 2580PRETTIFY_DONTHEX = { 2581 'stackshot_in_pid': True, 2582 'tts_pid': True, 2583 'ts_pid': True, 2584 'donating_pids': True, 2585 'ppid': True, 2586} 2587 2588# Only hex() the value if it is multiple digits 2589def prettify_hex(v): 2590 if v < -9 or v > 9: 2591 return hex(v) 2592 return str(v) 2593 2594def prettify_flags(v, flags): 2595 output="" 2596 seen = 0 2597 if v == 0: 2598 return "0" 2599 for (s, n) in zip(range(len(flags)),flags): 2600 if n is None: 2601 continue 2602 if (v & (2 ** s)): 2603 output += "|" + n 2604 seen |= 2 ** s 2605 if output == "": 2606 return prettify_hex(v) 2607 rest = (v & ~seen) 2608 if (rest != 0): 2609 output += "|" + prettify_hex(rest) 2610 return prettify_hex(v) + " (" + output[1:] + ")" 2611 2612def prettify_core(data, mosthex, key, portlabels): 2613 if key == 'stack_contents': 2614 (address,) = struct.unpack("<Q", struct.pack("B"*8, *data)) 2615 return '0x%X' % address 2616 2617 elif isinstance(data, list): 2618 if 'uuid' in key.lower() and len(data) == 16: 2619 return '%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X' % tuple(data) 2620 2621 return [prettify_core(x, mosthex, key, portlabels) for x in data] 2622 2623 elif key == 'thread_waitinfo': 2624 return formatWaitInfo(data, mosthex, portlabels) 2625 2626 elif isinstance(data, dict): 2627 if 'portlabels' in data: 2628 portlabels = data['portlabels'] 2629 newdata = dict() 2630 for key, value in data.items(): 2631 if mosthex and key != 'task_snapshots' and len(key) > 0 and key.isnumeric(): 2632 key = prettify_hex(int(key)) 2633 newdata[key] = prettify_core(value, mosthex, key, portlabels) 2634 return newdata 2635 2636 elif 'address' in key.lower() and isinstance(data, (int, long)): 2637 return '0x%X' % data 2638 elif key == 'lr' or key == SC_SLID_FIRSTMAPPING_KEY: 2639 return '0x%X' % data 2640 elif key in PRETTIFY_FLAGS and isinstance(data, (int, long)): 2641 return prettify_flags(data, PRETTIFY_FLAGS[key]) 2642 elif key.endswith('_flags') and isinstance(data, (int, long)): 2643 return prettify_hex(data) 2644 2645 elif mosthex and not PRETTIFY_DONTHEX.get(key, False): 2646 if isinstance(data, (int, long)): 2647 return prettify_hex(data) 2648 elif isinstance(data, str) and len(data) > 0 and data.isnumeric(): 2649 return prettify_hex(int(data)) 2650 return data 2651 2652 else: 2653 return data 2654 2655def prettify(data, mosthex): 2656 return prettify_core(data, mosthex, "", None) 2657 2658# N.B.: This is called directly from `xnu.py` for `panicdata -S XXX.ips`'s implementation. 2659def decode_kcdata_file(kcdata_file, stackshot_file, multiple=False, prettyhex=False, pretty=False, output_as_plist=False): 2660 for i,kcdata_buffer in enumerate(iterate_kcdatas(kcdata_file)): 2661 if i > 0 and not multiple: 2662 break 2663 2664 str_data = "{" + kcdata_buffer.GetJsonRepr() + "}" 2665 str_data = str_data.replace("\t", " ") 2666 2667 try: 2668 json_obj = json.loads(str_data) 2669 except: 2670 print("JSON reparsing failed! Printing string data!\n", file=sys.stderr) 2671 import textwrap 2672 print(textwrap.fill(str_data, 100)) 2673 raise 2674 2675 if prettyhex: 2676 json_obj = prettify(json_obj, True) 2677 elif pretty: 2678 json_obj = prettify(json_obj, False) 2679 2680 if stackshot_file: 2681 SaveStackshotReport(json_obj, stackshot_file, G.data_was_incomplete) 2682 elif output_as_plist: 2683 import Foundation 2684 plist = Foundation.NSPropertyListSerialization.dataWithPropertyList_format_options_error_( 2685 json_obj, Foundation.NSPropertyListXMLFormat_v1_0, 0, None)[0].bytes().tobytes() 2686 #sigh. on some pythons long integers are getting output with L's in the plist. 2687 plist = re.sub(r'^(\s*<integer>\d+)L(</integer>\s*)$', r"\1\2", BytesToString(plist), flags=re.MULTILINE) 2688 print(plist,) 2689 else: 2690 print(json.dumps(json_obj, sort_keys=True, indent=4, separators=(',', ': '))) 2691 2692if __name__ == '__main__': 2693 parser = argparse.ArgumentParser(description="Decode a kcdata binary file.") 2694 parser.add_argument("-l", "--listtypes", action="store_true", required=False, default=False, 2695 help="List all known types", 2696 dest="list_known_types") 2697 2698 parser.add_argument("-s", "--stackshot", required=False, default=False, 2699 help="Generate a stackshot report file", 2700 dest="stackshot_file") 2701 2702 parser.add_argument("--multiple", help="look for multiple stackshots in a single file", action='store_true') 2703 2704 parser.add_argument("-p", "--plist", required=False, default=False, 2705 help="output as plist", action="store_true") 2706 2707 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") 2708 parser.add_argument("-P", "--pretty", default=False, action='store_true', help="make the output a little more human readable") 2709 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") 2710 parser.add_argument("--incomplete", action='store_true', help="accept incomplete data") 2711 parser.add_argument("kcdata_file", type=argparse.FileType('r'), help="Path to a kcdata binary file.") 2712 2713 class VerboseAction(argparse.Action): 2714 def __call__(self, parser, namespace, values, option_string=None): 2715 logging.basicConfig(level=logging.INFO, stream=sys.stderr, format='%(message)s') 2716 parser.add_argument('-v', "--verbose", action=VerboseAction, nargs=0) 2717 2718 args = parser.parse_args() 2719 2720 if args.multiple and args.stackshot_file: 2721 raise NotImplementedError 2722 2723 if args.pretty and args.stackshot_file: 2724 raise NotImplementedError 2725 2726 if args.list_known_types: 2727 for (n, t) in KNOWN_TYPES_COLLECTION.items(): 2728 print("%d : %s " % (n, str(t))) 2729 sys.exit(1) 2730 2731 if args.incomplete or args.stackshot_file: 2732 G.accept_incomplete_data = True 2733 2734 decode_kcdata_file(args.kcdata_file, args.stackshot_file, args.multiple, args.prettyhex, args.pretty, args.plist) 2735