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 <kern/kcdata.h> |
33 | #include <mach/mach_types.h> |
34 | #ifdef XNU_KERNEL_PRIVATE |
35 | #include <libkern/zlib.h> |
36 | #endif |
37 | |
38 | /* |
39 | * Do not use these macros! |
40 | * |
41 | * Instead, you should use kcdata_iter_* functions defined in kcdata.h. These |
42 | * macoros have no idea where the kcdata buffer ends, so they are all unsafe. |
43 | */ |
44 | #define (sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint64_t)) |
45 | #define KCDATA_ITEM_ITER(item) kcdata_iter_unsafe((void*)(item)) |
46 | #define KCDATA_ITEM_TYPE(item) kcdata_iter_type(KCDATA_ITEM_ITER(item)) |
47 | #define KCDATA_ITEM_SIZE(item) kcdata_iter_size(KCDATA_ITEM_ITER(item)) |
48 | #define KCDATA_ITEM_FLAGS(item) kcdata_iter_flags(KCDATA_ITEM_ITER(item)) |
49 | #define KCDATA_ITEM_ARRAY_GET_EL_TYPE(item) kcdata_iter_array_elem_type(KCDATA_ITEM_ITER(item)) |
50 | #define KCDATA_ITEM_ARRAY_GET_EL_COUNT(item) kcdata_iter_array_elem_count(KCDATA_ITEM_ITER(item)) |
51 | #define KCDATA_ITEM_ARRAY_GET_EL_SIZE(item) kcdata_iter_array_elem_size(KCDATA_ITEM_ITER(item)) |
52 | #define KCDATA_CONTAINER_ID(item) kcdata_iter_container_id(KCDATA_ITEM_ITER(item)) |
53 | #define (itemx) (kcdata_iter_next(KCDATA_ITEM_ITER(itemx)).item) |
54 | #define KCDATA_ITEM_FOREACH(head) for (; KCDATA_ITEM_TYPE(head) != KCDATA_TYPE_BUFFER_END; (head) = KCDATA_ITEM_NEXT_HEADER(head)) |
55 | #define KCDATA_ITEM_DATA_PTR(item) kcdata_iter_payload(KCDATA_ITEM_ITER(item)) |
56 | #define KCDATA_ITEM_FIND_TYPE(itemx, type) (kcdata_iter_find_type(KCDATA_ITEM_ITER(itemx), type).item) |
57 | #define kcdata_get_container_type(buffer) kcdata_iter_container_type(KCDATA_ITEM_ITER(buffer)) |
58 | #define kcdata_get_data_with_desc(buf, desc, data) kcdata_iter_get_data_with_desc(KCDATA_ITEM_ITER(buf),desc,data,NULL) |
59 | /* Do not use these macros! */ |
60 | |
61 | __options_decl(kcd_compression_type_t, uint64_t, { |
62 | KCDCT_NONE = 0x00, |
63 | KCDCT_ZLIB = 0x01, |
64 | }); |
65 | |
66 | #ifdef KERNEL |
67 | #ifdef XNU_KERNEL_PRIVATE |
68 | |
69 | __options_decl(kcd_cd_flag_t, uint64_t, { |
70 | KCD_CD_FLAG_IN_MARK = 0x01, |
71 | KCD_CD_FLAG_FINALIZE = 0x02, |
72 | }); |
73 | |
74 | /* Structure to save zstream and other compression metadata */ |
75 | struct kcdata_compress_descriptor { |
76 | z_stream kcd_cd_zs; |
77 | void *kcd_cd_base; |
78 | uint64_t kcd_cd_offset; |
79 | size_t kcd_cd_maxoffset; |
80 | uint64_t kcd_cd_mark_begin; |
81 | kcd_cd_flag_t kcd_cd_flags; |
82 | kcd_compression_type_t kcd_cd_compression_type; |
83 | void (*kcd_cd_memcpy_f)(void *, const void *, size_t); |
84 | mach_vm_address_t kcd_cd_totalout_addr; |
85 | mach_vm_address_t kcd_cd_totalin_addr; |
86 | }; |
87 | |
88 | /* |
89 | * Various, compression algorithm agnostic flags for controlling writes to the |
90 | * output buffer. |
91 | */ |
92 | enum kcdata_compression_flush { |
93 | /* |
94 | * Hint that no flush is needed because more data is expected. Doesn't |
95 | * guarantee that no data will be written to the output buffer, since the |
96 | * underlying algorithm may decide that it's running out of space and may |
97 | * flush to the output buffer. |
98 | */ |
99 | KCDCF_NO_FLUSH, |
100 | /* |
101 | * Hint to flush all internal buffers to the output buffers. |
102 | */ |
103 | KCDCF_SYNC_FLUSH, |
104 | /* |
105 | * Hint that this is going to be the last call to the compression function, |
106 | * so flush all output buffers and mark state as finished. |
107 | */ |
108 | KCDCF_FINISH, |
109 | }; |
110 | |
111 | /* Structure to save information about kcdata */ |
112 | struct kcdata_descriptor { |
113 | uint32_t kcd_length; |
114 | uint16_t kcd_flags; |
115 | #define KCFLAG_USE_MEMCOPY 0x0 |
116 | #define KCFLAG_USE_COPYOUT 0x1 |
117 | #define KCFLAG_NO_AUTO_ENDBUFFER 0x2 |
118 | #define KCFLAG_USE_COMPRESSION 0x4 |
119 | uint16_t kcd_user_flags; /* reserved for subsystems using kcdata */ |
120 | mach_vm_address_t kcd_addr_begin; |
121 | mach_vm_address_t kcd_addr_end; |
122 | struct kcdata_compress_descriptor kcd_comp_d; |
123 | uint32_t kcd_endalloced; |
124 | }; |
125 | |
126 | typedef struct kcdata_descriptor * kcdata_descriptor_t; |
127 | |
128 | #define MAX_INFLIGHT_KCOBJECT_LW_CORPSE 15 |
129 | __options_decl(kcdata_obj_flags_t, uint32_t, { |
130 | KCDATA_OBJECT_TYPE_LW_CORPSE = 0x1, /* for lightweight corpse */ |
131 | }); |
132 | |
133 | struct kcdata_object { |
134 | kcdata_descriptor_t ko_data; |
135 | kcdata_obj_flags_t ko_flags; |
136 | ipc_port_t ko_port; |
137 | uint32_t ko_alloc_size; |
138 | os_refcnt_t ko_refs; |
139 | }; |
140 | |
141 | kcdata_descriptor_t kcdata_memory_alloc_init(mach_vm_address_t crash_data_p, unsigned data_type, unsigned size, unsigned flags); |
142 | kern_return_t kcdata_memory_static_init( |
143 | kcdata_descriptor_t data, mach_vm_address_t buffer_addr_p, unsigned data_type, unsigned size, unsigned flags); |
144 | kern_return_t kcdata_memory_destroy(kcdata_descriptor_t data); |
145 | kern_return_t |
146 | kcdata_add_container_marker(kcdata_descriptor_t data, uint32_t , uint32_t container_type, uint64_t identifier); |
147 | kern_return_t kcdata_add_type_definition(kcdata_descriptor_t data, |
148 | uint32_t type_id, |
149 | char * type_name, |
150 | struct kcdata_subtype_descriptor * elements_array_addr, |
151 | uint32_t elements_count); |
152 | |
153 | kern_return_t kcdata_add_uint64_with_description(kcdata_descriptor_t crashinfo, uint64_t data, const char * description); |
154 | kern_return_t kcdata_add_uint32_with_description(kcdata_descriptor_t crashinfo, uint32_t data, const char * description); |
155 | |
156 | kern_return_t kcdata_undo_add_container_begin(kcdata_descriptor_t data); |
157 | |
158 | kern_return_t kcdata_write_buffer_end(kcdata_descriptor_t data); |
159 | void *kcdata_memory_get_begin_addr(kcdata_descriptor_t data); |
160 | kern_return_t kcdata_init_compress(kcdata_descriptor_t, int hdr_tag, void (*memcpy_f)(void *, const void *, size_t), uint64_t type); |
161 | kern_return_t kcdata_push_data(kcdata_descriptor_t data, uint32_t type, uint32_t size, const void *input_data); |
162 | kern_return_t kcdata_push_array(kcdata_descriptor_t data, uint32_t type_of_element, uint32_t size_of_element, uint32_t count, const void *input_data); |
163 | kern_return_t kcdata_compress_memory_addr(kcdata_descriptor_t data, void *ptr); |
164 | void *kcdata_endalloc(kcdata_descriptor_t data, size_t length); |
165 | kern_return_t kcdata_finish(kcdata_descriptor_t data); |
166 | void kcdata_compression_window_open(kcdata_descriptor_t data); |
167 | kern_return_t kcdata_compression_window_close(kcdata_descriptor_t data); |
168 | void kcd_finalize_compression(kcdata_descriptor_t data); |
169 | |
170 | /* kcdata mach port representation */ |
171 | kern_return_t kcdata_object_throttle_get(kcdata_obj_flags_t flags); |
172 | void kcdata_object_throttle_release(kcdata_obj_flags_t flags); |
173 | kern_return_t kcdata_create_object(kcdata_descriptor_t data, kcdata_obj_flags_t flags, uint32_t size, kcdata_object_t *objp); |
174 | void kcdata_object_release(kcdata_object_t obj); |
175 | void kcdata_object_reference(kcdata_object_t obj); |
176 | kcdata_object_t convert_port_to_kcdata_object(ipc_port_t port); |
177 | ipc_port_t convert_kcdata_object_to_port(kcdata_object_t obj); |
178 | #else /* XNU_KERNEL_PRIVATE */ |
179 | |
180 | typedef void * kcdata_descriptor_t; |
181 | |
182 | #endif /* XNU_KERNEL_PRIVATE */ |
183 | |
184 | uint32_t kcdata_estimate_required_buffer_size(uint32_t num_items, uint32_t payload_size); |
185 | uint64_t kcdata_memory_get_used_bytes(kcdata_descriptor_t kcd); |
186 | uint64_t kcdata_memory_get_uncompressed_bytes(kcdata_descriptor_t kcd); |
187 | kern_return_t kcdata_memcpy(kcdata_descriptor_t data, mach_vm_address_t dst_addr, const void * src_addr, uint32_t size); |
188 | kern_return_t kcdata_bzero(kcdata_descriptor_t data, mach_vm_address_t dst_addr, uint32_t size); |
189 | kern_return_t kcdata_get_memory_addr(kcdata_descriptor_t data, uint32_t type, uint32_t size, mach_vm_address_t * user_addr); |
190 | kern_return_t kcdata_get_memory_addr_for_array( |
191 | kcdata_descriptor_t data, uint32_t type_of_element, uint32_t size_of_element, uint32_t count, mach_vm_address_t * user_addr); |
192 | |
193 | #endif /* KERNEL */ |
194 | #endif /* _KERN_CDATA_H_ */ |
195 | |