]>
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 | ||
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 | } | |
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; | |
539 | _SUBTYPE(KC_ST_UINT64, struct stackshot_cpu_times, user_usec); | |
540 | _SUBTYPE(KC_ST_UINT64, struct stackshot_cpu_times, system_usec); | |
541 | setup_type_definition(retval, type_id, i, "cpu_times"); | |
542 | break; | |
543 | } | |
544 | ||
545 | case STACKSHOT_KCTYPE_STACKSHOT_DURATION: { | |
546 | i = 0; | |
547 | _SUBTYPE(KC_ST_UINT64, struct stackshot_duration, stackshot_duration); | |
548 | _SUBTYPE(KC_ST_UINT64, struct stackshot_duration, stackshot_duration_outer); | |
549 | subtypes[0].kcs_flags |= KCS_SUBTYPE_FLAGS_MERGE; | |
550 | subtypes[1].kcs_flags |= KCS_SUBTYPE_FLAGS_MERGE; | |
551 | setup_type_definition(retval, type_id, i, "stackshot_duration"); | |
552 | break; | |
553 | } | |
554 | ||
555 | case STACKSHOT_KCTYPE_STACKSHOT_FAULT_STATS: { | |
556 | i = 0; | |
557 | _SUBTYPE(KC_ST_UINT32, struct stackshot_fault_stats, sfs_pages_faulted_in); | |
558 | _SUBTYPE(KC_ST_UINT64, struct stackshot_fault_stats, sfs_time_spent_faulting); | |
559 | _SUBTYPE(KC_ST_UINT64, struct stackshot_fault_stats, sfs_system_max_fault_time); | |
560 | _SUBTYPE(KC_ST_UINT8, struct stackshot_fault_stats, sfs_stopped_faulting); | |
561 | ||
562 | setup_type_definition(retval, type_id, i, "stackshot_fault_stats"); | |
563 | break; | |
564 | } | |
565 | ||
813fb2f6 A |
566 | case STACKSHOT_KCTYPE_THREAD_WAITINFO: { |
567 | i = 0; | |
568 | _SUBTYPE(KC_ST_UINT64, struct stackshot_thread_waitinfo, owner); | |
569 | _SUBTYPE(KC_ST_UINT64, struct stackshot_thread_waitinfo, waiter); | |
570 | _SUBTYPE(KC_ST_UINT64, struct stackshot_thread_waitinfo, context); | |
571 | _SUBTYPE(KC_ST_UINT8, struct stackshot_thread_waitinfo, wait_type); | |
572 | setup_type_definition(retval, type_id, i, "thread_waitinfo"); | |
573 | break; | |
574 | } | |
575 | ||
5ba3f43e A |
576 | case STACKSHOT_KCTYPE_THREAD_GROUP_SNAPSHOT: { |
577 | i = 0; | |
5c9f4661 A |
578 | _SUBTYPE(KC_ST_UINT64, struct thread_group_snapshot_v2, tgs_id); |
579 | _SUBTYPE_ARRAY(KC_ST_CHAR, struct thread_group_snapshot_v2, tgs_name, 16); | |
580 | _SUBTYPE(KC_ST_UINT64, struct thread_group_snapshot_v2, tgs_flags); | |
5ba3f43e A |
581 | setup_type_definition(retval, type_id, i, "thread_group_snapshot"); |
582 | break; | |
583 | } | |
584 | ||
585 | case STACKSHOT_KCTYPE_THREAD_GROUP: { | |
586 | i = 0; | |
587 | setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "thread_group"); | |
588 | setup_type_definition(retval, type_id, i, "thread_group"); | |
589 | break; | |
590 | }; | |
591 | ||
592 | case STACKSHOT_KCTYPE_JETSAM_COALITION_SNAPSHOT: { | |
593 | i = 0; | |
594 | _SUBTYPE(KC_ST_UINT64, struct jetsam_coalition_snapshot, jcs_id); | |
595 | _SUBTYPE(KC_ST_UINT64, struct jetsam_coalition_snapshot, jcs_flags); | |
596 | _SUBTYPE(KC_ST_UINT64, struct jetsam_coalition_snapshot, jcs_thread_group); | |
597 | _SUBTYPE(KC_ST_UINT64, struct jetsam_coalition_snapshot, jcs_leader_task_uniqueid); | |
598 | setup_type_definition(retval, type_id, i, "jetsam_coalition_snapshot"); | |
599 | break; | |
600 | } | |
601 | ||
602 | case STACKSHOT_KCTYPE_JETSAM_COALITION: { | |
603 | i = 0; | |
604 | setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "jetsam_coalition"); | |
605 | setup_type_definition(retval, type_id, i, "jetsam_coalition"); | |
606 | break; | |
607 | }; | |
608 | ||
609 | case STACKSHOT_KCTYPE_INSTRS_CYCLES: { | |
610 | i = 0; | |
611 | _SUBTYPE(KC_ST_UINT64, struct instrs_cycles_snapshot, ics_instructions); | |
612 | _SUBTYPE(KC_ST_UINT64, struct instrs_cycles_snapshot, ics_cycles); | |
613 | setup_type_definition(retval, type_id, i, "instrs_cycles_snapshot"); | |
614 | break; | |
615 | } | |
616 | ||
39037602 A |
617 | case TASK_CRASHINFO_PROC_STARTTIME: { |
618 | i = 0; | |
619 | _SUBTYPE(KC_ST_INT64, struct timeval64, tv_sec); | |
620 | _SUBTYPE(KC_ST_INT64, struct timeval64, tv_usec); | |
621 | setup_type_definition(retval, type_id, i, "proc_starttime"); | |
622 | break; | |
623 | } | |
624 | ||
625 | case TASK_CRASHINFO_EXCEPTION_CODES: { | |
626 | i = 0; | |
627 | char codenum[100]; | |
628 | for (i = 0; i < EXCEPTION_CODE_MAX; i++) { | |
629 | snprintf(codenum, sizeof(codenum), "code_%d", i); | |
630 | setup_subtype_description(&subtypes[i], KC_ST_UINT64, i * (sizeof(uint64_t)), codenum); | |
631 | } | |
632 | setup_type_definition(retval, type_id, i, "mach_exception_data_t"); | |
633 | break; | |
634 | } | |
635 | ||
636 | case TASK_CRASHINFO_PROC_NAME: { | |
637 | i = 0; | |
638 | _STRINGTYPE("p_comm"); | |
639 | setup_type_definition(retval, type_id, i, "p_comm"); | |
640 | break; | |
641 | } | |
642 | ||
643 | case TASK_CRASHINFO_USERSTACK: { | |
644 | i = 0; | |
645 | setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "userstack_ptr"); | |
646 | setup_type_definition(retval, type_id, 1, "userstack_ptr"); | |
647 | break; | |
648 | } | |
649 | ||
650 | case TASK_CRASHINFO_ARGSLEN: { | |
651 | i = 0; | |
652 | setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "p_argslen"); | |
653 | setup_type_definition(retval, type_id, 1, "p_argslen"); | |
654 | break; | |
655 | } | |
656 | ||
657 | case TASK_CRASHINFO_PROC_PATH: { | |
658 | i = 0; | |
659 | _STRINGTYPE("p_path"); | |
660 | setup_type_definition(retval, type_id, i, "p_path"); | |
661 | break; | |
662 | } | |
663 | ||
664 | case TASK_CRASHINFO_PROC_CSFLAGS: { | |
665 | setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "p_csflags"); | |
666 | setup_type_definition(retval, type_id, 1, "p_csflags"); | |
667 | break; | |
668 | } | |
669 | ||
670 | case TASK_CRASHINFO_PROC_STATUS: { | |
671 | setup_subtype_description(&subtypes[0], KC_ST_UINT8, 0, "p_status"); | |
672 | setup_type_definition(retval, type_id, 1, "p_status"); | |
673 | break; | |
674 | } | |
675 | ||
676 | case TASK_CRASHINFO_UID: { | |
677 | setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "uid"); | |
678 | setup_type_definition(retval, type_id, 1, "uid"); | |
679 | break; | |
680 | } | |
681 | ||
682 | case TASK_CRASHINFO_GID: { | |
683 | setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "gid"); | |
684 | setup_type_definition(retval, type_id, 1, "gid"); | |
685 | break; | |
686 | } | |
687 | ||
688 | case TASK_CRASHINFO_PROC_ARGC: { | |
689 | setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "argc"); | |
690 | setup_type_definition(retval, type_id, 1, "argc"); | |
691 | break; | |
692 | } | |
693 | ||
694 | case TASK_CRASHINFO_PROC_FLAGS: { | |
695 | setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "p_flags"); | |
696 | setup_type_definition(retval, type_id, 1, "p_flags"); | |
697 | break; | |
698 | } | |
699 | ||
700 | case TASK_CRASHINFO_CPUTYPE: { | |
701 | setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "cputype"); | |
702 | setup_type_definition(retval, type_id, 1, "cputype"); | |
703 | break; | |
704 | } | |
705 | ||
706 | case TASK_CRASHINFO_RESPONSIBLE_PID: { | |
707 | setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "responsible_pid"); | |
708 | setup_type_definition(retval, type_id, 1, "responsible_pid"); | |
709 | break; | |
710 | } | |
711 | ||
712 | case TASK_CRASHINFO_DIRTY_FLAGS: { | |
713 | setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "dirty_flags"); | |
714 | setup_type_definition(retval, type_id, 1, "dirty_flags"); | |
715 | break; | |
716 | } | |
717 | ||
718 | case TASK_CRASHINFO_CRASHED_THREADID: { | |
719 | setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "crashed_threadid"); | |
720 | setup_type_definition(retval, type_id, 1, "crashed_threadid"); | |
721 | break; | |
722 | } | |
723 | ||
724 | case TASK_CRASHINFO_COALITION_ID: { | |
725 | setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "coalition_id"); | |
726 | setup_type_definition(retval, type_id, 1, "coalition_id"); | |
727 | break; | |
728 | } | |
729 | ||
730 | case TASK_CRASHINFO_UDATA_PTRS: { | |
731 | setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "udata_ptrs"); | |
732 | setup_type_definition(retval, type_id, 1, "udata_ptrs"); | |
733 | break; | |
734 | } | |
735 | ||
736 | case TASK_CRASHINFO_MEMORY_LIMIT: { | |
737 | setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "task_phys_mem_limit"); | |
738 | setup_type_definition(retval, type_id, 1, "task_phys_mem_limit"); | |
739 | break; | |
740 | } | |
741 | ||
742 | case EXIT_REASON_SNAPSHOT: { | |
743 | _SUBTYPE(KC_ST_UINT32, struct exit_reason_snapshot, ers_namespace); | |
744 | _SUBTYPE(KC_ST_UINT64, struct exit_reason_snapshot, ers_code); | |
745 | _SUBTYPE(KC_ST_UINT64, struct exit_reason_snapshot, ers_flags); | |
746 | setup_type_definition(retval, type_id, i, "exit_reason_basic_info"); | |
747 | ||
748 | break; | |
749 | ||
750 | } | |
751 | ||
752 | case EXIT_REASON_USER_DESC: { | |
753 | i = 0; | |
754 | ||
755 | _STRINGTYPE("exit_reason_user_description"); | |
756 | setup_type_definition(retval, type_id, i, "exit_reason_user_description"); | |
757 | break; | |
758 | } | |
759 | ||
760 | case EXIT_REASON_USER_PAYLOAD: { | |
761 | i = 0; | |
762 | ||
763 | setup_subtype_array_description(&subtypes[i++], KC_ST_UINT8, 0, EXIT_REASON_PAYLOAD_MAX_LEN, "exit_reason_user_payload"); | |
764 | setup_type_definition(retval, type_id, i, "exit_reason_user_payload"); | |
765 | break; | |
766 | } | |
767 | ||
768 | case EXIT_REASON_CODESIGNING_INFO: { | |
769 | _SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_virt_addr); | |
770 | _SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_file_offset); | |
771 | _SUBTYPE_ARRAY(KC_ST_CHAR, struct codesigning_exit_reason_info, ceri_pathname, EXIT_REASON_CODESIG_PATH_MAX); | |
772 | _SUBTYPE_ARRAY(KC_ST_CHAR, struct codesigning_exit_reason_info, ceri_filename, EXIT_REASON_CODESIG_PATH_MAX); | |
773 | _SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_codesig_modtime_secs); | |
774 | _SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_codesig_modtime_nsecs); | |
775 | _SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_page_modtime_secs); | |
776 | _SUBTYPE(KC_ST_UINT64, struct codesigning_exit_reason_info, ceri_page_modtime_nsecs); | |
777 | _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_path_truncated); | |
778 | _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_object_codesigned); | |
779 | _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_codesig_validated); | |
780 | _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_codesig_tainted); | |
781 | _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_codesig_nx); | |
782 | _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_wpmapped); | |
783 | _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_slid); | |
784 | _SUBTYPE(KC_ST_UINT8, struct codesigning_exit_reason_info, ceri_page_dirty); | |
785 | _SUBTYPE(KC_ST_UINT32, struct codesigning_exit_reason_info, ceri_page_shadow_depth); | |
786 | setup_type_definition(retval, type_id, i, "exit_reason_codesigning_info"); | |
787 | ||
788 | break; | |
789 | ||
5ba3f43e A |
790 | case EXIT_REASON_WORKLOOP_ID: { |
791 | i = 0; | |
792 | setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "exit_reason_workloop_id"); | |
793 | setup_type_definition(retval, type_id, i, "exit_reason_workloop_id"); | |
794 | break; | |
795 | } | |
796 | ||
797 | case EXIT_REASON_DISPATCH_QUEUE_NO: { | |
798 | i = 0; | |
799 | setup_subtype_description(&subtypes[i++], KC_ST_UINT64, 0, "exit_reason_dispatch_queue_no"); | |
800 | setup_type_definition(retval, type_id, i, "exit_reason_dispatch_queue_no"); | |
801 | break; | |
802 | } | |
803 | ||
39037602 A |
804 | } |
805 | ||
806 | default: | |
807 | retval = NULL; | |
808 | break; | |
809 | } | |
810 | ||
811 | assert(retval == NULL || (buffer_size > sizeof(struct kcdata_type_definition) + | |
812 | (retval->kct_num_elements * sizeof(struct kcdata_subtype_descriptor)))); | |
813 | return retval; | |
814 | } | |
815 | ||
816 | static void | |
817 | setup_type_definition(struct kcdata_type_definition * d, uint32_t type, uint32_t num_elems, char * name) | |
818 | { | |
819 | d->kct_type_identifier = type; | |
820 | d->kct_num_elements = num_elems; | |
821 | memcpy(d->kct_name, name, sizeof(d->kct_name)); | |
822 | d->kct_name[sizeof(d->kct_name) - 1] = '\0'; | |
823 | } | |
824 | ||
825 | static uint32_t | |
826 | get_kctype_subtype_size(kctype_subtype_t type) | |
827 | { | |
828 | switch (type) { | |
829 | case KC_ST_CHAR: | |
830 | case KC_ST_INT8: | |
831 | case KC_ST_UINT8: | |
832 | return sizeof(uint8_t); | |
833 | break; | |
834 | case KC_ST_INT16: | |
835 | case KC_ST_UINT16: | |
836 | return sizeof(uint16_t); | |
837 | break; | |
838 | case KC_ST_INT32: | |
839 | case KC_ST_UINT32: | |
840 | return sizeof(uint32_t); | |
841 | break; | |
842 | case KC_ST_INT64: | |
843 | case KC_ST_UINT64: | |
844 | return sizeof(uint64_t); | |
845 | break; | |
846 | ||
847 | default: | |
848 | assert(0); | |
849 | break; | |
850 | } | |
851 | return 0; | |
852 | } | |
853 | ||
854 | static void | |
855 | setup_subtype_array_description( | |
856 | kcdata_subtype_descriptor_t desc, kctype_subtype_t type, uint32_t offset, uint32_t count, char * name) | |
857 | { | |
858 | desc->kcs_flags = KCS_SUBTYPE_FLAGS_ARRAY; | |
859 | desc->kcs_elem_type = type; | |
860 | desc->kcs_elem_offset = offset; | |
861 | desc->kcs_elem_size = KCS_SUBTYPE_PACK_SIZE(count, get_kctype_subtype_size(type)); | |
862 | memcpy(desc->kcs_name, name, sizeof(desc->kcs_name)); | |
863 | desc->kcs_name[sizeof(desc->kcs_name) - 1] = '\0'; | |
864 | } | |
865 | ||
866 | static void | |
867 | setup_subtype_description(kcdata_subtype_descriptor_t desc, kctype_subtype_t type, uint32_t offset, char * name) | |
868 | { | |
869 | desc->kcs_flags = KCS_SUBTYPE_FLAGS_NONE; | |
870 | desc->kcs_elem_type = type; | |
871 | desc->kcs_elem_offset = offset; | |
872 | desc->kcs_elem_size = get_kctype_subtype_size(type); | |
873 | memcpy(desc->kcs_name, name, sizeof(desc->kcs_name)); | |
874 | desc->kcs_name[sizeof(desc->kcs_name) - 1] = '\0'; | |
875 | } | |
876 |