mmtk/util/os/imp/unix_like/
unix_common.rs

1use crate::util::address::Address;
2use crate::util::os::*;
3use std::io::Result;
4
5impl MmapProtection {
6    fn get_native_flags(&self) -> i32 {
7        use libc::{PROT_EXEC, PROT_NONE, PROT_READ, PROT_WRITE};
8        match self {
9            Self::ReadWrite => PROT_READ | PROT_WRITE,
10            Self::ReadWriteExec => PROT_READ | PROT_WRITE | PROT_EXEC,
11            Self::NoAccess => PROT_NONE,
12        }
13    }
14}
15
16pub fn mmap(
17    start: Address,
18    size: usize,
19    strategy: MmapStrategy,
20    annotation: &MmapAnnotation<'_>,
21) -> MmapResult<Address> {
22    let ptr = start.to_mut_ptr();
23    let prot = strategy.prot.get_native_flags();
24    let flags = strategy.get_posix_mmap_flags();
25    wrap_libc_call(
26        &|| unsafe { libc::mmap(start.to_mut_ptr(), size, prot, flags, -1, 0) },
27        ptr,
28    )
29    .map_err(|e| MmapError::new(start, size, annotation, e))?;
30    Ok(start)
31}
32
33pub fn is_mmap_oom(os_errno: i32) -> bool {
34    os_errno == libc::ENOMEM
35}
36
37pub fn munmap(start: Address, size: usize) -> Result<()> {
38    wrap_libc_call(&|| unsafe { libc::munmap(start.to_mut_ptr(), size) }, 0)
39}
40
41pub fn mprotect(start: Address, size: usize, prot: MmapProtection) -> Result<()> {
42    wrap_libc_call(
43        &|| unsafe { libc::mprotect(start.to_mut_ptr(), size, prot.get_native_flags()) },
44        0,
45    )
46}
47
48pub type ProcessIDType = libc::pid_t;
49pub type ThreadIDType = libc::pthread_t;
50
51pub fn get_process_id() -> Result<ProcessIDType> {
52    Ok(unsafe { libc::getpid() })
53}
54
55pub fn get_thread_id() -> Result<ThreadIDType> {
56    Ok(unsafe { libc::pthread_self() })
57}
58
59pub fn wrap_libc_call<T: PartialEq>(f: &dyn Fn() -> T, expect: T) -> Result<()> {
60    let ret = f();
61    if ret == expect {
62        Ok(())
63    } else {
64        Err(std::io::Error::last_os_error())
65    }
66}