]> git.saurik.com Git - apple/xnu.git/blame - libkdd/kcdata/kcdtypes.c
xnu-3247.1.106.tar.gz
[apple/xnu.git] / libkdd / kcdata / kcdtypes.c
CommitLineData
3e170ce0
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
25#include <Kernel/kern/kern_cdata.h>
26#include <Kernel/kern/debug.h>
27#include <sys/time.h>
28#include <stdlib.h>
29#include <stddef.h>
30#include <string.h>
31#include <assert.h>
32#include <mach/mach_time.h>
33#include <sys/proc_info.h>
34#include <corpses/task_corpse.h>
35
36/*!
37 * @function kcdata_get_typedescription
38 *
39 * @abstract
40 * Search the known type definitions for type with id type_id.
41 *
42 * @param type_id
43 * A unsinged int type specified by the KCDATA.
44 *
45 * @param buffer
46 * pointer to data area where type definition will be saved.
47 *
48 * @param buffer_size
49 * size of the buffer provided.
50 *
51 * @return struct kcdata_type_definition *
52 * pointer to a malloc'ed buffer holding the type definition and each subtype defintion for its fields.
53 * It may return NULL if no type with id == type_id is found.
54 * Note: The caller is responsible to free() the memory when its no longer used.
55 *
56 * @discussion
57 * This function queries the known type definitions table. If found the defintion data is returned
58 * else NULL is returned. It is advised to cache the return value from this function since the data
59 * is always going to be the same for same type_id. The definition setup requires memory on heap.
60 * The caller should make sure to free() the data once its done with using it.
61 *
62 */
63struct kcdata_type_definition *kcdata_get_typedescription(unsigned type_id, uint8_t *buffer, uint32_t buffer_size);
64
65
66
67/* forward declarations for helper routines */
68static uint32_t get_kctype_subtype_size(kctype_subtype_t type);
69static void setup_subtype_description(kcdata_subtype_descriptor_t desc, kctype_subtype_t type, uint32_t offset, char *name);
70static void setup_subtype_array_description(kcdata_subtype_descriptor_t desc, kctype_subtype_t type, uint32_t offset, uint32_t count, char *name);
71static void setup_type_definition(struct kcdata_type_definition *d, uint32_t type, uint32_t num_elems, char *name);
72
73struct kcdata_type_definition *kcdata_get_typedescription(unsigned type_id, uint8_t *buffer, uint32_t buffer_size)
74{
75 int i = 0;
76#define _STR_VALUE(x) #x
77#define _SUBTYPE(t, s, f) setup_subtype_description(&subtypes[i++], (t), offsetof(s,f), _STR_VALUE(f))
78#define _SUBTYPE_ARRAY(t, s, f, c) setup_subtype_array_description(&subtypes[i++], (t), offsetof(s,f), (c), _STR_VALUE(f))
79#define _STRINGTYPE(f) setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, UINT16_MAX, f)
80
81
82
83 if (buffer_size < sizeof(struct kcdata_type_definition) || buffer == NULL)
84 return NULL;
85
86 struct kcdata_type_definition *retval = (struct kcdata_type_definition *)&buffer[0];
87 kcdata_subtype_descriptor_t subtypes = (kcdata_subtype_descriptor_t)&buffer[sizeof(struct kcdata_type_definition)];
88 switch (type_id) {
89
90 case KCDATA_TYPE_STRING_DESC: {
91 i = 0;
92 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, KCDATA_DESC_MAXLEN, "desc");
93 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, KCDATA_DESC_MAXLEN, UINT16_MAX, "data");
94 setup_type_definition(retval, type_id, i, "string_desc");
95 break;
96 }
97
98 case KCDATA_TYPE_UINT32_DESC: {
99 i = 0;
100 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, KCDATA_DESC_MAXLEN, "desc");
101 setup_subtype_description(&subtypes[i++], KC_ST_UINT32, KCDATA_DESC_MAXLEN, "data");
102 setup_type_definition(retval, type_id, i, "uint32_desc");
103 break;
104 }
105
106 case KCDATA_TYPE_UINT64_DESC: {
107 i = 0;
108 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, KCDATA_DESC_MAXLEN, "desc");
109 setup_subtype_description(&subtypes[i++], KC_ST_UINT64, KCDATA_DESC_MAXLEN, "data");
110 setup_type_definition(retval, type_id, i, "uint64_desc");
111 break;
112 }
113
114 case KCDATA_TYPE_INT32_DESC: {
115 i = 0;
116 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, KCDATA_DESC_MAXLEN, "desc");
117 setup_subtype_description(&subtypes[i++], KC_ST_INT32, KCDATA_DESC_MAXLEN, "data");
118 setup_type_definition(retval, type_id, i, "int32_desc");
119 break;
120 }
121
122 case KCDATA_TYPE_INT64_DESC: {
123 i = 0;
124 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, KCDATA_DESC_MAXLEN, "desc");
125 setup_subtype_description(&subtypes[i++], KC_ST_INT64, KCDATA_DESC_MAXLEN, "data");
126 setup_type_definition(retval, type_id, i, "int64_desc");
127 break;
128 }
129
130 case KCDATA_TYPE_CONTAINER_BEGIN :{
131 i = 0;
132 setup_subtype_description(&subtypes[i++], KC_ST_UINT32, 0, "kcContainerType");
133 setup_type_definition(retval, type_id, i, "container_begin");
134 break;
135 }
136
137 case KCDATA_TYPE_LIBRARY_LOADINFO: {
138 i = 0;
139 _SUBTYPE(KC_ST_UINT32, struct dyld_uuid_info_32, imageLoadAddress);
140 _SUBTYPE_ARRAY(KC_ST_UINT8, struct dyld_uuid_info_32, imageUUID, 16);
141 setup_type_definition(retval, type_id, i, "dyld_load_info");
142 break;
143
144 }
145
146 case KCDATA_TYPE_LIBRARY_LOADINFO64: /* fall through */
147 case STACKSHOT_KCTYPE_SHAREDCACHE_LOADINFO: {
148 i = 0;
149 _SUBTYPE(KC_ST_UINT64, struct dyld_uuid_info_64, imageLoadAddress);
150 _SUBTYPE_ARRAY(KC_ST_UINT8, struct dyld_uuid_info_64, imageUUID, 16);
151 setup_type_definition(retval, type_id, i, "dyld_load_info");
152 break;
153 }
154
155 case KCDATA_TYPE_TIMEBASE: {
156 i = 0;
157 _SUBTYPE(KC_ST_UINT32, struct mach_timebase_info, numer);
158 _SUBTYPE(KC_ST_UINT32, struct mach_timebase_info, denom);
159 setup_type_definition(retval, type_id, i, "mach_timebase_info");
160 }
161
162 case KCDATA_TYPE_MACH_ABSOLUTE_TIME:
163 setup_type_definition(retval, type_id, 1, "mach_absolute_time");
164 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "mach_absolute_time");
165 break;
166
167 case KCDATA_TYPE_TIMEVAL: {
168 i = 0;
169 _SUBTYPE(KC_ST_INT64, struct timeval64, tv_sec);
170 _SUBTYPE(KC_ST_INT64, struct timeval64, tv_usec);
171 setup_type_definition(retval, type_id, i, "timeval");
172 }
173
174 case KCDATA_TYPE_USECS_SINCE_EPOCH:
175 setup_type_definition(retval, type_id, 1, "usecs_since_epoch");
176 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "usecs_since_epoch");
177 break;
178
179
180 /* stackshot specific types */
181 case STACKSHOT_KCTYPE_IOSTATS: {
182 i = 0;
183 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_disk_reads_count);
184 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_disk_reads_size);
185 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_disk_writes_count);
186 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_disk_writes_size);
187 _SUBTYPE_ARRAY(KC_ST_UINT64, struct io_stats_snapshot, ss_io_priority_count, STACKSHOT_IO_NUM_PRIORITIES);
188 _SUBTYPE_ARRAY(KC_ST_UINT64, struct io_stats_snapshot, ss_io_priority_size, STACKSHOT_IO_NUM_PRIORITIES);
189 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_paging_count);
190 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_paging_size);
191 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_non_paging_count);
192 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_non_paging_size);
193 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_data_count);
194 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_data_size);
195 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_metadata_count);
196 _SUBTYPE(KC_ST_UINT64, struct io_stats_snapshot, ss_metadata_size);
197
198 setup_type_definition(retval, type_id, i, "io_statistics");
199 break;
200 }
201
202 case STACKSHOT_KCTYPE_GLOBAL_MEM_STATS :
203 { i = 0;
204 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, snapshot_magic);
205 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, free_pages);
206 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, active_pages);
207 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, inactive_pages);
208 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, purgeable_pages);
209 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, wired_pages);
210 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, speculative_pages);
211 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, throttled_pages);
212 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, filebacked_pages);
213 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, compressions);
214 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, decompressions);
215 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, compressor_size);
216 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, busy_buffer_count);
217 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, pages_wanted);
218 _SUBTYPE(KC_ST_UINT32, struct mem_and_io_snapshot, pages_reclaimed);
219 _SUBTYPE(KC_ST_UINT8, struct mem_and_io_snapshot, pages_wanted_reclaimed_valid);
220 setup_type_definition(retval, type_id, i, "mem_and_io_snapshot");
221 break;
222 }
223
224 case STACKSHOT_KCCONTAINER_TASK:
225 setup_type_definition(retval, type_id, 0, "task_snapshots");
226 break;
227
228 case STACKSHOT_KCCONTAINER_THREAD:
229 setup_type_definition(retval, type_id, 0, "thread_snapshots");
230 break;
231
232
233 case STACKSHOT_KCTYPE_TASK_SNAPSHOT: {
234 i = 0;
235 _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_unique_pid);
236 _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_ss_flags);
237 _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_user_time_in_terminated_threads);
238 _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_system_time_in_terminated_threads);
239 _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_p_start_sec);
240 _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_task_size);
241 _SUBTYPE(KC_ST_UINT64, struct task_snapshot_v2, ts_max_resident_size);
242 _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_suspend_count);
243 _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_faults);
244 _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_pageins);
245 _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_cow_faults);
246 _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_was_throttled);
247 _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_did_throttle);
248 _SUBTYPE(KC_ST_UINT32, struct task_snapshot_v2, ts_latency_qos);
249 _SUBTYPE(KC_ST_INT32, struct task_snapshot_v2, ts_pid);
250 _SUBTYPE_ARRAY(KC_ST_CHAR, struct task_snapshot_v2, ts_p_comm, 32);
251 setup_type_definition(retval, type_id, i, "task_snapshot");
252 break;
253 }
254
255 case STACKSHOT_KCTYPE_THREAD_SNAPSHOT: {
256 i = 0;
257
258 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v2, ths_thread_id);
259 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v2, ths_wait_event);
260 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v2, ths_continuation);
261 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v2, ths_total_syscalls);
262 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v2, ths_voucher_identifier);
263 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v2, ths_dqserialnum);
264 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v2, ths_user_time);
265 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v2, ths_sys_time);
266 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v2, ths_ss_flags);
267 _SUBTYPE(KC_ST_UINT64, struct thread_snapshot_v2, ths_last_run_time);
268 _SUBTYPE(KC_ST_UINT32, struct thread_snapshot_v2, ths_state);
269 _SUBTYPE(KC_ST_UINT32, struct thread_snapshot_v2, ths_sched_flags);
270 _SUBTYPE(KC_ST_INT16, struct thread_snapshot_v2, ths_base_priority);
271 _SUBTYPE(KC_ST_INT16, struct thread_snapshot_v2, ths_sched_priority);
272 _SUBTYPE(KC_ST_UINT8, struct thread_snapshot_v2, ths_eqos);
273 _SUBTYPE(KC_ST_UINT8, struct thread_snapshot_v2, ths_rqos);
274 _SUBTYPE(KC_ST_UINT8, struct thread_snapshot_v2, ths_rqos_override);
275 _SUBTYPE(KC_ST_UINT8, struct thread_snapshot_v2, ths_io_tier);
276
277 setup_type_definition(retval, type_id, i, "thread_snapshot");
278 break;
279 }
280
281
282 case STASKSHOT_KCTYPE_DONATING_PIDS:
283 setup_type_definition(retval, type_id, 1, "donating_pids");
284 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "pid");
285 break;
286
287 case STACKSHOT_KCTYPE_THREAD_NAME:{
288 i = 0;
289 setup_subtype_array_description(&subtypes[i++], KC_ST_CHAR, 0, 64, "pth_name");
290 setup_type_definition(retval, type_id, i, "pth_name");
291 break;
292 }
293
294 case STACKSHOT_KCTYPE_KERN_STACKFRAME :
295 setup_type_definition(retval, type_id, 2, "kernel_stack_frames");
296 setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "lr");
297 setup_subtype_description(&subtypes[1], KC_ST_UINT32, sizeof(uint32_t), "sp");
298 break;
299
300 case STACKSHOT_KCTYPE_KERN_STACKFRAME64 :
301 setup_type_definition(retval, type_id, 2, "kernel_stack_frames");
302 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "lr");
303 setup_subtype_description(&subtypes[1], KC_ST_UINT64, sizeof(uint64_t), "sp");
304 break;
305
306 case STACKSHOT_KCTYPE_USER_STACKFRAME :
307 setup_type_definition(retval, type_id, 2, "user_stack_frames");
308 setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "lr");
309 setup_subtype_description(&subtypes[1], KC_ST_UINT32, sizeof(uint32_t), "sp");
310 break;
311
312 case STACKSHOT_KCTYPE_USER_STACKFRAME64 :
313 setup_type_definition(retval, type_id, 2, "user_stack_frames");
314 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "lr");
315 setup_subtype_description(&subtypes[1], KC_ST_UINT64, sizeof(uint64_t), "sp");
316 break;
317
318 case STACKSHOT_KCTYPE_BOOTARGS: {
319 i = 0;
320 _STRINGTYPE("boot_args");
321 setup_type_definition(retval, type_id, i, "boot_args");
322 break;
323 }
324
325 case STACKSHOT_KCTYPE_OSVERSION: {
326 i = 0;
327 _STRINGTYPE("osversion");
328 setup_type_definition(retval, type_id, i, "osversion");
329 break;
330 }
331
332 case STACKSHOT_KCTYPE_KERN_PAGE_SIZE: {
333 i = 0;
334 setup_subtype_description(&subtypes[i++], KC_ST_UINT32, 0, "kernel_page_size");
335 setup_type_definition(retval, type_id, i, "kernel_page_size");
336 break;
337 }
338
339 case STACKSHOT_KCTYPE_JETSAM_LEVEL: {
340 i = 0;
341 setup_subtype_description(&subtypes[i++], KC_ST_UINT32, 0, "jetsam_level");
342 setup_type_definition(retval, type_id, i, "jetsam_level");
343 break;
344 }
345
346 /* crashinfo types */
347 case TASK_CRASHINFO_BSDINFOWITHUNIQID:
348 { i = 0;
349 _SUBTYPE_ARRAY(KC_ST_UINT8, struct proc_uniqidentifierinfo, p_uuid, 16);
350 _SUBTYPE(KC_ST_UINT64, struct proc_uniqidentifierinfo, p_uniqueid);
351 _SUBTYPE(KC_ST_UINT64, struct proc_uniqidentifierinfo, p_puniqueid);
352 /* Ignore the p_reserve fields */
353 setup_type_definition(retval, type_id, i, "proc_uniqidentifierinfo");
354 break;
355 }
356
357 case TASK_CRASHINFO_PID:{
358 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "pid");
359 setup_type_definition(retval, type_id, 1, "pid");
360 break;
361 }
362
363 case TASK_CRASHINFO_PPID:{
364 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "ppid");
365 setup_type_definition(retval, type_id, 1, "ppid");
366 break;
367 }
368
369 case TASK_CRASHINFO_RUSAGE_INFO: {
370 i = 0;
371 _SUBTYPE_ARRAY(KC_ST_UINT8, struct rusage_info_v3, ri_uuid, 16);
372 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_user_time);
373 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_system_time);
374 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_pkg_idle_wkups);
375 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_interrupt_wkups);
376 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_pageins);
377 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_wired_size);
378 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_resident_size);
379 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_phys_footprint);
380 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_proc_start_abstime);
381 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_proc_exit_abstime);
382 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_user_time);
383 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_system_time);
384 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_pkg_idle_wkups);
385 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_interrupt_wkups);
386 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_pageins);
387 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_child_elapsed_abstime);
388 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_diskio_bytesread);
389 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_diskio_byteswritten);
390 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_default);
391 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_maintenance);
392 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_background);
393 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_utility);
394 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_legacy);
395 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_user_initiated);
396 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_cpu_time_qos_user_interactive);
397 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_billed_system_time);
398 _SUBTYPE(KC_ST_UINT64, struct rusage_info_v3, ri_serviced_system_time);
399 setup_type_definition(retval, type_id, i, "rusage_info");
400 }
401
402 case TASK_CRASHINFO_PROC_NAME: {
403 i = 0;
404 _STRINGTYPE("p_comm");
405 setup_type_definition(retval, type_id, i, "p_comm");
406 }
407
408 case TASK_CRASHINFO_USERSTACK: {
409 i = 0;
410 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "userstack_ptr");
411 setup_type_definition(retval, type_id, 1, "userstack_ptr");
412 break;
413 }
414
415 case TASK_CRASHINFO_ARGSLEN: {
416 i = 0;
417 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "p_argslen");
418 setup_type_definition(retval, type_id, 1, "p_argslen");
419 break;
420 }
421
422 case TASK_CRASHINFO_PROC_PATH: {
423 i = 0;
424 _STRINGTYPE("p_path");
425 setup_type_definition(retval, type_id, i, "p_path");
426 }
427
428 case TASK_CRASHINFO_PROC_CSFLAGS:{
429 setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "p_csflags");
430 setup_type_definition(retval, type_id, 1, "p_csflags");
431 break;
432 }
433
434 case TASK_CRASHINFO_PROC_STATUS: {
435 setup_subtype_description(&subtypes[0], KC_ST_UINT8, 0, "p_status");
436 setup_type_definition(retval, type_id, 1, "p_status");
437 break;
438 }
439
440 case TASK_CRASHINFO_UID:{
441 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "uid");
442 setup_type_definition(retval, type_id, 1, "uid");
443 break;
444 }
445
446 case TASK_CRASHINFO_GID:{
447 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "gid");
448 setup_type_definition(retval, type_id, 1, "gid");
449 break;
450 }
451
452 case TASK_CRASHINFO_PROC_ARGC:{
453 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "argc");
454 setup_type_definition(retval, type_id, 1, "argc");
455 break;
456 }
457
458 case TASK_CRASHINFO_PROC_FLAGS:{
459 setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "p_flags");
460 setup_type_definition(retval, type_id, 1, "p_flags");
461 break;
462 }
463
464 case TASK_CRASHINFO_CPUTYPE:{
465 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "cputype");
466 setup_type_definition(retval, type_id, 1, "cputype");
467 break;
468 }
469
470 case TASK_CRASHINFO_RESPONSIBLE_PID:{
471 setup_subtype_description(&subtypes[0], KC_ST_INT32, 0, "responsible_pid");
472 setup_type_definition(retval, type_id, 1, "responsible_pid");
473 break;
474 }
475
476 case TASK_CRASHINFO_DIRTY_FLAGS:{
477 setup_subtype_description(&subtypes[0], KC_ST_UINT32, 0, "dirty_flags");
478 setup_type_definition(retval, type_id, 1, "dirty_flags");
479 break;
480 }
481
482 case TASK_CRASHINFO_CRASHED_THREADID: {
483 setup_subtype_description(&subtypes[0], KC_ST_UINT64, 0, "crashed_threadid");
484 setup_type_definition(retval, type_id, 1, "crashed_threadid");
485 break;
486 }
487
488 default:
489 retval = NULL;
490 break;
491 }
492
493 assert(retval == NULL || (buffer_size > sizeof(struct kcdata_type_definition) + (retval->kct_num_elements * sizeof(struct kcdata_subtype_descriptor))));
494 return retval;
495}
496
497
498static void setup_type_definition(struct kcdata_type_definition *d, uint32_t type, uint32_t num_elems, char *name)
499{
500 d->kct_type_identifier = type;
501 d->kct_num_elements = num_elems;
502 memcpy(d->kct_name, name, sizeof(d->kct_name));
503 d->kct_name[sizeof(d->kct_name) - 1] = '\0';
504}
505
506static uint32_t get_kctype_subtype_size(kctype_subtype_t type){
507 switch (type) {
508 case KC_ST_CHAR:
509 case KC_ST_INT8:
510 case KC_ST_UINT8:
511 return sizeof(uint8_t);
512 break;
513 case KC_ST_INT16:
514 case KC_ST_UINT16:
515 return sizeof(uint16_t);
516 break;
517 case KC_ST_INT32:
518 case KC_ST_UINT32:
519 return sizeof(uint32_t);
520 break;
521 case KC_ST_INT64:
522 case KC_ST_UINT64:
523 return sizeof(uint64_t);
524 break;
525
526 default:
527 assert(0);
528 break;
529 }
530 return 0;
531}
532
533static void setup_subtype_array_description(kcdata_subtype_descriptor_t desc, kctype_subtype_t type, uint32_t offset, uint32_t count, char *name)
534{
535 desc->kcs_flags = KCS_SUBTYPE_FLAGS_ARRAY;
536 desc->kcs_elem_type = type;
537 desc->kcs_elem_offset = offset;
538 desc->kcs_elem_size = KCS_SUBTYPE_PACK_SIZE(count, get_kctype_subtype_size(type));
539 memcpy(desc->kcs_name, name, sizeof(desc->kcs_name));
540 desc->kcs_name[sizeof(desc->kcs_name) - 1] = '\0';
541}
542
543static void setup_subtype_description(kcdata_subtype_descriptor_t desc, kctype_subtype_t type, uint32_t offset, char *name)
544{
545 desc->kcs_flags = KCS_SUBTYPE_FLAGS_NONE;
546 desc->kcs_elem_type = type;
547 desc->kcs_elem_offset = offset;
548 desc->kcs_elem_size = get_kctype_subtype_size(type);
549 memcpy(desc->kcs_name, name, sizeof(desc->kcs_name));
550 desc->kcs_name[sizeof(desc->kcs_name) - 1] = '\0';
551}
552