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