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