extern crate mach;
use self::mach::vm_prot::*;
use Protection;
use Region;
use error::*;
fn prot_from_native(protection: vm_prot_t) -> Protection {
let mut result = Protection::None;
if (protection & VM_PROT_READ) == VM_PROT_READ {
result |= Protection::Read;
}
if (protection & VM_PROT_WRITE) == VM_PROT_WRITE {
result |= Protection::Write;
}
if (protection & VM_PROT_EXECUTE) == VM_PROT_EXECUTE {
result |= Protection::Execute;
}
result
}
pub fn get_region(base: *const u8) -> Result<Region> {
extern crate mach;
const SHARE_MODES: [u8; 3] = [
mach::vm_region::SM_SHARED,
mach::vm_region::SM_TRUESHARED,
mach::vm_region::SM_SHARED_ALIASED,
];
let mut region_base = base as mach::vm_types::mach_vm_address_t;
let mut region_size: mach::vm_types::mach_vm_size_t = 0;
let mut info: mach::vm_region::vm_region_extended_info = unsafe { ::std::mem::zeroed() };
let result = unsafe {
let mut object_name: mach::port::mach_port_t = 0;
mach::vm::mach_vm_region(
mach::traps::mach_task_self(),
&mut region_base,
&mut region_size,
mach::vm_region::VM_REGION_EXTENDED_INFO,
(&mut info as *mut _) as mach::vm_region::vm_region_info_t,
&mut mach::vm_region::vm_region_extended_info::count(),
&mut object_name,
)
};
match result {
mach::kern_return::KERN_SUCCESS => {
if region_base > base as mach::vm_types::mach_vm_address_t {
Err(Error::Free)
} else {
Ok(Region {
base: region_base as *const _,
guarded: (info.user_tag == mach::vm_statistics::VM_MEMORY_GUARD),
protection: prot_from_native(info.protection),
shared: SHARE_MODES.contains(&info.share_mode),
size: region_size as usize,
})
}
},
_ => Err(Error::MachRegion(result)),
}
}