]>
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( | |
0a7de745 | 66 | kcdata_subtype_descriptor_t desc, kctype_subtype_t type, uint32_t offset, uint32_t count, char * name); |
39037602 A |
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 | ||
0a7de745 | 78 | if (buffer_size < sizeof(struct kcdata_type_definition) || buffer == NULL) { |
39037602 | 79 | return NULL; |
0a7de745 | 80 | } |
39037602 A |
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 | } | |
0a7de745 | 124 | |
d9a64523 A |
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 | } | |
39037602 A |
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); | |
5ba3f43e A |
328 | _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v4, ths_requested_policy); |
329 | _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v4, ths_effective_policy); | |
39037602 A |
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); | |
a39ff7e2 A |
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); | |
39037602 A |
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 | ||
5ba3f43e A |
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 | ||
39037602 A |
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; | |
a39ff7e2 A |
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); | |
39037602 A |
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: { */ | |
0a7de745 A |
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; */ | |
39037602 A |
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; | |
d9a64523 A |
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); | |
39037602 A |
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 | ||
813fb2f6 A |
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 | ||
5ba3f43e A |
578 | case STACKSHOT_KCTYPE_THREAD_GROUP_SNAPSHOT: { |
579 | i = 0; | |
5c9f4661 A |
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); | |
5ba3f43e A |
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; | |
0a7de745 | 602 | } |
5ba3f43e A |
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; | |
0a7de745 | 617 | } |
5ba3f43e | 618 | |
d9a64523 A |
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 | ||
39037602 A |
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; | |
39037602 A |
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 | } | |
0a7de745 | 834 | |
cb323159 A |
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 | ||
39037602 A |
853 | default: |
854 | retval = NULL; | |
855 | break; | |
856 | } | |
857 | ||
858 | assert(retval == NULL || (buffer_size > sizeof(struct kcdata_type_definition) + | |
0a7de745 | 859 | (retval->kct_num_elements * sizeof(struct kcdata_subtype_descriptor)))); |
39037602 A |
860 | return retval; |
861 | } | |
862 | ||
863 | static void | |
864 | setup_type_definition(struct kcdata_type_definition * d, uint32_t type, uint32_t num_elems, char * name) | |
865 | { | |
866 | d->kct_type_identifier = type; | |
867 | d->kct_num_elements = num_elems; | |
868 | memcpy(d->kct_name, name, sizeof(d->kct_name)); | |
869 | d->kct_name[sizeof(d->kct_name) - 1] = '\0'; | |
870 | } | |
871 | ||
872 | static uint32_t | |
873 | get_kctype_subtype_size(kctype_subtype_t type) | |
874 | { | |
875 | switch (type) { | |
876 | case KC_ST_CHAR: | |
877 | case KC_ST_INT8: | |
878 | case KC_ST_UINT8: | |
879 | return sizeof(uint8_t); | |
880 | break; | |
881 | case KC_ST_INT16: | |
882 | case KC_ST_UINT16: | |
883 | return sizeof(uint16_t); | |
884 | break; | |
885 | case KC_ST_INT32: | |
886 | case KC_ST_UINT32: | |
887 | return sizeof(uint32_t); | |
888 | break; | |
889 | case KC_ST_INT64: | |
890 | case KC_ST_UINT64: | |
891 | return sizeof(uint64_t); | |
892 | break; | |
893 | ||
894 | default: | |
895 | assert(0); | |
896 | break; | |
897 | } | |
898 | return 0; | |
899 | } | |
900 | ||
901 | static void | |
902 | setup_subtype_array_description( | |
0a7de745 | 903 | kcdata_subtype_descriptor_t desc, kctype_subtype_t type, uint32_t offset, uint32_t count, char * name) |
39037602 A |
904 | { |
905 | desc->kcs_flags = KCS_SUBTYPE_FLAGS_ARRAY; | |
906 | desc->kcs_elem_type = type; | |
907 | desc->kcs_elem_offset = offset; | |
908 | desc->kcs_elem_size = KCS_SUBTYPE_PACK_SIZE(count, get_kctype_subtype_size(type)); | |
909 | memcpy(desc->kcs_name, name, sizeof(desc->kcs_name)); | |
910 | desc->kcs_name[sizeof(desc->kcs_name) - 1] = '\0'; | |
911 | } | |
912 | ||
913 | static void | |
914 | setup_subtype_description(kcdata_subtype_descriptor_t desc, kctype_subtype_t type, uint32_t offset, char * name) | |
915 | { | |
916 | desc->kcs_flags = KCS_SUBTYPE_FLAGS_NONE; | |
917 | desc->kcs_elem_type = type; | |
918 | desc->kcs_elem_offset = offset; | |
919 | desc->kcs_elem_size = get_kctype_subtype_size(type); | |
920 | memcpy(desc->kcs_name, name, sizeof(desc->kcs_name)); | |
921 | desc->kcs_name[sizeof(desc->kcs_name) - 1] = '\0'; | |
922 | } |