1use 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