xref: /xnu-8020.121.3/libkdd/kcdtypes.c (revision fdd8201d7b966f0c3ea610489d29bd841d358941)
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 
167 	case STACKSHOT_KCTYPE_SHAREDCACHE_LOADINFO: {
168 		i = 0;
169 		/*
170 		 * for backwards compatibility, we keep the old field names, but the
171 		 * new data is being put in dyld_shared_cache_loadinfo
172 		 */
173 		_SUBTYPE(KC_ST_UINT64, struct dyld_uuid_info_64_v2, imageLoadAddress);
174 		_SUBTYPE_ARRAY(KC_ST_UINT8, struct dyld_uuid_info_64_v2, imageUUID, 16);
175 		_SUBTYPE(KC_ST_UINT64, struct dyld_uuid_info_64_v2, imageSlidBaseAddress);
176 		_SUBTYPE(KC_ST_UINT64, struct dyld_shared_cache_loadinfo, sharedCacheSlidFirstMapping);
177 		setup_type_definition(retval, type_id, i, "shared_cache_dyld_load_info");
178 		break;
179 	}
180 
181 	case STACKSHOT_KCTYPE_KERNELCACHE_LOADINFO: {
182 		i = 0;
183 		_SUBTYPE(KC_ST_UINT64, struct dyld_uuid_info_64, imageLoadAddress);
184 		_SUBTYPE_ARRAY(KC_ST_UINT8, struct dyld_uuid_info_64, imageUUID, 16);
185 		setup_type_definition(retval, type_id, i, "kernelcache_load_info");
186 		break;
187 	}
188 
189 	case KCDATA_TYPE_TIMEBASE: {
190 		i = 0;
191 		_SUBTYPE(KC_ST_UINT32, struct mach_timebase_info, numer);
192 		_SUBTYPE(KC_ST_UINT32, struct mach_timebase_info, denom);
193 		setup_type_definition(retval, type_id, i, "mach_timebase_info");
194 		break;
195 	}
196 
197 	case KCDATA_TYPE_MACH_ABSOLUTE_TIME:
198 		setup_type_definition(retval, type_id, 1, "mach_absolute_time");
199 		setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "mach_absolute_time");
200 		break;
201 
202 	case KCDATA_TYPE_TIMEVAL: {
203 		i = 0;
204 		_SUBTYPE(KC_ST_INT64, struct timeval64, tv_sec);
205 		_SUBTYPE(KC_ST_INT64, struct timeval64, tv_usec);
206 		setup_type_definition(retval, type_id, i, "timeval");
207 		break;
208 	}
209 
210 	case KCDATA_TYPE_USECS_SINCE_EPOCH:
211 		setup_type_definition(retval, type_id, 1, "usecs_since_epoch");
212 		setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "usecs_since_epoch");
213 		break;
214 
215 	case KCDATA_TYPE_PID:
216 		setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "pid");
217 		setup_type_definition(retval, type_id, 1, "pid");
218 		break;
219 
220 	case KCDATA_TYPE_PROCNAME:
221 		i = 0;
222 		setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, 64, "proc_name");
223 		setup_type_definition(retval, type_id, i, "proc_name");
224 		break;
225 
226 	case KCDATA_TYPE_LIBRARY_AOTINFO: {
227 		i = 0;
228 		_SUBTYPE(KC_ST_UINT64, struct user64_dyld_aot_info, x86LoadAddress);
229 		_SUBTYPE(KC_ST_UINT64, struct user64_dyld_aot_info, aotLoadAddress);
230 		_SUBTYPE(KC_ST_UINT64, struct user64_dyld_aot_info, aotImageSize);
231 		_SUBTYPE_ARRAY(KC_ST_UINT8, struct user64_dyld_aot_info, aotImageKey, DYLD_AOT_IMAGE_KEY_SIZE);
232 		setup_type_definition(retval, type_id, i, "dyld_aot_info");
233 		break;
234 	}
235 	case STACKSHOT_KCTYPE_AOTCACHE_LOADINFO: {
236 		i = 0;
237 		_SUBTYPE(KC_ST_UINT64, struct dyld_aot_cache_uuid_info, x86SlidBaseAddress);
238 		_SUBTYPE_ARRAY(KC_ST_UINT8, struct dyld_aot_cache_uuid_info, x86UUID, 16);
239 		_SUBTYPE(KC_ST_UINT64, struct dyld_aot_cache_uuid_info, aotSlidBaseAddress);
240 		_SUBTYPE_ARRAY(KC_ST_UINT8, struct dyld_aot_cache_uuid_info, aotUUID, 16);
241 		setup_type_definition(retval, type_id, i, "dyld_aot_cache_uuid_info");
242 		break;
243 	}
244 
245 	/* stackshot specific types */
246 	case STACKSHOT_KCTYPE_IOSTATS: {
247 		i = 0;
248 		_SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_disk_reads_count);
249 		_SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_disk_reads_size);
250 		_SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_disk_writes_count);
251 		_SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_disk_writes_size);
252 		_SUBTYPE_ARRAY(KC_ST_UINT64, struct io_stats_snapshot, ss_io_priority_count, STACKSHOT_IO_NUM_PRIORITIES);
253 		_SUBTYPE_ARRAY(KC_ST_UINT64, struct io_stats_snapshot, ss_io_priority_size, STACKSHOT_IO_NUM_PRIORITIES);
254 		_SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_paging_count);
255 		_SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_paging_size);
256 		_SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_non_paging_count);
257 		_SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_non_paging_size);
258 		_SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_data_count);
259 		_SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_data_size);
260 		_SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_metadata_count);
261 		_SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_metadata_size);
262 
263 		setup_type_definition(retval, type_id, i, "io_statistics");
264 		break;
265 	}
266 
267 	case STACKSHOT_KCTYPE_GLOBAL_MEM_STATS: {
268 		i = 0;
269 		_SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, snapshot_magic);
270 		_SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, free_pages);
271 		_SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, active_pages);
272 		_SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, inactive_pages);
273 		_SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, purgeable_pages);
274 		_SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, wired_pages);
275 		_SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, speculative_pages);
276 		_SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, throttled_pages);
277 		_SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, filebacked_pages);
278 		_SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, compressions);
279 		_SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, decompressions);
280 		_SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, compressor_size);
281 		_SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, busy_buffer_count);
282 		_SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, pages_wanted);
283 		_SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, pages_reclaimed);
284 		_SUBTYPE(KC_ST_UINT8, struct mem_and_io_snapshot, pages_wanted_reclaimed_valid);
285 		setup_type_definition(retval, type_id, i, "mem_and_io_snapshot");
286 		break;
287 	}
288 
289 	case STACKSHOT_KCCONTAINER_TASK:
290 		setup_type_definition(retval, type_id, 0, "task_snapshots");
291 		break;
292 
293 	case STACKSHOT_KCCONTAINER_TRANSITIONING_TASK:
294 		setup_type_definition(retval, type_id, 0, "transitioning_task_snapshots");
295 		break;
296 
297 	case STACKSHOT_KCCONTAINER_THREAD:
298 		setup_type_definition(retval, type_id, 0, "thread_snapshots");
299 		break;
300 
301 	case STACKSHOT_KCCONTAINER_PORTLABEL:
302 		setup_type_definition(retval, type_id, 0, "portlabels");
303 		break;
304 
305 	case STACKSHOT_KCTYPE_TASK_SNAPSHOT: {
306 		i = 0;
307 		_SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_unique_pid);
308 		_SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_ss_flags);
309 		_SUBTYPE_TRUNC(KC_ST_UINT64, struct task_snapshot_v2, ts_user_time_in_terminated_threads, "ts_user_time_in_terminated_thre");
310 		_SUBTYPE_TRUNC(KC_ST_UINT64, struct task_snapshot_v2, ts_system_time_in_terminated_threads, "ts_system_time_in_terminated_th");
311 		_SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_p_start_sec);
312 		_SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_task_size);
313 		_SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_max_resident_size);
314 		_SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_suspend_count);
315 		_SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_faults);
316 		_SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_pageins);
317 		_SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_cow_faults);
318 		_SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_was_throttled);
319 		_SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_did_throttle);
320 		_SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_latency_qos);
321 		_SUBTYPE(KC_ST_INT32, struct task_snapshot_v2, ts_pid);
322 		_SUBTYPE_ARRAY(KC_ST_CHAR, struct task_snapshot_v2, ts_p_comm, 32);
323 		setup_type_definition(retval, type_id, i, "task_snapshot");
324 		break;
325 	}
326 
327 	case STACKSHOT_KCTYPE_TRANSITIONING_TASK_SNAPSHOT: {
328 		i = 0;
329 		_SUBTYPE(KC_ST_UINT64, struct transitioning_task_snapshot, tts_unique_pid);
330 		_SUBTYPE(KC_ST_UINT64, struct transitioning_task_snapshot, tts_ss_flags);
331 		_SUBTYPE(KC_ST_UINT64, struct transitioning_task_snapshot, tts_transition_type);
332 		_SUBTYPE(KC_ST_INT32, struct transitioning_task_snapshot, tts_pid);
333 		_SUBTYPE_ARRAY(KC_ST_CHAR, struct transitioning_task_snapshot, tts_p_comm, 32);
334 		setup_type_definition(retval, type_id, i, "transitioning_task_snapshot");
335 		break;
336 	}
337 
338 	case STACKSHOT_KCTYPE_TASK_DELTA_SNAPSHOT: {
339 		i = 0;
340 		_SUBTYPE(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_unique_pid);
341 		_SUBTYPE(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_ss_flags);
342 		_SUBTYPE_TRUNC(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_user_time_in_terminated_threads, "tds_user_time_in_terminated_thr");
343 		_SUBTYPE_TRUNC(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_system_time_in_terminated_threads, "tds_system_time_in_terminated_t");
344 		_SUBTYPE(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_task_size);
345 		_SUBTYPE(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_max_resident_size);
346 		_SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_suspend_count);
347 		_SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_faults);
348 		_SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_pageins);
349 		_SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_cow_faults);
350 		_SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_was_throttled);
351 		_SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_did_throttle);
352 		_SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_latency_qos);
353 		setup_type_definition(retval, type_id, i, "task_delta_snapshot");
354 		break;
355 	}
356 
357 	case STACKSHOT_KCTYPE_THREAD_SNAPSHOT: {
358 		i = 0;
359 
360 		_SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_thread_id);
361 		_SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_wait_event);
362 		_SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_continuation);
363 		_SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_total_syscalls);
364 		_SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_voucher_identifier);
365 		_SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_dqserialnum);
366 		_SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_user_time);
367 		_SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_sys_time);
368 		_SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_ss_flags);
369 		_SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_last_run_time);
370 		_SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_last_made_runnable_time);
371 		_SUBTYPE(KC_ST_UINT32, struct thread_snapshot_v3, ths_state);
372 		_SUBTYPE(KC_ST_UINT32, struct thread_snapshot_v3, ths_sched_flags);
373 		_SUBTYPE(KC_ST_INT16, struct thread_snapshot_v3, ths_base_priority);
374 		_SUBTYPE(KC_ST_INT16, struct thread_snapshot_v3, ths_sched_priority);
375 		_SUBTYPE(KC_ST_UINT8, struct thread_snapshot_v3, ths_eqos);
376 		_SUBTYPE(KC_ST_UINT8, struct thread_snapshot_v3, ths_rqos);
377 		_SUBTYPE(KC_ST_UINT8, struct thread_snapshot_v3, ths_rqos_override);
378 		_SUBTYPE(KC_ST_UINT8, struct thread_snapshot_v3, ths_io_tier);
379 		_SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_thread_t);
380 		_SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v4, ths_requested_policy);
381 		_SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v4, ths_effective_policy);
382 
383 		setup_type_definition(retval, type_id, i, "thread_snapshot");
384 		break;
385 	}
386 
387 	case STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT: {
388 		i = 0;
389 
390 		_SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v2, tds_thread_id);
391 		_SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v2, tds_voucher_identifier);
392 		_SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v2, tds_ss_flags);
393 		_SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v2, tds_last_made_runnable_time);
394 		_SUBTYPE(KC_ST_UINT32, struct thread_delta_snapshot_v2, tds_state);
395 		_SUBTYPE(KC_ST_UINT32, struct thread_delta_snapshot_v2, tds_sched_flags);
396 		_SUBTYPE(KC_ST_INT16, struct thread_delta_snapshot_v2, tds_base_priority);
397 		_SUBTYPE(KC_ST_INT16, struct thread_delta_snapshot_v2, tds_sched_priority);
398 		_SUBTYPE(KC_ST_UINT8, struct thread_delta_snapshot_v2, tds_eqos);
399 		_SUBTYPE(KC_ST_UINT8, struct thread_delta_snapshot_v2, tds_rqos);
400 		_SUBTYPE(KC_ST_UINT8, struct thread_delta_snapshot_v2, tds_rqos_override);
401 		_SUBTYPE(KC_ST_UINT8, struct thread_delta_snapshot_v2, tds_io_tier);
402 		_SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v3, tds_requested_policy);
403 		_SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v3, tds_effective_policy);
404 
405 		setup_type_definition(retval, type_id, i, "thread_delta_snapshot");
406 
407 		break;
408 	}
409 
410 	case STACKSHOT_KCTYPE_DONATING_PIDS:
411 		setup_type_definition(retval, type_id, 1, "donating_pids");
412 		setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "donating_pids");
413 		break;
414 
415 	case STACKSHOT_KCTYPE_THREAD_NAME: {
416 		i = 0;
417 		setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, 64, "pth_name");
418 		setup_type_definition(retval, type_id, i, "pth_name");
419 		break;
420 	}
421 
422 	case STACKSHOT_KCTYPE_KERN_STACKFRAME:
423 		setup_type_definition(retval, type_id, 2, "kernel_stack_frames");
424 		setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "lr");
425 		setup_subtype_description(&subtypes[1], KC_ST_UINT32, sizeof(uint32_t), "sp");
426 		break;
427 
428 	case STACKSHOT_KCTYPE_KERN_STACKFRAME64:
429 		setup_type_definition(retval, type_id, 2, "kernel_stack_frames");
430 		setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "lr");
431 		setup_subtype_description(&subtypes[1], KC_ST_UINT64, sizeof(uint64_t), "sp");
432 		break;
433 
434 	case STACKSHOT_KCTYPE_USER_STACKFRAME:
435 		setup_type_definition(retval, type_id, 2, "user_stack_frames");
436 		setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "lr");
437 		setup_subtype_description(&subtypes[1], KC_ST_UINT32, sizeof(uint32_t), "sp");
438 		break;
439 
440 	case STACKSHOT_KCTYPE_USER_STACKFRAME64:
441 		setup_type_definition(retval, type_id, 2, "user_stack_frames");
442 		setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "lr");
443 		setup_subtype_description(&subtypes[1], KC_ST_UINT64, sizeof(uint64_t), "sp");
444 		break;
445 
446 	case STACKSHOT_KCTYPE_KERN_STACKLR:
447 		setup_type_definition(retval, type_id, 1, "kernel_stack_frames");
448 		setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "lr");
449 		subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_STRUCT;
450 		break;
451 
452 	case STACKSHOT_KCTYPE_KERN_STACKLR64:
453 		setup_type_definition(retval, type_id, 1, "kernel_stack_frames");
454 		setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "lr");
455 		subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_STRUCT;
456 		break;
457 
458 	case STACKSHOT_KCTYPE_USER_STACKLR:
459 		setup_type_definition(retval, type_id, 1, "user_stack_frames");
460 		setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "lr");
461 		subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_STRUCT;
462 		break;
463 
464 	case STACKSHOT_KCTYPE_USER_STACKLR64:
465 		setup_type_definition(retval, type_id, 1, "user_stack_frames");
466 		setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "lr");
467 		subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_STRUCT;
468 		break;
469 
470 	case STACKSHOT_KCTYPE_USER_ASYNC_START_INDEX:
471 		setup_type_definition(retval, type_id, 1, "user_async_start_index");
472 		setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "user_async_start_index");
473 		break;
474 
475 	case STACKSHOT_KCTYPE_USER_ASYNC_STACKLR64:
476 		setup_type_definition(retval, type_id, 1, "user_async_stack_frames");
477 		setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "lr");
478 		subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_STRUCT;
479 		break;
480 
481 	case STACKSHOT_KCTYPE_NONRUNNABLE_TIDS:
482 		setup_type_definition(retval, type_id, 1, "nonrunnable_threads");
483 		setup_subtype_description(&subtypes[0], KC_ST_INT64, 0, "nonrunnable_threads");
484 		break;
485 
486 	case STACKSHOT_KCTYPE_NONRUNNABLE_TASKS:
487 		setup_type_definition(retval, type_id, 1, "nonrunnable_tasks");
488 		setup_subtype_description(&subtypes[0], KC_ST_INT64, 0, "nonrunnable_tasks");
489 		break;
490 
491 	case STACKSHOT_KCTYPE_BOOTARGS: {
492 		i = 0;
493 		_STRINGTYPE("boot_args");
494 		setup_type_definition(retval, type_id, i, "boot_args");
495 		break;
496 	}
497 
498 	case STACKSHOT_KCTYPE_OSVERSION: {
499 		i = 0;
500 		_STRINGTYPE("osversion");
501 		setup_type_definition(retval, type_id, i, "osversion");
502 		break;
503 	}
504 
505 	case STACKSHOT_KCTYPE_KERN_PAGE_SIZE: {
506 		i = 0;
507 		setup_subtype_description(&subtypes[i++], KC_ST_UINT32, 0, "kernel_page_size");
508 		setup_type_definition(retval, type_id, i, "kernel_page_size");
509 		break;
510 	}
511 
512 	case STACKSHOT_KCTYPE_THREAD_POLICY_VERSION: {
513 		i = 0;
514 		setup_subtype_description(&subtypes[i++], KC_ST_UINT32, 0, "thread_policy_version");
515 		setup_type_definition(retval, type_id, i, "thread_policy_version");
516 		break;
517 	}
518 
519 	case STACKSHOT_KCTYPE_JETSAM_LEVEL: {
520 		i = 0;
521 		setup_subtype_description(&subtypes[i++], KC_ST_UINT32, 0, "jetsam_level");
522 		setup_type_definition(retval, type_id, i, "jetsam_level");
523 		break;
524 	}
525 
526 	case STACKSHOT_KCTYPE_DELTA_SINCE_TIMESTAMP: {
527 		i = 0;
528 		setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "stackshot_delta_since_timestamp");
529 		setup_type_definition(retval, type_id, i, "stackshot_delta_since_timestamp");
530 		break;
531 	}
532 
533 	/* crashinfo types */
534 	case TASK_CRASHINFO_BSDINFOWITHUNIQID: {
535 		i = 0;
536 		_SUBTYPE_ARRAY(KC_ST_UINT8, struct crashinfo_proc_uniqidentifierinfo, p_uuid, 16);
537 		_SUBTYPE(KC_ST_UINT64, struct crashinfo_proc_uniqidentifierinfo, p_uniqueid);
538 		_SUBTYPE(KC_ST_UINT64, struct crashinfo_proc_uniqidentifierinfo, p_puniqueid);
539 		/* Ignore the p_reserve fields */
540 		setup_type_definition(retval, type_id, i, "proc_uniqidentifierinfo");
541 		break;
542 	}
543 
544 	case TASK_CRASHINFO_PID: {
545 		setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "pid");
546 		setup_type_definition(retval, type_id, 1, "pid");
547 		break;
548 	}
549 
550 	case TASK_CRASHINFO_PPID: {
551 		setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "ppid");
552 		setup_type_definition(retval, type_id, 1, "ppid");
553 		break;
554 	}
555 
556 	/* case TASK_CRASHINFO_RUSAGE: { */
557 	/*      /\* */
558 	/*       * rusage is a complex structure and is only for legacy use for crashed processes rusage info. */
559 	/*       * So we just consider it as opaque data. */
560 	/*       *\/ */
561 	/*      i = 0; */
562 	/*      setup_subtype_array_description(&subtypes[i++], KC_ST_UINT8, 0, sizeof(struct rusage), "rusage"); */
563 	/*      setup_type_definition(retval, type_id, i, "rusage"); */
564 	/*      break; */
565 	/* } */
566 
567 	case TASK_CRASHINFO_RUSAGE_INFO: {
568 		i = 0;
569 		_SUBTYPE_ARRAY(KC_ST_UINT8, struct rusage_info_v3, ri_uuid, 16);
570 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_user_time);
571 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_system_time);
572 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_pkg_idle_wkups);
573 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_interrupt_wkups);
574 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_pageins);
575 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_wired_size);
576 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_resident_size);
577 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_phys_footprint);
578 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_proc_start_abstime);
579 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_proc_exit_abstime);
580 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_user_time);
581 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_system_time);
582 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_pkg_idle_wkups);
583 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_interrupt_wkups);
584 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_pageins);
585 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_elapsed_abstime);
586 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_diskio_bytesread);
587 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_diskio_byteswritten);
588 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_default);
589 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_maintenance);
590 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_background);
591 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_utility);
592 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_legacy);
593 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_user_initiated);
594 		_SUBTYPE_TRUNC(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_user_interactive, "ri_cpu_time_qos_user_interactiv");
595 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_billed_system_time);
596 		_SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_serviced_system_time);
597 		setup_type_definition(retval, type_id, i, "rusage_info");
598 		break;
599 	}
600 
601 	case STACKSHOT_KCTYPE_CPU_TIMES: {
602 		i = 0;
603 		_SUBTYPE(KC_ST_UINT64, struct stackshot_cpu_times_v2, user_usec);
604 		_SUBTYPE(KC_ST_UINT64, struct stackshot_cpu_times_v2, system_usec);
605 		_SUBTYPE(KC_ST_UINT64, struct stackshot_cpu_times_v2, runnable_usec);
606 		setup_type_definition(retval, type_id, i, "cpu_times");
607 		break;
608 	}
609 
610 	case STACKSHOT_KCTYPE_STACKSHOT_DURATION: {
611 		i = 0;
612 		_SUBTYPE(KC_ST_UINT64, struct stackshot_duration_v2, stackshot_duration);
613 		_SUBTYPE(KC_ST_UINT64, struct stackshot_duration_v2, stackshot_duration_outer);
614 		_SUBTYPE(KC_ST_UINT64, struct stackshot_duration_v2, stackshot_duration_prior);
615 		subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_MERGE;
616 		subtypes[1].kcs_flags |= KCS_SUBTYPE_FLAGS_MERGE;
617 		subtypes[2].kcs_flags |= KCS_SUBTYPE_FLAGS_MERGE;
618 		setup_type_definition(retval, type_id, i, "stackshot_duration");
619 		break;
620 	}
621 
622 	case STACKSHOT_KCTYPE_STACKSHOT_FAULT_STATS: {
623 		i = 0;
624 		_SUBTYPE(KC_ST_UINT32, struct stackshot_fault_stats, sfs_pages_faulted_in);
625 		_SUBTYPE(KC_ST_UINT64, struct stackshot_fault_stats, sfs_time_spent_faulting);
626 		_SUBTYPE(KC_ST_UINT64, struct stackshot_fault_stats, sfs_system_max_fault_time);
627 		_SUBTYPE(KC_ST_UINT8, struct stackshot_fault_stats, sfs_stopped_faulting);
628 
629 		setup_type_definition(retval, type_id, i, "stackshot_fault_stats");
630 		break;
631 	}
632 
633 	case STACKSHOT_KCTYPE_THREAD_WAITINFO: {
634 		i = 0;
635 		_SUBTYPE(KC_ST_UINT64, struct stackshot_thread_waitinfo_v2, owner);
636 		_SUBTYPE(KC_ST_UINT64, struct stackshot_thread_waitinfo_v2, waiter);
637 		_SUBTYPE(KC_ST_UINT64, struct stackshot_thread_waitinfo_v2, context);
638 		_SUBTYPE(KC_ST_UINT8, struct stackshot_thread_waitinfo_v2, wait_type);
639 		_SUBTYPE(KC_ST_INT16, struct stackshot_thread_waitinfo_v2, portlabel_id);
640 		_SUBTYPE(KC_ST_UINT32, struct stackshot_thread_waitinfo_v2, wait_flags);
641 		setup_type_definition(retval, type_id, i, "thread_waitinfo");
642 		break;
643 	}
644 
645 	case STACKSHOT_KCTYPE_THREAD_GROUP_SNAPSHOT: {
646 		i = 0;
647 		_SUBTYPE(KC_ST_UINT64, struct thread_group_snapshot_v3, tgs_id);
648 		_SUBTYPE_ARRAY(KC_ST_CHAR, struct thread_group_snapshot_v3, tgs_name, 16);
649 		_SUBTYPE(KC_ST_UINT64, struct thread_group_snapshot_v3, tgs_flags);
650 		_SUBTYPE_ARRAY(KC_ST_CHAR, struct thread_group_snapshot_v3, tgs_name_cont, 16);
651 		setup_type_definition(retval, type_id, i, "thread_group_snapshot");
652 		break;
653 	}
654 
655 	case STACKSHOT_KCTYPE_THREAD_GROUP: {
656 		i = 0;
657 		setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "thread_group");
658 		setup_type_definition(retval, type_id, i, "thread_group");
659 		break;
660 	};
661 
662 	case STACKSHOT_KCTYPE_JETSAM_COALITION_SNAPSHOT: {
663 		i = 0;
664 		_SUBTYPE(KC_ST_UINT64, struct jetsam_coalition_snapshot, jcs_id);
665 		_SUBTYPE(KC_ST_UINT64, struct jetsam_coalition_snapshot, jcs_flags);
666 		_SUBTYPE(KC_ST_UINT64, struct jetsam_coalition_snapshot, jcs_thread_group);
667 		_SUBTYPE(KC_ST_UINT64, struct jetsam_coalition_snapshot, jcs_leader_task_uniqueid);
668 		setup_type_definition(retval, type_id, i, "jetsam_coalition_snapshot");
669 		break;
670 	}
671 
672 	case STACKSHOT_KCTYPE_JETSAM_COALITION: {
673 		i = 0;
674 		setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "jetsam_coalition");
675 		setup_type_definition(retval, type_id, i, "jetsam_coalition");
676 		break;
677 	};
678 
679 	case STACKSHOT_KCTYPE_INSTRS_CYCLES: {
680 		i = 0;
681 		_SUBTYPE(KC_ST_UINT64, struct instrs_cycles_snapshot, ics_instructions);
682 		_SUBTYPE(KC_ST_UINT64, struct instrs_cycles_snapshot, ics_cycles);
683 		setup_type_definition(retval, type_id, i, "instrs_cycles_snapshot");
684 		break;
685 	}
686 
687 	case STACKSHOT_KCTYPE_USER_STACKTOP: {
688 		i = 0;
689 		_SUBTYPE(KC_ST_UINT64, struct stack_snapshot_stacktop, sp);
690 		_SUBTYPE_ARRAY(KC_ST_UINT8, struct stack_snapshot_stacktop, stack_contents, 8);
691 		setup_type_definition(retval, type_id, i, "user_stacktop");
692 		break;
693 	}
694 
695 	case TASK_CRASHINFO_PROC_STARTTIME: {
696 		i = 0;
697 		_SUBTYPE(KC_ST_INT64, struct timeval64, tv_sec);
698 		_SUBTYPE(KC_ST_INT64, struct timeval64, tv_usec);
699 		setup_type_definition(retval, type_id, i, "proc_starttime");
700 		break;
701 	}
702 
703 	case TASK_CRASHINFO_EXCEPTION_CODES: {
704 		i = 0;
705 		char codenum[100];
706 		for (i = 0; i < EXCEPTION_CODE_MAX; i++) {
707 			snprintf(codenum, sizeof(codenum), "code_%d", i);
708 			setup_subtype_description(&subtypes[i], KC_ST_UINT64, i * (sizeof(uint64_t)), codenum);
709 		}
710 		setup_type_definition(retval, type_id, i, "mach_exception_data_t");
711 		break;
712 	}
713 
714 	case TASK_CRASHINFO_PROC_NAME: {
715 		i = 0;
716 		_STRINGTYPE("p_comm");
717 		setup_type_definition(retval, type_id, i, "p_comm");
718 		break;
719 	}
720 
721 	case TASK_CRASHINFO_USERSTACK: {
722 		i = 0;
723 		setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "userstack_ptr");
724 		setup_type_definition(retval, type_id, 1, "userstack_ptr");
725 		break;
726 	}
727 
728 	case TASK_CRASHINFO_ARGSLEN: {
729 		i = 0;
730 		setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "p_argslen");
731 		setup_type_definition(retval, type_id, 1, "p_argslen");
732 		break;
733 	}
734 
735 	case TASK_CRASHINFO_PROC_PATH: {
736 		i = 0;
737 		_STRINGTYPE("p_path");
738 		setup_type_definition(retval, type_id, i, "p_path");
739 		break;
740 	}
741 
742 	case TASK_CRASHINFO_PROC_CSFLAGS: {
743 		setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "p_csflags");
744 		setup_type_definition(retval, type_id, 1, "p_csflags");
745 		break;
746 	}
747 
748 	case TASK_CRASHINFO_PROC_STATUS: {
749 		setup_subtype_description(&subtypes[0], KC_ST_UINT8, 0, "p_status");
750 		setup_type_definition(retval, type_id, 1, "p_status");
751 		break;
752 	}
753 
754 	case TASK_CRASHINFO_UID: {
755 		setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "uid");
756 		setup_type_definition(retval, type_id, 1, "uid");
757 		break;
758 	}
759 
760 	case TASK_CRASHINFO_GID: {
761 		setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "gid");
762 		setup_type_definition(retval, type_id, 1, "gid");
763 		break;
764 	}
765 
766 	case TASK_CRASHINFO_PROC_ARGC: {
767 		setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "argc");
768 		setup_type_definition(retval, type_id, 1, "argc");
769 		break;
770 	}
771 
772 	case TASK_CRASHINFO_PROC_FLAGS: {
773 		setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "p_flags");
774 		setup_type_definition(retval, type_id, 1, "p_flags");
775 		break;
776 	}
777 
778 	case TASK_CRASHINFO_CPUTYPE: {
779 		setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "cputype");
780 		setup_type_definition(retval, type_id, 1, "cputype");
781 		break;
782 	}
783 
784 	case TASK_CRASHINFO_RESPONSIBLE_PID: {
785 		setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "responsible_pid");
786 		setup_type_definition(retval, type_id, 1, "responsible_pid");
787 		break;
788 	}
789 
790 	case TASK_CRASHINFO_DIRTY_FLAGS: {
791 		setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "dirty_flags");
792 		setup_type_definition(retval, type_id, 1, "dirty_flags");
793 		break;
794 	}
795 
796 	case TASK_CRASHINFO_CRASHED_THREADID: {
797 		setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "crashed_threadid");
798 		setup_type_definition(retval, type_id, 1, "crashed_threadid");
799 		break;
800 	}
801 
802 	case TASK_CRASHINFO_COALITION_ID: {
803 		setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "coalition_id");
804 		setup_type_definition(retval, type_id, 1, "coalition_id");
805 		break;
806 	}
807 
808 	case TASK_CRASHINFO_UDATA_PTRS: {
809 		setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "udata_ptrs");
810 		setup_type_definition(retval, type_id, 1, "udata_ptrs");
811 		break;
812 	}
813 
814 	case TASK_CRASHINFO_MEMORY_LIMIT: {
815 		setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "task_phys_mem_limit");
816 		setup_type_definition(retval, type_id, 1, "task_phys_mem_limit");
817 		break;
818 	}
819 
820 	case TASK_CRASHINFO_TASK_IS_CORPSE_FORK: {
821 		setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "task_is_corpse_fork");
822 		setup_type_definition(retval, type_id, 1, "task_is_corpse_fork");
823 		break;
824 	}
825 
826 	case TASK_CRASHINFO_EXCEPTION_TYPE: {
827 		setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "exception_type");
828 		setup_type_definition(retval, type_id, 1, "exception_type");
829 		break;
830 	}
831 
832 	case EXIT_REASON_SNAPSHOT: {
833 		_SUBTYPE(KC_ST_UINT32, struct exit_reason_snapshot, ers_namespace);
834 		_SUBTYPE(KC_ST_UINT64, struct exit_reason_snapshot, ers_code);
835 		_SUBTYPE(KC_ST_UINT64, struct exit_reason_snapshot, ers_flags);
836 		setup_type_definition(retval, type_id, i, "exit_reason_basic_info");
837 
838 		break;
839 	}
840 
841 	case EXIT_REASON_USER_DESC: {
842 		i = 0;
843 
844 		_STRINGTYPE("exit_reason_user_description");
845 		setup_type_definition(retval, type_id, i, "exit_reason_user_description");
846 		break;
847 	}
848 
849 	case EXIT_REASON_USER_PAYLOAD: {
850 		i = 0;
851 
852 		setup_subtype_array_description(&subtypes[i++], KC_ST_UINT8, 0, EXIT_REASON_PAYLOAD_MAX_LEN, "exit_reason_user_payload");
853 		setup_type_definition(retval, type_id, i, "exit_reason_user_payload");
854 		break;
855 	}
856 
857 	case EXIT_REASON_CODESIGNING_INFO: {
858 		_SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_virt_addr);
859 		_SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_file_offset);
860 		_SUBTYPE_ARRAY(KC_ST_CHAR, struct codesigning_exit_reason_info, ceri_pathname, EXIT_REASON_CODESIG_PATH_MAX);
861 		_SUBTYPE_ARRAY(KC_ST_CHAR, struct codesigning_exit_reason_info, ceri_filename, EXIT_REASON_CODESIG_PATH_MAX);
862 		_SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_codesig_modtime_secs);
863 		_SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_codesig_modtime_nsecs);
864 		_SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_page_modtime_secs);
865 		_SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_page_modtime_nsecs);
866 		_SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_path_truncated);
867 		_SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_object_codesigned);
868 		_SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_codesig_validated);
869 		_SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_codesig_tainted);
870 		_SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_codesig_nx);
871 		_SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_wpmapped);
872 		_SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_slid);
873 		_SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_dirty);
874 		_SUBTYPE(KC_ST_UINT32, struct codesigning_exit_reason_info, ceri_page_shadow_depth);
875 		setup_type_definition(retval, type_id, i, "exit_reason_codesigning_info");
876 		break;
877 	}
878 
879 	case EXIT_REASON_WORKLOOP_ID: {
880 		i = 0;
881 		setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "exit_reason_workloop_id");
882 		setup_type_definition(retval, type_id, i, "exit_reason_workloop_id");
883 		break;
884 	}
885 
886 	case EXIT_REASON_DISPATCH_QUEUE_NO: {
887 		i = 0;
888 		setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "exit_reason_dispatch_queue_no");
889 		setup_type_definition(retval, type_id, i, "exit_reason_dispatch_queue_no");
890 		break;
891 	}
892 
893 	case STACKSHOT_KCTYPE_ASID: {
894 		i = 0;
895 		setup_subtype_description(&subtypes[i++], KC_ST_UINT32, 0, "ts_asid");
896 		setup_type_definition(retval, type_id, i, "ts_asid");
897 		break;
898 	}
899 
900 	case STACKSHOT_KCTYPE_PAGE_TABLES: {
901 		i = 0;
902 		setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "ts_pagetable");
903 		setup_type_definition(retval, type_id, i, "ts_pagetable");
904 		break;
905 	}
906 
907 	case STACKSHOT_KCTYPE_SYS_SHAREDCACHE_LAYOUT: {
908 		i = 0;
909 		_SUBTYPE(KC_ST_UINT64, struct user64_dyld_uuid_info, imageLoadAddress);
910 		_SUBTYPE_ARRAY(KC_ST_UINT8, struct user64_dyld_uuid_info, imageUUID, 16);
911 		setup_type_definition(retval, type_id, i, "system_shared_cache_layout");
912 		break;
913 	}
914 
915 	case STACKSHOT_KCTYPE_THREAD_DISPATCH_QUEUE_LABEL: {
916 		i = 0;
917 		_STRINGTYPE("dispatch_queue_label");
918 		setup_type_definition(retval, type_id, i, "dispatch_queue_label");
919 		break;
920 	}
921 
922 	case STACKSHOT_KCTYPE_THREAD_TURNSTILEINFO: {
923 		i = 0;
924 		_SUBTYPE(KC_ST_UINT64, struct stackshot_thread_turnstileinfo_v2, waiter);
925 		_SUBTYPE(KC_ST_UINT64, struct stackshot_thread_turnstileinfo_v2, turnstile_context);
926 		_SUBTYPE(KC_ST_UINT8, struct stackshot_thread_turnstileinfo_v2, turnstile_priority);
927 		_SUBTYPE(KC_ST_UINT8, struct stackshot_thread_turnstileinfo_v2, number_of_hops);
928 		_SUBTYPE(KC_ST_UINT64, struct stackshot_thread_turnstileinfo_v2, turnstile_flags);
929 		_SUBTYPE(KC_ST_INT16, struct stackshot_thread_turnstileinfo_v2, portlabel_id);
930 		setup_type_definition(retval, type_id, i, "thread_turnstileinfo");
931 		break;
932 	}
933 
934 	case STACKSHOT_KCTYPE_PORTLABEL: {
935 		i = 0;
936 		_SUBTYPE(KC_ST_INT16, struct portlabel_info, portlabel_id);
937 		_SUBTYPE(KC_ST_UINT16, struct portlabel_info, portlabel_flags);
938 		_SUBTYPE(KC_ST_INT8, struct portlabel_info, portlabel_domain);
939 		subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_MERGE;
940 		subtypes[1].kcs_flags |= KCS_SUBTYPE_FLAGS_MERGE;
941 		subtypes[2].kcs_flags |= KCS_SUBTYPE_FLAGS_MERGE;
942 		setup_type_definition(retval, type_id, i, "portlabel_info");
943 		break;
944 	}
945 
946 	case STACKSHOT_KCTYPE_PORTLABEL_NAME:
947 		i = 0;
948 		_STRINGTYPE("portlabel_name");
949 		setup_type_definition(retval, type_id, i, "portlabel_name");
950 		break;
951 
952 	case STACKSHOT_KCTYPE_TASK_CPU_ARCHITECTURE: {
953 		i = 0;
954 		_SUBTYPE(KC_ST_INT32, struct stackshot_cpu_architecture, cputype);
955 		_SUBTYPE(KC_ST_INT32, struct stackshot_cpu_architecture, cpusubtype);
956 		setup_type_definition(retval, type_id, i, "task_cpu_architecture");
957 		break;
958 	}
959 
960 	case STACKSHOT_KCTYPE_LATENCY_INFO: {
961 		i = 0;
962 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_collection, latency_version);
963 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_collection, setup_latency);
964 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_collection, total_task_iteration_latency);
965 		_SUBTYPE_TRUNC(KC_ST_UINT64, struct stackshot_latency_collection, total_terminated_task_iteration_latency, "total_terminated_task_iteration");
966 		setup_type_definition(retval, type_id, i, "stackshot_latency_collection");
967 		break;
968 	}
969 	case STACKSHOT_KCTYPE_LATENCY_INFO_TASK: {
970 		i = 0;
971 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_task, task_uniqueid);
972 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_task, setup_latency);
973 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_task, task_thread_count_loop_latency);
974 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_task, task_thread_data_loop_latency);
975 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_task, cur_tsnap_latency);
976 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_task, pmap_latency);
977 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_task, bsd_proc_ids_latency);
978 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_task, misc_latency);
979 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_task, misc2_latency);
980 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_task, end_latency);
981 		setup_type_definition(retval, type_id, i, "stackshot_latency_task");
982 		break;
983 	}
984 	case STACKSHOT_KCTYPE_LATENCY_INFO_THREAD: {
985 		i = 0;
986 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_thread, thread_id);
987 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_thread, cur_thsnap1_latency);
988 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_thread, dispatch_serial_latency);
989 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_thread, dispatch_label_latency);
990 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_thread, cur_thsnap2_latency);
991 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_thread, thread_name_latency);
992 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_thread, sur_times_latency);
993 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_thread, user_stack_latency);
994 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_thread, kernel_stack_latency);
995 		_SUBTYPE(KC_ST_UINT64, struct stackshot_latency_thread, misc_latency);
996 		setup_type_definition(retval, type_id, i, "stackshot_latency_thread");
997 		break;
998 	}
999 
1000 	case TASK_CRASHINFO_KERNEL_TRIAGE_INFO_V1: {
1001 		i = 0;
1002 		_SUBTYPE_ARRAY(KC_ST_CHAR, struct kernel_triage_info_v1, triage_string1, MAX_TRIAGE_STRING_LEN);
1003 		_SUBTYPE_ARRAY(KC_ST_CHAR, struct kernel_triage_info_v1, triage_string2, MAX_TRIAGE_STRING_LEN);
1004 		_SUBTYPE_ARRAY(KC_ST_CHAR, struct kernel_triage_info_v1, triage_string3, MAX_TRIAGE_STRING_LEN);
1005 		_SUBTYPE_ARRAY(KC_ST_CHAR, struct kernel_triage_info_v1, triage_string4, MAX_TRIAGE_STRING_LEN);
1006 		_SUBTYPE_ARRAY(KC_ST_CHAR, struct kernel_triage_info_v1, triage_string5, MAX_TRIAGE_STRING_LEN);
1007 		setup_type_definition(retval, type_id, i, "kernel_triage_info_v1");
1008 		break;
1009 	}
1010 
1011 	default:
1012 		retval = NULL;
1013 		break;
1014 	}
1015 
1016 	assert(retval == NULL || (buffer_size > sizeof(struct kcdata_type_definition) +
1017 	    (retval->kct_num_elements * sizeof(struct kcdata_subtype_descriptor))));
1018 	return retval;
1019 }
1020 
1021 static void
setup_type_definition(struct kcdata_type_definition * d,uint32_t type,uint32_t num_elems,char * name)1022 setup_type_definition(struct kcdata_type_definition * d, uint32_t type, uint32_t num_elems, char * name)
1023 {
1024 	d->kct_type_identifier = type;
1025 	d->kct_num_elements = num_elems;
1026 	memcpy(d->kct_name, name, sizeof(d->kct_name));
1027 	d->kct_name[sizeof(d->kct_name) - 1] = '\0';
1028 }
1029 
1030 static uint32_t
get_kctype_subtype_size(kctype_subtype_t type)1031 get_kctype_subtype_size(kctype_subtype_t type)
1032 {
1033 	switch (type) {
1034 	case KC_ST_CHAR:
1035 	case KC_ST_INT8:
1036 	case KC_ST_UINT8:
1037 		return sizeof(uint8_t);
1038 		break;
1039 	case KC_ST_INT16:
1040 	case KC_ST_UINT16:
1041 		return sizeof(uint16_t);
1042 		break;
1043 	case KC_ST_INT32:
1044 	case KC_ST_UINT32:
1045 		return sizeof(uint32_t);
1046 		break;
1047 	case KC_ST_INT64:
1048 	case KC_ST_UINT64:
1049 		return sizeof(uint64_t);
1050 		break;
1051 
1052 	default:
1053 		assert(0);
1054 		break;
1055 	}
1056 	return 0;
1057 }
1058 
1059 static void
setup_subtype_array_description(kcdata_subtype_descriptor_t desc,kctype_subtype_t type,uint32_t offset,uint32_t count,char * name)1060 setup_subtype_array_description(
1061 	kcdata_subtype_descriptor_t desc, kctype_subtype_t type, uint32_t offset, uint32_t count, char * name)
1062 {
1063 	desc->kcs_flags       = KCS_SUBTYPE_FLAGS_ARRAY;
1064 	desc->kcs_elem_type   = type;
1065 	desc->kcs_elem_offset = offset;
1066 	desc->kcs_elem_size = KCS_SUBTYPE_PACK_SIZE(count, get_kctype_subtype_size(type));
1067 	memcpy(desc->kcs_name, name, sizeof(desc->kcs_name));
1068 	desc->kcs_name[sizeof(desc->kcs_name) - 1] = '\0';
1069 }
1070 
1071 static void
setup_subtype_description(kcdata_subtype_descriptor_t desc,kctype_subtype_t type,uint32_t offset,char * name)1072 setup_subtype_description(kcdata_subtype_descriptor_t desc, kctype_subtype_t type, uint32_t offset, char * name)
1073 {
1074 	desc->kcs_flags       = KCS_SUBTYPE_FLAGS_NONE;
1075 	desc->kcs_elem_type   = type;
1076 	desc->kcs_elem_offset = offset;
1077 	desc->kcs_elem_size = get_kctype_subtype_size(type);
1078 	memcpy(desc->kcs_name, name, sizeof(desc->kcs_name));
1079 	desc->kcs_name[sizeof(desc->kcs_name) - 1] = '\0';
1080 }
1081