]> git.saurik.com Git - apple/xnu.git/blob - osfmk/kern/kern_cdata.h
xnu-3248.40.184.tar.gz
[apple/xnu.git] / osfmk / kern / kern_cdata.h
1 /*
2 * Copyright (c) 2015 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_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. 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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 #ifndef _KERN_CDATA_H_
30 #define _KERN_CDATA_H_
31
32 #include <stdint.h>
33 #include <mach/mach_types.h>
34
35 #define KCDATA_DESC_MAXLEN 32 /* including NULL byte at end */
36
37 struct kcdata_item {
38 uint32_t type;
39 uint32_t size; /* len(data) */
40 uint64_t flags;
41 #ifndef KERNEL
42 char data[]; /* must be at the end */
43 #endif
44 };
45
46 typedef struct kcdata_item * kcdata_item_t;
47
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;
50
51 /*
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
55 * by the parser.
56 */
57 struct kcdata_subtype_descriptor {
58 uint8_t kcs_flags;
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 */
65 };
66
67 typedef struct kcdata_subtype_descriptor * kcdata_subtype_descriptor_t;
68
69 /*
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.
73 */
74 #define KCS_SUBTYPE_PACK_SIZE(e_count,e_size) (((e_count) & 0xffff) << 16 | ((e_size) & 0xffff))
75
76 static inline uint32_t
77 kcs_get_elem_size(kcdata_subtype_descriptor_t d)
78 {
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));
82 }
83 return d->kcs_elem_size;
84 }
85
86 static inline uint32_t
87 kcs_get_elem_count(kcdata_subtype_descriptor_t d)
88 {
89 if (d->kcs_flags & KCS_SUBTYPE_FLAGS_ARRAY)
90 return (d->kcs_elem_size >> 16) & 0xffff;
91 return 1;
92 }
93
94 static inline kern_return_t
95 kcs_set_elem_size(kcdata_subtype_descriptor_t d, uint32_t size, uint32_t count)
96 {
97 if (count > 1) {
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));
102 }
103 else
104 {
105 d->kcs_elem_size = size;
106 }
107 return KERN_SUCCESS;
108 }
109
110 struct kcdata_type_definition {
111 uint32_t kct_type_identifier;
112 uint32_t kct_num_elements;
113 char kct_name[KCDATA_DESC_MAXLEN];
114 #ifndef KERNEL
115 struct kcdata_subtype_descriptor kct_elements[];
116 #endif
117 };
118
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.
122 */
123
124 /*
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
128 */
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
136
137 /*
138 * Compound type definitions
139 */
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.
145 */
146 #define KCDATA_TYPE_CONTAINER_END 0x14
147
148
149 /*
150 * Generic data types that are most commonly used
151 */
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 */
158
159 #define KCDATA_TYPE_BUFFER_END 0xF19158ED
160
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 */
166
167 /* next type range number available 0x1000 */
168
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)
175
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))
179
180 #define KCDATA_CONTAINER_ID(item) ((uint64_t)KCDATA_ITEM_FLAGS(item))
181
182 #define KCDATA_ITEM_NEXT_HEADER(item) ((kcdata_item_t)((uint64_t)((uintptr_t)(item)) + KCDATA_ITEM_HEADER_SIZE + KCDATA_ITEM_SIZE(item)))
183
184 #define KCDATA_ITEM_FOREACH(head) for (; KCDATA_ITEM_TYPE(head) != KCDATA_TYPE_BUFFER_END; (head) = KCDATA_ITEM_NEXT_HEADER(head))
185
186 static inline kcdata_item_t
187 KCDATA_ITEM_FIND_TYPE(kcdata_item_t head, uint32_t type)
188 {
189 KCDATA_ITEM_FOREACH(head)
190 {
191 if (KCDATA_ITEM_TYPE(head) == type) {
192 break;
193 }
194 }
195 return (KCDATA_ITEM_TYPE(head) == type) ? (kcdata_item_t)head : 0;
196 }
197
198 #ifndef KERNEL
199 #define KCDATA_ITEM_DATA_PTR(item) (&((kcdata_item_t)(item))->data)
200
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);
204 return 0;
205 }
206
207 static inline void kcdata_get_data_with_desc(kcdata_item_t buffer, char **desc_ptr, void **data_ptr) {
208 if (desc_ptr)
209 *desc_ptr = (char *)KCDATA_ITEM_DATA_PTR(buffer);
210 if (data_ptr)
211 *data_ptr = (void *)((uintptr_t)KCDATA_ITEM_DATA_PTR(buffer) + KCDATA_DESC_MAXLEN);
212 }
213 #endif /* KERNEL */
214
215 #ifdef XNU_KERNEL_PRIVATE
216
217 /* Structure to save information about corpse data */
218 struct kcdata_descriptor {
219 uint32_t kcd_length;
220 uint32_t kcd_flags;
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;
225 };
226
227 typedef struct kcdata_descriptor * kcdata_descriptor_t;
228
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);
234
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);
239
240
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);
243
244 #endif /* XNU_KERNEL_PRIVATE */
245
246 #endif /* _KERN_CDATA_H_ */