2 * Copyright (c) 2015 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 #include <Kernel/kern/kern_cdata.h>
26 #include <Kernel/kern/debug.h>
32 #include <mach/mach_time.h>
33 #include <sys/proc_info.h>
34 #include <corpses/task_corpse.h>
37 * @function kcdata_get_typedescription
40 * Search the known type definitions for type with id type_id.
43 * A unsinged int type specified by the KCDATA.
46 * pointer to data area where type definition will be saved.
49 * size of the buffer provided.
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.
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.
63 struct kcdata_type_definition
*kcdata_get_typedescription(unsigned type_id
, uint8_t *buffer
, uint32_t buffer_size
);
67 /* forward declarations for helper routines */
68 static uint32_t get_kctype_subtype_size(kctype_subtype_t type
);
69 static void setup_subtype_description(kcdata_subtype_descriptor_t desc
, kctype_subtype_t type
, uint32_t offset
, char *name
);
70 static void setup_subtype_array_description(kcdata_subtype_descriptor_t desc
, kctype_subtype_t type
, uint32_t offset
, uint32_t count
, char *name
);
71 static void setup_type_definition(struct kcdata_type_definition
*d
, uint32_t type
, uint32_t num_elems
, char *name
);
73 struct kcdata_type_definition
*kcdata_get_typedescription(unsigned type_id
, uint8_t *buffer
, uint32_t buffer_size
)
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)
83 if (buffer_size
< sizeof(struct kcdata_type_definition
) || buffer
== NULL
)
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
)];
90 case KCDATA_TYPE_STRING_DESC
: {
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");
98 case KCDATA_TYPE_UINT32_DESC
: {
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");
106 case KCDATA_TYPE_UINT64_DESC
: {
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");
114 case KCDATA_TYPE_INT32_DESC
: {
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");
122 case KCDATA_TYPE_INT64_DESC
: {
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");
130 case KCDATA_TYPE_CONTAINER_BEGIN
:{
132 setup_subtype_description(&subtypes
[i
++], KC_ST_UINT32
, 0, "kcContainerType");
133 setup_type_definition(retval
, type_id
, i
, "container_begin");
137 case KCDATA_TYPE_LIBRARY_LOADINFO
: {
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");
146 case KCDATA_TYPE_LIBRARY_LOADINFO64
: /* fall through */
147 case STACKSHOT_KCTYPE_SHAREDCACHE_LOADINFO
: {
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");
155 case KCDATA_TYPE_TIMEBASE
: {
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");
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");
167 case KCDATA_TYPE_TIMEVAL
: {
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");
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");
180 /* stackshot specific types */
181 case STACKSHOT_KCTYPE_IOSTATS
: {
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
);
198 setup_type_definition(retval
, type_id
, i
, "io_statistics");
202 case STACKSHOT_KCTYPE_GLOBAL_MEM_STATS
:
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");
224 case STACKSHOT_KCCONTAINER_TASK
:
225 setup_type_definition(retval
, type_id
, 0, "task_snapshots");
228 case STACKSHOT_KCCONTAINER_THREAD
:
229 setup_type_definition(retval
, type_id
, 0, "thread_snapshots");
233 case STACKSHOT_KCTYPE_TASK_SNAPSHOT
: {
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");
255 case STACKSHOT_KCTYPE_THREAD_SNAPSHOT
: {
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
);
277 setup_type_definition(retval
, type_id
, i
, "thread_snapshot");
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");
287 case STACKSHOT_KCTYPE_THREAD_NAME
:{
289 setup_subtype_array_description(&subtypes
[i
++], KC_ST_CHAR
, 0, 64, "pth_name");
290 setup_type_definition(retval
, type_id
, i
, "pth_name");
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");
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");
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");
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");
318 case STACKSHOT_KCTYPE_BOOTARGS
: {
320 _STRINGTYPE("boot_args");
321 setup_type_definition(retval
, type_id
, i
, "boot_args");
325 case STACKSHOT_KCTYPE_OSVERSION
: {
327 _STRINGTYPE("osversion");
328 setup_type_definition(retval
, type_id
, i
, "osversion");
332 case STACKSHOT_KCTYPE_KERN_PAGE_SIZE
: {
334 setup_subtype_description(&subtypes
[i
++], KC_ST_UINT32
, 0, "kernel_page_size");
335 setup_type_definition(retval
, type_id
, i
, "kernel_page_size");
339 case STACKSHOT_KCTYPE_JETSAM_LEVEL
: {
341 setup_subtype_description(&subtypes
[i
++], KC_ST_UINT32
, 0, "jetsam_level");
342 setup_type_definition(retval
, type_id
, i
, "jetsam_level");
346 /* crashinfo types */
347 case TASK_CRASHINFO_BSDINFOWITHUNIQID
:
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");
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");
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");
369 case TASK_CRASHINFO_RUSAGE_INFO
: {
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");
402 case TASK_CRASHINFO_PROC_NAME
: {
404 _STRINGTYPE("p_comm");
405 setup_type_definition(retval
, type_id
, i
, "p_comm");
408 case TASK_CRASHINFO_USERSTACK
: {
410 setup_subtype_description(&subtypes
[0], KC_ST_UINT64
, 0, "userstack_ptr");
411 setup_type_definition(retval
, type_id
, 1, "userstack_ptr");
415 case TASK_CRASHINFO_ARGSLEN
: {
417 setup_subtype_description(&subtypes
[0], KC_ST_INT32
, 0, "p_argslen");
418 setup_type_definition(retval
, type_id
, 1, "p_argslen");
422 case TASK_CRASHINFO_PROC_PATH
: {
424 _STRINGTYPE("p_path");
425 setup_type_definition(retval
, type_id
, i
, "p_path");
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");
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");
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");
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");
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");
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");
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");
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");
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");
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");
493 assert(retval
== NULL
|| (buffer_size
> sizeof(struct kcdata_type_definition
) + (retval
->kct_num_elements
* sizeof(struct kcdata_subtype_descriptor
))));
498 static void setup_type_definition(struct kcdata_type_definition
*d
, uint32_t type
, uint32_t num_elems
, char *name
)
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';
506 static uint32_t get_kctype_subtype_size(kctype_subtype_t type
){
511 return sizeof(uint8_t);
515 return sizeof(uint16_t);
519 return sizeof(uint32_t);
523 return sizeof(uint64_t);
533 static void setup_subtype_array_description(kcdata_subtype_descriptor_t desc
, kctype_subtype_t type
, uint32_t offset
, uint32_t count
, char *name
)
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';
543 static void setup_subtype_description(kcdata_subtype_descriptor_t desc
, kctype_subtype_t type
, uint32_t offset
, char *name
)
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';