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 1645kThreadWaitExclaveCore = 0x1e 1646kThreadWaitExclaveKit = 0x1f 1647 1648 1649UINT64_MAX = 0xffffffffffffffff 1650STACKSHOT_WAITOWNER_KERNEL = (UINT64_MAX - 1) 1651STACKSHOT_WAITOWNER_PORT_LOCKED = (UINT64_MAX - 2) 1652STACKSHOT_WAITOWNER_PSET_LOCKED = (UINT64_MAX - 3) 1653STACKSHOT_WAITOWNER_INTRANSIT = (UINT64_MAX - 4) 1654STACKSHOT_WAITOWNER_MTXSPIN = (UINT64_MAX - 5) 1655STACKSHOT_WAITOWNER_THREQUESTED = (UINT64_MAX - 6) 1656STACKSHOT_WAITOWNER_SUSPENDED = (UINT64_MAX - 7) 1657 1658STACKSHOT_TURNSTILE_STATUS_UNKNOWN = 0x01 1659STACKSHOT_TURNSTILE_STATUS_LOCKED_WAITQ = 0x02 1660STACKSHOT_TURNSTILE_STATUS_WORKQUEUE = 0x04 1661STACKSHOT_TURNSTILE_STATUS_THREAD = 0x08 1662STACKSHOT_TURNSTILE_STATUS_BLOCKED_ON_TASK = 0x10 1663STACKSHOT_TURNSTILE_STATUS_HELD_IPLOCK = 0x20 1664STACKSHOT_TURNSTILE_STATUS_SENDPORT = 0x40 1665STACKSHOT_TURNSTILE_STATUS_RECEIVEPORT = 0x80 1666 1667# 1668# These come from xpc_domain_type_t in <xpc/launch_private.h> 1669PORTLABEL_DOMAINS = { 1670 1: 'system', # XPC_DOMAIN_SYSTEM 1671 2: 'user', # XPC_DOMAIN_USER 1672 5: 'pid', # XPC_DOMAIN_PID 1673 7: 'port', # XPC_DOMAIN_PORT 1674} 1675def portlabel_domain(x): 1676 if x is None: 1677 return "unknown" 1678 return PORTLABEL_DOMAINS.get(x, "unknown.{}".format(x)) 1679 1680STACKSHOT_WAITINFO_FLAGS_SPECIALREPLY = 0x1 1681STACKSHOT_PORTLABEL_THROTTLED = 0x2 1682 1683def portThrottledSuffix(portlabel_flags): 1684 if (portlabel_flags & STACKSHOT_PORTLABEL_THROTTLED): 1685 return " (service port throttled by launchd)" 1686 else: 1687 return "" 1688 1689def formatPortLabelID(portlabel_id, portlabels): 1690 portlabel = {} 1691 if portlabel_id > 0: 1692 if portlabels is not None: 1693 portlabel = portlabels.get(str(portlabel_id), {}) 1694 portlabel_name = portlabel_domain(portlabel.get('portlabel_domain')) + " " 1695 portlabel_name += portlabel.get("portlabel_name", "!!!unknown, ID {} !!!".format(portlabel_id)); 1696 return " {" + portlabel_name + portThrottledSuffix(portlabel.get('portlabel_flags', 0)) + "}" 1697 if portlabel_id < 0: 1698 return " {labeled, info truncated" + portThrottledSuffix(portlabel.get('portlabel_flags', 0)) + "}" 1699 return "" 1700 1701def formatWaitInfo(info, wantHex, portlabels): 1702 base='#x' if wantHex else 'd' 1703 s = 'thread {0:{base}}: '.format(info['waiter'], base=base) 1704 type = info['wait_type'] 1705 context = info['context'] 1706 owner = info['owner'] 1707 ownerThread = "{0:{base}}".format(owner, base=base) 1708 portlabel_id = info.get('portlabel_id', 0) 1709 flags = info.get('wait_flags', 0) 1710 1711 if type == kThreadWaitKernelMutex: 1712 s += 'kernel mutex %x' % context 1713 if owner == STACKSHOT_WAITOWNER_MTXSPIN: 1714 s += " in spin mode" 1715 elif owner: 1716 s += " owned by thread %s" % ownerThread 1717 else: 1718 s += "with unknown owner" 1719 elif type == kThreadWaitPortReceive: 1720 s += "mach_msg receive on " 1721 if flags & STACKSHOT_WAITINFO_FLAGS_SPECIALREPLY: 1722 s += "REPLY " 1723 flags = flags - STACKSHOT_WAITINFO_FLAGS_SPECIALREPLY 1724 if owner == STACKSHOT_WAITOWNER_PORT_LOCKED: 1725 s += "locked port %x" % context 1726 elif owner == STACKSHOT_WAITOWNER_INTRANSIT: 1727 s += "intransit port %x" % context 1728 elif owner: 1729 s += "port %x name %x" % (context, owner) 1730 else: 1731 s += "port %x" % context 1732 elif type == kThreadWaitPortSetReceive: 1733 if owner == STACKSHOT_WAITOWNER_PSET_LOCKED: 1734 s += "mach_msg receive on locked port set %x" % context 1735 else: 1736 s += "mach_msg receive on port set %x" % context 1737 elif type == kThreadWaitPortSend: 1738 s += "mach_msg send on " 1739 if owner == STACKSHOT_WAITOWNER_PORT_LOCKED: 1740 s += "locked port %x" % context 1741 elif owner == STACKSHOT_WAITOWNER_INTRANSIT: 1742 s += "intransit port %x" % context 1743 elif owner == STACKSHOT_WAITOWNER_KERNEL: 1744 s += "port %x owned by kernel" % context 1745 elif owner: 1746 s += "port %x owned by pid %d" % (context, owner) 1747 else: 1748 s += "port %x with unknown owner" % context 1749 elif type == kThreadWaitPortSendInTransit: 1750 s += "mach_msg send on port %x in transit to " % context 1751 if owner: 1752 s += "port %x" % owner 1753 else: 1754 s += "unknown port" 1755 elif type == kThreadWaitSemaphore: 1756 s += "semaphore port %x " % context 1757 if owner: 1758 s += "owned by pid %d" % owner 1759 else: 1760 s += "with unknown owner" 1761 elif type == kThreadWaitKernelRWLockRead: 1762 s += "krwlock %x for reading" % context 1763 if owner: 1764 s += " owned by thread %s" % ownerThread 1765 elif type == kThreadWaitKernelRWLockWrite: 1766 s += "krwlock %x for writing" % context 1767 if owner: 1768 s += " owned by thread %s" % ownerThread 1769 elif type == kThreadWaitKernelRWLockUpgrade: 1770 s += "krwlock %x for upgrading" % context 1771 if owner: 1772 s += " owned by thread %s" % ownerThread 1773 elif type == kThreadWaitUserLock: 1774 if owner: 1775 s += "unfair lock %x owned by thread %s" % (context, ownerThread) 1776 else: 1777 s += "spin lock %x" % context 1778 elif type == kThreadWaitPThreadMutex: 1779 s += "pthread mutex %x" % context 1780 if owner: 1781 s += " owned by thread %s" % ownerThread 1782 else: 1783 s += " with unknown owner" 1784 elif type == kThreadWaitPThreadRWLockRead: 1785 s += "pthread rwlock %x for reading" % context 1786 elif type == kThreadWaitPThreadRWLockWrite: 1787 s += "pthread rwlock %x for writing" % context 1788 elif type == kThreadWaitPThreadCondVar: 1789 s += "pthread condvar %x" % context 1790 elif type == kThreadWaitWorkloopSyncWait: 1791 s += "workloop sync wait" 1792 if owner == STACKSHOT_WAITOWNER_SUSPENDED: 1793 s += ", suspended" 1794 elif owner == STACKSHOT_WAITOWNER_THREQUESTED: 1795 s += ", thread requested" 1796 elif owner != 0: 1797 s += ", owned by thread %s" % ownerThread 1798 else: 1799 s += ", unknown owner" 1800 s += ", workloop id %x" % context 1801 elif type == kThreadWaitOnProcess: 1802 if owner == 2**64-1: 1803 s += "waitpid, for any children" 1804 elif 2**32 <= owner and owner < 2**64-1: 1805 s += "waitpid, for process group %d" % abs(owner - 2**64) 1806 else: 1807 s += "waitpid, for pid %d" % owner 1808 elif type == kThreadWaitSleepWithInheritor: 1809 if owner == 0: 1810 s += "turnstile, held waitq" 1811 else: 1812 s += "turnstile, pushing thread %s" % ownerThread 1813 elif type == kThreadWaitEventlink: 1814 if owner == 0: 1815 s += "eventlink, held waitq" 1816 else: 1817 s += "eventlink, signaled by thread %s" % ownerThread 1818 elif type == kThreadWaitCompressor: 1819 s += "in compressor segment %x, busy for thread %s" % (context, ownerThread) 1820 elif type == kThreadWaitExclaveCore: 1821 if owner == 0: 1822 s += "exclavecore wait, id 0x%x" % context 1823 else: 1824 s += "exclavecore wait, id 0x%x, owner thread %s" % (context, ownerThread) 1825 elif type == kThreadWaitExclaveKit: 1826 if owner == 0: 1827 s += "exclavekit wait, id 0x%x" % context 1828 else: 1829 s += "exclavekit wait, id 0x%x, owner thread %s" % (context, ownerThread) 1830 elif type == kThreadWaitPageBusy: 1831 s += f"busy page 0x{context:x}" 1832 elif type == kThreadWaitPagerInit: 1833 s += f"pager initialization for vm object 0x{context:x}" 1834 elif type == kThreadWaitPagerReady: 1835 s += f"pager ready for vm object 0x{context:x}" 1836 elif type == kThreadWaitPagingActivity: 1837 s += f"paging/activity in progress for vm object 0x{context:x}" 1838 elif type == kThreadWaitMappingInProgress: 1839 s += f"mapping in progress for vm object 0x{context:x}" 1840 elif type == kThreadWaitMemoryBlocked: 1841 s += f"blocked vm object 0x{context:x}" 1842 elif type == kThreadWaitPagingInProgress: 1843 s += f"paging in progress for vm object 0x{context:x}" 1844 elif type == kThreadWaitPageInThrottle: 1845 s += f"throttled vm object 0x{context:x}" 1846 else: 1847 s += "unknown type %d (owner %s, context %x)" % (type, ownerThread, context) 1848 1849 s += formatPortLabelID(portlabel_id, portlabels) 1850 1851 if flags != 0: 1852 s += "flags {}".format(hex(flags)) 1853 return s 1854 1855def formatTurnstileInfo(ti, wi_portlabel_id, portlabels): 1856 if ti is None: 1857 return " [no turnstile]" 1858 1859 ts_flags = int(ti['turnstile_flags']) 1860 ctx = int(ti['turnstile_context']) 1861 hop = int(ti['number_of_hops']) 1862 prio = int(ti['turnstile_priority']) 1863 portlabel_id = ti.get("portlabel_id", 0) 1864 1865 portlabel_summary = "" 1866 if portlabel_id != 0 and portlabel_id != wi_portlabel_id: 1867 portlabel_summary += formatPortLabelID(portlabel_id, portlabels) 1868 1869 if ts_flags & STACKSHOT_TURNSTILE_STATUS_HELD_IPLOCK: 1870 return " [turnstile blocked on task, but ip_lock was held]" + portlabel_summary 1871 if ts_flags & STACKSHOT_TURNSTILE_STATUS_BLOCKED_ON_TASK: 1872 return " [turnstile blocked on task pid %d, hops: %d, priority: %d]%s" % (ctx, hop, prio, portlabel_summary) 1873 if ts_flags & STACKSHOT_TURNSTILE_STATUS_LOCKED_WAITQ: 1874 return " [turnstile was in process of being updated]" + portlabel_summary 1875 if ts_flags & STACKSHOT_TURNSTILE_STATUS_WORKQUEUE: 1876 return " [blocked on workqueue: 0x%x, hops: %x, priority: %d]%s" % (ctx, hop, prio, portlabel_summary) 1877 if ts_flags & STACKSHOT_TURNSTILE_STATUS_THREAD: 1878 return " [blocked on: %d, hops: %x, priority: %d]%s" % (ctx, hop, prio, portlabel_summary) 1879 if ts_flags & STACKSHOT_TURNSTILE_STATUS_UNKNOWN: 1880 return " [turnstile with unknown inheritor]" + portlabel_summary 1881 1882 return " [unknown turnstile status!]" + portlabel_summary 1883 1884def formatWaitInfoWithTurnstiles(waitinfos, tsinfos, portlabels): 1885 wis_tis = [] 1886 for w in waitinfos: 1887 found_pair = False 1888 for t in tsinfos: 1889 if int(w['waiter']) == int(t['waiter']): 1890 wis_tis.append((w, t)) 1891 found_pair = True 1892 break 1893 if not found_pair: 1894 wis_tis.append((w, None)) 1895 1896 return [formatWaitInfo(wi, False, portlabels) + formatTurnstileInfo(ti, wi.get('portlabel_id', 0), portlabels) for (wi, ti) in wis_tis] 1897 1898 1899def FindTextLayout(text_layouts, text_layout_id): 1900 for layout in text_layouts.values(): 1901 if layout['exclave_textlayout_info']['layout_id'] == text_layout_id: 1902 return layout 1903 return None 1904 1905 1906def GetExclaveLibs(text_layouts, text_layout_id): 1907 from operator import itemgetter 1908 textlayout = text_layouts.get(str(text_layout_id)) 1909 1910 # This fallback is needed to preserve compatibility with kcdata generated before rdar://123838752 1911 # FindTextLayout function should be removed in future 1912 if not textlayout or textlayout['exclave_textlayout_info']['layout_id'] != text_layout_id: 1913 textlayout = FindTextLayout(text_layouts, text_layout_id) 1914 1915 exclave_libs = [ [format_uuid(layout['layoutSegment_uuid']), layout['layoutSegment_loadAddress'], 'P'] for layout in textlayout['exclave_textlayout_segments'] ] 1916 exclave_libs.sort(key=itemgetter(1)) 1917 return exclave_libs 1918 1919 1920# kcdata is json at path 'kcdata_stackshot/threads_exclave/0' 1921def GetEASFrames(AllImageCatalog, kcdata, ipc_entry, notes, scid): 1922 info = ipc_entry['exclave_ipcstackentry_info'] 1923 asid = info['eise_asid'] 1924 1925 address_spaces = kcdata.get('exclave_addressspace') 1926 if not address_spaces: 1927 notes.warn("PID ${PID} TID ${TID} SCID %d Missing address spaces info" % scid) 1928 return [] 1929 as_info = address_spaces.get(str(asid)) 1930 if not as_info: 1931 notes.warn("PID ${PID} TID ${TID} SCID %d Missing address space info for ASID 0x%x" % (scid, asid)) 1932 return [] 1933 text_layout_id = as_info['exclave_addressspace_info']['eas_layoutid'] 1934 addr_space_name = as_info['exclave_addressspace_name'] 1935 1936 exclave_libs = GetExclaveLibs(kcdata['exclave_textlayout'], text_layout_id) 1937 1938 frames = [] 1939 stack = ipc_entry.get('secure_ecstack_entry', []) 1940 for stack_item in stack: 1941 lr = GetLongForAddress(stack_item['lr']) 1942 # this is a buggy value of unknown origin 1943 # rdar://123508690 (Some Exclave Stackshot frames ends with invalid value 0xFFFF000000000000) 1944 if lr == 0xFFFF000000000000: 1945 continue 1946 frames.append(GetSymbolInfoForFrame(AllImageCatalog, exclave_libs, lr)) 1947 1948 if frames: 1949 frame_info = "frames %d to %d" % (notes.offset, notes.offset + len(frames) - 1) 1950 else: 1951 frame_info = "no frames" 1952 notes.info("PID ${PID} TID ${TID} SCID %d ASID 0x%x has address space name '%s' (%s)" % (scid, asid, addr_space_name, frame_info)) 1953 notes.addToOffset(len(frames)) 1954 return frames 1955 1956 1957def GetExclavesFrames(AllImageCatalog, json, scid, notes): 1958 kcdata = json['kcdata_stackshot'] 1959 threads_exclave = kcdata.get('threads_exclave') 1960 if not threads_exclave: 1961 notes.warn("PID ${PID} TID ${TID} no threads_exclave info found, skipping exclaves frames") 1962 return [] 1963 1964 exclaves_content = threads_exclave.get('0') 1965 if not exclaves_content: 1966 notes.warn("PID ${PID} TID ${TID} threads_exclave data not found, skipping exclaves frames") 1967 return [] 1968 1969 threads_info = exclaves_content.get('thread_exclave') 1970 if not threads_info: 1971 notes.warn("PID ${PID} TID ${TID} no thread_exclave info found, skipping exclaves frames") 1972 return [] 1973 1974 scid_info = threads_info.get(str(scid)) 1975 if not scid_info: 1976 notes.warn("PID ${PID} TID ${TID} no exclaves info available for SCID %d, skipping exclaves frames" % scid) 1977 return [] 1978 1979 frames = [] 1980 1981 ipc_stack = scid_info.get("exclave_ipcstackentry") 1982 if not ipc_stack: 1983 notes.info("\nPID ${PID} TID ${TID} SCID %d IPC chain is missing" % scid) 1984 return [] 1985 notes.info("\nPID ${PID} TID ${TID} SCID %d has IPC chain with %d items:" % (scid, len(ipc_stack))) 1986 for i in reversed(range(len(ipc_stack))): 1987 ipc_entry = ipc_stack[str(i)] 1988 entry_frames = GetEASFrames(AllImageCatalog, exclaves_content, ipc_entry, notes, scid) 1989 frames.extend(entry_frames) 1990 1991 return frames 1992 1993 1994def InsertExclavesFrames(AllImageCatalog, json, thdata, notes, kernel_frames): 1995 thread_info = thdata.get('exclaves_thread_info') 1996 if not thread_info: 1997 # this is not exclave thread 1998 return 1999 2000 scid = thread_info["tei_scid"] 2001 offset = thread_info["tei_thread_offset"] 2002 notes.offset = offset 2003 2004 exclaves_frames = GetExclavesFrames(AllImageCatalog, json, scid, notes) 2005 2006 # insert exclaves frames to offset 2007 for i in range(len(exclaves_frames)): 2008 kernel_frames.insert(offset + i, exclaves_frames[i]) 2009 2010class NotesBuilder: 2011 2012 notes = [] 2013 pid = None 2014 tis = None 2015 offset = 0 2016 2017 def __init__(self, pid, tid): 2018 self.pid = pid 2019 self.tid = tid 2020 self.notes = [] 2021 self.offset = 0 # offset of next IPC stack in kernel stack 2022 2023 # Replace ${PID} with a PID and ${TID} with TID and add newline 2024 def format(self, note): 2025 note = note.replace('${PID}', str(self.pid)) 2026 note = note.replace('${TID}', str(self.tid)) 2027 return note + '\n' 2028 2029 def warn(self, note): 2030 note = self.format(note) 2031 sys.stdout.write(note) 2032 self.notes.append(note) 2033 2034 def info(self, note): 2035 note = self.format(note) 2036 self.notes.append(note) 2037 2038 def isEmpty(self): 2039 return len(self.notes) == 0 2040 2041 def text(self): 2042 return ''.join(self.notes) 2043 2044 def addToOffset(self, frame_count): 2045 self.offset += frame_count 2046 2047def SaveStackshotReport(j, outfile_name, incomplete): 2048 import time 2049 from operator import itemgetter, attrgetter 2050 ss = j.get('kcdata_stackshot') 2051 if not ss: 2052 print("No KCDATA_BUFFER_BEGIN_STACKSHOT object found. Skipping writing report.") 2053 return 2054 2055 timestamp = ss.get('usecs_since_epoch') 2056 try: 2057 timestamp = time.strftime("%Y-%m-%d %H:%M:%S +0000",time.gmtime(timestamp // 1000000 if timestamp else None)) 2058 except ValueError as e: 2059 print("couldn't convert timestamp:", str(e)) 2060 timestamp = None 2061 2062 os_version = ss.get('osversion', 'Unknown') 2063 timebase = ss.get('mach_timebase_info', {"denom": 1, "numer": 1}) 2064 2065 sc_note = None 2066 extra_note = None 2067 dsc_common = None 2068 shared_cache_info = ss.get('shared_cache_dyld_load_info') 2069 if shared_cache_info: 2070 shared_cache_base_addr = shared_cache_info['imageSlidBaseAddress'] 2071 # If we have a slidFirstMapping and it's >= base_address, use that. 2072 # 2073 # Otherwise we're processing a stackshot from before the slidFirstMapping 2074 # field was introduced and corrected. On ARM the SlidBaseAddress is the 2075 # same, but on x86 it's off by 0x20000000. We use 'X86_64' in the 2076 # kernel version string plus checking kern_page_size == 4k' as 2077 # proxy for x86_64, and only adjust SlidBaseAddress if the unslid 2078 # address is precisely the expected incorrect value. 2079 # 2080 is_intel = ('X86_64' in ss.get('osversion', "") and 2081 ss.get('kernel_page_size', 0) == 4096) 2082 slidFirstMapping = shared_cache_info.get(SC_SLID_FIRSTMAPPING_KEY, -1); 2083 if slidFirstMapping >= shared_cache_base_addr: 2084 shared_cache_base_addr = slidFirstMapping 2085 sc_note = "base-accurate" 2086 2087 elif is_intel: 2088 sc_slide = shared_cache_info['imageLoadAddress'] 2089 if (shared_cache_base_addr - sc_slide) == 0x7fff00000000: 2090 shared_cache_base_addr += 0x20000000 2091 sc_note = "base-x86-adjusted" 2092 extra_note = "Shared cache base adjusted for x86. " 2093 else: 2094 sc_note = "base-x86-unknown" 2095 2096 dsc_common = [format_uuid(shared_cache_info['imageUUID']), 2097 shared_cache_base_addr, "S" ] 2098 print("Shared cache UUID found from the binary data is <%s> " % str(dsc_common[0])) 2099 2100 dsc_layout = ss.get('system_shared_cache_layout') 2101 2102 dsc_libs = [] 2103 if dsc_layout: 2104 print("Found in memory system shared cache layout with {} images".format(len(dsc_layout))) 2105 slide = ss.get('shared_cache_dyld_load_info')['imageLoadAddress'] 2106 2107 for image in dsc_layout: 2108 dsc_libs.append([format_uuid(image['imageUUID']), image['imageLoadAddress'] + slide, "C"]) 2109 2110 AllImageCatalog = [] 2111 obj = {} 2112 obj["kernel"] = os_version 2113 if timestamp is not None: 2114 obj["date"] = timestamp 2115 obj["reason"] = "kernel panic stackshot" 2116 obj["incident"] = "ABCDEFGH-1234-56IJ-789K-0LMNOPQRSTUV" 2117 obj["crashReporterKey"] = "12ab34cd45aabbccdd6712ab34cd45aabbccdd67" 2118 obj["bootArgs"] = ss.get('boot_args','') 2119 obj["frontmostPids"] = [0] 2120 obj["exception"] = "0xDEADF157" 2121 obj["processByPid"] = {} 2122 if sc_note is not None: 2123 obj["sharedCacheNote"] = sc_note 2124 2125 if incomplete: 2126 obj["reason"] = "!!!INCOMPLETE!!! kernel panic stackshot" 2127 obj["notes"] = "Generated by xnu kcdata.py from incomplete data! Some information is missing! " 2128 else: 2129 obj["notes"] = "Generated by xnu kcdata.py. " 2130 2131 if extra_note is not None: 2132 obj["notes"] = obj["notes"] + extra_note 2133 2134 processByPid = obj["processByPid"] 2135 ssplist = ss.get('task_snapshots', {}) 2136 ssplist.update(ss.get('transitioning_task_snapshots', {})) 2137 kern_load_info = [] 2138 if "0" in ssplist: 2139 kc_uuid = ssplist["0"].get('kernelcache_load_info', None) 2140 if kc_uuid: 2141 kernelcache_uuid = [format_uuid(kc_uuid['imageUUID']), kc_uuid['imageLoadAddress'], "U" ] 2142 kern_load_info.append(kernelcache_uuid) 2143 2144 kl_infos = ssplist["0"].get("dyld_load_info", []) 2145 for dlinfo in kl_infos: 2146 kern_load_info.append([format_uuid(dlinfo['imageUUID']), dlinfo['imageLoadAddress'], "K"]) 2147 2148 kl_infos_text_exec = ssplist["0"].get("dyld_load_info_text_exec", []) 2149 for dlinfo in kl_infos_text_exec: 2150 kern_load_info.append([format_uuid(dlinfo['imageUUID']), dlinfo['imageLoadAddress'], "T"]) 2151 2152 for pid,piddata in sorted(ssplist.items()): 2153 processByPid[str(pid)] = {} 2154 tsnap = processByPid[str(pid)] 2155 pr_lib_dsc = dsc_common 2156 2157 # see if there's an alternate shared cache 2158 scd = piddata.get('shared_cache_dyld_load_info') 2159 if scd is not None: 2160 if 'imageSlidBaseAddress' not in scd: 2161 print("Specific task shared cache format does not include slid shared cache base address. Skipping writing report.") 2162 return 2163 2164 scd_uuid = format_uuid(scd['imageUUID']) 2165 scd_base_addr = scd['imageSlidBaseAddress'] 2166 pr_lib_dsc = [scd_uuid, scd_base_addr, "S"] 2167 2168 pr_libs = [] 2169 if len(dsc_libs) == 0 and pr_lib_dsc: 2170 pr_libs.append(pr_lib_dsc) 2171 _lib_type = "P" 2172 if int(pid) == 0: 2173 _lib_type = "K" 2174 pr_libs = [] 2175 else: 2176 for dlinfo in piddata.get('dyld_load_info',[]): 2177 pr_libs.append([format_uuid(dlinfo['imageUUID']), dlinfo['imageLoadAddress'], _lib_type]) 2178 2179 pr_libs.extend(kern_load_info) 2180 pr_libs.extend(dsc_libs) 2181 2182 if 'jit_address_range' in piddata: 2183 address_range = piddata.get('jit_address_range', {}) 2184 tsnap['jitStartAddress'] = address_range['start_address'] 2185 tsnap['jitEndAddress'] = address_range['end_address'] 2186 pr_libs.append([format_uuid("00000000000000000000000000000000"), tsnap['jitStartAddress'] , "J"]) 2187 pr_libs.sort(key=itemgetter(1)) 2188 ttsnap = piddata.get('transitioning_task_snapshot', None) 2189 if ttsnap is not None: 2190 # Transitioning task snapshots have "tts_" prefixes; change them to 2191 # "ts_". 2192 ttsnap = { key[1:] : value for key,value in ttsnap.items() } 2193 # Add a note to let people know 2194 obj["notes"] = obj["notes"] + "PID {} is a transitioning (exiting) task. ".format(pid) 2195 tasksnap = piddata.get('task_snapshot', ttsnap); 2196 if tasksnap is None: 2197 continue; 2198 tsnap["pid"] = tasksnap["ts_pid"] 2199 if 'ts_asid' in piddata: 2200 tsnap["asid"] = piddata["ts_asid"] 2201 2202 if 'ts_pagetable' in piddata: 2203 pagetables = [] 2204 for tte in piddata["ts_pagetable"]: 2205 pagetables.append(tte) 2206 tsnap["pageTables"] = pagetables 2207 2208 # Some fields are missing from transitioning_task snapshots. 2209 if ttsnap is None: 2210 tsnap["residentMemoryBytes"] = tasksnap["ts_task_size"] 2211 tsnap["timesDidThrottle"] = tasksnap["ts_did_throttle"] 2212 tsnap["systemTimeTask"] = GetSecondsFromMATime(tasksnap["ts_system_time_in_terminated_th"], timebase) 2213 tsnap["pageIns"] = tasksnap["ts_pageins"] 2214 tsnap["pageFaults"] = tasksnap["ts_faults"] 2215 tsnap["userTimeTask"] = GetSecondsFromMATime(tasksnap["ts_user_time_in_terminated_thre"], timebase) 2216 tsnap["procname"] = tasksnap["ts_p_comm"] 2217 if ttsnap is None: 2218 tsnap["copyOnWriteFaults"] = tasksnap["ts_cow_faults"] 2219 tsnap["timesThrottled"] = tasksnap["ts_was_throttled"] 2220 tsnap["threadById"] = {} 2221 threadByID = tsnap["threadById"] 2222 thlist = piddata.get('thread_snapshots', {}) 2223 for tid,thdata in sorted(thlist.items()): 2224 threadByID[str(tid)] = {} 2225 thsnap = threadByID[str(tid)] 2226 if "thread_snapshot" not in thdata: 2227 print("Found broken thread state for thread ID: %s." % tid) 2228 break 2229 threadsnap = thdata["thread_snapshot"] 2230 thsnap["userTime"] = GetSecondsFromMATime(threadsnap["ths_user_time"], timebase) 2231 thsnap["id"] = threadsnap["ths_thread_id"] 2232 thsnap["basePriority"] = threadsnap["ths_base_priority"] 2233 thsnap["systemTime"] = GetSecondsFromMATime(threadsnap["ths_sys_time"], timebase) 2234 thsnap["schedPriority"] = threadsnap["ths_sched_priority"] 2235 thsnap["state"] = GetStateDescription(threadsnap['ths_state']) 2236 thsnap["qosEffective"] = threadsnap["ths_eqos"] 2237 thsnap["qosRequested"] = threadsnap["ths_rqos"] 2238 2239 if "pth_name" in thdata: 2240 thsnap["name"] = thdata["pth_name"]; 2241 2242 if threadsnap['ths_continuation']: 2243 thsnap["continuation"] = GetSymbolInfoForFrame(AllImageCatalog, pr_libs, threadsnap['ths_continuation']) 2244 if "kernel_stack_frames" in thdata: 2245 kuserframes = [] 2246 for f in thdata["kernel_stack_frames"]: 2247 kuserframes.append(GetSymbolInfoForFrame(AllImageCatalog, pr_libs, f['lr'])) 2248 notesBuilder = NotesBuilder(tsnap['pid'], tid) 2249 InsertExclavesFrames(AllImageCatalog, j, thdata, notesBuilder, kuserframes) 2250 if not notesBuilder.isEmpty(): 2251 obj['notes'] += notesBuilder.text() 2252 thsnap["kernelFrames"] = kuserframes 2253 2254 if "user_stack_frames" in thdata: 2255 uframes = [] 2256 for f in thdata["user_stack_frames"]: 2257 uframes.append(GetSymbolInfoForFrame(AllImageCatalog, pr_libs, f['lr'])) 2258 thsnap["userFrames"] = uframes 2259 2260 if "user_stacktop" in thdata: 2261 (address,) = struct.unpack("<Q", struct.pack("B"*8, *thdata["user_stacktop"]["stack_contents"])) 2262 thsnap["userStacktop"] = GetSymbolInfoForFrame(AllImageCatalog, pr_libs, address) 2263 2264 if threadsnap['ths_wait_event']: 2265 thsnap["waitEvent"] = GetSymbolInfoForFrame(AllImageCatalog, pr_libs, threadsnap['ths_wait_event']) 2266 2267 if 'thread_waitinfo' in piddata and 'thread_turnstileinfo' in piddata: 2268 tsnap['waitInfo'] = formatWaitInfoWithTurnstiles(piddata['thread_waitinfo'], piddata['thread_turnstileinfo'], piddata.get('portlabels', None)) 2269 elif 'thread_waitinfo' in piddata: 2270 portlabels = ss.get('portlabels', None) 2271 tsnap['waitInfo'] = [formatWaitInfo(x, False, portlabels) for x in piddata['thread_waitinfo']] 2272 if 'stackshot_task_codesigning_info' in piddata: 2273 csinfo = piddata.get('stackshot_task_codesigning_info', {}) 2274 tsnap['csFlags'] = csinfo['csflags'] 2275 tsnap['csTrustLevel'] = csinfo['cs_trust_level'] 2276 if 'suspension_info' in piddata: 2277 suspinfo = piddata.get('suspension_info', {}) 2278 tsnap['suspension_count'] = suspinfo['tss_count'] 2279 tsnap['suspension_duration_secs'] = GetSecondsFromMATime(suspinfo['tss_duration'], timebase) 2280 tsnap['suspension_last_start'] = GetSecondsFromMATime(suspinfo['tss_last_start'], timebase) 2281 tsnap['suspension_last_end'] = GetSecondsFromMATime(suspinfo['tss_last_end'], timebase) 2282 2283 suspsources = piddata.get('suspension_source', []) 2284 suspension_sources = [] 2285 for source in filter(lambda x: x['tss_time'] != 0, suspsources): 2286 suspension_sources.append({ 2287 'suspension_time': GetSecondsFromMATime(source['tss_time'], timebase), 2288 'suspension_tid': source['tss_tid'], 2289 'suspension_pid': source['tss_pid'], 2290 'suspension_procname': source['tss_procname'], 2291 }) 2292 2293 tsnap['suspension_sources'] = suspension_sources 2294 # check if process is currently suspended 2295 if tsnap['suspension_last_start'] > tsnap['suspension_last_end']: 2296 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']) 2297 for source in suspension_sources: 2298 obj['notes'] += "From PID {} TID {} ({}) - at {}\n".format(source['suspension_pid'], source['suspension_tid'], source['suspension_procname'], source['suspension_time']) 2299 2300 obj['binaryImages'] = AllImageCatalog 2301 if outfile_name == '-': 2302 fh = sys.stdout 2303 else: 2304 fh = open(outfile_name, "w") 2305 2306 header = {} 2307 header['bug_type'] = 288 2308 if timestamp is not None: 2309 header['timestamp'] = timestamp 2310 header['os_version'] = os_version 2311 fh.write(json.dumps(header, sort_keys=True)) 2312 fh.write("\n") 2313 2314 fh.write(json.dumps(obj, sort_keys=True, indent=2, separators=(',', ': '))) 2315 fh.close() 2316 2317 2318@contextlib.contextmanager 2319def data_from_stream(stream): 2320 try: 2321 fmap = mmap.mmap(stream.fileno(), 0, mmap.MAP_SHARED, mmap.PROT_READ) 2322 except: 2323 yield stream.buffer.read() 2324 else: 2325 try: 2326 yield fmap 2327 finally: 2328 fmap.close() 2329 2330def iterate_kcdatas(kcdata_file): 2331 with data_from_stream(kcdata_file) as data: 2332 iterator = kcdata_item_iterator(data) 2333 kcdata_buffer = KCObject.FromKCItem(next(iterator)) 2334 2335 if isinstance(kcdata_buffer, KCCompressedBufferObject): 2336 kcdata_buffer.ReadItems(iterator) 2337 decompressed = kcdata_buffer.Decompress(data) 2338 iterator = kcdata_item_iterator(decompressed) 2339 kcdata_buffer = KCObject.FromKCItem(next(iterator)) 2340 2341 if not isinstance(kcdata_buffer, KCBufferObject): 2342 # ktrace stackshot chunk 2343 iterator = kcdata_item_iterator(data[16:]) 2344 kcdata_buffer = KCObject.FromKCItem(next(iterator)) 2345 2346 if not isinstance(kcdata_buffer, KCBufferObject): 2347 try: 2348 decoded = base64.b64decode(data) 2349 except: 2350 pass 2351 else: 2352 iterator = kcdata_item_iterator(decoded) 2353 kcdata_buffer = KCObject.FromKCItem(next(iterator)) 2354 if not isinstance(kcdata_buffer, KCBufferObject): 2355 import gzip 2356 from io import BytesIO 2357 try: 2358 decompressed = gzip.GzipFile(fileobj=BytesIO(data[:])).read() 2359 except: 2360 pass 2361 else: 2362 iterator = kcdata_item_iterator(decompressed) 2363 kcdata_buffer = KCObject.FromKCItem(next(iterator)) 2364 2365 if not isinstance(kcdata_buffer, KCBufferObject): 2366 raise Exception("unknown file type") 2367 2368 2369 kcdata_buffer.ReadItems(iterator) 2370 yield kcdata_buffer 2371 2372 for magic in iterator: 2373 kcdata_buffer = KCObject.FromKCItem(magic) 2374 if kcdata_buffer.i_type == 0: 2375 continue 2376 if not isinstance(kcdata_buffer, KCBufferObject): 2377 raise Exception("unknown file type") 2378 kcdata_buffer.ReadItems(iterator) 2379 yield kcdata_buffer 2380 2381# 2382# Values for various flag fields. Each entry's key is the key seen in the 2383# processed kcdata, the value is an array of bits, from low (0x1) to high, with 2384# either a string flag name or None for unused holes. 2385# 2386# Only put flags in here which are stable - this is run against stackshots 2387# of all different versions. For anything unstable, we'll need a decoder ring 2388# added to the stackshot. 2389# 2390PRETTIFY_FLAGS = { 2391 'jcs_flags': [ 2392 'kCoalitionTermRequested', 2393 'kCoalitionTerminated', 2394 'kCoalitionReaped', 2395 'kCoalitionPrivileged', 2396 ], 2397 'sharedCacheFlags': [ 2398 'kSharedCacheSystemPrimary', 2399 'kSharedCacheDriverkit' 2400 'kSharedCacheAOT', 2401 ], 2402 'stackshot_in_flags': [ # STACKSHOT_*, also stackshot_out_flags 2403 'get_dq', 2404 'save_loadinfo', 2405 'get_global_mem_stats', 2406 'save_kext_loadinfo', 2407 None, 2408 None, 2409 None, 2410 None, 2411 'active_kernel_threads_only', 2412 'get_boot_profile', 2413 'do_compress', 2414 None, 2415 None, 2416 'save_imp_donation_pids', 2417 'save_in_kernel_buffer', 2418 'retrieve_existing_buffer', 2419 'kcdata_format', 2420 'enable_bt_faulting', 2421 'collect_delta_snapshot', 2422 'collect_sharedcache_layout', 2423 'trylock', 2424 'enable_uuid_faulting', 2425 'from_panic', 2426 'no_io_stats', 2427 'thread_waitinfo', 2428 'thread_group', 2429 'save_jetsam_coalitions', 2430 'instrs_cycles', 2431 'asid', 2432 'page_tables', 2433 'disable_latency_info', 2434 'save_dyld_compactinfo', 2435 'include_driver_threads_in_kernel', 2436 'exclaves', 2437 ], 2438 'system_state_flags': [ 2439 'kUser64_p', 2440 'kKern64_p', 2441 ], 2442 'tgs_flags': [ 2443 'kThreadGroupEfficient', 2444 'kThreadGroupApplication', 2445 'kThreadGroupCritical', 2446 'kThreadGroupBestEffort', 2447 None, 2448 None, 2449 None, 2450 None, 2451 'kThreadGroupUIApplication', 2452 'kThreadGroupManaged', 2453 'kThreadGroupStrictTimers', 2454 ], 2455 'ths_ss_flags': [ 2456 'kUser64_p', 2457 'kKern64_p', 2458 'kHasDispatchSerial', 2459 'kStacksPCOnly', 2460 'kThreadDarwinBG', 2461 'kThreadIOPassive', 2462 'kThreadSuspended', 2463 'kThreadTruncatedBT', 2464 'kGlobalForcedIdle', 2465 'kThreadFaultedBT', 2466 'kThreadTriedFaultBT', 2467 'kThreadOnCore', 2468 'kThreadIdleWorker', 2469 'kThreadMain', 2470 'kThreadTruncKernBT', 2471 'kThreadTruncUserBT', 2472 'kThreadTruncUserAsyncBT', 2473 'kThreadExclaveRPCActive', 2474 'kThreadExclaveUpcallActive', 2475 'kThreadExclaveSchedulerRequest', 2476 ], 2477 'ths_state': [ 2478 'TH_WAIT', 2479 'TH_SUSP', 2480 'TH_RUN', 2481 'TH_UNINT', 2482 'TH_TERMINATE', 2483 'TH_TERMINATE2', 2484 'TH_WAIT_REPORT', 2485 'TH_IDLE', 2486 ], 2487 'ts_ss_flags': [ 2488 'kUser64_p', 2489 'kKern64_p', 2490 'kTaskRsrcFlagged', 2491 'kTerminatedSnapshot', 2492 'kPidSuspended', 2493 'kFrozen', 2494 'kTaskDarwinBG', 2495 'kTaskExtDarwinBG', 2496 'kTaskVisVisible', 2497 'kTaskVisNonvisible', 2498 'kTaskIsForeground', 2499 'kTaskIsBoosted', 2500 'kTaskIsSuppressed', 2501 'kTaskIsTimerThrottled', 2502 'kTaskIsImpDonor', 2503 'kTaskIsLiveImpDonor', 2504 'kTaskIsDirty', 2505 'kTaskWqExceededConstrainedThreadLimit', 2506 'kTaskWqExceededTotalThreadLimit', 2507 'kTaskWqFlagsAvailable', 2508 'kTaskUUIDInfoFaultedIn', 2509 'kTaskUUIDInfoMissing', 2510 'kTaskUUIDInfoTriedFault', 2511 'kTaskSharedRegionInfoUnavailable', 2512 'kTaskTALEngaged', 2513 None, 2514 'kTaskIsDirtyTracked', 2515 'kTaskAllowIdleExit', 2516 'kTaskIsTranslated', 2517 'kTaskSharedRegionNone', 2518 'kTaskSharedRegionSystem', 2519 'kTaskSharedRegionOther', 2520 'kTaskDyldCompactInfoNone', 2521 'kTaskDyldCompactInfoTooBig', 2522 'kTaskDyldCompactInfoFaultedIn', 2523 'kTaskDyldCompactInfoMissing', 2524 'kTaskDyldCompactInfoTriedFault', 2525 'kTaskWqExceededCooperativeThreadLimit', 2526 'kTaskWqExceededActiveConstrainedThreadLimit', 2527 ], 2528 'turnstile_flags': [ 2529 'turnstile_status_unknown', 2530 'turnstile_status_locked_waitq', 2531 'turnstile_status_workqueue', 2532 'turnstile_status_thread', 2533 'turnstile_status_blocked_on_task', 2534 'turnstile_status_held_iplock', 2535 ], 2536 'portlabel_flags': [ 2537 'label_read_failed', 2538 'service_throttled', 2539 ], 2540 'esc_flags': [ 2541 'kExclaveScresultHaveIPCStack', 2542 ], 2543 'eise_flags': [ 2544 'kExclaveIpcStackEntryHaveInvocationID', 2545 'kExclaveIpcStackEntryHaveStack', 2546 ], 2547 'eas_flags': [ 2548 'kExclaveAddressSpaceHaveSlide', 2549 ], 2550 'etl_flags': [ 2551 'kExclaveTextLayoutLoadAddressesSynthetic', 2552 'kExclaveTextLayoutLoadAddressesUnslid', 2553 ], 2554} 2555PRETTIFY_FLAGS['stackshot_out_flags'] = PRETTIFY_FLAGS['stackshot_in_flags'] 2556PRETTIFY_FLAGS['tts_ss_flags'] = PRETTIFY_FLAGS['ts_ss_flags'] 2557 2558# Fields which should never be hexified 2559PRETTIFY_DONTHEX = { 2560 'stackshot_in_pid': True, 2561 'tts_pid': True, 2562 'ts_pid': True, 2563 'donating_pids': True, 2564 'ppid': True, 2565} 2566 2567# Only hex() the value if it is multiple digits 2568def prettify_hex(v): 2569 if v < -9 or v > 9: 2570 return hex(v) 2571 return str(v) 2572 2573def prettify_flags(v, flags): 2574 output="" 2575 seen = 0 2576 if v == 0: 2577 return "0" 2578 for (s, n) in zip(range(len(flags)),flags): 2579 if n is None: 2580 continue 2581 if (v & (2 ** s)): 2582 output += "|" + n 2583 seen |= 2 ** s 2584 if output == "": 2585 return prettify_hex(v) 2586 rest = (v & ~seen) 2587 if (rest != 0): 2588 output += "|" + prettify_hex(rest) 2589 return prettify_hex(v) + " (" + output[1:] + ")" 2590 2591def prettify_core(data, mosthex, key, portlabels): 2592 if key == 'stack_contents': 2593 (address,) = struct.unpack("<Q", struct.pack("B"*8, *data)) 2594 return '0x%X' % address 2595 2596 elif isinstance(data, list): 2597 if 'uuid' in key.lower() and len(data) == 16: 2598 return '%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X' % tuple(data) 2599 2600 return [prettify_core(x, mosthex, key, portlabels) for x in data] 2601 2602 elif key == 'thread_waitinfo': 2603 return formatWaitInfo(data, mosthex, portlabels) 2604 2605 elif isinstance(data, dict): 2606 if 'portlabels' in data: 2607 portlabels = data['portlabels'] 2608 newdata = dict() 2609 for key, value in data.items(): 2610 if mosthex and key != 'task_snapshots' and len(key) > 0 and key.isnumeric(): 2611 key = prettify_hex(int(key)) 2612 newdata[key] = prettify_core(value, mosthex, key, portlabels) 2613 return newdata 2614 2615 elif 'address' in key.lower() and isinstance(data, (int, long)): 2616 return '0x%X' % data 2617 elif key == 'lr' or key == SC_SLID_FIRSTMAPPING_KEY: 2618 return '0x%X' % data 2619 elif key in PRETTIFY_FLAGS and isinstance(data, (int, long)): 2620 return prettify_flags(data, PRETTIFY_FLAGS[key]) 2621 elif key.endswith('_flags') and isinstance(data, (int, long)): 2622 return prettify_hex(data) 2623 2624 elif mosthex and not PRETTIFY_DONTHEX.get(key, False): 2625 if isinstance(data, (int, long)): 2626 return prettify_hex(data) 2627 elif isinstance(data, str) and len(data) > 0 and data.isnumeric(): 2628 return prettify_hex(int(data)) 2629 return data 2630 2631 else: 2632 return data 2633 2634def prettify(data, mosthex): 2635 return prettify_core(data, mosthex, "", None) 2636 2637# N.B.: This is called directly from `xnu.py` for `panicdata -S XXX.ips`'s implementation. 2638def decode_kcdata_file(kcdata_file, stackshot_file, multiple=False, prettyhex=False, pretty=False, output_as_plist=False): 2639 for i,kcdata_buffer in enumerate(iterate_kcdatas(kcdata_file)): 2640 if i > 0 and not multiple: 2641 break 2642 2643 str_data = "{" + kcdata_buffer.GetJsonRepr() + "}" 2644 str_data = str_data.replace("\t", " ") 2645 2646 try: 2647 json_obj = json.loads(str_data) 2648 except: 2649 print("JSON reparsing failed! Printing string data!\n", file=sys.stderr) 2650 import textwrap 2651 print(textwrap.fill(str_data, 100)) 2652 raise 2653 2654 if prettyhex: 2655 json_obj = prettify(json_obj, True) 2656 elif pretty: 2657 json_obj = prettify(json_obj, False) 2658 2659 if stackshot_file: 2660 SaveStackshotReport(json_obj, stackshot_file, G.data_was_incomplete) 2661 elif output_as_plist: 2662 import Foundation 2663 plist = Foundation.NSPropertyListSerialization.dataWithPropertyList_format_options_error_( 2664 json_obj, Foundation.NSPropertyListXMLFormat_v1_0, 0, None)[0].bytes().tobytes() 2665 #sigh. on some pythons long integers are getting output with L's in the plist. 2666 plist = re.sub(r'^(\s*<integer>\d+)L(</integer>\s*)$', r"\1\2", BytesToString(plist), flags=re.MULTILINE) 2667 print(plist,) 2668 else: 2669 print(json.dumps(json_obj, sort_keys=True, indent=4, separators=(',', ': '))) 2670 2671if __name__ == '__main__': 2672 parser = argparse.ArgumentParser(description="Decode a kcdata binary file.") 2673 parser.add_argument("-l", "--listtypes", action="store_true", required=False, default=False, 2674 help="List all known types", 2675 dest="list_known_types") 2676 2677 parser.add_argument("-s", "--stackshot", required=False, default=False, 2678 help="Generate a stackshot report file", 2679 dest="stackshot_file") 2680 2681 parser.add_argument("--multiple", help="look for multiple stackshots in a single file", action='store_true') 2682 2683 parser.add_argument("-p", "--plist", required=False, default=False, 2684 help="output as plist", action="store_true") 2685 2686 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") 2687 parser.add_argument("-P", "--pretty", default=False, action='store_true', help="make the output a little more human readable") 2688 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") 2689 parser.add_argument("--incomplete", action='store_true', help="accept incomplete data") 2690 parser.add_argument("kcdata_file", type=argparse.FileType('r'), help="Path to a kcdata binary file.") 2691 2692 class VerboseAction(argparse.Action): 2693 def __call__(self, parser, namespace, values, option_string=None): 2694 logging.basicConfig(level=logging.INFO, stream=sys.stderr, format='%(message)s') 2695 parser.add_argument('-v', "--verbose", action=VerboseAction, nargs=0) 2696 2697 args = parser.parse_args() 2698 2699 if args.multiple and args.stackshot_file: 2700 raise NotImplementedError 2701 2702 if args.pretty and args.stackshot_file: 2703 raise NotImplementedError 2704 2705 if args.list_known_types: 2706 for (n, t) in KNOWN_TYPES_COLLECTION.items(): 2707 print("%d : %s " % (n, str(t))) 2708 sys.exit(1) 2709 2710 if args.incomplete or args.stackshot_file: 2711 G.accept_incomplete_data = True 2712 2713 decode_kcdata_file(args.kcdata_file, args.stackshot_file, args.multiple, args.prettyhex, args.pretty, args.plist) 2714