]>
Commit | Line | Data |
---|---|---|
2d21ac55 A |
1 | /* |
2 | * Copyright (c) 2007 Apple Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
0a7de745 | 5 | * |
2d21ac55 A |
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. | |
0a7de745 | 12 | * |
2d21ac55 A |
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. | |
0a7de745 | 20 | * |
2d21ac55 A |
21 | * @APPLE_LICENSE_HEADER_END@ |
22 | */ | |
23 | /* | |
24 | * | |
25 | * File: vm/vm_shared_region.h | |
26 | * | |
0a7de745 | 27 | * protos and struct definitions for shared region |
2d21ac55 A |
28 | */ |
29 | ||
30 | #ifndef _VM_SHARED_REGION_H_ | |
31 | #define _VM_SHARED_REGION_H_ | |
32 | ||
0a7de745 | 33 | #ifdef KERNEL_PRIVATE |
2d21ac55 A |
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; | |
0a7de745 A |
49 | #define SHARED_REGION_DEBUG(args) \ |
50 | MACRO_BEGIN \ | |
51 | if (shared_region_debug) { \ | |
52 | kprintf args; \ | |
53 | } \ | |
2d21ac55 A |
54 | MACRO_END |
55 | #else /* DEBUG */ | |
56 | #define SHARED_REGION_DEBUG(args) | |
57 | #endif /* DEBUG */ | |
58 | ||
59 | extern int shared_region_trace_level; | |
d9a64523 A |
60 | |
61 | extern struct vm_shared_region *init_task_shared_region; | |
62 | ||
0a7de745 A |
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 | } \ | |
2d21ac55 A |
72 | MACRO_END |
73 | #define SHARED_REGION_TRACE_NONE(args) | |
0a7de745 A |
74 | #define SHARED_REGION_TRACE_ERROR(args) \ |
75 | MACRO_BEGIN \ | |
76 | SHARED_REGION_TRACE(SHARED_REGION_TRACE_ERROR_LVL, \ | |
77 | args); \ | |
2d21ac55 | 78 | MACRO_END |
0a7de745 A |
79 | #define SHARED_REGION_TRACE_INFO(args) \ |
80 | MACRO_BEGIN \ | |
81 | SHARED_REGION_TRACE(SHARED_REGION_TRACE_INFO_LVL, \ | |
82 | args); \ | |
2d21ac55 | 83 | MACRO_END |
0a7de745 A |
84 | #define SHARED_REGION_TRACE_DEBUG(args) \ |
85 | MACRO_BEGIN \ | |
86 | SHARED_REGION_TRACE(SHARED_REGION_TRACE_DEBUG_LVL, \ | |
87 | args); \ | |
2d21ac55 A |
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 | ||
0a7de745 | 98 | #define PAGE_SIZE_FOR_SR_SLIDE 4096 |
39037602 A |
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 { | |
0a7de745 A |
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; | |
39037602 A |
110 | // uint16_t toc[toc_count]; |
111 | // entrybitmap entries[entries_count]; | |
6d2010ae A |
112 | }; |
113 | ||
0a7de745 A |
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 { | |
6d2010ae A |
118 | uint8_t entry[NUM_SLIDING_BITMAPS_PER_PAGE]; |
119 | }; | |
120 | ||
39037602 A |
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 { | |
0a7de745 A |
123 | uint32_t version; |
124 | uint32_t page_size; | |
125 | uint32_t page_starts_offset; | |
126 | uint32_t page_starts_count; | |
127 | uint32_t page_extras_offset; | |
128 | uint32_t page_extras_count; | |
129 | uint64_t delta_mask; // which (contiguous) set of bits contains the delta to the next rebase location | |
130 | uint64_t value_add; | |
39037602 A |
131 | // uint16_t page_starts[page_starts_count]; |
132 | // uint16_t page_extras[page_extras_count]; | |
133 | }; | |
134 | ||
0a7de745 A |
135 | #define DYLD_CACHE_SLIDE_PAGE_ATTRS 0xC000 // high bits of uint16_t are flags |
136 | #define DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA 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 | |
39037602 | 141 | |
d9a64523 | 142 | typedef struct vm_shared_region_slide_info_entry_v3 *vm_shared_region_slide_info_entry_v3_t; |
0a7de745 A |
143 | struct vm_shared_region_slide_info_entry_v3 { |
144 | uint32_t version; // currently 3 | |
145 | uint32_t page_size; // currently 4096 (may also be 16384) | |
146 | uint32_t page_starts_count; | |
147 | uint64_t value_add; | |
148 | uint16_t page_starts[] /* page_starts_count */; | |
d9a64523 A |
149 | }; |
150 | ||
0a7de745 | 151 | #define DYLD_CACHE_SLIDE_V3_PAGE_ATTR_NO_REBASE 0xFFFF // page has no rebasing |
d9a64523 A |
152 | |
153 | ||
154 | typedef struct vm_shared_region_slide_info_entry_v4 *vm_shared_region_slide_info_entry_v4_t; | |
155 | struct vm_shared_region_slide_info_entry_v4 { | |
0a7de745 A |
156 | uint32_t version; // currently 4 |
157 | uint32_t page_size; // currently 4096 (may also be 16384) | |
158 | uint32_t page_starts_offset; | |
159 | uint32_t page_starts_count; | |
160 | uint32_t page_extras_offset; | |
161 | uint32_t page_extras_count; | |
162 | uint64_t delta_mask; // which (contiguous) set of bits contains the delta to the next rebase location (0xC0000000) | |
163 | uint64_t value_add; // base address of cache | |
164 | // uint16_t page_starts[page_starts_count]; | |
165 | // uint16_t page_extras[page_extras_count]; | |
d9a64523 A |
166 | }; |
167 | ||
168 | #define DYLD_CACHE_SLIDE4_PAGE_NO_REBASE 0xFFFF // page has no rebasing | |
169 | #define DYLD_CACHE_SLIDE4_PAGE_INDEX 0x7FFF // index into starts or extras | |
170 | #define DYLD_CACHE_SLIDE4_PAGE_USE_EXTRA 0x8000 // index is into extras array (not starts array) | |
171 | #define DYLD_CACHE_SLIDE4_PAGE_EXTRA_END 0x8000 // last chain entry for page | |
172 | ||
173 | ||
174 | ||
39037602 A |
175 | typedef union vm_shared_region_slide_info_entry *vm_shared_region_slide_info_entry_t; |
176 | union vm_shared_region_slide_info_entry { | |
0a7de745 A |
177 | uint32_t version; |
178 | struct vm_shared_region_slide_info_entry_v1 v1; | |
179 | struct vm_shared_region_slide_info_entry_v2 v2; | |
180 | struct vm_shared_region_slide_info_entry_v3 v3; | |
181 | struct vm_shared_region_slide_info_entry_v4 v4; | |
39037602 A |
182 | }; |
183 | ||
39236c6e | 184 | typedef struct vm_shared_region_slide_info *vm_shared_region_slide_info_t; |
6d2010ae | 185 | struct vm_shared_region_slide_info { |
0a7de745 A |
186 | mach_vm_address_t slid_address; |
187 | mach_vm_offset_t start; | |
188 | mach_vm_offset_t end; | |
189 | uint32_t slide; | |
cb323159 A |
190 | #if defined(HAS_APPLE_PAC) |
191 | boolean_t si_ptrauth; | |
192 | #endif /* HAS_APPLE_PAC */ | |
0a7de745 A |
193 | vm_object_t slide_object; |
194 | mach_vm_size_t slide_info_size; | |
195 | vm_shared_region_slide_info_entry_t slide_info_entry; | |
6d2010ae A |
196 | }; |
197 | ||
39236c6e A |
198 | /* address space shared region descriptor */ |
199 | struct vm_shared_region { | |
0a7de745 A |
200 | uint32_t sr_ref_count; |
201 | queue_chain_t sr_q; | |
202 | void *sr_root_dir; | |
203 | cpu_type_t sr_cpu_type; | |
204 | cpu_subtype_t sr_cpu_subtype; | |
205 | boolean_t sr_64bit; | |
206 | boolean_t sr_mapping_in_progress; | |
207 | boolean_t sr_slide_in_progress; | |
208 | boolean_t sr_persists; | |
209 | boolean_t sr_slid; | |
210 | ipc_port_t sr_mem_entry; | |
211 | mach_vm_offset_t sr_first_mapping; | |
212 | mach_vm_offset_t sr_base_address; | |
213 | mach_vm_size_t sr_size; | |
214 | mach_vm_offset_t sr_pmap_nesting_start; | |
215 | mach_vm_size_t sr_pmap_nesting_size; | |
216 | thread_call_t sr_timer_call; | |
39236c6e | 217 | struct vm_shared_region_slide_info sr_slide_info; |
0a7de745 A |
218 | uuid_t sr_uuid; |
219 | boolean_t sr_uuid_copied; | |
220 | uint32_t sr_images_count; | |
d9a64523 | 221 | struct dyld_uuid_info_64 *sr_images; |
39236c6e | 222 | }; |
6d2010ae | 223 | |
39236c6e | 224 | extern kern_return_t vm_shared_region_slide_page(vm_shared_region_slide_info_t si, |
0a7de745 A |
225 | vm_offset_t vaddr, |
226 | mach_vm_offset_t uservaddr, | |
227 | uint32_t pageIndex); | |
39236c6e | 228 | extern vm_shared_region_slide_info_t vm_shared_region_get_slide_info(vm_shared_region_t sr); |
2d21ac55 A |
229 | #else /* !MACH_KERNEL_PRIVATE */ |
230 | ||
231 | struct vm_shared_region; | |
6d2010ae A |
232 | struct vm_shared_region_slide_info; |
233 | struct vm_shared_region_slide_info_entry; | |
234 | struct slide_info_entry_toc; | |
2d21ac55 A |
235 | |
236 | #endif /* MACH_KERNEL_PRIVATE */ | |
237 | ||
238 | extern void vm_shared_region_init(void); | |
239 | extern kern_return_t vm_shared_region_enter( | |
0a7de745 A |
240 | struct _vm_map *map, |
241 | struct task *task, | |
242 | boolean_t is_64bit, | |
243 | void *fsroot, | |
244 | cpu_type_t cpu, | |
245 | cpu_subtype_t cpu_subtype); | |
2d21ac55 | 246 | extern kern_return_t vm_shared_region_remove( |
0a7de745 A |
247 | struct _vm_map *map, |
248 | struct task *task); | |
2d21ac55 | 249 | extern vm_shared_region_t vm_shared_region_get( |
0a7de745 | 250 | struct task *task); |
d9a64523 | 251 | extern vm_shared_region_t vm_shared_region_trim_and_get( |
0a7de745 | 252 | struct task *task); |
2d21ac55 | 253 | extern void vm_shared_region_deallocate( |
0a7de745 | 254 | struct vm_shared_region *shared_region); |
2d21ac55 | 255 | extern mach_vm_offset_t vm_shared_region_base_address( |
0a7de745 | 256 | struct vm_shared_region *shared_region); |
2d21ac55 | 257 | extern mach_vm_size_t vm_shared_region_size( |
0a7de745 | 258 | struct vm_shared_region *shared_region); |
2d21ac55 | 259 | extern ipc_port_t vm_shared_region_mem_entry( |
0a7de745 | 260 | struct vm_shared_region *shared_region); |
d9a64523 | 261 | extern vm_map_t vm_shared_region_vm_map( |
0a7de745 | 262 | struct vm_shared_region *shared_region); |
39236c6e | 263 | extern uint32_t vm_shared_region_get_slide( |
0a7de745 | 264 | vm_shared_region_t shared_region); |
2d21ac55 | 265 | extern void vm_shared_region_set( |
0a7de745 A |
266 | struct task *task, |
267 | struct vm_shared_region *new_shared_region); | |
2d21ac55 | 268 | extern vm_shared_region_t vm_shared_region_lookup( |
0a7de745 A |
269 | void *root_dir, |
270 | cpu_type_t cpu, | |
271 | cpu_subtype_t cpu_subtype, | |
272 | boolean_t is_64bit); | |
2d21ac55 | 273 | extern kern_return_t vm_shared_region_start_address( |
0a7de745 A |
274 | struct vm_shared_region *shared_region, |
275 | mach_vm_offset_t *start_address); | |
6d2010ae | 276 | extern void vm_shared_region_undo_mappings( |
0a7de745 A |
277 | vm_map_t sr_map, |
278 | mach_vm_offset_t sr_base_address, | |
279 | struct shared_file_mapping_np *mappings, | |
280 | unsigned int mappings_count); | |
2d21ac55 | 281 | extern kern_return_t vm_shared_region_map_file( |
0a7de745 A |
282 | struct vm_shared_region *shared_region, |
283 | unsigned int mappings_count, | |
2d21ac55 | 284 | struct shared_file_mapping_np *mappings, |
0a7de745 A |
285 | memory_object_control_t file_control, |
286 | memory_object_size_t file_size, | |
287 | void *root_dir, | |
288 | uint32_t slide, | |
289 | user_addr_t slide_start, | |
290 | user_addr_t slide_size); | |
6d2010ae | 291 | extern kern_return_t vm_shared_region_sliding_valid(uint32_t slide); |
39236c6e | 292 | extern kern_return_t vm_shared_region_slide_sanity_check(vm_shared_region_t sr); |
39236c6e | 293 | extern void* vm_shared_region_get_slide_info_entry(vm_shared_region_t sr); |
2d21ac55 | 294 | extern void vm_commpage_init(void); |
316670eb | 295 | extern void vm_commpage_text_init(void); |
2d21ac55 | 296 | extern kern_return_t vm_commpage_enter( |
0a7de745 A |
297 | struct _vm_map *map, |
298 | struct task *task, | |
299 | boolean_t is64bit); | |
2d21ac55 | 300 | extern kern_return_t vm_commpage_remove( |
0a7de745 A |
301 | struct _vm_map *map, |
302 | struct task *task); | |
303 | int vm_shared_region_slide(uint32_t, | |
304 | mach_vm_offset_t, | |
305 | mach_vm_size_t, | |
306 | mach_vm_offset_t, | |
307 | mach_vm_size_t, | |
308 | mach_vm_offset_t, | |
309 | memory_object_control_t); | |
2d21ac55 A |
310 | |
311 | #endif /* KERNEL_PRIVATE */ | |
312 | ||
0a7de745 | 313 | #endif /* _VM_SHARED_REGION_H_ */ |