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