]>
Commit | Line | Data |
---|---|---|
39037602 A |
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> | |
39037602 A |
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 | struct kcdata_type_definition * retval = (struct kcdata_type_definition *)&buffer[0]; | |
82 | kcdata_subtype_descriptor_t subtypes = (kcdata_subtype_descriptor_t)&buffer[sizeof(struct kcdata_type_definition)]; | |
83 | switch (type_id) { | |
84 | case KCDATA_TYPE_STRING_DESC: { | |
85 | i = 0; | |
86 | setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, KCDATA_DESC_MAXLEN, "desc"); | |
87 | setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, KCDATA_DESC_MAXLEN, UINT16_MAX, "data"); | |
88 | setup_type_definition(retval, type_id, i, "string_desc"); | |
89 | break; | |
90 | } | |
91 | ||
92 | case KCDATA_TYPE_UINT32_DESC: { | |
93 | i = 0; | |
94 | setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, KCDATA_DESC_MAXLEN, "desc"); | |
95 | setup_subtype_description(&subtypes[i++], KC_ST_UINT32, KCDATA_DESC_MAXLEN, "data"); | |
96 | setup_type_definition(retval, type_id, i, "uint32_desc"); | |
97 | break; | |
98 | } | |
99 | ||
100 | case KCDATA_TYPE_UINT64_DESC: { | |
101 | i = 0; | |
102 | setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, KCDATA_DESC_MAXLEN, "desc"); | |
103 | setup_subtype_description(&subtypes[i++], KC_ST_UINT64, KCDATA_DESC_MAXLEN, "data"); | |
104 | setup_type_definition(retval, type_id, i, "uint64_desc"); | |
105 | break; | |
106 | } | |
107 | ||
108 | case KCDATA_TYPE_INT32_DESC: { | |
109 | i = 0; | |
110 | setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, KCDATA_DESC_MAXLEN, "desc"); | |
111 | setup_subtype_description(&subtypes[i++], KC_ST_INT32, KCDATA_DESC_MAXLEN, "data"); | |
112 | setup_type_definition(retval, type_id, i, "int32_desc"); | |
113 | break; | |
114 | } | |
115 | ||
116 | case KCDATA_TYPE_INT64_DESC: { | |
117 | i = 0; | |
118 | setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, KCDATA_DESC_MAXLEN, "desc"); | |
119 | setup_subtype_description(&subtypes[i++], KC_ST_INT64, KCDATA_DESC_MAXLEN, "data"); | |
120 | setup_type_definition(retval, type_id, i, "int64_desc"); | |
121 | break; | |
122 | } | |
123 | ||
d9a64523 A |
124 | case KCDATA_TYPE_TYPEDEFINTION: { |
125 | i = 0; | |
126 | setup_subtype_description(&subtypes[i++], KC_ST_UINT32, offsetof(struct kcdata_type_definition, kct_type_identifier), "typeID"); | |
127 | setup_subtype_description(&subtypes[i++], KC_ST_UINT32, offsetof(struct kcdata_type_definition, kct_num_elements), "numOfFields"); | |
128 | setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, offsetof(struct kcdata_type_definition, kct_name), KCDATA_DESC_MAXLEN, "name"); | |
129 | // Note "fields" is an array of run time defined length. So we populate fields at parsing time. | |
130 | setup_type_definition(retval, type_id, i, "typedef"); | |
131 | break; | |
132 | } | |
39037602 A |
133 | |
134 | case KCDATA_TYPE_CONTAINER_BEGIN: { | |
135 | i = 0; | |
136 | setup_subtype_description(&subtypes[i++], KC_ST_UINT32, 0, "kcContainerType"); | |
137 | setup_type_definition(retval, type_id, i, "container_begin"); | |
138 | break; | |
139 | } | |
140 | ||
141 | case KCDATA_TYPE_LIBRARY_LOADINFO: { | |
142 | i = 0; | |
143 | _SUBTYPE(KC_ST_UINT32, struct user32_dyld_uuid_info, imageLoadAddress); | |
144 | _SUBTYPE_ARRAY(KC_ST_UINT8, struct user32_dyld_uuid_info, imageUUID, 16); | |
145 | setup_type_definition(retval, type_id, i, "dyld_load_info"); | |
146 | break; | |
147 | } | |
148 | ||
149 | case KCDATA_TYPE_LIBRARY_LOADINFO64: { | |
150 | i = 0; | |
151 | _SUBTYPE(KC_ST_UINT64, struct user64_dyld_uuid_info, imageLoadAddress); | |
152 | _SUBTYPE_ARRAY(KC_ST_UINT8, struct user64_dyld_uuid_info, imageUUID, 16); | |
153 | setup_type_definition(retval, type_id, i, "dyld_load_info"); | |
154 | break; | |
155 | } | |
156 | ||
157 | case STACKSHOT_KCTYPE_SHAREDCACHE_LOADINFO: { | |
158 | i = 0; | |
159 | _SUBTYPE(KC_ST_UINT64, struct dyld_uuid_info_64_v2, imageLoadAddress); | |
160 | _SUBTYPE_ARRAY(KC_ST_UINT8, struct dyld_uuid_info_64_v2, imageUUID, 16); | |
161 | _SUBTYPE(KC_ST_UINT64, struct dyld_uuid_info_64_v2, imageSlidBaseAddress); | |
162 | setup_type_definition(retval, type_id, i, "shared_cache_dyld_load_info"); | |
163 | break; | |
164 | } | |
165 | ||
166 | case STACKSHOT_KCTYPE_KERNELCACHE_LOADINFO: { | |
167 | i = 0; | |
168 | _SUBTYPE(KC_ST_UINT64, struct dyld_uuid_info_64, imageLoadAddress); | |
169 | _SUBTYPE_ARRAY(KC_ST_UINT8, struct dyld_uuid_info_64, imageUUID, 16); | |
170 | setup_type_definition(retval, type_id, i, "kernelcache_load_info"); | |
171 | break; | |
172 | } | |
173 | ||
174 | case KCDATA_TYPE_TIMEBASE: { | |
175 | i = 0; | |
176 | _SUBTYPE(KC_ST_UINT32, struct mach_timebase_info, numer); | |
177 | _SUBTYPE(KC_ST_UINT32, struct mach_timebase_info, denom); | |
178 | setup_type_definition(retval, type_id, i, "mach_timebase_info"); | |
179 | break; | |
180 | } | |
181 | ||
182 | case KCDATA_TYPE_MACH_ABSOLUTE_TIME: | |
183 | setup_type_definition(retval, type_id, 1, "mach_absolute_time"); | |
184 | setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "mach_absolute_time"); | |
185 | break; | |
186 | ||
187 | case KCDATA_TYPE_TIMEVAL: { | |
188 | i = 0; | |
189 | _SUBTYPE(KC_ST_INT64, struct timeval64, tv_sec); | |
190 | _SUBTYPE(KC_ST_INT64, struct timeval64, tv_usec); | |
191 | setup_type_definition(retval, type_id, i, "timeval"); | |
192 | break; | |
193 | } | |
194 | ||
195 | case KCDATA_TYPE_USECS_SINCE_EPOCH: | |
196 | setup_type_definition(retval, type_id, 1, "usecs_since_epoch"); | |
197 | setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "usecs_since_epoch"); | |
198 | break; | |
199 | ||
200 | case KCDATA_TYPE_PID: | |
201 | setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "pid"); | |
202 | setup_type_definition(retval, type_id, 1, "pid"); | |
203 | break; | |
204 | ||
205 | case KCDATA_TYPE_PROCNAME: | |
206 | i = 0; | |
207 | setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, 64, "proc_name"); | |
208 | setup_type_definition(retval, type_id, i, "proc_name"); | |
209 | break; | |
210 | ||
211 | /* stackshot specific types */ | |
212 | case STACKSHOT_KCTYPE_IOSTATS: { | |
213 | i = 0; | |
214 | _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_disk_reads_count); | |
215 | _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_disk_reads_size); | |
216 | _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_disk_writes_count); | |
217 | _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_disk_writes_size); | |
218 | _SUBTYPE_ARRAY(KC_ST_UINT64, struct io_stats_snapshot, ss_io_priority_count, STACKSHOT_IO_NUM_PRIORITIES); | |
219 | _SUBTYPE_ARRAY(KC_ST_UINT64, struct io_stats_snapshot, ss_io_priority_size, STACKSHOT_IO_NUM_PRIORITIES); | |
220 | _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_paging_count); | |
221 | _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_paging_size); | |
222 | _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_non_paging_count); | |
223 | _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_non_paging_size); | |
224 | _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_data_count); | |
225 | _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_data_size); | |
226 | _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_metadata_count); | |
227 | _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_metadata_size); | |
228 | ||
229 | setup_type_definition(retval, type_id, i, "io_statistics"); | |
230 | break; | |
231 | } | |
232 | ||
233 | case STACKSHOT_KCTYPE_GLOBAL_MEM_STATS: { | |
234 | i = 0; | |
235 | _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, snapshot_magic); | |
236 | _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, free_pages); | |
237 | _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, active_pages); | |
238 | _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, inactive_pages); | |
239 | _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, purgeable_pages); | |
240 | _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, wired_pages); | |
241 | _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, speculative_pages); | |
242 | _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, throttled_pages); | |
243 | _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, filebacked_pages); | |
244 | _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, compressions); | |
245 | _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, decompressions); | |
246 | _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, compressor_size); | |
247 | _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, busy_buffer_count); | |
248 | _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, pages_wanted); | |
249 | _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, pages_reclaimed); | |
250 | _SUBTYPE(KC_ST_UINT8, struct mem_and_io_snapshot, pages_wanted_reclaimed_valid); | |
251 | setup_type_definition(retval, type_id, i, "mem_and_io_snapshot"); | |
252 | break; | |
253 | } | |
254 | ||
255 | case STACKSHOT_KCCONTAINER_TASK: | |
256 | setup_type_definition(retval, type_id, 0, "task_snapshots"); | |
257 | break; | |
258 | ||
259 | case STACKSHOT_KCCONTAINER_THREAD: | |
260 | setup_type_definition(retval, type_id, 0, "thread_snapshots"); | |
261 | break; | |
262 | ||
263 | case STACKSHOT_KCTYPE_TASK_SNAPSHOT: { | |
264 | i = 0; | |
265 | _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_unique_pid); | |
266 | _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_ss_flags); | |
267 | _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_user_time_in_terminated_threads); | |
268 | _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_system_time_in_terminated_threads); | |
269 | _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_p_start_sec); | |
270 | _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_task_size); | |
271 | _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_max_resident_size); | |
272 | _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_suspend_count); | |
273 | _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_faults); | |
274 | _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_pageins); | |
275 | _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_cow_faults); | |
276 | _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_was_throttled); | |
277 | _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_did_throttle); | |
278 | _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_latency_qos); | |
279 | _SUBTYPE(KC_ST_INT32, struct task_snapshot_v2, ts_pid); | |
280 | _SUBTYPE_ARRAY(KC_ST_CHAR, struct task_snapshot_v2, ts_p_comm, 32); | |
281 | setup_type_definition(retval, type_id, i, "task_snapshot"); | |
282 | break; | |
283 | } | |
284 | ||
285 | case STACKSHOT_KCTYPE_TASK_DELTA_SNAPSHOT: { | |
286 | i = 0; | |
287 | _SUBTYPE(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_unique_pid); | |
288 | _SUBTYPE(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_ss_flags); | |
289 | _SUBTYPE(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_user_time_in_terminated_threads); | |
290 | _SUBTYPE(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_system_time_in_terminated_threads); | |
291 | _SUBTYPE(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_task_size); | |
292 | _SUBTYPE(KC_ST_UINT64, struct task_delta_snapshot_v2, tds_max_resident_size); | |
293 | _SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_suspend_count); | |
294 | _SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_faults); | |
295 | _SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_pageins); | |
296 | _SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_cow_faults); | |
297 | _SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_was_throttled); | |
298 | _SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_did_throttle); | |
299 | _SUBTYPE(KC_ST_UINT32, struct task_delta_snapshot_v2, tds_latency_qos); | |
300 | setup_type_definition(retval, type_id, i, "task_delta_snapshot"); | |
301 | break; | |
302 | } | |
303 | ||
304 | case STACKSHOT_KCTYPE_THREAD_SNAPSHOT: { | |
305 | i = 0; | |
306 | ||
307 | _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_thread_id); | |
308 | _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_wait_event); | |
309 | _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_continuation); | |
310 | _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_total_syscalls); | |
311 | _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_voucher_identifier); | |
312 | _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_dqserialnum); | |
313 | _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_user_time); | |
314 | _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_sys_time); | |
315 | _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_ss_flags); | |
316 | _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_last_run_time); | |
317 | _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_last_made_runnable_time); | |
318 | _SUBTYPE(KC_ST_UINT32, struct thread_snapshot_v3, ths_state); | |
319 | _SUBTYPE(KC_ST_UINT32, struct thread_snapshot_v3, ths_sched_flags); | |
320 | _SUBTYPE(KC_ST_INT16, struct thread_snapshot_v3, ths_base_priority); | |
321 | _SUBTYPE(KC_ST_INT16, struct thread_snapshot_v3, ths_sched_priority); | |
322 | _SUBTYPE(KC_ST_UINT8, struct thread_snapshot_v3, ths_eqos); | |
323 | _SUBTYPE(KC_ST_UINT8, struct thread_snapshot_v3, ths_rqos); | |
324 | _SUBTYPE(KC_ST_UINT8, struct thread_snapshot_v3, ths_rqos_override); | |
325 | _SUBTYPE(KC_ST_UINT8, struct thread_snapshot_v3, ths_io_tier); | |
326 | _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v3, ths_thread_t); | |
5ba3f43e A |
327 | _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v4, ths_requested_policy); |
328 | _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v4, ths_effective_policy); | |
39037602 A |
329 | |
330 | setup_type_definition(retval, type_id, i, "thread_snapshot"); | |
331 | break; | |
332 | } | |
333 | ||
334 | case STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT: { | |
335 | i = 0; | |
336 | ||
337 | _SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v2, tds_thread_id); | |
338 | _SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v2, tds_voucher_identifier); | |
339 | _SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v2, tds_ss_flags); | |
340 | _SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v2, tds_last_made_runnable_time); | |
341 | _SUBTYPE(KC_ST_UINT32, struct thread_delta_snapshot_v2, tds_state); | |
342 | _SUBTYPE(KC_ST_UINT32, struct thread_delta_snapshot_v2, tds_sched_flags); | |
343 | _SUBTYPE(KC_ST_INT16, struct thread_delta_snapshot_v2, tds_base_priority); | |
344 | _SUBTYPE(KC_ST_INT16, struct thread_delta_snapshot_v2, tds_sched_priority); | |
345 | _SUBTYPE(KC_ST_UINT8, struct thread_delta_snapshot_v2, tds_eqos); | |
346 | _SUBTYPE(KC_ST_UINT8, struct thread_delta_snapshot_v2, tds_rqos); | |
347 | _SUBTYPE(KC_ST_UINT8, struct thread_delta_snapshot_v2, tds_rqos_override); | |
348 | _SUBTYPE(KC_ST_UINT8, struct thread_delta_snapshot_v2, tds_io_tier); | |
a39ff7e2 A |
349 | _SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v3, tds_requested_policy); |
350 | _SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v3, tds_effective_policy); | |
39037602 A |
351 | |
352 | setup_type_definition(retval, type_id, i, "thread_delta_snapshot"); | |
353 | ||
354 | break; | |
355 | } | |
356 | ||
357 | case STACKSHOT_KCTYPE_DONATING_PIDS: | |
358 | setup_type_definition(retval, type_id, 1, "donating_pids"); | |
359 | setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "donating_pids"); | |
360 | break; | |
361 | ||
362 | case STACKSHOT_KCTYPE_THREAD_NAME: { | |
363 | i = 0; | |
364 | setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, 64, "pth_name"); | |
365 | setup_type_definition(retval, type_id, i, "pth_name"); | |
366 | break; | |
367 | } | |
368 | ||
369 | case STACKSHOT_KCTYPE_KERN_STACKFRAME: | |
370 | setup_type_definition(retval, type_id, 2, "kernel_stack_frames"); | |
371 | setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "lr"); | |
372 | setup_subtype_description(&subtypes[1], KC_ST_UINT32, sizeof(uint32_t), "sp"); | |
373 | break; | |
374 | ||
375 | case STACKSHOT_KCTYPE_KERN_STACKFRAME64: | |
376 | setup_type_definition(retval, type_id, 2, "kernel_stack_frames"); | |
377 | setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "lr"); | |
378 | setup_subtype_description(&subtypes[1], KC_ST_UINT64, sizeof(uint64_t), "sp"); | |
379 | break; | |
380 | ||
381 | case STACKSHOT_KCTYPE_USER_STACKFRAME: | |
382 | setup_type_definition(retval, type_id, 2, "user_stack_frames"); | |
383 | setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "lr"); | |
384 | setup_subtype_description(&subtypes[1], KC_ST_UINT32, sizeof(uint32_t), "sp"); | |
385 | break; | |
386 | ||
387 | case STACKSHOT_KCTYPE_USER_STACKFRAME64: | |
388 | setup_type_definition(retval, type_id, 2, "user_stack_frames"); | |
389 | setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "lr"); | |
390 | setup_subtype_description(&subtypes[1], KC_ST_UINT64, sizeof(uint64_t), "sp"); | |
391 | break; | |
392 | ||
393 | case STACKSHOT_KCTYPE_KERN_STACKLR: | |
394 | setup_type_definition(retval, type_id, 1, "kernel_stack_frames"); | |
395 | setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "lr"); | |
396 | subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_STRUCT; | |
397 | break; | |
398 | ||
399 | case STACKSHOT_KCTYPE_KERN_STACKLR64: | |
400 | setup_type_definition(retval, type_id, 1, "kernel_stack_frames"); | |
401 | setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "lr"); | |
402 | subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_STRUCT; | |
403 | break; | |
404 | ||
405 | case STACKSHOT_KCTYPE_USER_STACKLR: | |
406 | setup_type_definition(retval, type_id, 1, "user_stack_frames"); | |
407 | setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "lr"); | |
408 | subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_STRUCT; | |
409 | break; | |
410 | ||
411 | case STACKSHOT_KCTYPE_USER_STACKLR64: | |
412 | setup_type_definition(retval, type_id, 1, "user_stack_frames"); | |
413 | setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "lr"); | |
414 | subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_STRUCT; | |
415 | break; | |
416 | ||
417 | case STACKSHOT_KCTYPE_NONRUNNABLE_TIDS: | |
418 | setup_type_definition(retval, type_id, 1, "nonrunnable_threads"); | |
419 | setup_subtype_description(&subtypes[0], KC_ST_INT64, 0, "nonrunnable_threads"); | |
420 | break; | |
421 | ||
422 | case STACKSHOT_KCTYPE_NONRUNNABLE_TASKS: | |
423 | setup_type_definition(retval, type_id, 1, "nonrunnable_tasks"); | |
424 | setup_subtype_description(&subtypes[0], KC_ST_INT64, 0, "nonrunnable_tasks"); | |
425 | break; | |
426 | ||
427 | case STACKSHOT_KCTYPE_BOOTARGS: { | |
428 | i = 0; | |
429 | _STRINGTYPE("boot_args"); | |
430 | setup_type_definition(retval, type_id, i, "boot_args"); | |
431 | break; | |
432 | } | |
433 | ||
434 | case STACKSHOT_KCTYPE_OSVERSION: { | |
435 | i = 0; | |
436 | _STRINGTYPE("osversion"); | |
437 | setup_type_definition(retval, type_id, i, "osversion"); | |
438 | break; | |
439 | } | |
440 | ||
441 | case STACKSHOT_KCTYPE_KERN_PAGE_SIZE: { | |
442 | i = 0; | |
443 | setup_subtype_description(&subtypes[i++], KC_ST_UINT32, 0, "kernel_page_size"); | |
444 | setup_type_definition(retval, type_id, i, "kernel_page_size"); | |
445 | break; | |
446 | } | |
447 | ||
5ba3f43e A |
448 | case STACKSHOT_KCTYPE_THREAD_POLICY_VERSION: { |
449 | i = 0; | |
450 | setup_subtype_description(&subtypes[i++], KC_ST_UINT32, 0, "thread_policy_version"); | |
451 | setup_type_definition(retval, type_id, i, "thread_policy_version"); | |
452 | break; | |
453 | } | |
454 | ||
39037602 A |
455 | case STACKSHOT_KCTYPE_JETSAM_LEVEL: { |
456 | i = 0; | |
457 | setup_subtype_description(&subtypes[i++], KC_ST_UINT32, 0, "jetsam_level"); | |
458 | setup_type_definition(retval, type_id, i, "jetsam_level"); | |
459 | break; | |
460 | } | |
461 | ||
462 | case STACKSHOT_KCTYPE_DELTA_SINCE_TIMESTAMP: { | |
463 | i = 0; | |
464 | setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "stackshot_delta_since_timestamp"); | |
465 | setup_type_definition(retval, type_id, i, "stackshot_delta_since_timestamp"); | |
466 | break; | |
467 | } | |
468 | ||
469 | /* crashinfo types */ | |
470 | case TASK_CRASHINFO_BSDINFOWITHUNIQID: { | |
471 | i = 0; | |
a39ff7e2 A |
472 | _SUBTYPE_ARRAY(KC_ST_UINT8, struct crashinfo_proc_uniqidentifierinfo, p_uuid, 16); |
473 | _SUBTYPE(KC_ST_UINT64, struct crashinfo_proc_uniqidentifierinfo, p_uniqueid); | |
474 | _SUBTYPE(KC_ST_UINT64, struct crashinfo_proc_uniqidentifierinfo, p_puniqueid); | |
39037602 A |
475 | /* Ignore the p_reserve fields */ |
476 | setup_type_definition(retval, type_id, i, "proc_uniqidentifierinfo"); | |
477 | break; | |
478 | } | |
479 | ||
480 | case TASK_CRASHINFO_PID: { | |
481 | setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "pid"); | |
482 | setup_type_definition(retval, type_id, 1, "pid"); | |
483 | break; | |
484 | } | |
485 | ||
486 | case TASK_CRASHINFO_PPID: { | |
487 | setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "ppid"); | |
488 | setup_type_definition(retval, type_id, 1, "ppid"); | |
489 | break; | |
490 | } | |
491 | ||
492 | /* case TASK_CRASHINFO_RUSAGE: { */ | |
493 | /* /\* */ | |
494 | /* * rusage is a complex structure and is only for legacy use for crashed processes rusage info. */ | |
495 | /* * So we just consider it as opaque data. */ | |
496 | /* *\/ */ | |
497 | /* i = 0; */ | |
498 | /* setup_subtype_array_description(&subtypes[i++], KC_ST_UINT8, 0, sizeof(struct rusage), "rusage"); */ | |
499 | /* setup_type_definition(retval, type_id, i, "rusage"); */ | |
500 | /* break; */ | |
501 | /* } */ | |
502 | ||
503 | case TASK_CRASHINFO_RUSAGE_INFO: { | |
504 | i = 0; | |
505 | _SUBTYPE_ARRAY(KC_ST_UINT8, struct rusage_info_v3, ri_uuid, 16); | |
506 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_user_time); | |
507 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_system_time); | |
508 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_pkg_idle_wkups); | |
509 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_interrupt_wkups); | |
510 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_pageins); | |
511 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_wired_size); | |
512 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_resident_size); | |
513 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_phys_footprint); | |
514 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_proc_start_abstime); | |
515 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_proc_exit_abstime); | |
516 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_user_time); | |
517 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_system_time); | |
518 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_pkg_idle_wkups); | |
519 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_interrupt_wkups); | |
520 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_pageins); | |
521 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_elapsed_abstime); | |
522 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_diskio_bytesread); | |
523 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_diskio_byteswritten); | |
524 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_default); | |
525 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_maintenance); | |
526 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_background); | |
527 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_utility); | |
528 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_legacy); | |
529 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_user_initiated); | |
530 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_user_interactive); | |
531 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_billed_system_time); | |
532 | _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_serviced_system_time); | |
533 | setup_type_definition(retval, type_id, i, "rusage_info"); | |
534 | break; | |
535 | } | |
536 | ||
537 | case STACKSHOT_KCTYPE_CPU_TIMES: { | |
538 | i = 0; | |
d9a64523 A |
539 | _SUBTYPE(KC_ST_UINT64, struct stackshot_cpu_times_v2, user_usec); |
540 | _SUBTYPE(KC_ST_UINT64, struct stackshot_cpu_times_v2, system_usec); | |
541 | _SUBTYPE(KC_ST_UINT64, struct stackshot_cpu_times_v2, runnable_usec); | |
39037602 A |
542 | setup_type_definition(retval, type_id, i, "cpu_times"); |
543 | break; | |
544 | } | |
545 | ||
546 | case STACKSHOT_KCTYPE_STACKSHOT_DURATION: { | |
547 | i = 0; | |
548 | _SUBTYPE(KC_ST_UINT64, struct stackshot_duration, stackshot_duration); | |
549 | _SUBTYPE(KC_ST_UINT64, struct stackshot_duration, stackshot_duration_outer); | |
550 | subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_MERGE; | |
551 | subtypes[1].kcs_flags |= KCS_SUBTYPE_FLAGS_MERGE; | |
552 | setup_type_definition(retval, type_id, i, "stackshot_duration"); | |
553 | break; | |
554 | } | |
555 | ||
556 | case STACKSHOT_KCTYPE_STACKSHOT_FAULT_STATS: { | |
557 | i = 0; | |
558 | _SUBTYPE(KC_ST_UINT32, struct stackshot_fault_stats, sfs_pages_faulted_in); | |
559 | _SUBTYPE(KC_ST_UINT64, struct stackshot_fault_stats, sfs_time_spent_faulting); | |
560 | _SUBTYPE(KC_ST_UINT64, struct stackshot_fault_stats, sfs_system_max_fault_time); | |
561 | _SUBTYPE(KC_ST_UINT8, struct stackshot_fault_stats, sfs_stopped_faulting); | |
562 | ||
563 | setup_type_definition(retval, type_id, i, "stackshot_fault_stats"); | |
564 | break; | |
565 | } | |
566 | ||
813fb2f6 A |
567 | case STACKSHOT_KCTYPE_THREAD_WAITINFO: { |
568 | i = 0; | |
569 | _SUBTYPE(KC_ST_UINT64, struct stackshot_thread_waitinfo, owner); | |
570 | _SUBTYPE(KC_ST_UINT64, struct stackshot_thread_waitinfo, waiter); | |
571 | _SUBTYPE(KC_ST_UINT64, struct stackshot_thread_waitinfo, context); | |
572 | _SUBTYPE(KC_ST_UINT8, struct stackshot_thread_waitinfo, wait_type); | |
573 | setup_type_definition(retval, type_id, i, "thread_waitinfo"); | |
574 | break; | |
575 | } | |
576 | ||
5ba3f43e A |
577 | case STACKSHOT_KCTYPE_THREAD_GROUP_SNAPSHOT: { |
578 | i = 0; | |
5c9f4661 A |
579 | _SUBTYPE(KC_ST_UINT64, struct thread_group_snapshot_v2, tgs_id); |
580 | _SUBTYPE_ARRAY(KC_ST_CHAR, struct thread_group_snapshot_v2, tgs_name, 16); | |
581 | _SUBTYPE(KC_ST_UINT64, struct thread_group_snapshot_v2, tgs_flags); | |
5ba3f43e A |
582 | setup_type_definition(retval, type_id, i, "thread_group_snapshot"); |
583 | break; | |
584 | } | |
585 | ||
586 | case STACKSHOT_KCTYPE_THREAD_GROUP: { | |
587 | i = 0; | |
588 | setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "thread_group"); | |
589 | setup_type_definition(retval, type_id, i, "thread_group"); | |
590 | break; | |
591 | }; | |
592 | ||
593 | case STACKSHOT_KCTYPE_JETSAM_COALITION_SNAPSHOT: { | |
594 | i = 0; | |
595 | _SUBTYPE(KC_ST_UINT64, struct jetsam_coalition_snapshot, jcs_id); | |
596 | _SUBTYPE(KC_ST_UINT64, struct jetsam_coalition_snapshot, jcs_flags); | |
597 | _SUBTYPE(KC_ST_UINT64, struct jetsam_coalition_snapshot, jcs_thread_group); | |
598 | _SUBTYPE(KC_ST_UINT64, struct jetsam_coalition_snapshot, jcs_leader_task_uniqueid); | |
599 | setup_type_definition(retval, type_id, i, "jetsam_coalition_snapshot"); | |
600 | break; | |
601 | } | |
602 | ||
603 | case STACKSHOT_KCTYPE_JETSAM_COALITION: { | |
604 | i = 0; | |
605 | setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "jetsam_coalition"); | |
606 | setup_type_definition(retval, type_id, i, "jetsam_coalition"); | |
607 | break; | |
608 | }; | |
609 | ||
610 | case STACKSHOT_KCTYPE_INSTRS_CYCLES: { | |
611 | i = 0; | |
612 | _SUBTYPE(KC_ST_UINT64, struct instrs_cycles_snapshot, ics_instructions); | |
613 | _SUBTYPE(KC_ST_UINT64, struct instrs_cycles_snapshot, ics_cycles); | |
614 | setup_type_definition(retval, type_id, i, "instrs_cycles_snapshot"); | |
615 | break; | |
616 | } | |
617 | ||
d9a64523 A |
618 | case STACKSHOT_KCTYPE_USER_STACKTOP: { |
619 | i = 0; | |
620 | _SUBTYPE(KC_ST_UINT64, struct stack_snapshot_stacktop, sp); | |
621 | _SUBTYPE_ARRAY(KC_ST_UINT8, struct stack_snapshot_stacktop, stack_contents, 8); | |
622 | setup_type_definition(retval, type_id, i, "user_stacktop"); | |
623 | break; | |
624 | } | |
625 | ||
39037602 A |
626 | case TASK_CRASHINFO_PROC_STARTTIME: { |
627 | i = 0; | |
628 | _SUBTYPE(KC_ST_INT64, struct timeval64, tv_sec); | |
629 | _SUBTYPE(KC_ST_INT64, struct timeval64, tv_usec); | |
630 | setup_type_definition(retval, type_id, i, "proc_starttime"); | |
631 | break; | |
632 | } | |
633 | ||
634 | case TASK_CRASHINFO_EXCEPTION_CODES: { | |
635 | i = 0; | |
636 | char codenum[100]; | |
637 | for (i = 0; i < EXCEPTION_CODE_MAX; i++) { | |
638 | snprintf(codenum, sizeof(codenum), "code_%d", i); | |
639 | setup_subtype_description(&subtypes[i], KC_ST_UINT64, i * (sizeof(uint64_t)), codenum); | |
640 | } | |
641 | setup_type_definition(retval, type_id, i, "mach_exception_data_t"); | |
642 | break; | |
643 | } | |
644 | ||
645 | case TASK_CRASHINFO_PROC_NAME: { | |
646 | i = 0; | |
647 | _STRINGTYPE("p_comm"); | |
648 | setup_type_definition(retval, type_id, i, "p_comm"); | |
649 | break; | |
650 | } | |
651 | ||
652 | case TASK_CRASHINFO_USERSTACK: { | |
653 | i = 0; | |
654 | setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "userstack_ptr"); | |
655 | setup_type_definition(retval, type_id, 1, "userstack_ptr"); | |
656 | break; | |
657 | } | |
658 | ||
659 | case TASK_CRASHINFO_ARGSLEN: { | |
660 | i = 0; | |
661 | setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "p_argslen"); | |
662 | setup_type_definition(retval, type_id, 1, "p_argslen"); | |
663 | break; | |
664 | } | |
665 | ||
666 | case TASK_CRASHINFO_PROC_PATH: { | |
667 | i = 0; | |
668 | _STRINGTYPE("p_path"); | |
669 | setup_type_definition(retval, type_id, i, "p_path"); | |
670 | break; | |
671 | } | |
672 | ||
673 | case TASK_CRASHINFO_PROC_CSFLAGS: { | |
674 | setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "p_csflags"); | |
675 | setup_type_definition(retval, type_id, 1, "p_csflags"); | |
676 | break; | |
677 | } | |
678 | ||
679 | case TASK_CRASHINFO_PROC_STATUS: { | |
680 | setup_subtype_description(&subtypes[0], KC_ST_UINT8, 0, "p_status"); | |
681 | setup_type_definition(retval, type_id, 1, "p_status"); | |
682 | break; | |
683 | } | |
684 | ||
685 | case TASK_CRASHINFO_UID: { | |
686 | setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "uid"); | |
687 | setup_type_definition(retval, type_id, 1, "uid"); | |
688 | break; | |
689 | } | |
690 | ||
691 | case TASK_CRASHINFO_GID: { | |
692 | setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "gid"); | |
693 | setup_type_definition(retval, type_id, 1, "gid"); | |
694 | break; | |
695 | } | |
696 | ||
697 | case TASK_CRASHINFO_PROC_ARGC: { | |
698 | setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "argc"); | |
699 | setup_type_definition(retval, type_id, 1, "argc"); | |
700 | break; | |
701 | } | |
702 | ||
703 | case TASK_CRASHINFO_PROC_FLAGS: { | |
704 | setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "p_flags"); | |
705 | setup_type_definition(retval, type_id, 1, "p_flags"); | |
706 | break; | |
707 | } | |
708 | ||
709 | case TASK_CRASHINFO_CPUTYPE: { | |
710 | setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "cputype"); | |
711 | setup_type_definition(retval, type_id, 1, "cputype"); | |
712 | break; | |
713 | } | |
714 | ||
715 | case TASK_CRASHINFO_RESPONSIBLE_PID: { | |
716 | setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "responsible_pid"); | |
717 | setup_type_definition(retval, type_id, 1, "responsible_pid"); | |
718 | break; | |
719 | } | |
720 | ||
721 | case TASK_CRASHINFO_DIRTY_FLAGS: { | |
722 | setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "dirty_flags"); | |
723 | setup_type_definition(retval, type_id, 1, "dirty_flags"); | |
724 | break; | |
725 | } | |
726 | ||
727 | case TASK_CRASHINFO_CRASHED_THREADID: { | |
728 | setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "crashed_threadid"); | |
729 | setup_type_definition(retval, type_id, 1, "crashed_threadid"); | |
730 | break; | |
731 | } | |
732 | ||
733 | case TASK_CRASHINFO_COALITION_ID: { | |
734 | setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "coalition_id"); | |
735 | setup_type_definition(retval, type_id, 1, "coalition_id"); | |
736 | break; | |
737 | } | |
738 | ||
739 | case TASK_CRASHINFO_UDATA_PTRS: { | |
740 | setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "udata_ptrs"); | |
741 | setup_type_definition(retval, type_id, 1, "udata_ptrs"); | |
742 | break; | |
743 | } | |
744 | ||
745 | case TASK_CRASHINFO_MEMORY_LIMIT: { | |
746 | setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "task_phys_mem_limit"); | |
747 | setup_type_definition(retval, type_id, 1, "task_phys_mem_limit"); | |
748 | break; | |
749 | } | |
750 | ||
751 | case EXIT_REASON_SNAPSHOT: { | |
752 | _SUBTYPE(KC_ST_UINT32, struct exit_reason_snapshot, ers_namespace); | |
753 | _SUBTYPE(KC_ST_UINT64, struct exit_reason_snapshot, ers_code); | |
754 | _SUBTYPE(KC_ST_UINT64, struct exit_reason_snapshot, ers_flags); | |
755 | setup_type_definition(retval, type_id, i, "exit_reason_basic_info"); | |
756 | ||
757 | break; | |
758 | ||
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"); | |
39037602 | 796 | break; |
d9a64523 | 797 | } |
39037602 | 798 | |
5ba3f43e A |
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 | ||
d9a64523 A |
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; | |
39037602 A |
818 | } |
819 | ||
d9a64523 A |
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 | ||
39037602 A |
835 | default: |
836 | retval = NULL; | |
837 | break; | |
838 | } | |
839 | ||
840 | assert(retval == NULL || (buffer_size > sizeof(struct kcdata_type_definition) + | |
841 | (retval->kct_num_elements * sizeof(struct kcdata_subtype_descriptor)))); | |
842 | return retval; | |
843 | } | |
844 | ||
845 | static void | |
846 | setup_type_definition(struct kcdata_type_definition * d, uint32_t type, uint32_t num_elems, char * name) | |
847 | { | |
848 | d->kct_type_identifier = type; | |
849 | d->kct_num_elements = num_elems; | |
850 | memcpy(d->kct_name, name, sizeof(d->kct_name)); | |
851 | d->kct_name[sizeof(d->kct_name) - 1] = '\0'; | |
852 | } | |
853 | ||
854 | static uint32_t | |
855 | get_kctype_subtype_size(kctype_subtype_t type) | |
856 | { | |
857 | switch (type) { | |
858 | case KC_ST_CHAR: | |
859 | case KC_ST_INT8: | |
860 | case KC_ST_UINT8: | |
861 | return sizeof(uint8_t); | |
862 | break; | |
863 | case KC_ST_INT16: | |
864 | case KC_ST_UINT16: | |
865 | return sizeof(uint16_t); | |
866 | break; | |
867 | case KC_ST_INT32: | |
868 | case KC_ST_UINT32: | |
869 | return sizeof(uint32_t); | |
870 | break; | |
871 | case KC_ST_INT64: | |
872 | case KC_ST_UINT64: | |
873 | return sizeof(uint64_t); | |
874 | break; | |
875 | ||
876 | default: | |
877 | assert(0); | |
878 | break; | |
879 | } | |
880 | return 0; | |
881 | } | |
882 | ||
883 | static void | |
884 | setup_subtype_array_description( | |
885 | kcdata_subtype_descriptor_t desc, kctype_subtype_t type, uint32_t offset, uint32_t count, char * name) | |
886 | { | |
887 | desc->kcs_flags = KCS_SUBTYPE_FLAGS_ARRAY; | |
888 | desc->kcs_elem_type = type; | |
889 | desc->kcs_elem_offset = offset; | |
890 | desc->kcs_elem_size = KCS_SUBTYPE_PACK_SIZE(count, get_kctype_subtype_size(type)); | |
891 | memcpy(desc->kcs_name, name, sizeof(desc->kcs_name)); | |
892 | desc->kcs_name[sizeof(desc->kcs_name) - 1] = '\0'; | |
893 | } | |
894 | ||
895 | static void | |
896 | setup_subtype_description(kcdata_subtype_descriptor_t desc, kctype_subtype_t type, uint32_t offset, char * name) | |
897 | { | |
898 | desc->kcs_flags = KCS_SUBTYPE_FLAGS_NONE; | |
899 | desc->kcs_elem_type = type; | |
900 | desc->kcs_elem_offset = offset; | |
901 | desc->kcs_elem_size = get_kctype_subtype_size(type); | |
902 | memcpy(desc->kcs_name, name, sizeof(desc->kcs_name)); | |
903 | desc->kcs_name[sizeof(desc->kcs_name) - 1] = '\0'; | |
904 | } | |
905 |