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