1 | /* |
2 | * Copyright (c) 2007 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 | * File: vm/vm_shared_region.h |
26 | * |
27 | * protos and struct definitions for shared region |
28 | */ |
29 | |
30 | #ifndef _VM_SHARED_REGION_H_ |
31 | #define _VM_SHARED_REGION_H_ |
32 | |
33 | #ifdef KERNEL_PRIVATE |
34 | |
35 | #include <mach/vm_prot.h> |
36 | #include <mach/mach_types.h> |
37 | #include <mach/shared_region.h> |
38 | |
39 | #include <kern/kern_types.h> |
40 | #include <kern/macro_help.h> |
41 | |
42 | #include <vm/vm_map.h> |
43 | |
44 | extern int shared_region_version; |
45 | extern int shared_region_persistence; |
46 | |
47 | #if DEBUG |
48 | extern int shared_region_debug; |
49 | #define SHARED_REGION_DEBUG(args) \ |
50 | MACRO_BEGIN \ |
51 | if (shared_region_debug) { \ |
52 | kprintf args; \ |
53 | } \ |
54 | MACRO_END |
55 | #else /* DEBUG */ |
56 | #define SHARED_REGION_DEBUG(args) |
57 | #endif /* DEBUG */ |
58 | |
59 | extern int shared_region_trace_level; |
60 | |
61 | extern struct vm_shared_region *init_task_shared_region; |
62 | |
63 | #define SHARED_REGION_TRACE_NONE_LVL 0 /* no trace */ |
64 | #define SHARED_REGION_TRACE_ERROR_LVL 1 /* trace abnormal events */ |
65 | #define SHARED_REGION_TRACE_INFO_LVL 2 /* trace all events */ |
66 | #define SHARED_REGION_TRACE_DEBUG_LVL 3 /* extra traces for debug */ |
67 | #define SHARED_REGION_TRACE(level, args) \ |
68 | MACRO_BEGIN \ |
69 | if (shared_region_trace_level >= level) { \ |
70 | printf args; \ |
71 | } \ |
72 | MACRO_END |
73 | #define SHARED_REGION_TRACE_NONE(args) |
74 | #define SHARED_REGION_TRACE_ERROR(args) \ |
75 | MACRO_BEGIN \ |
76 | SHARED_REGION_TRACE(SHARED_REGION_TRACE_ERROR_LVL, \ |
77 | args); \ |
78 | MACRO_END |
79 | #define SHARED_REGION_TRACE_INFO(args) \ |
80 | MACRO_BEGIN \ |
81 | SHARED_REGION_TRACE(SHARED_REGION_TRACE_INFO_LVL, \ |
82 | args); \ |
83 | MACRO_END |
84 | #define SHARED_REGION_TRACE_DEBUG(args) \ |
85 | MACRO_BEGIN \ |
86 | SHARED_REGION_TRACE(SHARED_REGION_TRACE_DEBUG_LVL, \ |
87 | args); \ |
88 | MACRO_END |
89 | |
90 | typedef struct vm_shared_region *vm_shared_region_t; |
91 | |
92 | #ifdef MACH_KERNEL_PRIVATE |
93 | |
94 | #include <kern/queue.h> |
95 | #include <vm/vm_object.h> |
96 | #include <vm/memory_object.h> |
97 | |
98 | #define PAGE_SIZE_FOR_SR_SLIDE 4096 |
99 | |
100 | /* Documentation for the slide info format can be found in the dyld project in |
101 | * the file 'launch-cache/dyld_cache_format.h'. */ |
102 | |
103 | typedef struct vm_shared_region_slide_info_entry_v1 *vm_shared_region_slide_info_entry_v1_t; |
104 | struct vm_shared_region_slide_info_entry_v1 { |
105 | uint32_t version; |
106 | uint32_t toc_offset; // offset from start of header to table-of-contents |
107 | uint32_t toc_count; // number of entries in toc (same as number of pages in r/w mapping) |
108 | uint32_t entry_offset; |
109 | uint32_t entry_count; |
110 | // uint16_t toc[toc_count]; |
111 | // entrybitmap entries[entries_count]; |
112 | }; |
113 | |
114 | #define NBBY 8 |
115 | #define NUM_SLIDING_BITMAPS_PER_PAGE (0x1000/sizeof(int)/NBBY) /*128*/ |
116 | typedef struct slide_info_entry_toc *slide_info_entry_toc_t; |
117 | struct slide_info_entry_toc { |
118 | uint8_t entry[NUM_SLIDING_BITMAPS_PER_PAGE]; |
119 | }; |
120 | |
121 | typedef struct vm_shared_region_slide_info_entry_v2 *vm_shared_region_slide_info_entry_v2_t; |
122 | struct vm_shared_region_slide_info_entry_v2 { |
123 | uint32_t version; |
124 | uint32_t page_size; |
125 | uint32_t page_starts_offset; |
126 | uint32_t page_starts_count; |
127 | uint32_t ; |
128 | uint32_t ; |
129 | uint64_t delta_mask; // which (contiguous) set of bits contains the delta to the next rebase location |
130 | uint64_t value_add; |
131 | // uint16_t page_starts[page_starts_count]; |
132 | // uint16_t page_extras[page_extras_count]; |
133 | }; |
134 | |
135 | #define DYLD_CACHE_SLIDE_PAGE_ATTRS 0xC000 // high bits of uint16_t are flags |
136 | #define 0x8000 // index is into extras array (not starts array) |
137 | #define DYLD_CACHE_SLIDE_PAGE_ATTR_NO_REBASE 0x4000 // page has no rebasing |
138 | #define DYLD_CACHE_SLIDE_PAGE_ATTR_END 0x8000 // last chain entry for page |
139 | #define DYLD_CACHE_SLIDE_PAGE_VALUE 0x3FFF // bitwise negation of DYLD_CACHE_SLIDE_PAGE_ATTRS |
140 | #define DYLD_CACHE_SLIDE_PAGE_OFFSET_SHIFT 2 |
141 | |
142 | typedef struct vm_shared_region_slide_info_entry_v3 *vm_shared_region_slide_info_entry_v3_t; |
143 | struct vm_shared_region_slide_info_entry_v3 |
144 | { |
145 | uint32_t version; // currently 3 |
146 | uint32_t page_size; // currently 4096 (may also be 16384) |
147 | uint32_t page_starts_count; |
148 | uint64_t value_add; |
149 | uint16_t page_starts[/* page_starts_count */]; |
150 | }; |
151 | |
152 | #define DYLD_CACHE_SLIDE_V3_PAGE_ATTR_NO_REBASE 0xFFFF // page has no rebasing |
153 | |
154 | |
155 | typedef struct vm_shared_region_slide_info_entry_v4 *vm_shared_region_slide_info_entry_v4_t; |
156 | struct vm_shared_region_slide_info_entry_v4 { |
157 | uint32_t version; // currently 4 |
158 | uint32_t page_size; // currently 4096 (may also be 16384) |
159 | uint32_t page_starts_offset; |
160 | uint32_t page_starts_count; |
161 | uint32_t ; |
162 | uint32_t ; |
163 | uint64_t delta_mask; // which (contiguous) set of bits contains the delta to the next rebase location (0xC0000000) |
164 | uint64_t value_add; // base address of cache |
165 | // uint16_t page_starts[page_starts_count]; |
166 | // uint16_t page_extras[page_extras_count]; |
167 | }; |
168 | |
169 | #define DYLD_CACHE_SLIDE4_PAGE_NO_REBASE 0xFFFF // page has no rebasing |
170 | #define DYLD_CACHE_SLIDE4_PAGE_INDEX 0x7FFF // index into starts or extras |
171 | #define 0x8000 // index is into extras array (not starts array) |
172 | #define 0x8000 // last chain entry for page |
173 | |
174 | |
175 | |
176 | typedef union vm_shared_region_slide_info_entry *vm_shared_region_slide_info_entry_t; |
177 | union vm_shared_region_slide_info_entry { |
178 | uint32_t version; |
179 | struct vm_shared_region_slide_info_entry_v1 v1; |
180 | struct vm_shared_region_slide_info_entry_v2 v2; |
181 | struct vm_shared_region_slide_info_entry_v3 v3; |
182 | struct vm_shared_region_slide_info_entry_v4 v4; |
183 | }; |
184 | |
185 | typedef struct vm_shared_region_slide_info *vm_shared_region_slide_info_t; |
186 | struct vm_shared_region_slide_info { |
187 | mach_vm_address_t slid_address; |
188 | mach_vm_offset_t start; |
189 | mach_vm_offset_t end; |
190 | uint32_t slide; |
191 | vm_object_t slide_object; |
192 | mach_vm_size_t slide_info_size; |
193 | vm_shared_region_slide_info_entry_t slide_info_entry; |
194 | }; |
195 | |
196 | /* address space shared region descriptor */ |
197 | struct vm_shared_region { |
198 | uint32_t sr_ref_count; |
199 | queue_chain_t sr_q; |
200 | void *sr_root_dir; |
201 | cpu_type_t sr_cpu_type; |
202 | cpu_subtype_t sr_cpu_subtype; |
203 | boolean_t sr_64bit; |
204 | boolean_t sr_mapping_in_progress; |
205 | boolean_t sr_slide_in_progress; |
206 | boolean_t sr_persists; |
207 | boolean_t sr_slid; |
208 | ipc_port_t sr_mem_entry; |
209 | mach_vm_offset_t sr_first_mapping; |
210 | mach_vm_offset_t sr_base_address; |
211 | mach_vm_size_t sr_size; |
212 | mach_vm_offset_t sr_pmap_nesting_start; |
213 | mach_vm_size_t sr_pmap_nesting_size; |
214 | thread_call_t sr_timer_call; |
215 | struct vm_shared_region_slide_info sr_slide_info; |
216 | uuid_t sr_uuid; |
217 | boolean_t sr_uuid_copied; |
218 | uint32_t sr_images_count; |
219 | struct dyld_uuid_info_64 *sr_images; |
220 | }; |
221 | |
222 | extern kern_return_t vm_shared_region_slide_page(vm_shared_region_slide_info_t si, |
223 | vm_offset_t vaddr, |
224 | mach_vm_offset_t uservaddr, |
225 | uint32_t pageIndex); |
226 | extern vm_shared_region_slide_info_t vm_shared_region_get_slide_info(vm_shared_region_t sr); |
227 | #else /* !MACH_KERNEL_PRIVATE */ |
228 | |
229 | struct vm_shared_region; |
230 | struct vm_shared_region_slide_info; |
231 | struct vm_shared_region_slide_info_entry; |
232 | struct slide_info_entry_toc; |
233 | |
234 | #endif /* MACH_KERNEL_PRIVATE */ |
235 | |
236 | extern void vm_shared_region_init(void); |
237 | extern kern_return_t vm_shared_region_enter( |
238 | struct _vm_map *map, |
239 | struct task *task, |
240 | boolean_t is_64bit, |
241 | void *fsroot, |
242 | cpu_type_t cpu, |
243 | cpu_subtype_t cpu_subtype); |
244 | extern kern_return_t vm_shared_region_remove( |
245 | struct _vm_map *map, |
246 | struct task *task); |
247 | extern vm_shared_region_t vm_shared_region_get( |
248 | struct task *task); |
249 | extern vm_shared_region_t vm_shared_region_trim_and_get( |
250 | struct task *task); |
251 | extern void vm_shared_region_deallocate( |
252 | struct vm_shared_region *shared_region); |
253 | extern mach_vm_offset_t vm_shared_region_base_address( |
254 | struct vm_shared_region *shared_region); |
255 | extern mach_vm_size_t vm_shared_region_size( |
256 | struct vm_shared_region *shared_region); |
257 | extern ipc_port_t vm_shared_region_mem_entry( |
258 | struct vm_shared_region *shared_region); |
259 | extern vm_map_t vm_shared_region_vm_map( |
260 | struct vm_shared_region *shared_region); |
261 | extern uint32_t vm_shared_region_get_slide( |
262 | vm_shared_region_t shared_region); |
263 | extern void vm_shared_region_set( |
264 | struct task *task, |
265 | struct vm_shared_region *new_shared_region); |
266 | extern vm_shared_region_t vm_shared_region_lookup( |
267 | void *root_dir, |
268 | cpu_type_t cpu, |
269 | cpu_subtype_t cpu_subtype, |
270 | boolean_t is_64bit); |
271 | extern kern_return_t vm_shared_region_start_address( |
272 | struct vm_shared_region *shared_region, |
273 | mach_vm_offset_t *start_address); |
274 | extern void vm_shared_region_undo_mappings( |
275 | vm_map_t sr_map, |
276 | mach_vm_offset_t sr_base_address, |
277 | struct shared_file_mapping_np *mappings, |
278 | unsigned int mappings_count); |
279 | extern kern_return_t vm_shared_region_map_file( |
280 | struct vm_shared_region *shared_region, |
281 | unsigned int mappings_count, |
282 | struct shared_file_mapping_np *mappings, |
283 | memory_object_control_t file_control, |
284 | memory_object_size_t file_size, |
285 | void *root_dir, |
286 | uint32_t slide, |
287 | user_addr_t slide_start, |
288 | user_addr_t slide_size); |
289 | extern kern_return_t vm_shared_region_sliding_valid(uint32_t slide); |
290 | extern kern_return_t vm_shared_region_slide_sanity_check(vm_shared_region_t sr); |
291 | extern void* vm_shared_region_get_slide_info_entry(vm_shared_region_t sr); |
292 | extern void vm_commpage_init(void); |
293 | extern void vm_commpage_text_init(void); |
294 | extern kern_return_t vm_commpage_enter( |
295 | struct _vm_map *map, |
296 | struct task *task, |
297 | boolean_t is64bit); |
298 | extern kern_return_t vm_commpage_remove( |
299 | struct _vm_map *map, |
300 | struct task *task); |
301 | int vm_shared_region_slide(uint32_t, |
302 | mach_vm_offset_t, |
303 | mach_vm_size_t, |
304 | mach_vm_offset_t, |
305 | mach_vm_size_t, |
306 | mach_vm_offset_t, |
307 | memory_object_control_t); |
308 | |
309 | #endif /* KERNEL_PRIVATE */ |
310 | |
311 | #endif /* _VM_SHARED_REGION_H_ */ |
312 | |