2 * Copyright (c) 2007 Apple Inc. All rights reserved.
4 * @APPLE_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. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
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.
21 * @APPLE_LICENSE_HEADER_END@
25 * File: vm/vm_shared_region.h
27 * protos and struct definitions for shared region
30 #ifndef _VM_SHARED_REGION_H_
31 #define _VM_SHARED_REGION_H_
35 #include <mach/vm_prot.h>
36 #include <mach/mach_types.h>
37 #include <mach/shared_region.h>
39 #include <kern/kern_types.h>
40 #include <kern/macro_help.h>
42 #include <vm/vm_map.h>
44 extern int shared_region_version
;
45 extern int shared_region_persistence
;
48 extern int shared_region_debug
;
49 #define SHARED_REGION_DEBUG(args) \
51 if (shared_region_debug) { \
56 #define SHARED_REGION_DEBUG(args)
59 extern int shared_region_trace_level
;
61 extern struct vm_shared_region
*init_task_shared_region
;
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) \
69 if (shared_region_trace_level >= level) { \
73 #define SHARED_REGION_TRACE_NONE(args)
74 #define SHARED_REGION_TRACE_ERROR(args) \
76 SHARED_REGION_TRACE(SHARED_REGION_TRACE_ERROR_LVL, \
79 #define SHARED_REGION_TRACE_INFO(args) \
81 SHARED_REGION_TRACE(SHARED_REGION_TRACE_INFO_LVL, \
84 #define SHARED_REGION_TRACE_DEBUG(args) \
86 SHARED_REGION_TRACE(SHARED_REGION_TRACE_DEBUG_LVL, \
90 typedef struct vm_shared_region
*vm_shared_region_t
;
92 #ifdef MACH_KERNEL_PRIVATE
94 #include <kern/queue.h>
95 #include <vm/vm_object.h>
96 #include <vm/memory_object.h>
98 #define PAGE_SIZE_FOR_SR_SLIDE 4096
100 /* Documentation for the slide info format can be found in the dyld project in
101 * the file 'launch-cache/dyld_cache_format.h'. */
104 typedef struct vm_shared_region_slide_info_entry_v2
*vm_shared_region_slide_info_entry_v2_t
;
105 struct vm_shared_region_slide_info_entry_v2
{
108 uint32_t page_starts_offset
;
109 uint32_t page_starts_count
;
110 uint32_t page_extras_offset
;
111 uint32_t page_extras_count
;
112 uint64_t delta_mask
; // which (contiguous) set of bits contains the delta to the next rebase location
114 // uint16_t page_starts[page_starts_count];
115 // uint16_t page_extras[page_extras_count];
118 #define DYLD_CACHE_SLIDE_PAGE_ATTRS 0xC000 // high bits of uint16_t are flags
119 #define DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA 0x8000 // index is into extras array (not starts array)
120 #define DYLD_CACHE_SLIDE_PAGE_ATTR_NO_REBASE 0x4000 // page has no rebasing
121 #define DYLD_CACHE_SLIDE_PAGE_ATTR_END 0x8000 // last chain entry for page
122 #define DYLD_CACHE_SLIDE_PAGE_VALUE 0x3FFF // bitwise negation of DYLD_CACHE_SLIDE_PAGE_ATTRS
123 #define DYLD_CACHE_SLIDE_PAGE_OFFSET_SHIFT 2
125 typedef struct vm_shared_region_slide_info_entry_v3
*vm_shared_region_slide_info_entry_v3_t
;
126 struct vm_shared_region_slide_info_entry_v3
{
127 uint32_t version
; // currently 3
128 uint32_t page_size
; // currently 4096 (may also be 16384)
129 uint32_t page_starts_count
;
131 uint16_t page_starts
[] /* page_starts_count */;
134 #define DYLD_CACHE_SLIDE_V3_PAGE_ATTR_NO_REBASE 0xFFFF // page has no rebasing
137 typedef struct vm_shared_region_slide_info_entry_v4
*vm_shared_region_slide_info_entry_v4_t
;
138 struct vm_shared_region_slide_info_entry_v4
{
139 uint32_t version
; // currently 4
140 uint32_t page_size
; // currently 4096 (may also be 16384)
141 uint32_t page_starts_offset
;
142 uint32_t page_starts_count
;
143 uint32_t page_extras_offset
;
144 uint32_t page_extras_count
;
145 uint64_t delta_mask
; // which (contiguous) set of bits contains the delta to the next rebase location (0xC0000000)
146 uint64_t value_add
; // base address of cache
147 // uint16_t page_starts[page_starts_count];
148 // uint16_t page_extras[page_extras_count];
151 #define DYLD_CACHE_SLIDE4_PAGE_NO_REBASE 0xFFFF // page has no rebasing
152 #define DYLD_CACHE_SLIDE4_PAGE_INDEX 0x7FFF // index into starts or extras
153 #define DYLD_CACHE_SLIDE4_PAGE_USE_EXTRA 0x8000 // index is into extras array (not starts array)
154 #define DYLD_CACHE_SLIDE4_PAGE_EXTRA_END 0x8000 // last chain entry for page
158 typedef union vm_shared_region_slide_info_entry
*vm_shared_region_slide_info_entry_t
;
159 union vm_shared_region_slide_info_entry
{
161 struct vm_shared_region_slide_info_entry_v2 v2
;
162 struct vm_shared_region_slide_info_entry_v3 v3
;
163 struct vm_shared_region_slide_info_entry_v4 v4
;
166 #define MIN_SLIDE_INFO_SIZE \
167 MIN(sizeof(struct vm_shared_region_slide_info_entry_v2), \
168 MIN(sizeof(struct vm_shared_region_slide_info_entry_v3), \
169 sizeof(struct vm_shared_region_slide_info_entry_v4)))
172 * This is the information used by the shared cache pager for sub-sections
173 * which must be modified for relocations and/or pointer authentications
174 * before it can be used. The shared_region_pager gets source pages from
175 * the shared cache file and modifies them -- see shared_region_pager_data_request().
177 * A single pager may be used from multiple shared regions provided:
178 * - same si_slide_object, si_start, si_end, si_slide, si_ptrauth and si_jop_key
179 * - The size and contents of si_slide_info_entry are the same.
181 typedef struct vm_shared_region_slide_info
{
182 uint32_t si_slide
; /* the distance that the file data is relocated */
184 #if __has_feature(ptrauth_calls)
187 struct vm_shared_region
*si_shared_region
; /* so we can ref/dealloc for authenticated slide info */
188 #endif /* __has_feature(ptrauth_calls) */
189 mach_vm_address_t si_slid_address
;
190 mach_vm_offset_t si_start
; /* start offset in si_slide_object */
191 mach_vm_offset_t si_end
;
192 vm_object_t si_slide_object
; /* The source object for the pages to be modified */
193 mach_vm_size_t si_slide_info_size
; /* size of dyld provided relocation information */
194 vm_shared_region_slide_info_entry_t si_slide_info_entry
; /* dyld provided relocation information */
195 } *vm_shared_region_slide_info_t
;
198 * Data structure that represents a unique shared cache region.
200 struct vm_shared_region
{
201 uint32_t sr_ref_count
;
205 cpu_type_t sr_cpu_type
;
206 cpu_subtype_t sr_cpu_subtype
;
207 ipc_port_t sr_mem_entry
;
208 mach_vm_offset_t sr_first_mapping
;
209 mach_vm_offset_t sr_base_address
;
210 mach_vm_size_t sr_size
;
211 mach_vm_offset_t sr_pmap_nesting_start
;
212 mach_vm_size_t sr_pmap_nesting_size
;
213 thread_call_t sr_timer_call
;
216 bool sr_mapping_in_progress
;
217 bool sr_slide_in_progress
;
221 bool sr_stale
; /* This region should never be used again. */
223 #if __has_feature(ptrauth_calls)
224 bool sr_reslide
; /* Special shared region for suspected attacked processes */
225 #define NUM_SR_AUTH_SECTIONS 2
226 vm_shared_region_slide_info_t sr_auth_section
[NUM_SR_AUTH_SECTIONS
];
227 uint_t sr_num_auth_section
;
228 #endif /* __has_feature(ptrauth_calls) */
230 uint32_t sr_images_count
;
231 struct dyld_uuid_info_64
*sr_images
;
234 extern kern_return_t
vm_shared_region_slide_page(
235 vm_shared_region_slide_info_t si
,
237 mach_vm_offset_t uservaddr
,
240 extern uint64_t shared_region_find_key(char *shared_region_id
);
241 #else /* !MACH_KERNEL_PRIVATE */
243 struct vm_shared_region
;
244 struct vm_shared_region_slide_info
;
245 struct vm_shared_region_slide_info_entry
;
246 struct slide_info_entry_toc
;
248 #endif /* MACH_KERNEL_PRIVATE */
250 struct _sr_file_mappings
{
252 uint32_t mappings_count
;
253 struct shared_file_mapping_slide_np
*mappings
;
257 memory_object_size_t file_size
;
258 memory_object_control_t file_control
;
261 extern void vm_shared_region_init(void);
262 extern kern_return_t
vm_shared_region_enter(
268 cpu_subtype_t cpu_subtype
,
270 extern kern_return_t
vm_shared_region_remove(
273 extern vm_shared_region_t
vm_shared_region_get(
275 extern vm_shared_region_t
vm_shared_region_trim_and_get(
277 extern void vm_shared_region_deallocate(
278 struct vm_shared_region
*shared_region
);
279 extern mach_vm_offset_t
vm_shared_region_base_address(
280 struct vm_shared_region
*shared_region
);
281 extern mach_vm_size_t
vm_shared_region_size(
282 struct vm_shared_region
*shared_region
);
283 extern ipc_port_t
vm_shared_region_mem_entry(
284 struct vm_shared_region
*shared_region
);
285 extern vm_map_t
vm_shared_region_vm_map(
286 struct vm_shared_region
*shared_region
);
287 extern void vm_shared_region_set(
289 struct vm_shared_region
*new_shared_region
);
290 extern vm_shared_region_t
vm_shared_region_lookup(
293 cpu_subtype_t cpu_subtype
,
296 extern kern_return_t
vm_shared_region_start_address(
297 struct vm_shared_region
*shared_region
,
298 mach_vm_offset_t
*start_address
);
299 extern void vm_shared_region_undo_mappings(
301 mach_vm_offset_t sr_base_address
,
302 struct _sr_file_mappings
*srf_mappings
,
303 struct _sr_file_mappings
*srf_mappings_count
,
304 unsigned int mappings_count
);
305 __attribute__((noinline
))
306 extern kern_return_t
vm_shared_region_map_file(
307 struct vm_shared_region
*shared_region
,
309 int sr_mappings_count
,
310 struct _sr_file_mappings
*sr_mappings
);
311 extern kern_return_t
vm_shared_region_sliding_valid(uint32_t slide
);
312 extern void vm_commpage_init(void);
313 extern void vm_commpage_text_init(void);
314 extern kern_return_t
vm_commpage_enter(
318 extern kern_return_t
vm_commpage_remove(
321 int vm_shared_region_slide(uint32_t,
327 memory_object_control_t
,
329 extern void vm_shared_region_pivot(void);
330 extern void vm_shared_region_reslide_stale(void);
331 #if __has_feature(ptrauth_calls)
332 __attribute__((noinline
))
333 extern kern_return_t
vm_shared_region_auth_remap(vm_shared_region_t sr
);
334 #endif /* __has_feature(ptrauth_calls) */
335 extern void vm_shared_region_reference(vm_shared_region_t sr
);
337 #endif /* KERNEL_PRIVATE */
339 #endif /* _VM_SHARED_REGION_H_ */