mach_sys/
vm.rs

1//! This module roughly corresponds to `mach/mach_vm.defs`.
2
3use crate::ffi::{c_int, policy_t};
4
5use crate::boolean::boolean_t;
6use crate::kern_return::kern_return_t;
7use crate::mach_types::{
8    mem_entry_name_port_t,
9    vm_task_entry_t
10};
11use crate::memory_object_types::{
12    memory_object_offset_t,
13    memory_object_size_t
14};
15use crate::message::mach_msg_type_number_t;
16use crate::port::mach_port_t;
17use crate::vm_attributes::{
18    vm_machine_attribute_t,
19    vm_machine_attribute_val_t
20};
21use crate::vm_behavior::vm_behavior_t;
22use crate::vm_inherit::vm_inherit_t;
23use crate::vm_prot::vm_prot_t;
24use crate::vm_purgable::vm_purgable_t;
25use crate::vm_region::{
26    mach_vm_read_entry_t,
27    vm_page_info_flavor_t,
28    vm_page_info_t,
29    vm_region_flavor_t,
30    vm_region_info_t,
31    vm_region_recurse_info_t,
32};
33use crate::vm_sync::vm_sync_t;
34use crate::clock_types::time_value_t;
35use crate::vm_types::{
36    integer_t,
37    mach_vm_address_t,
38    mach_vm_offset_t,
39    mach_vm_size_t,
40    natural_t,
41    vm_map_t,
42    vm_offset_t,
43    vm_size_t,
44};
45
46extern "C" {
47    pub fn mach_vm_allocate(
48        target:  vm_task_entry_t,
49        address: *mut mach_vm_address_t,
50        size:    mach_vm_size_t,
51        flags:   c_int,
52    ) -> kern_return_t;
53
54    pub fn mach_vm_deallocate(
55        target:  vm_task_entry_t,
56        address: mach_vm_address_t,
57        size:    mach_vm_size_t,
58    ) -> kern_return_t;
59
60    pub fn mach_vm_protect(
61        target_task:    vm_task_entry_t,
62        address:        mach_vm_address_t,
63        size:           mach_vm_size_t,
64        set_maximum:    boolean_t,
65        new_protection: vm_prot_t,
66    ) -> kern_return_t;
67
68    pub fn mach_vm_inherit(
69        target_task:     vm_task_entry_t,
70        address:         mach_vm_address_t,
71        size:            mach_vm_size_t,
72        new_inheritance: vm_inherit_t,
73    ) -> kern_return_t;
74
75    pub fn mach_vm_read(
76        target_task: vm_task_entry_t,
77        address:     mach_vm_address_t,
78        size:        mach_vm_size_t,
79        data:        *mut vm_offset_t,
80        dataCnt:     *mut mach_msg_type_number_t,
81    ) -> kern_return_t;
82
83    #[allow(improper_ctypes)]
84    pub fn mach_vm_read_list(
85        target_task: vm_task_entry_t,
86        data_list:   mach_vm_read_entry_t,
87        count:       natural_t,
88    ) -> kern_return_t;
89
90    pub fn mach_vm_write(
91        target_task: vm_map_t,
92        address:     mach_vm_address_t,
93        data:        vm_offset_t,
94        dataCnt:     mach_msg_type_number_t,
95    ) -> kern_return_t;
96
97    pub fn mach_vm_copy(
98        target_task:    vm_task_entry_t,
99        source_address: mach_vm_address_t,
100        size:           mach_vm_size_t,
101        dest_address:   mach_vm_address_t,
102    ) -> kern_return_t;
103
104    pub fn mach_vm_read_overwrite(
105        target_task: vm_task_entry_t,
106        address:     mach_vm_address_t,
107        size:        mach_vm_size_t,
108        data:        mach_vm_address_t,
109        outsize:     *mut mach_vm_size_t,
110    ) -> kern_return_t;
111
112    pub fn mach_vm_msync(
113        target_task: vm_task_entry_t,
114        address:     mach_vm_address_t,
115        size:        mach_vm_size_t,
116        sync_flags:  vm_sync_t,
117    ) -> kern_return_t;
118
119    pub fn mach_vm_behavior_set(
120        target_task:  vm_task_entry_t,
121        address:      mach_vm_address_t,
122        size:         mach_vm_size_t,
123        new_behavior: vm_behavior_t,
124    ) -> kern_return_t;
125
126    pub fn mach_vm_map(
127        target_task:    vm_task_entry_t,
128        inout:          *mut mach_vm_address_t,
129        size:           mach_vm_size_t,
130        mask:           mach_vm_offset_t,
131        flags:          c_int,
132        object:         mem_entry_name_port_t,
133        offset:         memory_object_offset_t,
134        copy:           boolean_t,
135        cur_protection: vm_prot_t,
136        max_protection: vm_prot_t,
137        inheritance:    vm_inherit_t,
138    ) -> kern_return_t;
139
140    pub fn mach_vm_machine_attribute(
141        target_task: vm_task_entry_t,
142        address:     mach_vm_address_t,
143        size:        mach_vm_size_t,
144        attribute:   vm_machine_attribute_t,
145        value:       *mut vm_machine_attribute_val_t,
146    ) -> kern_return_t;
147
148    pub fn mach_vm_remap(
149        target_task:    vm_task_entry_t,
150        target_address: *mut mach_vm_address_t,
151        size:           mach_vm_size_t,
152        mask:           mach_vm_offset_t,
153        flags:          c_int,
154        src_task:       vm_task_entry_t,
155        src_address:    mach_vm_address_t,
156        copy:           boolean_t,
157        cur_protection: *mut vm_prot_t,
158        out:            *mut vm_prot_t,
159        inheritance:    vm_inherit_t,
160    ) -> kern_return_t;
161
162    pub fn mach_vm_page_query(
163        target_map:  vm_map_t,
164        offset:      mach_vm_offset_t,
165        disposition: *mut integer_t,
166        ref_count:   *mut integer_t,
167    ) -> kern_return_t;
168
169    pub fn mach_vm_region_recurse(
170        target_task:   vm_task_entry_t,
171        address:       *mut mach_vm_address_t,
172        size:          *mut mach_vm_size_t,
173        nesting_depth: *mut natural_t,
174        info:          vm_region_recurse_info_t,
175        infoCnt:       *mut mach_msg_type_number_t,
176    ) -> kern_return_t;
177
178    pub fn mach_vm_region(
179        target_task: vm_task_entry_t,
180        address:     *mut mach_vm_address_t,
181        size:        *mut mach_vm_size_t,
182        flavor:      vm_region_flavor_t,
183        info:        vm_region_info_t,
184        infoCnt:     *mut mach_msg_type_number_t,
185        object_name: *mut mach_port_t,
186    ) -> kern_return_t;
187
188    pub fn mach_make_memory_entry(
189        target_task:   vm_map_t,
190        size:          *mut vm_size_t,
191        offset:        vm_offset_t,
192        permission:    vm_prot_t,
193        object_handle: *mut mem_entry_name_port_t,
194        parent_handle: mem_entry_name_port_t,
195    ) -> kern_return_t;
196
197    pub fn mach_make_memory_entry_64(
198        target_task:   vm_map_t,
199        size:          *mut memory_object_size_t,
200        offset:        memory_object_offset_t,
201        permission:    vm_prot_t,
202        object_handle: *mut mach_port_t,
203        parent_entry:  mem_entry_name_port_t,
204    ) -> kern_return_t;
205
206    pub fn mach_vm_purgable_control(
207        target_task: vm_task_entry_t,
208        address:     mach_vm_address_t,
209        control:     vm_purgable_t,
210        state:       *mut c_int,
211    ) -> kern_return_t;
212
213    pub fn mach_vm_page_info(
214        target_task: vm_task_entry_t,
215        address:     mach_vm_address_t,
216        flavor:      vm_page_info_flavor_t,
217        info:        vm_page_info_t,
218        infoCnt:     *mut mach_msg_type_number_t,
219    ) -> kern_return_t;
220}
221
222pub type thread_basic_info_data = thread_basic_info_t;
223
224#[repr(C)]
225#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
226pub struct thread_basic_info_t {
227    pub user_time:     time_value_t,
228    pub system_time:   time_value_t,
229    pub cpu_usage:     integer_t,
230    pub policy:        policy_t,
231    pub run_state:     integer_t,
232    pub flags:         integer_t,
233    pub suspend_count: integer_t,
234    pub sleep_time:    integer_t,
235}
236
237#[cfg(test)]
238mod tests {
239    use super::*;
240
241    use crate::kern_return::KERN_SUCCESS;
242    use crate::traps::mach_task_self;
243    use crate::vm_statistics::VM_FLAGS_ANYWHERE;
244
245    #[test]
246    fn mach_vm_allocate_sanity() {
247        unsafe {
248            let size = 0x100;
249            let task = mach_task_self();
250
251            let mut address: mach_vm_address_t = 0;
252            assert_eq!(mach_vm_allocate(task, &mut address, size, VM_FLAGS_ANYWHERE), KERN_SUCCESS);
253            assert_eq!(mach_vm_deallocate(task, address, size), KERN_SUCCESS);
254        }
255    }
256
257    #[test]
258    fn mach_vm_region_sanity() {
259        use core::mem;
260
261        use crate::vm_prot::{VM_PROT_EXECUTE, VM_PROT_READ};
262        use crate::vm_region::{vm_region_basic_info_64, VM_REGION_BASIC_INFO_64};
263
264        unsafe {
265            let mut size = 0x10;
266            let mut object_name = 0;
267            #[allow(clippy::fn_to_numeric_cast)]
268            let mut address = mach_vm_region_sanity as mach_vm_address_t;
269            let mut info: vm_region_basic_info_64 = mem::zeroed();
270            let mut info_size = vm_region_basic_info_64::count();
271
272            let result = mach_vm_region(
273                mach_task_self(),
274                &mut address,
275                &mut size,
276                VM_REGION_BASIC_INFO_64,
277                (&mut info as *mut _) as vm_region_info_t,
278                &mut info_size,
279                &mut object_name,
280            );
281            assert_eq!(result, KERN_SUCCESS);
282            assert_eq!(info.protection, VM_PROT_READ | VM_PROT_EXECUTE);
283        }
284    }
285}
286