2 * Copyright (c) 2015 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_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. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #ifndef _KERN_CDATA_H_
30 #define _KERN_CDATA_H_
33 #include <mach/mach_types.h>
35 #define KCDATA_DESC_MAXLEN 32 /* including NULL byte at end */
39 uint32_t size
; /* len(data) */
42 char data
[]; /* must be at the end */
46 typedef struct kcdata_item
* kcdata_item_t
;
48 enum KCDATA_SUBTYPE_TYPES
{ KC_ST_CHAR
= 1, KC_ST_INT8
, KC_ST_UINT8
, KC_ST_INT16
, KC_ST_UINT16
, KC_ST_INT32
, KC_ST_UINT32
, KC_ST_INT64
, KC_ST_UINT64
};
49 typedef enum KCDATA_SUBTYPE_TYPES kctype_subtype_t
;
52 * A subtype description structure that defines
53 * how a compound data is laid out in memory. This
54 * provides on the fly definition of types and consumption
57 struct kcdata_subtype_descriptor
{
59 #define KCS_SUBTYPE_FLAGS_NONE 0x0
60 #define KCS_SUBTYPE_FLAGS_ARRAY 0x1
61 uint8_t kcs_elem_type
; /* restricted to kctype_subtype_t */
62 uint16_t kcs_elem_offset
; /* offset in struct where data is found */
63 uint32_t kcs_elem_size
; /* size of element (or) packed state for array type */
64 char kcs_name
[KCDATA_DESC_MAXLEN
]; /* max 31 bytes for name of field */
67 typedef struct kcdata_subtype_descriptor
* kcdata_subtype_descriptor_t
;
70 * In case of array of basic c types in kctype_subtype_t,
71 * size is packed in lower 16 bits and
72 * count is packed in upper 16 bits of kcs_elem_size field.
74 #define KCS_SUBTYPE_PACK_SIZE(e_count,e_size) (((e_count) & 0xffff) << 16 | ((e_size) & 0xffff))
76 static inline uint32_t
77 kcs_get_elem_size(kcdata_subtype_descriptor_t d
)
79 if (d
->kcs_flags
& KCS_SUBTYPE_FLAGS_ARRAY
) {
80 /* size is composed as ((count &0xffff)<<16 | (elem_size & 0xffff)) */
81 return (uint32_t)((d
->kcs_elem_size
& 0xffff) * ((d
->kcs_elem_size
& 0xffff0000)>>16));
83 return d
->kcs_elem_size
;
86 static inline uint32_t
87 kcs_get_elem_count(kcdata_subtype_descriptor_t d
)
89 if (d
->kcs_flags
& KCS_SUBTYPE_FLAGS_ARRAY
)
90 return (d
->kcs_elem_size
>> 16) & 0xffff;
94 static inline kern_return_t
95 kcs_set_elem_size(kcdata_subtype_descriptor_t d
, uint32_t size
, uint32_t count
)
98 /* means we are setting up an array */
99 if (size
> 0xffff || count
> 0xffff)
100 return KERN_INVALID_ARGUMENT
;
101 d
->kcs_elem_size
= ((count
& 0xffff) << 16 | (size
& 0xffff));
105 d
->kcs_elem_size
= size
;
110 struct kcdata_type_definition
{
111 uint32_t kct_type_identifier
;
112 uint32_t kct_num_elements
;
113 char kct_name
[KCDATA_DESC_MAXLEN
];
115 struct kcdata_subtype_descriptor kct_elements
[];
119 /* chunk type definitions. 0 - 0x7ff are reserved and defined here
120 * NOTE: Please update libkdd/kcdata/kcdtypes.c if you make any changes
121 * in STACKSHOT_KCTYPE_* types.
125 * Types with description value.
126 * these will have KCDATA_DESC_MAXLEN-1 length string description
127 * and rest of KCDATA_ITEM_SIZE() - KCDATA_DESC_MAXLEN bytes as data
129 #define KCDATA_TYPE_INVALID 0x0
130 #define KCDATA_TYPE_STRING_DESC 0x1
131 #define KCDATA_TYPE_UINT32_DESC 0x2
132 #define KCDATA_TYPE_UINT64_DESC 0x3
133 #define KCDATA_TYPE_INT32_DESC 0x4
134 #define KCDATA_TYPE_INT64_DESC 0x5
135 #define KCDATA_TYPE_BINDATA_DESC 0x6
138 * Compound type definitions
140 #define KCDATA_TYPE_ARRAY 0x11 /* Array of data */
141 #define KCDATA_TYPE_TYPEDEFINTION 0x12 /* Meta type that describes a type on the fly. */
142 #define KCDATA_TYPE_CONTAINER_BEGIN 0x13 /* Container type which has corresponding CONTAINER_END header.
143 * KCDATA_TYPE_CONTAINER_BEGIN has type in the data segment.
144 * Both headers have (uint64_t) ID for matching up nested data.
146 #define KCDATA_TYPE_CONTAINER_END 0x14
150 * Generic data types that are most commonly used
152 #define KCDATA_TYPE_LIBRARY_LOADINFO 0x30 /* struct dyld_uuid_info_32 */
153 #define KCDATA_TYPE_LIBRARY_LOADINFO64 0x31 /* struct dyld_uuid_info_64 */
154 #define KCDATA_TYPE_TIMEBASE 0x32 /* struct mach_timebase_info */
155 #define KCDATA_TYPE_MACH_ABSOLUTE_TIME 0x33 /* uint64_t */
156 #define KCDATA_TYPE_TIMEVAL 0x34 /* struct timeval64 */
157 #define KCDATA_TYPE_USECS_SINCE_EPOCH 0x35 /* time in usecs uint64_t */
159 #define KCDATA_TYPE_BUFFER_END 0xF19158ED
161 /* MAGIC numbers defined for each class of chunked data */
162 #define KCDATA_BUFFER_BEGIN_CRASHINFO 0xDEADF157 /* owner: corpses/task_corpse.h */
163 /* type-range: 0x800 - 0x8ff */
164 #define KCDATA_BUFFER_BEGIN_STACKSHOT 0x59a25807 /* owner: sys/stackshot.h */
165 /* type-range: 0x900 - 0x9ff */
167 /* next type range number available 0x1000 */
169 /* Common MACROS and library functions */
170 /* make header = sizeof(type, flags, size) */
171 #define KCDATA_ITEM_HEADER_SIZE (sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint64_t))
172 #define KCDATA_ITEM_TYPE(item) (((kcdata_item_t)(item))->type)
173 #define KCDATA_ITEM_SIZE(item) (((kcdata_item_t)(item))->size)
174 #define KCDATA_ITEM_FLAGS(item) (((kcdata_item_t)(item))->flags)
176 #define KCDATA_ITEM_ARRAY_GET_EL_TYPE(item) ((KCDATA_ITEM_FLAGS(item) >> 32) & UINT32_MAX)
177 #define KCDATA_ITEM_ARRAY_GET_EL_COUNT(item) (KCDATA_ITEM_FLAGS(item) & UINT32_MAX)
178 #define KCDATA_ITEM_ARRAY_GET_EL_SIZE(item) (KCDATA_ITEM_SIZE(item) / KCDATA_ITEM_ARRAY_GET_EL_COUNT(item))
180 #define KCDATA_CONTAINER_ID(item) ((uint64_t)KCDATA_ITEM_FLAGS(item))
182 #define KCDATA_ITEM_NEXT_HEADER(item) ((kcdata_item_t)((uint64_t)((uintptr_t)(item)) + KCDATA_ITEM_HEADER_SIZE + KCDATA_ITEM_SIZE(item)))
184 #define KCDATA_ITEM_FOREACH(head) for (; KCDATA_ITEM_TYPE(head) != KCDATA_TYPE_BUFFER_END; (head) = KCDATA_ITEM_NEXT_HEADER(head))
186 static inline kcdata_item_t
187 KCDATA_ITEM_FIND_TYPE(kcdata_item_t head
, uint32_t type
)
189 KCDATA_ITEM_FOREACH(head
)
191 if (KCDATA_ITEM_TYPE(head
) == type
) {
195 return (KCDATA_ITEM_TYPE(head
) == type
) ? (kcdata_item_t
)head
: 0;
199 #define KCDATA_ITEM_DATA_PTR(item) (&((kcdata_item_t)(item))->data)
201 static inline uint32_t kcdata_get_container_type(kcdata_item_t buffer
) {
202 if (KCDATA_ITEM_TYPE(buffer
) == KCDATA_TYPE_CONTAINER_BEGIN
)
203 return *(uint32_t *)KCDATA_ITEM_DATA_PTR(buffer
);
207 static inline void kcdata_get_data_with_desc(kcdata_item_t buffer
, char **desc_ptr
, void **data_ptr
) {
209 *desc_ptr
= (char *)KCDATA_ITEM_DATA_PTR(buffer
);
211 *data_ptr
= (void *)((uintptr_t)KCDATA_ITEM_DATA_PTR(buffer
) + KCDATA_DESC_MAXLEN
);
215 #ifdef XNU_KERNEL_PRIVATE
217 /* Structure to save information about corpse data */
218 struct kcdata_descriptor
{
221 #define KCFLAG_USE_MEMCOPY 0x0
222 #define KCFLAG_USE_COPYOUT 0x1
223 mach_vm_address_t kcd_addr_begin
;
224 mach_vm_address_t kcd_addr_end
;
227 typedef struct kcdata_descriptor
* kcdata_descriptor_t
;
229 kcdata_descriptor_t
kcdata_memory_alloc_init(mach_vm_address_t crash_data_p
, unsigned data_type
, unsigned size
, unsigned flags
);
230 kern_return_t
kcdata_memory_static_init(kcdata_descriptor_t data
, mach_vm_address_t buffer_addr_p
, unsigned data_type
, unsigned size
, unsigned flags
);
231 kern_return_t
kcdata_memory_destroy(kcdata_descriptor_t data
);
232 uint64_t kcdata_memory_get_used_bytes(kcdata_descriptor_t kcd
);
233 kern_return_t
kcdata_memcpy(kcdata_descriptor_t data
, mach_vm_address_t dst_addr
, void *src_addr
, uint32_t size
);
235 kern_return_t
kcdata_get_memory_addr(kcdata_descriptor_t data
, uint32_t type
, uint32_t size
, mach_vm_address_t
*user_addr
);
236 kern_return_t
kcdata_get_memory_addr_for_array(kcdata_descriptor_t data
, uint32_t type_of_element
, uint32_t size_of_element
, uint32_t count
, mach_vm_address_t
*user_addr
);
237 kern_return_t
kcdata_add_container_marker(kcdata_descriptor_t data
, uint32_t header_type
, uint32_t container_type
, uint64_t identifier
);
238 kern_return_t
kcdata_add_type_definition(kcdata_descriptor_t data
, uint32_t type_id
, char *type_name
, struct kcdata_subtype_descriptor
*elements_array_addr
, uint32_t elements_count
);
241 kern_return_t
kcdata_add_uint64_with_description(kcdata_descriptor_t crashinfo
, uint64_t data
, const char *description
);
242 kern_return_t
kcdata_add_uint32_with_description(kcdata_descriptor_t crashinfo
, uint32_t data
, const char *description
);
244 #endif /* XNU_KERNEL_PRIVATE */
246 #endif /* _KERN_CDATA_H_ */