use super::mach_sys;
use crate::{platform::MappedRegion, Error, MemoryRegion, Object};
const VM_FLAGS_ANYWHERE: libc::c_int = 0x0001;
const VM_PROT_READ: mach_sys::vm_prot_t = 0x01;
const VM_PROT_WRITE: mach_sys::vm_prot_t = 0x02;
const VM_PROT_DEFAULT: mach_sys::vm_prot_t = VM_PROT_READ | VM_PROT_WRITE;
const MAP_MEM_NAMED_CREATE: mach_sys::vm_prot_t = 0x020000;
const VM_INHERIT_NONE: mach_sys::vm_inherit_t = 2;
impl MemoryRegion {
pub(crate) fn obj_new(size: usize) -> Option<Object> {
let mut port = 0;
let mut alloc_size = size as _;
unsafe {
let r = mach_sys::mach_make_memory_entry_64(
mach_sys::mach_task_self(),
&mut alloc_size,
0,
MAP_MEM_NAMED_CREATE | VM_PROT_DEFAULT,
&mut port,
mach_sys::MACH_PORT_NULL,
);
if r != mach_sys::KERN_SUCCESS {
return None;
}
let obj = Object::from_raw(port);
if alloc_size < size as u64 {
return None;
}
Some(obj)
}
}
}
impl MappedRegion {
pub(crate) fn map(
obj: &Object,
aligned_offset: usize,
aligned_size: usize,
) -> Result<*mut u8, Error> {
let mut address = 0;
let r = unsafe {
mach_sys::vm_map(
mach_sys::mach_task_self(),
&mut address,
aligned_size,
0,
VM_FLAGS_ANYWHERE,
obj.as_raw(),
aligned_offset,
0,
VM_PROT_DEFAULT,
VM_PROT_DEFAULT,
VM_INHERIT_NONE,
)
};
if r != mach_sys::KERN_SUCCESS {
Err(Error::MemoryRegionMapping)
} else {
Ok(address as *mut u8)
}
}
pub(crate) fn unmap(addr: *mut u8, len: usize) {
let r = unsafe { mach_sys::vm_deallocate(mach_sys::mach_task_self(), addr as _, len) };
assert_eq!(r, mach_sys::KERN_SUCCESS);
}
}
pub(crate) fn page_mask() -> usize {
unsafe { mach_sys::vm_page_mask }
}