]> git.saurik.com Git - apple/xnu.git/blob - libkdd/kcdtypes.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / libkdd / kcdtypes.c
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
33 /*!
34 * @function kcdata_get_typedescription
35 *
36 * @abstract
37 * Search the known type definitions for type with id type_id.
38 *
39 * @param type_id
40 * A unsinged int type specified by the KCDATA.
41 *
42 * @param buffer
43 * pointer to data area where type definition will be saved.
44 *
45 * @param buffer_size
46 * size of the buffer provided.
47 *
48 * @return struct kcdata_type_definition *
49 * pointer to a malloc'ed buffer holding the type definition and each subtype defintion for its fields.
50 * It may return NULL if no type with id == type_id is found.
51 * Note: The caller is responsible to free() the memory when its no longer used.
52 *
53 * @discussion
54 * This function queries the known type definitions table. If found the defintion data is returned
55 * else NULL is returned. It is advised to cache the return value from this function since the data
56 * is always going to be the same for same type_id. The definition setup requires memory on heap.
57 * The caller should make sure to free() the data once its done with using it.
58 *
59 */
60 struct kcdata_type_definition * kcdata_get_typedescription(unsigned type_id, uint8_t * buffer, uint32_t buffer_size);
61
62 /* forward declarations for helper routines */
63 static uint32_t get_kctype_subtype_size(kctype_subtype_t type);
64 static void setup_subtype_description(kcdata_subtype_descriptor_t desc, kctype_subtype_t type, uint32_t offset, char * name);
65 static void setup_subtype_array_description(
66 kcdata_subtype_descriptor_t desc, kctype_subtype_t type, uint32_t offset, uint32_t count, char * name);
67 static void setup_type_definition(struct kcdata_type_definition * d, uint32_t type, uint32_t num_elems, char * name);
68
69 struct kcdata_type_definition *
70 kcdata_get_typedescription(unsigned type_id, uint8_t * buffer, uint32_t buffer_size)
71 {
72 unsigned int i = 0;
73 #define _STR_VALUE(x) #x
74 #define _SUBTYPE(t, s, f) setup_subtype_description(&subtypes[i++], (t), offsetof(s, f), _STR_VALUE(f))
75 #define _SUBTYPE_ARRAY(t, s, f, c) setup_subtype_array_description(&subtypes[i++], (t), offsetof(s, f), (c), _STR_VALUE(f))
76 #define _STRINGTYPE(f) setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, UINT16_MAX, f)
77
78 if (buffer_size < sizeof(struct kcdata_type_definition) || buffer == NULL) {
79 return NULL;
80 }
81
82 struct kcdata_type_definition * retval = (struct kcdata_type_definition *)&buffer[0];
83 kcdata_subtype_descriptor_t subtypes = (kcdata_subtype_descriptor_t)&buffer[sizeof(struct kcdata_type_definition)];
84 switch (type_id) {
85 case KCDATA_TYPE_STRING_DESC: {
86 i = 0;
87 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, KCDATA_DESC_MAXLEN, "desc");
88 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, KCDATA_DESC_MAXLEN, UINT16_MAX, "data");
89 setup_type_definition(retval, type_id, i, "string_desc");
90 break;
91 }
92
93 case KCDATA_TYPE_UINT32_DESC: {
94 i = 0;
95 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, KCDATA_DESC_MAXLEN, "desc");
96 setup_subtype_description(&subtypes[i++], KC_ST_UINT32, KCDATA_DESC_MAXLEN, "data");
97 setup_type_definition(retval, type_id, i, "uint32_desc");
98 break;
99 }
100
101 case KCDATA_TYPE_UINT64_DESC: {
102 i = 0;
103 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, KCDATA_DESC_MAXLEN, "desc");
104 setup_subtype_description(&subtypes[i++], KC_ST_UINT64, KCDATA_DESC_MAXLEN, "data");
105 setup_type_definition(retval, type_id, i, "uint64_desc");
106 break;
107 }
108
109 case KCDATA_TYPE_INT32_DESC: {
110 i = 0;
111 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, KCDATA_DESC_MAXLEN, "desc");
112 setup_subtype_description(&subtypes[i++], KC_ST_INT32, KCDATA_DESC_MAXLEN, "data");
113 setup_type_definition(retval, type_id, i, "int32_desc");
114 break;
115 }
116
117 case KCDATA_TYPE_INT64_DESC: {
118 i = 0;
119 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, KCDATA_DESC_MAXLEN, "desc");
120 setup_subtype_description(&subtypes[i++], KC_ST_INT64, KCDATA_DESC_MAXLEN, "data");
121 setup_type_definition(retval, type_id, i, "int64_desc");
122 break;
123 }
124
125 case KCDATA_TYPE_TYPEDEFINTION: {
126 i = 0;
127 setup_subtype_description(&subtypes[i++], KC_ST_UINT32, offsetof(struct kcdata_type_definition, kct_type_identifier), "typeID");
128 setup_subtype_description(&subtypes[i++], KC_ST_UINT32, offsetof(struct kcdata_type_definition, kct_num_elements), "numOfFields");
129 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, offsetof(struct kcdata_type_definition, kct_name), KCDATA_DESC_MAXLEN, "name");
130 // Note "fields" is an array of run time defined length. So we populate fields at parsing time.
131 setup_type_definition(retval, type_id, i, "typedef");
132 break;
133 }
134
135 case KCDATA_TYPE_CONTAINER_BEGIN: {
136 i = 0;
137 setup_subtype_description(&subtypes[i++], KC_ST_UINT32, 0, "kcContainerType");
138 setup_type_definition(retval, type_id, i, "container_begin");
139 break;
140 }
141
142 case KCDATA_TYPE_LIBRARY_LOADINFO: {
143 i = 0;
144 _SUBTYPE(KC_ST_UINT32, struct user32_dyld_uuid_info, imageLoadAddress);
145 _SUBTYPE_ARRAY(KC_ST_UINT8, struct user32_dyld_uuid_info, imageUUID, 16);
146 setup_type_definition(retval, type_id, i, "dyld_load_info");
147 break;
148 }
149
150 case KCDATA_TYPE_LIBRARY_LOADINFO64: {
151 i = 0;
152 _SUBTYPE(KC_ST_UINT64, struct user64_dyld_uuid_info, imageLoadAddress);
153 _SUBTYPE_ARRAY(KC_ST_UINT8, struct user64_dyld_uuid_info, imageUUID, 16);
154 setup_type_definition(retval, type_id, i, "dyld_load_info");
155 break;
156 }
157
158 case STACKSHOT_KCTYPE_SHAREDCACHE_LOADINFO: {
159 i = 0;
160 /*
161 * for backwards compatibility, we keep the old field names, but the
162 * new data is being put in dyld_shared_cache_loadinfo
163 */
164 _SUBTYPE(KC_ST_UINT64, struct dyld_uuid_info_64_v2, imageLoadAddress);
165 _SUBTYPE_ARRAY(KC_ST_UINT8, struct dyld_uuid_info_64_v2, imageUUID, 16);
166 _SUBTYPE(KC_ST_UINT64, struct dyld_uuid_info_64_v2, imageSlidBaseAddress);
167 _SUBTYPE(KC_ST_UINT64, struct dyld_shared_cache_loadinfo, sharedCacheSlidFirstMapping);
168 setup_type_definition(retval, type_id, i, "shared_cache_dyld_load_info");
169 break;
170 }
171
172 case STACKSHOT_KCTYPE_KERNELCACHE_LOADINFO: {
173 i = 0;
174 _SUBTYPE(KC_ST_UINT64, struct dyld_uuid_info_64, imageLoadAddress);
175 _SUBTYPE_ARRAY(KC_ST_UINT8, struct dyld_uuid_info_64, imageUUID, 16);
176 setup_type_definition(retval, type_id, i, "kernelcache_load_info");
177 break;
178 }
179
180 case KCDATA_TYPE_TIMEBASE: {
181 i = 0;
182 _SUBTYPE(KC_ST_UINT32, struct mach_timebase_info, numer);
183 _SUBTYPE(KC_ST_UINT32, struct mach_timebase_info, denom);
184 setup_type_definition(retval, type_id, i, "mach_timebase_info");
185 break;
186 }
187
188 case KCDATA_TYPE_MACH_ABSOLUTE_TIME:
189 setup_type_definition(retval, type_id, 1, "mach_absolute_time");
190 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "mach_absolute_time");
191 break;
192
193 case KCDATA_TYPE_TIMEVAL: {
194 i = 0;
195 _SUBTYPE(KC_ST_INT64, struct timeval64, tv_sec);
196 _SUBTYPE(KC_ST_INT64, struct timeval64, tv_usec);
197 setup_type_definition(retval, type_id, i, "timeval");
198 break;
199 }
200
201 case KCDATA_TYPE_USECS_SINCE_EPOCH:
202 setup_type_definition(retval, type_id, 1, "usecs_since_epoch");
203 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "usecs_since_epoch");
204 break;
205
206 case KCDATA_TYPE_PID:
207 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "pid");
208 setup_type_definition(retval, type_id, 1, "pid");
209 break;
210
211 case KCDATA_TYPE_PROCNAME:
212 i = 0;
213 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, 64, "proc_name");
214 setup_type_definition(retval, type_id, i, "proc_name");
215 break;
216
217 /* stackshot specific types */
218 case STACKSHOT_KCTYPE_IOSTATS: {
219 i = 0;
220 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_disk_reads_count);
221 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_disk_reads_size);
222 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_disk_writes_count);
223 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_disk_writes_size);
224 _SUBTYPE_ARRAY(KC_ST_UINT64, struct io_stats_snapshot, ss_io_priority_count, STACKSHOT_IO_NUM_PRIORITIES);
225 _SUBTYPE_ARRAY(KC_ST_UINT64, struct io_stats_snapshot, ss_io_priority_size, STACKSHOT_IO_NUM_PRIORITIES);
226 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_paging_count);
227 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_paging_size);
228 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_non_paging_count);
229 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_non_paging_size);
230 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_data_count);
231 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_data_size);
232 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_metadata_count);
233 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_metadata_size);
234
235 setup_type_definition(retval, type_id, i, "io_statistics");
236 break;
237 }
238
239 case STACKSHOT_KCTYPE_GLOBAL_MEM_STATS: {
240 i = 0;
241 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, snapshot_magic);
242 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, free_pages);
243 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, active_pages);
244 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, inactive_pages);
245 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, purgeable_pages);
246 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, wired_pages);
247 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, speculative_pages);
248 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, throttled_pages);
249 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, filebacked_pages);
250 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, compressions);
251 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, decompressions);
252 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, compressor_size);
253 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, busy_buffer_count);
254 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, pages_wanted);
255 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, pages_reclaimed);
256 _SUBTYPE(KC_ST_UINT8, struct mem_and_io_snapshot, pages_wanted_reclaimed_valid);
257 setup_type_definition(retval, type_id, i, "mem_and_io_snapshot");
258 break;
259 }
260
261 case STACKSHOT_KCCONTAINER_TASK:
262 setup_type_definition(retval, type_id, 0, "task_snapshots");
263 break;
264
265 case STACKSHOT_KCCONTAINER_THREAD:
266 setup_type_definition(retval, type_id, 0, "thread_snapshots");
267 break;
268
269 case STACKSHOT_KCTYPE_TASK_SNAPSHOT: {
270 i = 0;
271 _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_unique_pid);
272 _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_ss_flags);
273 _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_user_time_in_terminated_threads);
274 _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_system_time_in_terminated_threads);
275 _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_p_start_sec);
276 _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_task_size);
277 _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_max_resident_size);
278 _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_suspend_count);
279 _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_faults);
280 _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_pageins);
281 _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_cow_faults);
282 _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_was_throttled);
283 _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_did_throttle);
284 _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_latency_qos);
285 _SUBTYPE(KC_ST_INT32, struct task_snapshot_v2, ts_pid);
286 _SUBTYPE_ARRAY(KC_ST_CHAR, struct task_snapshot_v2, ts_p_comm, 32);
287 setup_type_definition(retval, type_id, i, "task_snapshot");
288 break;
289 }
290
291 case STACKSHOT_KCTYPE_TASK_DELTA_SNAPSHOT: {
292 i = 0;
293 _SUBTYPE(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_unique_pid);
294 _SUBTYPE(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_ss_flags);
295 _SUBTYPE(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_user_time_in_terminated_threads);
296 _SUBTYPE(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_system_time_in_terminated_threads);
297 _SUBTYPE(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_task_size);
298 _SUBTYPE(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_max_resident_size);
299 _SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_suspend_count);
300 _SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_faults);
301 _SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_pageins);
302 _SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_cow_faults);
303 _SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_was_throttled);
304 _SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_did_throttle);
305 _SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_latency_qos);
306 setup_type_definition(retval, type_id, i, "task_delta_snapshot");
307 break;
308 }
309
310 case STACKSHOT_KCTYPE_THREAD_SNAPSHOT: {
311 i = 0;
312
313 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_thread_id);
314 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_wait_event);
315 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_continuation);
316 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_total_syscalls);
317 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_voucher_identifier);
318 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_dqserialnum);
319 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_user_time);
320 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_sys_time);
321 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_ss_flags);
322 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_last_run_time);
323 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_last_made_runnable_time);
324 _SUBTYPE(KC_ST_UINT32, struct thread_snapshot_v3, ths_state);
325 _SUBTYPE(KC_ST_UINT32, struct thread_snapshot_v3, ths_sched_flags);
326 _SUBTYPE(KC_ST_INT16, struct thread_snapshot_v3, ths_base_priority);
327 _SUBTYPE(KC_ST_INT16, struct thread_snapshot_v3, ths_sched_priority);
328 _SUBTYPE(KC_ST_UINT8, struct thread_snapshot_v3, ths_eqos);
329 _SUBTYPE(KC_ST_UINT8, struct thread_snapshot_v3, ths_rqos);
330 _SUBTYPE(KC_ST_UINT8, struct thread_snapshot_v3, ths_rqos_override);
331 _SUBTYPE(KC_ST_UINT8, struct thread_snapshot_v3, ths_io_tier);
332 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_thread_t);
333 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v4, ths_requested_policy);
334 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v4, ths_effective_policy);
335
336 setup_type_definition(retval, type_id, i, "thread_snapshot");
337 break;
338 }
339
340 case STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT: {
341 i = 0;
342
343 _SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v2, tds_thread_id);
344 _SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v2, tds_voucher_identifier);
345 _SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v2, tds_ss_flags);
346 _SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v2, tds_last_made_runnable_time);
347 _SUBTYPE(KC_ST_UINT32, struct thread_delta_snapshot_v2, tds_state);
348 _SUBTYPE(KC_ST_UINT32, struct thread_delta_snapshot_v2, tds_sched_flags);
349 _SUBTYPE(KC_ST_INT16, struct thread_delta_snapshot_v2, tds_base_priority);
350 _SUBTYPE(KC_ST_INT16, struct thread_delta_snapshot_v2, tds_sched_priority);
351 _SUBTYPE(KC_ST_UINT8, struct thread_delta_snapshot_v2, tds_eqos);
352 _SUBTYPE(KC_ST_UINT8, struct thread_delta_snapshot_v2, tds_rqos);
353 _SUBTYPE(KC_ST_UINT8, struct thread_delta_snapshot_v2, tds_rqos_override);
354 _SUBTYPE(KC_ST_UINT8, struct thread_delta_snapshot_v2, tds_io_tier);
355 _SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v3, tds_requested_policy);
356 _SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v3, tds_effective_policy);
357
358 setup_type_definition(retval, type_id, i, "thread_delta_snapshot");
359
360 break;
361 }
362
363 case STACKSHOT_KCTYPE_DONATING_PIDS:
364 setup_type_definition(retval, type_id, 1, "donating_pids");
365 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "donating_pids");
366 break;
367
368 case STACKSHOT_KCTYPE_THREAD_NAME: {
369 i = 0;
370 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, 64, "pth_name");
371 setup_type_definition(retval, type_id, i, "pth_name");
372 break;
373 }
374
375 case STACKSHOT_KCTYPE_KERN_STACKFRAME:
376 setup_type_definition(retval, type_id, 2, "kernel_stack_frames");
377 setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "lr");
378 setup_subtype_description(&subtypes[1], KC_ST_UINT32, sizeof(uint32_t), "sp");
379 break;
380
381 case STACKSHOT_KCTYPE_KERN_STACKFRAME64:
382 setup_type_definition(retval, type_id, 2, "kernel_stack_frames");
383 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "lr");
384 setup_subtype_description(&subtypes[1], KC_ST_UINT64, sizeof(uint64_t), "sp");
385 break;
386
387 case STACKSHOT_KCTYPE_USER_STACKFRAME:
388 setup_type_definition(retval, type_id, 2, "user_stack_frames");
389 setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "lr");
390 setup_subtype_description(&subtypes[1], KC_ST_UINT32, sizeof(uint32_t), "sp");
391 break;
392
393 case STACKSHOT_KCTYPE_USER_STACKFRAME64:
394 setup_type_definition(retval, type_id, 2, "user_stack_frames");
395 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "lr");
396 setup_subtype_description(&subtypes[1], KC_ST_UINT64, sizeof(uint64_t), "sp");
397 break;
398
399 case STACKSHOT_KCTYPE_KERN_STACKLR:
400 setup_type_definition(retval, type_id, 1, "kernel_stack_frames");
401 setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "lr");
402 subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_STRUCT;
403 break;
404
405 case STACKSHOT_KCTYPE_KERN_STACKLR64:
406 setup_type_definition(retval, type_id, 1, "kernel_stack_frames");
407 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "lr");
408 subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_STRUCT;
409 break;
410
411 case STACKSHOT_KCTYPE_USER_STACKLR:
412 setup_type_definition(retval, type_id, 1, "user_stack_frames");
413 setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "lr");
414 subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_STRUCT;
415 break;
416
417 case STACKSHOT_KCTYPE_USER_STACKLR64:
418 setup_type_definition(retval, type_id, 1, "user_stack_frames");
419 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "lr");
420 subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_STRUCT;
421 break;
422
423 case STACKSHOT_KCTYPE_NONRUNNABLE_TIDS:
424 setup_type_definition(retval, type_id, 1, "nonrunnable_threads");
425 setup_subtype_description(&subtypes[0], KC_ST_INT64, 0, "nonrunnable_threads");
426 break;
427
428 case STACKSHOT_KCTYPE_NONRUNNABLE_TASKS:
429 setup_type_definition(retval, type_id, 1, "nonrunnable_tasks");
430 setup_subtype_description(&subtypes[0], KC_ST_INT64, 0, "nonrunnable_tasks");
431 break;
432
433 case STACKSHOT_KCTYPE_BOOTARGS: {
434 i = 0;
435 _STRINGTYPE("boot_args");
436 setup_type_definition(retval, type_id, i, "boot_args");
437 break;
438 }
439
440 case STACKSHOT_KCTYPE_OSVERSION: {
441 i = 0;
442 _STRINGTYPE("osversion");
443 setup_type_definition(retval, type_id, i, "osversion");
444 break;
445 }
446
447 case STACKSHOT_KCTYPE_KERN_PAGE_SIZE: {
448 i = 0;
449 setup_subtype_description(&subtypes[i++], KC_ST_UINT32, 0, "kernel_page_size");
450 setup_type_definition(retval, type_id, i, "kernel_page_size");
451 break;
452 }
453
454 case STACKSHOT_KCTYPE_THREAD_POLICY_VERSION: {
455 i = 0;
456 setup_subtype_description(&subtypes[i++], KC_ST_UINT32, 0, "thread_policy_version");
457 setup_type_definition(retval, type_id, i, "thread_policy_version");
458 break;
459 }
460
461 case STACKSHOT_KCTYPE_JETSAM_LEVEL: {
462 i = 0;
463 setup_subtype_description(&subtypes[i++], KC_ST_UINT32, 0, "jetsam_level");
464 setup_type_definition(retval, type_id, i, "jetsam_level");
465 break;
466 }
467
468 case STACKSHOT_KCTYPE_DELTA_SINCE_TIMESTAMP: {
469 i = 0;
470 setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "stackshot_delta_since_timestamp");
471 setup_type_definition(retval, type_id, i, "stackshot_delta_since_timestamp");
472 break;
473 }
474
475 /* crashinfo types */
476 case TASK_CRASHINFO_BSDINFOWITHUNIQID: {
477 i = 0;
478 _SUBTYPE_ARRAY(KC_ST_UINT8, struct crashinfo_proc_uniqidentifierinfo, p_uuid, 16);
479 _SUBTYPE(KC_ST_UINT64, struct crashinfo_proc_uniqidentifierinfo, p_uniqueid);
480 _SUBTYPE(KC_ST_UINT64, struct crashinfo_proc_uniqidentifierinfo, p_puniqueid);
481 /* Ignore the p_reserve fields */
482 setup_type_definition(retval, type_id, i, "proc_uniqidentifierinfo");
483 break;
484 }
485
486 case TASK_CRASHINFO_PID: {
487 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "pid");
488 setup_type_definition(retval, type_id, 1, "pid");
489 break;
490 }
491
492 case TASK_CRASHINFO_PPID: {
493 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "ppid");
494 setup_type_definition(retval, type_id, 1, "ppid");
495 break;
496 }
497
498 /* case TASK_CRASHINFO_RUSAGE: { */
499 /* /\* */
500 /* * rusage is a complex structure and is only for legacy use for crashed processes rusage info. */
501 /* * So we just consider it as opaque data. */
502 /* *\/ */
503 /* i = 0; */
504 /* setup_subtype_array_description(&subtypes[i++], KC_ST_UINT8, 0, sizeof(struct rusage), "rusage"); */
505 /* setup_type_definition(retval, type_id, i, "rusage"); */
506 /* break; */
507 /* } */
508
509 case TASK_CRASHINFO_RUSAGE_INFO: {
510 i = 0;
511 _SUBTYPE_ARRAY(KC_ST_UINT8, struct rusage_info_v3, ri_uuid, 16);
512 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_user_time);
513 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_system_time);
514 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_pkg_idle_wkups);
515 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_interrupt_wkups);
516 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_pageins);
517 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_wired_size);
518 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_resident_size);
519 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_phys_footprint);
520 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_proc_start_abstime);
521 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_proc_exit_abstime);
522 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_user_time);
523 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_system_time);
524 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_pkg_idle_wkups);
525 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_interrupt_wkups);
526 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_pageins);
527 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_elapsed_abstime);
528 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_diskio_bytesread);
529 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_diskio_byteswritten);
530 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_default);
531 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_maintenance);
532 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_background);
533 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_utility);
534 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_legacy);
535 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_user_initiated);
536 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_user_interactive);
537 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_billed_system_time);
538 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_serviced_system_time);
539 setup_type_definition(retval, type_id, i, "rusage_info");
540 break;
541 }
542
543 case STACKSHOT_KCTYPE_CPU_TIMES: {
544 i = 0;
545 _SUBTYPE(KC_ST_UINT64, struct stackshot_cpu_times_v2, user_usec);
546 _SUBTYPE(KC_ST_UINT64, struct stackshot_cpu_times_v2, system_usec);
547 _SUBTYPE(KC_ST_UINT64, struct stackshot_cpu_times_v2, runnable_usec);
548 setup_type_definition(retval, type_id, i, "cpu_times");
549 break;
550 }
551
552 case STACKSHOT_KCTYPE_STACKSHOT_DURATION: {
553 i = 0;
554 _SUBTYPE(KC_ST_UINT64, struct stackshot_duration_v2, stackshot_duration);
555 _SUBTYPE(KC_ST_UINT64, struct stackshot_duration_v2, stackshot_duration_outer);
556 _SUBTYPE(KC_ST_UINT64, struct stackshot_duration_v2, stackshot_duration_prior);
557 subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_MERGE;
558 subtypes[1].kcs_flags |= KCS_SUBTYPE_FLAGS_MERGE;
559 subtypes[2].kcs_flags |= KCS_SUBTYPE_FLAGS_MERGE;
560 setup_type_definition(retval, type_id, i, "stackshot_duration");
561 break;
562 }
563
564 case STACKSHOT_KCTYPE_STACKSHOT_FAULT_STATS: {
565 i = 0;
566 _SUBTYPE(KC_ST_UINT32, struct stackshot_fault_stats, sfs_pages_faulted_in);
567 _SUBTYPE(KC_ST_UINT64, struct stackshot_fault_stats, sfs_time_spent_faulting);
568 _SUBTYPE(KC_ST_UINT64, struct stackshot_fault_stats, sfs_system_max_fault_time);
569 _SUBTYPE(KC_ST_UINT8, struct stackshot_fault_stats, sfs_stopped_faulting);
570
571 setup_type_definition(retval, type_id, i, "stackshot_fault_stats");
572 break;
573 }
574
575 case STACKSHOT_KCTYPE_THREAD_WAITINFO: {
576 i = 0;
577 _SUBTYPE(KC_ST_UINT64, struct stackshot_thread_waitinfo, owner);
578 _SUBTYPE(KC_ST_UINT64, struct stackshot_thread_waitinfo, waiter);
579 _SUBTYPE(KC_ST_UINT64, struct stackshot_thread_waitinfo, context);
580 _SUBTYPE(KC_ST_UINT8, struct stackshot_thread_waitinfo, wait_type);
581 setup_type_definition(retval, type_id, i, "thread_waitinfo");
582 break;
583 }
584
585 case STACKSHOT_KCTYPE_THREAD_GROUP_SNAPSHOT: {
586 i = 0;
587 _SUBTYPE(KC_ST_UINT64, struct thread_group_snapshot_v2, tgs_id);
588 _SUBTYPE_ARRAY(KC_ST_CHAR, struct thread_group_snapshot_v2, tgs_name, 16);
589 _SUBTYPE(KC_ST_UINT64, struct thread_group_snapshot_v2, tgs_flags);
590 setup_type_definition(retval, type_id, i, "thread_group_snapshot");
591 break;
592 }
593
594 case STACKSHOT_KCTYPE_THREAD_GROUP: {
595 i = 0;
596 setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "thread_group");
597 setup_type_definition(retval, type_id, i, "thread_group");
598 break;
599 };
600
601 case STACKSHOT_KCTYPE_JETSAM_COALITION_SNAPSHOT: {
602 i = 0;
603 _SUBTYPE(KC_ST_UINT64, struct jetsam_coalition_snapshot, jcs_id);
604 _SUBTYPE(KC_ST_UINT64, struct jetsam_coalition_snapshot, jcs_flags);
605 _SUBTYPE(KC_ST_UINT64, struct jetsam_coalition_snapshot, jcs_thread_group);
606 _SUBTYPE(KC_ST_UINT64, struct jetsam_coalition_snapshot, jcs_leader_task_uniqueid);
607 setup_type_definition(retval, type_id, i, "jetsam_coalition_snapshot");
608 break;
609 }
610
611 case STACKSHOT_KCTYPE_JETSAM_COALITION: {
612 i = 0;
613 setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "jetsam_coalition");
614 setup_type_definition(retval, type_id, i, "jetsam_coalition");
615 break;
616 };
617
618 case STACKSHOT_KCTYPE_INSTRS_CYCLES: {
619 i = 0;
620 _SUBTYPE(KC_ST_UINT64, struct instrs_cycles_snapshot, ics_instructions);
621 _SUBTYPE(KC_ST_UINT64, struct instrs_cycles_snapshot, ics_cycles);
622 setup_type_definition(retval, type_id, i, "instrs_cycles_snapshot");
623 break;
624 }
625
626 case STACKSHOT_KCTYPE_USER_STACKTOP: {
627 i = 0;
628 _SUBTYPE(KC_ST_UINT64, struct stack_snapshot_stacktop, sp);
629 _SUBTYPE_ARRAY(KC_ST_UINT8, struct stack_snapshot_stacktop, stack_contents, 8);
630 setup_type_definition(retval, type_id, i, "user_stacktop");
631 break;
632 }
633
634 case TASK_CRASHINFO_PROC_STARTTIME: {
635 i = 0;
636 _SUBTYPE(KC_ST_INT64, struct timeval64, tv_sec);
637 _SUBTYPE(KC_ST_INT64, struct timeval64, tv_usec);
638 setup_type_definition(retval, type_id, i, "proc_starttime");
639 break;
640 }
641
642 case TASK_CRASHINFO_EXCEPTION_CODES: {
643 i = 0;
644 char codenum[100];
645 for (i = 0; i < EXCEPTION_CODE_MAX; i++) {
646 snprintf(codenum, sizeof(codenum), "code_%d", i);
647 setup_subtype_description(&subtypes[i], KC_ST_UINT64, i * (sizeof(uint64_t)), codenum);
648 }
649 setup_type_definition(retval, type_id, i, "mach_exception_data_t");
650 break;
651 }
652
653 case TASK_CRASHINFO_PROC_NAME: {
654 i = 0;
655 _STRINGTYPE("p_comm");
656 setup_type_definition(retval, type_id, i, "p_comm");
657 break;
658 }
659
660 case TASK_CRASHINFO_USERSTACK: {
661 i = 0;
662 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "userstack_ptr");
663 setup_type_definition(retval, type_id, 1, "userstack_ptr");
664 break;
665 }
666
667 case TASK_CRASHINFO_ARGSLEN: {
668 i = 0;
669 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "p_argslen");
670 setup_type_definition(retval, type_id, 1, "p_argslen");
671 break;
672 }
673
674 case TASK_CRASHINFO_PROC_PATH: {
675 i = 0;
676 _STRINGTYPE("p_path");
677 setup_type_definition(retval, type_id, i, "p_path");
678 break;
679 }
680
681 case TASK_CRASHINFO_PROC_CSFLAGS: {
682 setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "p_csflags");
683 setup_type_definition(retval, type_id, 1, "p_csflags");
684 break;
685 }
686
687 case TASK_CRASHINFO_PROC_STATUS: {
688 setup_subtype_description(&subtypes[0], KC_ST_UINT8, 0, "p_status");
689 setup_type_definition(retval, type_id, 1, "p_status");
690 break;
691 }
692
693 case TASK_CRASHINFO_UID: {
694 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "uid");
695 setup_type_definition(retval, type_id, 1, "uid");
696 break;
697 }
698
699 case TASK_CRASHINFO_GID: {
700 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "gid");
701 setup_type_definition(retval, type_id, 1, "gid");
702 break;
703 }
704
705 case TASK_CRASHINFO_PROC_ARGC: {
706 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "argc");
707 setup_type_definition(retval, type_id, 1, "argc");
708 break;
709 }
710
711 case TASK_CRASHINFO_PROC_FLAGS: {
712 setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "p_flags");
713 setup_type_definition(retval, type_id, 1, "p_flags");
714 break;
715 }
716
717 case TASK_CRASHINFO_CPUTYPE: {
718 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "cputype");
719 setup_type_definition(retval, type_id, 1, "cputype");
720 break;
721 }
722
723 case TASK_CRASHINFO_RESPONSIBLE_PID: {
724 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "responsible_pid");
725 setup_type_definition(retval, type_id, 1, "responsible_pid");
726 break;
727 }
728
729 case TASK_CRASHINFO_DIRTY_FLAGS: {
730 setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "dirty_flags");
731 setup_type_definition(retval, type_id, 1, "dirty_flags");
732 break;
733 }
734
735 case TASK_CRASHINFO_CRASHED_THREADID: {
736 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "crashed_threadid");
737 setup_type_definition(retval, type_id, 1, "crashed_threadid");
738 break;
739 }
740
741 case TASK_CRASHINFO_COALITION_ID: {
742 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "coalition_id");
743 setup_type_definition(retval, type_id, 1, "coalition_id");
744 break;
745 }
746
747 case TASK_CRASHINFO_UDATA_PTRS: {
748 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "udata_ptrs");
749 setup_type_definition(retval, type_id, 1, "udata_ptrs");
750 break;
751 }
752
753 case TASK_CRASHINFO_MEMORY_LIMIT: {
754 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "task_phys_mem_limit");
755 setup_type_definition(retval, type_id, 1, "task_phys_mem_limit");
756 break;
757 }
758
759 case EXIT_REASON_SNAPSHOT: {
760 _SUBTYPE(KC_ST_UINT32, struct exit_reason_snapshot, ers_namespace);
761 _SUBTYPE(KC_ST_UINT64, struct exit_reason_snapshot, ers_code);
762 _SUBTYPE(KC_ST_UINT64, struct exit_reason_snapshot, ers_flags);
763 setup_type_definition(retval, type_id, i, "exit_reason_basic_info");
764
765 break;
766 }
767
768 case EXIT_REASON_USER_DESC: {
769 i = 0;
770
771 _STRINGTYPE("exit_reason_user_description");
772 setup_type_definition(retval, type_id, i, "exit_reason_user_description");
773 break;
774 }
775
776 case EXIT_REASON_USER_PAYLOAD: {
777 i = 0;
778
779 setup_subtype_array_description(&subtypes[i++], KC_ST_UINT8, 0, EXIT_REASON_PAYLOAD_MAX_LEN, "exit_reason_user_payload");
780 setup_type_definition(retval, type_id, i, "exit_reason_user_payload");
781 break;
782 }
783
784 case EXIT_REASON_CODESIGNING_INFO: {
785 _SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_virt_addr);
786 _SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_file_offset);
787 _SUBTYPE_ARRAY(KC_ST_CHAR, struct codesigning_exit_reason_info, ceri_pathname, EXIT_REASON_CODESIG_PATH_MAX);
788 _SUBTYPE_ARRAY(KC_ST_CHAR, struct codesigning_exit_reason_info, ceri_filename, EXIT_REASON_CODESIG_PATH_MAX);
789 _SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_codesig_modtime_secs);
790 _SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_codesig_modtime_nsecs);
791 _SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_page_modtime_secs);
792 _SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_page_modtime_nsecs);
793 _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_path_truncated);
794 _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_object_codesigned);
795 _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_codesig_validated);
796 _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_codesig_tainted);
797 _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_codesig_nx);
798 _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_wpmapped);
799 _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_slid);
800 _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_dirty);
801 _SUBTYPE(KC_ST_UINT32, struct codesigning_exit_reason_info, ceri_page_shadow_depth);
802 setup_type_definition(retval, type_id, i, "exit_reason_codesigning_info");
803 break;
804 }
805
806 case EXIT_REASON_WORKLOOP_ID: {
807 i = 0;
808 setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "exit_reason_workloop_id");
809 setup_type_definition(retval, type_id, i, "exit_reason_workloop_id");
810 break;
811 }
812
813 case EXIT_REASON_DISPATCH_QUEUE_NO: {
814 i = 0;
815 setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "exit_reason_dispatch_queue_no");
816 setup_type_definition(retval, type_id, i, "exit_reason_dispatch_queue_no");
817 break;
818 }
819
820 case STACKSHOT_KCTYPE_ASID: {
821 i = 0;
822 setup_subtype_description(&subtypes[i++], KC_ST_UINT32, 0, "ts_asid");
823 setup_type_definition(retval, type_id, i, "ts_asid");
824 break;
825 }
826
827 case STACKSHOT_KCTYPE_PAGE_TABLES: {
828 i = 0;
829 setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "ts_pagetable");
830 setup_type_definition(retval, type_id, i, "ts_pagetable");
831 break;
832 }
833
834 case STACKSHOT_KCTYPE_SYS_SHAREDCACHE_LAYOUT: {
835 i = 0;
836 _SUBTYPE(KC_ST_UINT64, struct user64_dyld_uuid_info, imageLoadAddress);
837 _SUBTYPE_ARRAY(KC_ST_UINT8, struct user64_dyld_uuid_info, imageUUID, 16);
838 setup_type_definition(retval, type_id, i, "system_shared_cache_layout");
839 break;
840 }
841
842 case STACKSHOT_KCTYPE_THREAD_DISPATCH_QUEUE_LABEL: {
843 i = 0;
844 _STRINGTYPE("dispatch_queue_label");
845 setup_type_definition(retval, type_id, i, "dispatch_queue_label");
846 break;
847 }
848
849 case STACKSHOT_KCTYPE_THREAD_TURNSTILEINFO: {
850 i = 0;
851 _SUBTYPE(KC_ST_UINT64, struct stackshot_thread_turnstileinfo, waiter);
852 _SUBTYPE(KC_ST_UINT64, struct stackshot_thread_turnstileinfo, turnstile_context);
853 _SUBTYPE(KC_ST_UINT8, struct stackshot_thread_turnstileinfo, turnstile_priority);
854 _SUBTYPE(KC_ST_UINT8, struct stackshot_thread_turnstileinfo, number_of_hops);
855 _SUBTYPE(KC_ST_UINT64, struct stackshot_thread_turnstileinfo, turnstile_flags);
856 setup_type_definition(retval, type_id, i, "thread_turnstileinfo");
857 break;
858 }
859
860 case STACKSHOT_KCTYPE_TASK_CPU_ARCHITECTURE: {
861 i = 0;
862 _SUBTYPE(KC_ST_INT32, struct stackshot_cpu_architecture, cputype);
863 _SUBTYPE(KC_ST_INT32, struct stackshot_cpu_architecture, cpusubtype);
864 setup_type_definition(retval, type_id, i, "task_cpu_architecture");
865 break;
866 }
867
868 default:
869 retval = NULL;
870 break;
871 }
872
873 assert(retval == NULL || (buffer_size > sizeof(struct kcdata_type_definition) +
874 (retval->kct_num_elements * sizeof(struct kcdata_subtype_descriptor))));
875 return retval;
876 }
877
878 static void
879 setup_type_definition(struct kcdata_type_definition * d, uint32_t type, uint32_t num_elems, char * name)
880 {
881 d->kct_type_identifier = type;
882 d->kct_num_elements = num_elems;
883 memcpy(d->kct_name, name, sizeof(d->kct_name));
884 d->kct_name[sizeof(d->kct_name) - 1] = '\0';
885 }
886
887 static uint32_t
888 get_kctype_subtype_size(kctype_subtype_t type)
889 {
890 switch (type) {
891 case KC_ST_CHAR:
892 case KC_ST_INT8:
893 case KC_ST_UINT8:
894 return sizeof(uint8_t);
895 break;
896 case KC_ST_INT16:
897 case KC_ST_UINT16:
898 return sizeof(uint16_t);
899 break;
900 case KC_ST_INT32:
901 case KC_ST_UINT32:
902 return sizeof(uint32_t);
903 break;
904 case KC_ST_INT64:
905 case KC_ST_UINT64:
906 return sizeof(uint64_t);
907 break;
908
909 default:
910 assert(0);
911 break;
912 }
913 return 0;
914 }
915
916 static void
917 setup_subtype_array_description(
918 kcdata_subtype_descriptor_t desc, kctype_subtype_t type, uint32_t offset, uint32_t count, char * name)
919 {
920 desc->kcs_flags = KCS_SUBTYPE_FLAGS_ARRAY;
921 desc->kcs_elem_type = type;
922 desc->kcs_elem_offset = offset;
923 desc->kcs_elem_size = KCS_SUBTYPE_PACK_SIZE(count, get_kctype_subtype_size(type));
924 memcpy(desc->kcs_name, name, sizeof(desc->kcs_name));
925 desc->kcs_name[sizeof(desc->kcs_name) - 1] = '\0';
926 }
927
928 static void
929 setup_subtype_description(kcdata_subtype_descriptor_t desc, kctype_subtype_t type, uint32_t offset, char * name)
930 {
931 desc->kcs_flags = KCS_SUBTYPE_FLAGS_NONE;
932 desc->kcs_elem_type = type;
933 desc->kcs_elem_offset = offset;
934 desc->kcs_elem_size = get_kctype_subtype_size(type);
935 memcpy(desc->kcs_name, name, sizeof(desc->kcs_name));
936 desc->kcs_name[sizeof(desc->kcs_name) - 1] = '\0';
937 }