1 /*
2 * Copyright (c) 2015 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #include <kcdata.h>
25 #include <sys/time.h>
26 #include <stdlib.h>
27 #include <stddef.h>
28 #include <string.h>
29 #include <assert.h>
30 #include <stdio.h>
31 #include <mach/mach_time.h>
32 #include <assert.h>
33
34 /*!
35 * @function kcdata_get_typedescription
36 *
37 * @abstract
38 * Search the known type definitions for type with id type_id.
39 *
40 * @param type_id
41 * A unsinged int type specified by the KCDATA.
42 *
43 * @param buffer
44 * pointer to data area where type definition will be saved.
45 *
46 * @param buffer_size
47 * size of the buffer provided.
48 *
49 * @return struct kcdata_type_definition *
50 * pointer to a malloc'ed buffer holding the type definition and each subtype defintion for its fields.
51 * It may return NULL if no type with id == type_id is found.
52 * Note: The caller is responsible to free() the memory when its no longer used.
53 *
54 * @discussion
55 * This function queries the known type definitions table. If found the defintion data is returned
56 * else NULL is returned. It is advised to cache the return value from this function since the data
57 * is always going to be the same for same type_id. The definition setup requires memory on heap.
58 * The caller should make sure to free() the data once its done with using it.
59 *
60 */
61 struct kcdata_type_definition * kcdata_get_typedescription(unsigned type_id, uint8_t * buffer, uint32_t buffer_size);
62
63 /* forward declarations for helper routines */
64 static uint32_t get_kctype_subtype_size(kctype_subtype_t type);
65 static void setup_subtype_description(kcdata_subtype_descriptor_t desc, kctype_subtype_t type, uint32_t offset, char * name);
66 static void setup_subtype_array_description(
67 kcdata_subtype_descriptor_t desc, kctype_subtype_t type, uint32_t offset, uint32_t count, char * name);
68 static void setup_type_definition(struct kcdata_type_definition * d, uint32_t type, uint32_t num_elems, char * name);
69
70 struct kcdata_type_definition *
kcdata_get_typedescription(unsigned type_id,uint8_t * buffer,uint32_t buffer_size)71 kcdata_get_typedescription(unsigned type_id, uint8_t * buffer, uint32_t buffer_size)
72 {
73 unsigned int i = 0;
74 #define _STR_VALUE(x) #x
75 #define _SUBTYPE_TRUNC(t, s, f, name) do { \
76 setup_subtype_description(&subtypes[i++], (t), offsetof(s, f), name); \
77 _Static_assert(sizeof(name) == sizeof ((struct kcdata_subtype_descriptor *)0)->kcs_name, "\"" name "\" should fit exactly in kcs_name"); \
78 } while (0)
79 #define _SUBTYPE(t, s, f) do { \
80 setup_subtype_description(&subtypes[i++], (t), offsetof(s, f), _STR_VALUE(f)); \
81 _Static_assert(sizeof(_STR_VALUE(f)) <= sizeof ((struct kcdata_subtype_descriptor *)0)->kcs_name, "\"" _STR_VALUE(f) "\" should fit in kcs_name"); \
82 } while (0)
83
84 #define _SUBTYPE_ARRAY(t, s, f, c) setup_subtype_array_description(&subtypes[i++], (t), offsetof(s, f), (c), _STR_VALUE(f))
85 #define _STRINGTYPE(f) setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, UINT16_MAX, f)
86
87 if (buffer_size < sizeof(struct kcdata_type_definition) || buffer == NULL) {
88 return NULL;
89 }
90
91 struct kcdata_type_definition * retval = (struct kcdata_type_definition *)&buffer[0];
92 kcdata_subtype_descriptor_t subtypes = (kcdata_subtype_descriptor_t)&buffer[sizeof(struct kcdata_type_definition)];
93 switch (type_id) {
94 case KCDATA_TYPE_STRING_DESC: {
95 i = 0;
96 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, KCDATA_DESC_MAXLEN, "desc");
97 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, KCDATA_DESC_MAXLEN, UINT16_MAX, "data");
98 setup_type_definition(retval, type_id, i, "string_desc");
99 break;
100 }
101
102 case KCDATA_TYPE_UINT32_DESC: {
103 i = 0;
104 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, KCDATA_DESC_MAXLEN, "desc");
105 setup_subtype_description(&subtypes[i++], KC_ST_UINT32, KCDATA_DESC_MAXLEN, "data");
106 setup_type_definition(retval, type_id, i, "uint32_desc");
107 break;
108 }
109
110 case KCDATA_TYPE_UINT64_DESC: {
111 i = 0;
112 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, KCDATA_DESC_MAXLEN, "desc");
113 setup_subtype_description(&subtypes[i++], KC_ST_UINT64, KCDATA_DESC_MAXLEN, "data");
114 setup_type_definition(retval, type_id, i, "uint64_desc");
115 break;
116 }
117
118 case KCDATA_TYPE_INT32_DESC: {
119 i = 0;
120 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, KCDATA_DESC_MAXLEN, "desc");
121 setup_subtype_description(&subtypes[i++], KC_ST_INT32, KCDATA_DESC_MAXLEN, "data");
122 setup_type_definition(retval, type_id, i, "int32_desc");
123 break;
124 }
125
126 case KCDATA_TYPE_INT64_DESC: {
127 i = 0;
128 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, KCDATA_DESC_MAXLEN, "desc");
129 setup_subtype_description(&subtypes[i++], KC_ST_INT64, KCDATA_DESC_MAXLEN, "data");
130 setup_type_definition(retval, type_id, i, "int64_desc");
131 break;
132 }
133
134 case KCDATA_TYPE_TYPEDEFINTION: {
135 i = 0;
136 setup_subtype_description(&subtypes[i++], KC_ST_UINT32, offsetof(struct kcdata_type_definition, kct_type_identifier), "typeID");
137 setup_subtype_description(&subtypes[i++], KC_ST_UINT32, offsetof(struct kcdata_type_definition, kct_num_elements), "numOfFields");
138 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, offsetof(struct kcdata_type_definition, kct_name), KCDATA_DESC_MAXLEN, "name");
139 // Note "fields" is an array of run time defined length. So we populate fields at parsing time.
140 setup_type_definition(retval, type_id, i, "typedef");
141 break;
142 }
143
144 case KCDATA_TYPE_CONTAINER_BEGIN: {
145 i = 0;
146 setup_subtype_description(&subtypes[i++], KC_ST_UINT32, 0, "kcContainerType");
147 setup_type_definition(retval, type_id, i, "container_begin");
148 break;
149 }
150
151 case KCDATA_TYPE_LIBRARY_LOADINFO: {
152 i = 0;
153 _SUBTYPE(KC_ST_UINT32, struct user32_dyld_uuid_info, imageLoadAddress);
154 _SUBTYPE_ARRAY(KC_ST_UINT8, struct user32_dyld_uuid_info, imageUUID, 16);
155 setup_type_definition(retval, type_id, i, "dyld_load_info");
156 break;
157 }
158
159 case KCDATA_TYPE_LIBRARY_LOADINFO64: {
160 i = 0;
161 _SUBTYPE(KC_ST_UINT64, struct user64_dyld_uuid_info, imageLoadAddress);
162 _SUBTYPE_ARRAY(KC_ST_UINT8, struct user64_dyld_uuid_info, imageUUID, 16);
163 setup_type_definition(retval, type_id, i, "dyld_load_info");
164 break;
165 }
166 case STACKSHOT_KCTYPE_LOADINFO64_TEXT_EXEC: {
167 i = 0;
168 _SUBTYPE(KC_ST_UINT64, struct user64_dyld_uuid_info, imageLoadAddress);
169 _SUBTYPE_ARRAY(KC_ST_UINT8, struct user64_dyld_uuid_info, imageUUID, 16);
170 setup_type_definition(retval, type_id, i, "dyld_load_info_text_exec");
171 break;
172 }
173 case STACKSHOT_KCTYPE_SHAREDCACHE_LOADINFO: {
174 i = 0;
175 /*
176 * for backwards compatibility, we keep the old field names, but the
177 * new data is being put in dyld_shared_cache_loadinfo
178 */
179 _SUBTYPE(KC_ST_UINT64, struct dyld_uuid_info_64_v2, imageLoadAddress);
180 _SUBTYPE_ARRAY(KC_ST_UINT8, struct dyld_uuid_info_64_v2, imageUUID, 16);
181 _SUBTYPE(KC_ST_UINT64, struct dyld_uuid_info_64_v2, imageSlidBaseAddress);
182 _SUBTYPE(KC_ST_UINT64, struct dyld_shared_cache_loadinfo, sharedCacheSlidFirstMapping);
183 _SUBTYPE(KC_ST_UINT32, struct dyld_shared_cache_loadinfo_v2, sharedCacheID);
184 _SUBTYPE(KC_ST_UINT32, struct dyld_shared_cache_loadinfo_v2, sharedCacheFlags);
185 setup_type_definition(retval, type_id, i, "shared_cache_dyld_load_info");
186 break;
187 }
188 case STACKSHOT_KCTYPE_SHAREDCACHE_INFO: {
189 i = 0;
190 _SUBTYPE(KC_ST_UINT64, struct dyld_shared_cache_loadinfo_v2, sharedCacheSlide);
191 _SUBTYPE_ARRAY(KC_ST_UINT8, struct dyld_shared_cache_loadinfo_v2, sharedCacheUUID, 16);
192 _SUBTYPE_TRUNC(KC_ST_UINT64, struct dyld_shared_cache_loadinfo_v2, sharedCacheUnreliableSlidBaseAddress, "sharedCacheUnreliableSlidBaseAd");
193 _SUBTYPE(KC_ST_UINT64, struct dyld_shared_cache_loadinfo_v2, sharedCacheSlidFirstMapping);
194 _SUBTYPE(KC_ST_UINT32, struct dyld_shared_cache_loadinfo_v2, sharedCacheID);
195 _SUBTYPE(KC_ST_UINT32, struct dyld_shared_cache_loadinfo_v2, sharedCacheFlags);
196 setup_type_definition(retval, type_id, i, "shared_cache_dyld_load_info");
197 break;
198 }
199
200 case STACKSHOT_KCTYPE_KERNELCACHE_LOADINFO: {
201 i = 0;
202 _SUBTYPE(KC_ST_UINT64, struct dyld_uuid_info_64, imageLoadAddress);
203 _SUBTYPE_ARRAY(KC_ST_UINT8, struct dyld_uuid_info_64, imageUUID, 16);
204 setup_type_definition(retval, type_id, i, "kernelcache_load_info");
205 break;
206 }
207
208 case KCDATA_TYPE_TIMEBASE: {
209 i = 0;
210 _SUBTYPE(KC_ST_UINT32, struct mach_timebase_info, numer);
211 _SUBTYPE(KC_ST_UINT32, struct mach_timebase_info, denom);
212 setup_type_definition(retval, type_id, i, "mach_timebase_info");
213 break;
214 }
215
216 case KCDATA_TYPE_MACH_ABSOLUTE_TIME:
217 setup_type_definition(retval, type_id, 1, "mach_absolute_time");
218 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "mach_absolute_time");
219 break;
220
221 case KCDATA_TYPE_TIMEVAL: {
222 i = 0;
223 _SUBTYPE(KC_ST_INT64, struct timeval64, tv_sec);
224 _SUBTYPE(KC_ST_INT64, struct timeval64, tv_usec);
225 setup_type_definition(retval, type_id, i, "timeval");
226 break;
227 }
228
229 case KCDATA_TYPE_USECS_SINCE_EPOCH:
230 setup_type_definition(retval, type_id, 1, "usecs_since_epoch");
231 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "usecs_since_epoch");
232 break;
233
234 case KCDATA_TYPE_PID:
235 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "pid");
236 setup_type_definition(retval, type_id, 1, "pid");
237 break;
238
239 case KCDATA_TYPE_PROCNAME:
240 i = 0;
241 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, 64, "proc_name");
242 setup_type_definition(retval, type_id, i, "proc_name");
243 break;
244
245 case KCDATA_TYPE_LIBRARY_AOTINFO: {
246 i = 0;
247 _SUBTYPE(KC_ST_UINT64, struct user64_dyld_aot_info, x86LoadAddress);
248 _SUBTYPE(KC_ST_UINT64, struct user64_dyld_aot_info, aotLoadAddress);
249 _SUBTYPE(KC_ST_UINT64, struct user64_dyld_aot_info, aotImageSize);
250 _SUBTYPE_ARRAY(KC_ST_UINT8, struct user64_dyld_aot_info, aotImageKey, DYLD_AOT_IMAGE_KEY_SIZE);
251 setup_type_definition(retval, type_id, i, "dyld_aot_info");
252 break;
253 }
254 case STACKSHOT_KCTYPE_AOTCACHE_LOADINFO: {
255 i = 0;
256 _SUBTYPE(KC_ST_UINT64, struct dyld_aot_cache_uuid_info, x86SlidBaseAddress);
257 _SUBTYPE_ARRAY(KC_ST_UINT8, struct dyld_aot_cache_uuid_info, x86UUID, 16);
258 _SUBTYPE(KC_ST_UINT64, struct dyld_aot_cache_uuid_info, aotSlidBaseAddress);
259 _SUBTYPE_ARRAY(KC_ST_UINT8, struct dyld_aot_cache_uuid_info, aotUUID, 16);
260 setup_type_definition(retval, type_id, i, "dyld_aot_cache_uuid_info");
261 break;
262 }
263 case STACKSHOT_KCTYPE_SHAREDCACHE_AOTINFO: {
264 i = 0;
265 _SUBTYPE(KC_ST_UINT64, struct dyld_aot_cache_uuid_info, x86SlidBaseAddress);
266 _SUBTYPE_ARRAY(KC_ST_UINT8, struct dyld_aot_cache_uuid_info, x86UUID, 16);
267 _SUBTYPE(KC_ST_UINT64, struct dyld_aot_cache_uuid_info, aotSlidBaseAddress);
268 _SUBTYPE_ARRAY(KC_ST_UINT8, struct dyld_aot_cache_uuid_info, aotUUID, 16);
269 setup_type_definition(retval, type_id, i, "dyld_aot_cache_uuid_info");
270 break;
271 }
272
273 /* stackshot specific types */
274 case STACKSHOT_KCTYPE_IOSTATS: {
275 i = 0;
276 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_disk_reads_count);
277 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_disk_reads_size);
278 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_disk_writes_count);
279 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_disk_writes_size);
280 _SUBTYPE_ARRAY(KC_ST_UINT64, struct io_stats_snapshot, ss_io_priority_count, STACKSHOT_IO_NUM_PRIORITIES);
281 _SUBTYPE_ARRAY(KC_ST_UINT64, struct io_stats_snapshot, ss_io_priority_size, STACKSHOT_IO_NUM_PRIORITIES);
282 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_paging_count);
283 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_paging_size);
284 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_non_paging_count);
285 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_non_paging_size);
286 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_data_count);
287 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_data_size);
288 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_metadata_count);
289 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_metadata_size);
290
291 setup_type_definition(retval, type_id, i, "io_statistics");
292 break;
293 }
294
295 case STACKSHOT_KCTYPE_GLOBAL_MEM_STATS: {
296 i = 0;
297 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, snapshot_magic);
298 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, free_pages);
299 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, active_pages);
300 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, inactive_pages);
301 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, purgeable_pages);
302 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, wired_pages);
303 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, speculative_pages);
304 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, throttled_pages);
305 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, filebacked_pages);
306 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, compressions);
307 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, decompressions);
308 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, compressor_size);
309 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, busy_buffer_count);
310 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, pages_wanted);
311 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, pages_reclaimed);
312 _SUBTYPE(KC_ST_UINT8, struct mem_and_io_snapshot, pages_wanted_reclaimed_valid);
313 setup_type_definition(retval, type_id, i, "mem_and_io_snapshot");
314 break;
315 }
316
317 case STACKSHOT_KCCONTAINER_SHAREDCACHE:
318 setup_type_definition(retval, type_id, 0, "shared_caches");
319 break;
320
321 case STACKSHOT_KCCONTAINER_TASK:
322 setup_type_definition(retval, type_id, 0, "task_snapshots");
323 break;
324
325 case STACKSHOT_KCCONTAINER_TRANSITIONING_TASK:
326 setup_type_definition(retval, type_id, 0, "transitioning_task_snapshots");
327 break;
328
329 case STACKSHOT_KCCONTAINER_THREAD:
330 setup_type_definition(retval, type_id, 0, "thread_snapshots");
331 break;
332
333 case STACKSHOT_KCCONTAINER_PORTLABEL:
334 setup_type_definition(retval, type_id, 0, "portlabels");
335 break;
336
337 case STACKSHOT_KCTYPE_TASK_SNAPSHOT: {
338 i = 0;
339 _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_unique_pid);
340 _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_ss_flags);
341 _SUBTYPE_TRUNC(KC_ST_UINT64, struct task_snapshot_v2, ts_user_time_in_terminated_threads, "ts_user_time_in_terminated_thre");
342 _SUBTYPE_TRUNC(KC_ST_UINT64, struct task_snapshot_v2, ts_system_time_in_terminated_threads, "ts_system_time_in_terminated_th");
343 _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_p_start_sec);
344 _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_task_size);
345 _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_max_resident_size);
346 _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_suspend_count);
347 _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_faults);
348 _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_pageins);
349 _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_cow_faults);
350 _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_was_throttled);
351 _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_did_throttle);
352 _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_latency_qos);
353 _SUBTYPE(KC_ST_INT32, struct task_snapshot_v2, ts_pid);
354 _SUBTYPE_ARRAY(KC_ST_CHAR, struct task_snapshot_v2, ts_p_comm, 32);
355 setup_type_definition(retval, type_id, i, "task_snapshot");
356 break;
357 }
358
359 case STACKSHOT_KCTYPE_TRANSITIONING_TASK_SNAPSHOT: {
360 i = 0;
361 _SUBTYPE(KC_ST_UINT64, struct transitioning_task_snapshot, tts_unique_pid);
362 _SUBTYPE(KC_ST_UINT64, struct transitioning_task_snapshot, tts_ss_flags);
363 _SUBTYPE(KC_ST_UINT64, struct transitioning_task_snapshot, tts_transition_type);
364 _SUBTYPE(KC_ST_INT32, struct transitioning_task_snapshot, tts_pid);
365 _SUBTYPE_ARRAY(KC_ST_CHAR, struct transitioning_task_snapshot, tts_p_comm, 32);
366 setup_type_definition(retval, type_id, i, "transitioning_task_snapshot");
367 break;
368 }
369
370 case STACKSHOT_KCTYPE_TASK_DELTA_SNAPSHOT: {
371 i = 0;
372 _SUBTYPE(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_unique_pid);
373 _SUBTYPE(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_ss_flags);
374 _SUBTYPE_TRUNC(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_user_time_in_terminated_threads, "tds_user_time_in_terminated_thr");
375 _SUBTYPE_TRUNC(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_system_time_in_terminated_threads, "tds_system_time_in_terminated_t");
376 _SUBTYPE(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_task_size);
377 _SUBTYPE(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_max_resident_size);
378 _SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_suspend_count);
379 _SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_faults);
380 _SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_pageins);
381 _SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_cow_faults);
382 _SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_was_throttled);
383 _SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_did_throttle);
384 _SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_latency_qos);
385 setup_type_definition(retval, type_id, i, "task_delta_snapshot");
386 break;
387 }
388
389 case STACKSHOT_KCTYPE_THREAD_SNAPSHOT: {
390 i = 0;
391
392 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_thread_id);
393 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_wait_event);
394 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_continuation);
395 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_total_syscalls);
396 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_voucher_identifier);
397 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_dqserialnum);
398 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_user_time);
399 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_sys_time);
400 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_ss_flags);
401 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_last_run_time);
402 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_last_made_runnable_time);
403 _SUBTYPE(KC_ST_UINT32, struct thread_snapshot_v3, ths_state);
404 _SUBTYPE(KC_ST_UINT32, struct thread_snapshot_v3, ths_sched_flags);
405 _SUBTYPE(KC_ST_INT16, struct thread_snapshot_v3, ths_base_priority);
406 _SUBTYPE(KC_ST_INT16, struct thread_snapshot_v3, ths_sched_priority);
407 _SUBTYPE(KC_ST_UINT8, struct thread_snapshot_v3, ths_eqos);
408 _SUBTYPE(KC_ST_UINT8, struct thread_snapshot_v3, ths_rqos);
409 _SUBTYPE(KC_ST_UINT8, struct thread_snapshot_v3, ths_rqos_override);
410 _SUBTYPE(KC_ST_UINT8, struct thread_snapshot_v3, ths_io_tier);
411 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_thread_t);
412 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v4, ths_requested_policy);
413 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v4, ths_effective_policy);
414
415 setup_type_definition(retval, type_id, i, "thread_snapshot");
416 break;
417 }
418
419 case STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT: {
420 i = 0;
421
422 _SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v2, tds_thread_id);
423 _SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v2, tds_voucher_identifier);
424 _SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v2, tds_ss_flags);
425 _SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v2, tds_last_made_runnable_time);
426 _SUBTYPE(KC_ST_UINT32, struct thread_delta_snapshot_v2, tds_state);
427 _SUBTYPE(KC_ST_UINT32, struct thread_delta_snapshot_v2, tds_sched_flags);
428 _SUBTYPE(KC_ST_INT16, struct thread_delta_snapshot_v2, tds_base_priority);
429 _SUBTYPE(KC_ST_INT16, struct thread_delta_snapshot_v2, tds_sched_priority);
430 _SUBTYPE(KC_ST_UINT8, struct thread_delta_snapshot_v2, tds_eqos);
431 _SUBTYPE(KC_ST_UINT8, struct thread_delta_snapshot_v2, tds_rqos);
432 _SUBTYPE(KC_ST_UINT8, struct thread_delta_snapshot_v2, tds_rqos_override);
433 _SUBTYPE(KC_ST_UINT8, struct thread_delta_snapshot_v2, tds_io_tier);
434 _SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v3, tds_requested_policy);
435 _SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v3, tds_effective_policy);
436
437 setup_type_definition(retval, type_id, i, "thread_delta_snapshot");
438
439 break;
440 }
441
442 case STACKSHOT_KCTYPE_DONATING_PIDS:
443 setup_type_definition(retval, type_id, 1, "donating_pids");
444 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "donating_pids");
445 break;
446
447 case STACKSHOT_KCTYPE_THREAD_NAME: {
448 i = 0;
449 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, 64, "pth_name");
450 setup_type_definition(retval, type_id, i, "pth_name");
451 break;
452 }
453
454 case STACKSHOT_KCTYPE_KERN_STACKFRAME:
455 setup_type_definition(retval, type_id, 2, "kernel_stack_frames");
456 setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "lr");
457 setup_subtype_description(&subtypes[1], KC_ST_UINT32, sizeof(uint32_t), "sp");
458 break;
459
460 case STACKSHOT_KCTYPE_KERN_STACKFRAME64:
461 setup_type_definition(retval, type_id, 2, "kernel_stack_frames");
462 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "lr");
463 setup_subtype_description(&subtypes[1], KC_ST_UINT64, sizeof(uint64_t), "sp");
464 break;
465
466 case STACKSHOT_KCTYPE_USER_STACKFRAME:
467 setup_type_definition(retval, type_id, 2, "user_stack_frames");
468 setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "lr");
469 setup_subtype_description(&subtypes[1], KC_ST_UINT32, sizeof(uint32_t), "sp");
470 break;
471
472 case STACKSHOT_KCTYPE_USER_STACKFRAME64:
473 setup_type_definition(retval, type_id, 2, "user_stack_frames");
474 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "lr");
475 setup_subtype_description(&subtypes[1], KC_ST_UINT64, sizeof(uint64_t), "sp");
476 break;
477
478 case STACKSHOT_KCTYPE_KERN_STACKLR:
479 setup_type_definition(retval, type_id, 1, "kernel_stack_frames");
480 setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "lr");
481 subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_STRUCT;
482 break;
483
484 case STACKSHOT_KCTYPE_KERN_STACKLR64:
485 setup_type_definition(retval, type_id, 1, "kernel_stack_frames");
486 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "lr");
487 subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_STRUCT;
488 break;
489
490 case STACKSHOT_KCTYPE_USER_STACKLR:
491 setup_type_definition(retval, type_id, 1, "user_stack_frames");
492 setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "lr");
493 subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_STRUCT;
494 break;
495
496 case STACKSHOT_KCTYPE_USER_STACKLR64:
497 setup_type_definition(retval, type_id, 1, "user_stack_frames");
498 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "lr");
499 subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_STRUCT;
500 break;
501
502 case STACKSHOT_KCTYPE_USER_ASYNC_START_INDEX:
503 setup_type_definition(retval, type_id, 1, "user_async_start_index");
504 setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "user_async_start_index");
505 break;
506
507 case STACKSHOT_KCTYPE_USER_ASYNC_STACKLR64:
508 setup_type_definition(retval, type_id, 1, "user_async_stack_frames");
509 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "lr");
510 subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_STRUCT;
511 break;
512
513 case STACKSHOT_KCTYPE_NONRUNNABLE_TIDS:
514 setup_type_definition(retval, type_id, 1, "nonrunnable_threads");
515 setup_subtype_description(&subtypes[0], KC_ST_INT64, 0, "nonrunnable_threads");
516 break;
517
518 case STACKSHOT_KCTYPE_NONRUNNABLE_TASKS:
519 setup_type_definition(retval, type_id, 1, "nonrunnable_tasks");
520 setup_subtype_description(&subtypes[0], KC_ST_INT64, 0, "nonrunnable_tasks");
521 break;
522
523 case STACKSHOT_KCTYPE_SHAREDCACHE_ID:
524 setup_type_definition(retval, type_id, 1, "sharedCacheID");
525 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "sharedCacheID");
526 break;
527
528 case STACKSHOT_KCTYPE_BOOTARGS: {
529 i = 0;
530 _STRINGTYPE("boot_args");
531 setup_type_definition(retval, type_id, i, "boot_args");
532 break;
533 }
534
535 case STACKSHOT_KCTYPE_OSVERSION: {
536 i = 0;
537 _STRINGTYPE("osversion");
538 setup_type_definition(retval, type_id, i, "osversion");
539 break;
540 }
541
542 case STACKSHOT_KCTYPE_KERN_PAGE_SIZE: {
543 i = 0;
544 setup_subtype_description(&subtypes[i++], KC_ST_UINT32, 0, "kernel_page_size");
545 setup_type_definition(retval, type_id, i, "kernel_page_size");
546 break;
547 }
548
549 case STACKSHOT_KCTYPE_THREAD_POLICY_VERSION: {
550 i = 0;
551 setup_subtype_description(&subtypes[i++], KC_ST_UINT32, 0, "thread_policy_version");
552 setup_type_definition(retval, type_id, i, "thread_policy_version");
553 break;
554 }
555
556 case STACKSHOT_KCTYPE_JETSAM_LEVEL: {
557 i = 0;
558 setup_subtype_description(&subtypes[i++], KC_ST_UINT32, 0, "jetsam_level");
559 setup_type_definition(retval, type_id, i, "jetsam_level");
560 break;
561 }
562
563 case STACKSHOT_KCTYPE_DELTA_SINCE_TIMESTAMP: {
564 i = 0;
565 setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "stackshot_delta_since_timestamp");
566 setup_type_definition(retval, type_id, i, "stackshot_delta_since_timestamp");
567 break;
568 }
569
570 /* crashinfo types */
571 case TASK_CRASHINFO_BSDINFOWITHUNIQID: {
572 i = 0;
573 _SUBTYPE_ARRAY(KC_ST_UINT8, struct crashinfo_proc_uniqidentifierinfo, p_uuid, 16);
574 _SUBTYPE(KC_ST_UINT64, struct crashinfo_proc_uniqidentifierinfo, p_uniqueid);
575 _SUBTYPE(KC_ST_UINT64, struct crashinfo_proc_uniqidentifierinfo, p_puniqueid);
576 /* Ignore the p_reserve fields */
577 setup_type_definition(retval, type_id, i, "proc_uniqidentifierinfo");
578 break;
579 }
580
581 case TASK_CRASHINFO_PID: {
582 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "pid");
583 setup_type_definition(retval, type_id, 1, "pid");
584 break;
585 }
586
587 case TASK_CRASHINFO_PPID: {
588 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "ppid");
589 setup_type_definition(retval, type_id, 1, "ppid");
590 break;
591 }
592
593 /* case TASK_CRASHINFO_RUSAGE: { */
594 /* /\* */
595 /* * rusage is a complex structure and is only for legacy use for crashed processes rusage info. */
596 /* * So we just consider it as opaque data. */
597 /* *\/ */
598 /* i = 0; */
599 /* setup_subtype_array_description(&subtypes[i++], KC_ST_UINT8, 0, sizeof(struct rusage), "rusage"); */
600 /* setup_type_definition(retval, type_id, i, "rusage"); */
601 /* break; */
602 /* } */
603
604 case TASK_CRASHINFO_RUSAGE_INFO: {
605 i = 0;
606 _SUBTYPE_ARRAY(KC_ST_UINT8, struct rusage_info_v3, ri_uuid, 16);
607 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_user_time);
608 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_system_time);
609 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_pkg_idle_wkups);
610 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_interrupt_wkups);
611 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_pageins);
612 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_wired_size);
613 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_resident_size);
614 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_phys_footprint);
615 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_proc_start_abstime);
616 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_proc_exit_abstime);
617 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_user_time);
618 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_system_time);
619 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_pkg_idle_wkups);
620 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_interrupt_wkups);
621 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_pageins);
622 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_elapsed_abstime);
623 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_diskio_bytesread);
624 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_diskio_byteswritten);
625 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_default);
626 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_maintenance);
627 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_background);
628 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_utility);
629 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_legacy);
630 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_user_initiated);
631 _SUBTYPE_TRUNC(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_user_interactive, "ri_cpu_time_qos_user_interactiv");
632 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_billed_system_time);
633 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_serviced_system_time);
634 setup_type_definition(retval, type_id, i, "rusage_info");
635 break;
636 }
637
638 case STACKSHOT_KCTYPE_CPU_TIMES: {
639 i = 0;
640 _SUBTYPE(KC_ST_UINT64, struct stackshot_cpu_times_v2, user_usec);
641 _SUBTYPE(KC_ST_UINT64, struct stackshot_cpu_times_v2, system_usec);
642 _SUBTYPE(KC_ST_UINT64, struct stackshot_cpu_times_v2, runnable_usec);
643 setup_type_definition(retval, type_id, i, "cpu_times");
644 break;
645 }
646
647 case STACKSHOT_KCTYPE_STACKSHOT_DURATION: {
648 i = 0;
649 _SUBTYPE(KC_ST_UINT64, struct stackshot_duration_v2, stackshot_duration);
650 _SUBTYPE(KC_ST_UINT64, struct stackshot_duration_v2, stackshot_duration_outer);
651 _SUBTYPE(KC_ST_UINT64, struct stackshot_duration_v2, stackshot_duration_prior);
652 subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_MERGE;
653 subtypes[1].kcs_flags |= KCS_SUBTYPE_FLAGS_MERGE;
654 subtypes[2].kcs_flags |= KCS_SUBTYPE_FLAGS_MERGE;
655 setup_type_definition(retval, type_id, i, "stackshot_duration");
656 break;
657 }
658
659 case STACKSHOT_KCTYPE_STACKSHOT_FAULT_STATS: {
660 i = 0;
661 _SUBTYPE(KC_ST_UINT32, struct stackshot_fault_stats, sfs_pages_faulted_in);
662 _SUBTYPE(KC_ST_UINT64, struct stackshot_fault_stats, sfs_time_spent_faulting);
663 _SUBTYPE(KC_ST_UINT64, struct stackshot_fault_stats, sfs_system_max_fault_time);
664 _SUBTYPE(KC_ST_UINT8, struct stackshot_fault_stats, sfs_stopped_faulting);
665
666 setup_type_definition(retval, type_id, i, "stackshot_fault_stats");
667 break;
668 }
669
670 case STACKSHOT_KCTYPE_THREAD_WAITINFO: {
671 i = 0;
672 _SUBTYPE(KC_ST_UINT64, struct stackshot_thread_waitinfo_v2, owner);
673 _SUBTYPE(KC_ST_UINT64, struct stackshot_thread_waitinfo_v2, waiter);
674 _SUBTYPE(KC_ST_UINT64, struct stackshot_thread_waitinfo_v2, context);
675 _SUBTYPE(KC_ST_UINT8, struct stackshot_thread_waitinfo_v2, wait_type);
676 _SUBTYPE(KC_ST_INT16, struct stackshot_thread_waitinfo_v2, portlabel_id);
677 _SUBTYPE(KC_ST_UINT32, struct stackshot_thread_waitinfo_v2, wait_flags);
678 setup_type_definition(retval, type_id, i, "thread_waitinfo");
679 break;
680 }
681
682 case STACKSHOT_KCTYPE_THREAD_GROUP_SNAPSHOT: {
683 i = 0;
684 _SUBTYPE(KC_ST_UINT64, struct thread_group_snapshot_v3, tgs_id);
685 _SUBTYPE_ARRAY(KC_ST_CHAR, struct thread_group_snapshot_v3, tgs_name, 16);
686 _SUBTYPE(KC_ST_UINT64, struct thread_group_snapshot_v3, tgs_flags);
687 _SUBTYPE_ARRAY(KC_ST_CHAR, struct thread_group_snapshot_v3, tgs_name_cont, 16);
688 setup_type_definition(retval, type_id, i, "thread_group_snapshot");
689 break;
690 }
691
692 case STACKSHOT_KCTYPE_THREAD_GROUP: {
693 i = 0;
694 setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "thread_group");
695 setup_type_definition(retval, type_id, i, "thread_group");
696 break;
697 };
698
699 case STACKSHOT_KCTYPE_JETSAM_COALITION_SNAPSHOT: {
700 i = 0;
701 _SUBTYPE(KC_ST_UINT64, struct jetsam_coalition_snapshot, jcs_id);
702 _SUBTYPE(KC_ST_UINT64, struct jetsam_coalition_snapshot, jcs_flags);
703 _SUBTYPE(KC_ST_UINT64, struct jetsam_coalition_snapshot, jcs_thread_group);
704 _SUBTYPE(KC_ST_UINT64, struct jetsam_coalition_snapshot, jcs_leader_task_uniqueid);
705 setup_type_definition(retval, type_id, i, "jetsam_coalition_snapshot");
706 break;
707 }
708
709 case STACKSHOT_KCTYPE_JETSAM_COALITION: {
710 i = 0;
711 setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "jetsam_coalition");
712 setup_type_definition(retval, type_id, i, "jetsam_coalition");
713 break;
714 };
715
716 case STACKSHOT_KCTYPE_INSTRS_CYCLES: {
717 i = 0;
718 _SUBTYPE(KC_ST_UINT64, struct instrs_cycles_snapshot_v2, ics_instructions);
719 _SUBTYPE(KC_ST_UINT64, struct instrs_cycles_snapshot_v2, ics_cycles);
720 _SUBTYPE(KC_ST_UINT64, struct instrs_cycles_snapshot_v2, ics_p_instructions);
721 _SUBTYPE(KC_ST_UINT64, struct instrs_cycles_snapshot_v2, ics_p_cycles);
722 setup_type_definition(retval, type_id, i, "instrs_cycles_snapshot");
723 break;
724 }
725
726 case STACKSHOT_KCTYPE_USER_STACKTOP: {
727 i = 0;
728 _SUBTYPE(KC_ST_UINT64, struct stack_snapshot_stacktop, sp);
729 _SUBTYPE_ARRAY(KC_ST_UINT8, struct stack_snapshot_stacktop, stack_contents, 8);
730 setup_type_definition(retval, type_id, i, "user_stacktop");
731 break;
732 }
733
734 case TASK_CRASHINFO_PROC_STARTTIME: {
735 i = 0;
736 _SUBTYPE(KC_ST_INT64, struct timeval64, tv_sec);
737 _SUBTYPE(KC_ST_INT64, struct timeval64, tv_usec);
738 setup_type_definition(retval, type_id, i, "proc_starttime");
739 break;
740 }
741
742 case TASK_CRASHINFO_EXCEPTION_CODES: {
743 i = 0;
744 char codenum[100];
745 for (i = 0; i < EXCEPTION_CODE_MAX; i++) {
746 snprintf(codenum, sizeof(codenum), "code_%d", i);
747 setup_subtype_description(&subtypes[i], KC_ST_UINT64, i * (sizeof(uint64_t)), codenum);
748 }
749 setup_type_definition(retval, type_id, i, "mach_exception_data_t");
750 break;
751 }
752
753 case TASK_CRASHINFO_PROC_NAME: {
754 i = 0;
755 _STRINGTYPE("p_comm");
756 setup_type_definition(retval, type_id, i, "p_comm");
757 break;
758 }
759
760 case TASK_CRASHINFO_USERSTACK: {
761 i = 0;
762 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "userstack_ptr");
763 setup_type_definition(retval, type_id, 1, "userstack_ptr");
764 break;
765 }
766
767 case TASK_CRASHINFO_ARGSLEN: {
768 i = 0;
769 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "p_argslen");
770 setup_type_definition(retval, type_id, 1, "p_argslen");
771 break;
772 }
773
774 case TASK_CRASHINFO_PROC_PATH: {
775 i = 0;
776 _STRINGTYPE("p_path");
777 setup_type_definition(retval, type_id, i, "p_path");
778 break;
779 }
780
781 case TASK_CRASHINFO_PROC_CSFLAGS: {
782 setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "p_csflags");
783 setup_type_definition(retval, type_id, 1, "p_csflags");
784 break;
785 }
786
787 case TASK_CRASHINFO_PROC_STATUS: {
788 setup_subtype_description(&subtypes[0], KC_ST_UINT8, 0, "p_status");
789 setup_type_definition(retval, type_id, 1, "p_status");
790 break;
791 }
792
793 case TASK_CRASHINFO_UID: {
794 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "uid");
795 setup_type_definition(retval, type_id, 1, "uid");
796 break;
797 }
798
799 case TASK_CRASHINFO_GID: {
800 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "gid");
801 setup_type_definition(retval, type_id, 1, "gid");
802 break;
803 }
804
805 case TASK_CRASHINFO_PROC_ARGC: {
806 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "argc");
807 setup_type_definition(retval, type_id, 1, "argc");
808 break;
809 }
810
811 case TASK_CRASHINFO_PROC_FLAGS: {
812 setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "p_flags");
813 setup_type_definition(retval, type_id, 1, "p_flags");
814 break;
815 }
816
817 case TASK_CRASHINFO_CPUTYPE: {
818 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "cputype");
819 setup_type_definition(retval, type_id, 1, "cputype");
820 break;
821 }
822
823 case TASK_CRASHINFO_RESPONSIBLE_PID: {
824 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "responsible_pid");
825 setup_type_definition(retval, type_id, 1, "responsible_pid");
826 break;
827 }
828
829 case TASK_CRASHINFO_DIRTY_FLAGS: {
830 setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "dirty_flags");
831 setup_type_definition(retval, type_id, 1, "dirty_flags");
832 break;
833 }
834
835 case TASK_CRASHINFO_CRASHED_THREADID: {
836 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "crashed_threadid");
837 setup_type_definition(retval, type_id, 1, "crashed_threadid");
838 break;
839 }
840
841 case TASK_CRASHINFO_COALITION_ID: {
842 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "coalition_id");
843 setup_type_definition(retval, type_id, 1, "coalition_id");
844 break;
845 }
846
847 case TASK_CRASHINFO_UDATA_PTRS: {
848 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "udata_ptrs");
849 setup_type_definition(retval, type_id, 1, "udata_ptrs");
850 break;
851 }
852
853 case TASK_CRASHINFO_MEMORY_LIMIT: {
854 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "task_phys_mem_limit");
855 setup_type_definition(retval, type_id, 1, "task_phys_mem_limit");
856 break;
857 }
858
859 case TASK_CRASHINFO_TASK_IS_CORPSE_FORK: {
860 setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "task_is_corpse_fork");
861 setup_type_definition(retval, type_id, 1, "task_is_corpse_fork");
862 break;
863 }
864
865 case TASK_CRASHINFO_EXCEPTION_TYPE: {
866 setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "exception_type");
867 setup_type_definition(retval, type_id, 1, "exception_type");
868 break;
869 }
870
871 case EXIT_REASON_SNAPSHOT: {
872 _SUBTYPE(KC_ST_UINT32, struct exit_reason_snapshot, ers_namespace);
873 _SUBTYPE(KC_ST_UINT64, struct exit_reason_snapshot, ers_code);
874 _SUBTYPE(KC_ST_UINT64, struct exit_reason_snapshot, ers_flags);
875 setup_type_definition(retval, type_id, i, "exit_reason_basic_info");
876
877 break;
878 }
879
880 case EXIT_REASON_USER_DESC: {
881 i = 0;
882
883 _STRINGTYPE("exit_reason_user_description");
884 setup_type_definition(retval, type_id, i, "exit_reason_user_description");
885 break;
886 }
887
888 case EXIT_REASON_USER_PAYLOAD: {
889 i = 0;
890
891 setup_subtype_array_description(&subtypes[i++], KC_ST_UINT8, 0, EXIT_REASON_PAYLOAD_MAX_LEN, "exit_reason_user_payload");
892 setup_type_definition(retval, type_id, i, "exit_reason_user_payload");
893 break;
894 }
895
896 case EXIT_REASON_CODESIGNING_INFO: {
897 _SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_virt_addr);
898 _SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_file_offset);
899 _SUBTYPE_ARRAY(KC_ST_CHAR, struct codesigning_exit_reason_info, ceri_pathname, EXIT_REASON_CODESIG_PATH_MAX);
900 _SUBTYPE_ARRAY(KC_ST_CHAR, struct codesigning_exit_reason_info, ceri_filename, EXIT_REASON_CODESIG_PATH_MAX);
901 _SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_codesig_modtime_secs);
902 _SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_codesig_modtime_nsecs);
903 _SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_page_modtime_secs);
904 _SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_page_modtime_nsecs);
905 _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_path_truncated);
906 _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_object_codesigned);
907 _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_codesig_validated);
908 _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_codesig_tainted);
909 _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_codesig_nx);
910 _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_wpmapped);
911 _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_slid);
912 _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_dirty);
913 _SUBTYPE(KC_ST_UINT32, struct codesigning_exit_reason_info, ceri_page_shadow_depth);
914 setup_type_definition(retval, type_id, i, "exit_reason_codesigning_info");
915 break;
916 }
917
918 case EXIT_REASON_WORKLOOP_ID: {
919 i = 0;
920 setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "exit_reason_workloop_id");
921 setup_type_definition(retval, type_id, i, "exit_reason_workloop_id");
922 break;
923 }
924
925 case EXIT_REASON_DISPATCH_QUEUE_NO: {
926 i = 0;
927 setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "exit_reason_dispatch_queue_no");
928 setup_type_definition(retval, type_id, i, "exit_reason_dispatch_queue_no");
929 break;
930 }
931
932 case STACKSHOT_KCTYPE_ASID: {
933 i = 0;
934 setup_subtype_description(&subtypes[i++], KC_ST_UINT32, 0, "ts_asid");
935 setup_type_definition(retval, type_id, i, "ts_asid");
936 break;
937 }
938
939 case STACKSHOT_KCTYPE_PAGE_TABLES: {
940 i = 0;
941 setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "ts_pagetable");
942 setup_type_definition(retval, type_id, i, "ts_pagetable");
943 break;
944 }
945
946 case STACKSHOT_KCTYPE_SYS_SHAREDCACHE_LAYOUT: {
947 i = 0;
948 _SUBTYPE(KC_ST_UINT64, struct user64_dyld_uuid_info, imageLoadAddress);
949 _SUBTYPE_ARRAY(KC_ST_UINT8, struct user64_dyld_uuid_info, imageUUID, 16);
950 setup_type_definition(retval, type_id, i, "system_shared_cache_layout");
951 break;
952 }
953
954 case STACKSHOT_KCTYPE_THREAD_DISPATCH_QUEUE_LABEL: {
955 i = 0;
956 _STRINGTYPE("dispatch_queue_label");
957 setup_type_definition(retval, type_id, i, "dispatch_queue_label");
958 break;
959 }
960
961 case STACKSHOT_KCTYPE_THREAD_TURNSTILEINFO: {
962 i = 0;
963 _SUBTYPE(KC_ST_UINT64, struct stackshot_thread_turnstileinfo_v2, waiter);
964 _SUBTYPE(KC_ST_UINT64, struct stackshot_thread_turnstileinfo_v2, turnstile_context);
965 _SUBTYPE(KC_ST_UINT8, struct stackshot_thread_turnstileinfo_v2, turnstile_priority);
966 _SUBTYPE(KC_ST_UINT8, struct stackshot_thread_turnstileinfo_v2, number_of_hops);
967 _SUBTYPE(KC_ST_UINT64, struct stackshot_thread_turnstileinfo_v2, turnstile_flags);
968 _SUBTYPE(KC_ST_INT16, struct stackshot_thread_turnstileinfo_v2, portlabel_id);
969 setup_type_definition(retval, type_id, i, "thread_turnstileinfo");
970 break;
971 }
972
973 case STACKSHOT_KCTYPE_PORTLABEL: {
974 i = 0;
975 _SUBTYPE(KC_ST_INT16, struct portlabel_info, portlabel_id);
976 _SUBTYPE(KC_ST_UINT16, struct portlabel_info, portlabel_flags);
977 _SUBTYPE(KC_ST_INT8, struct portlabel_info, portlabel_domain);
978 subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_MERGE;
979 subtypes[1].kcs_flags |= KCS_SUBTYPE_FLAGS_MERGE;
980 subtypes[2].kcs_flags |= KCS_SUBTYPE_FLAGS_MERGE;
981 setup_type_definition(retval, type_id, i, "portlabel_info");
982 break;
983 }
984
985 case STACKSHOT_KCTYPE_PORTLABEL_NAME:
986 i = 0;
987 _STRINGTYPE("portlabel_name");
988 setup_type_definition(retval, type_id, i, "portlabel_name");
989 break;
990
991 case STACKSHOT_KCTYPE_TASK_CPU_ARCHITECTURE: {
992 i = 0;
993 _SUBTYPE(KC_ST_INT32, struct stackshot_cpu_architecture, cputype);
994 _SUBTYPE(KC_ST_INT32, struct stackshot_cpu_architecture, cpusubtype);
995 setup_type_definition(retval, type_id, i, "task_cpu_architecture");
996 break;
997 }
998
999 case STACKSHOT_KCTYPE_LATENCY_INFO: {
1000 i = 0;
1001 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_collection, latency_version);
1002 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_collection, setup_latency);
1003 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_collection, total_task_iteration_latency);
1004 _SUBTYPE_TRUNC(KC_ST_UINT64, struct stackshot_latency_collection, total_terminated_task_iteration_latency, "total_terminated_task_iteration");
1005 setup_type_definition(retval, type_id, i, "stackshot_latency_collection");
1006 break;
1007 }
1008 case STACKSHOT_KCTYPE_LATENCY_INFO_TASK: {
1009 i = 0;
1010 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_task, task_uniqueid);
1011 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_task, setup_latency);
1012 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_task, task_thread_count_loop_latency);
1013 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_task, task_thread_data_loop_latency);
1014 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_task, cur_tsnap_latency);
1015 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_task, pmap_latency);
1016 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_task, bsd_proc_ids_latency);
1017 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_task, misc_latency);
1018 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_task, misc2_latency);
1019 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_task, end_latency);
1020 setup_type_definition(retval, type_id, i, "stackshot_latency_task");
1021 break;
1022 }
1023 case STACKSHOT_KCTYPE_LATENCY_INFO_THREAD: {
1024 i = 0;
1025 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_thread, thread_id);
1026 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_thread, cur_thsnap1_latency);
1027 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_thread, dispatch_serial_latency);
1028 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_thread, dispatch_label_latency);
1029 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_thread, cur_thsnap2_latency);
1030 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_thread, thread_name_latency);
1031 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_thread, sur_times_latency);
1032 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_thread, user_stack_latency);
1033 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_thread, kernel_stack_latency);
1034 _SUBTYPE(KC_ST_UINT64, struct stackshot_latency_thread, misc_latency);
1035 setup_type_definition(retval, type_id, i, "stackshot_latency_thread");
1036 break;
1037 }
1038
1039 case TASK_CRASHINFO_KERNEL_TRIAGE_INFO_V1: {
1040 i = 0;
1041 _SUBTYPE_ARRAY(KC_ST_CHAR, struct kernel_triage_info_v1, triage_string1, MAX_TRIAGE_STRING_LEN);
1042 _SUBTYPE_ARRAY(KC_ST_CHAR, struct kernel_triage_info_v1, triage_string2, MAX_TRIAGE_STRING_LEN);
1043 _SUBTYPE_ARRAY(KC_ST_CHAR, struct kernel_triage_info_v1, triage_string3, MAX_TRIAGE_STRING_LEN);
1044 _SUBTYPE_ARRAY(KC_ST_CHAR, struct kernel_triage_info_v1, triage_string4, MAX_TRIAGE_STRING_LEN);
1045 _SUBTYPE_ARRAY(KC_ST_CHAR, struct kernel_triage_info_v1, triage_string5, MAX_TRIAGE_STRING_LEN);
1046 setup_type_definition(retval, type_id, i, "kernel_triage_info_v1");
1047 break;
1048 }
1049
1050 default:
1051 retval = NULL;
1052 break;
1053 }
1054
1055 assert(retval == NULL || (buffer_size > sizeof(struct kcdata_type_definition) +
1056 (retval->kct_num_elements * sizeof(struct kcdata_subtype_descriptor))));
1057 return retval;
1058 }
1059
1060 static void
setup_type_definition(struct kcdata_type_definition * d,uint32_t type,uint32_t num_elems,char * name)1061 setup_type_definition(struct kcdata_type_definition * d, uint32_t type, uint32_t num_elems, char * name)
1062 {
1063 d->kct_type_identifier = type;
1064 d->kct_num_elements = num_elems;
1065 memcpy(d->kct_name, name, sizeof(d->kct_name));
1066 d->kct_name[sizeof(d->kct_name) - 1] = '\0';
1067 }
1068
1069 static uint32_t
get_kctype_subtype_size(kctype_subtype_t type)1070 get_kctype_subtype_size(kctype_subtype_t type)
1071 {
1072 switch (type) {
1073 case KC_ST_CHAR:
1074 case KC_ST_INT8:
1075 case KC_ST_UINT8:
1076 return sizeof(uint8_t);
1077 break;
1078 case KC_ST_INT16:
1079 case KC_ST_UINT16:
1080 return sizeof(uint16_t);
1081 break;
1082 case KC_ST_INT32:
1083 case KC_ST_UINT32:
1084 return sizeof(uint32_t);
1085 break;
1086 case KC_ST_INT64:
1087 case KC_ST_UINT64:
1088 return sizeof(uint64_t);
1089 break;
1090
1091 default:
1092 assert(0);
1093 break;
1094 }
1095 return 0;
1096 }
1097
1098 static void
setup_subtype_array_description(kcdata_subtype_descriptor_t desc,kctype_subtype_t type,uint32_t offset,uint32_t count,char * name)1099 setup_subtype_array_description(
1100 kcdata_subtype_descriptor_t desc, kctype_subtype_t type, uint32_t offset, uint32_t count, char * name)
1101 {
1102 desc->kcs_flags = KCS_SUBTYPE_FLAGS_ARRAY;
1103 desc->kcs_elem_type = type;
1104 desc->kcs_elem_offset = offset;
1105 desc->kcs_elem_size = KCS_SUBTYPE_PACK_SIZE(count, get_kctype_subtype_size(type));
1106 memcpy(desc->kcs_name, name, sizeof(desc->kcs_name));
1107 desc->kcs_name[sizeof(desc->kcs_name) - 1] = '\0';
1108 }
1109
1110 static void
setup_subtype_description(kcdata_subtype_descriptor_t desc,kctype_subtype_t type,uint32_t offset,char * name)1111 setup_subtype_description(kcdata_subtype_descriptor_t desc, kctype_subtype_t type, uint32_t offset, char * name)
1112 {
1113 desc->kcs_flags = KCS_SUBTYPE_FLAGS_NONE;
1114 desc->kcs_elem_type = type;
1115 desc->kcs_elem_offset = offset;
1116 desc->kcs_elem_size = get_kctype_subtype_size(type);
1117 memcpy(desc->kcs_name, name, sizeof(desc->kcs_name));
1118 desc->kcs_name[sizeof(desc->kcs_name) - 1] = '\0';
1119 }
1120