1//! The `mmap` API. 2//! 3//! # Safety 4//! 5//! `mmap` and related functions manipulate raw pointers and have special 6//! semantics and are wildly unsafe. 7#![allow(unsafe_code)] 8 9use crate::{backend, io}; 10use backend::fd::AsFd; 11use core::ffi::c_void; 12 13#[cfg(any(target_os = "android", target_os = "linux"))] 14pub use backend::mm::types::MlockFlags; 15#[cfg(any(linux_raw, all(libc, target_os = "linux")))] 16pub use backend::mm::types::MremapFlags; 17pub use backend::mm::types::{MapFlags, MprotectFlags, ProtFlags}; 18 19/// `mmap(ptr, len, prot, flags, fd, offset)`—Create a file-backed memory 20/// mapping. 21/// 22/// For anonymous mappings (`MAP_ANON`/`MAP_ANONYMOUS`), see 23/// [`mmap_anonymous`]. 24/// 25/// # Safety 26/// 27/// Raw pointers and lots of special semantics. 28/// 29/// # References 30/// - [POSIX] 31/// - [Linux] 32/// 33/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/mmap.html 34/// [Linux]: https://man7.org/linux/man-pages/man2/mmap.2.html 35#[inline] 36pub unsafe fn mmap<Fd: AsFd>( 37 ptr: *mut c_void, 38 len: usize, 39 prot: ProtFlags, 40 flags: MapFlags, 41 fd: Fd, 42 offset: u64, 43) -> io::Result<*mut c_void> { 44 backend::mm::syscalls::mmap(ptr, len, prot, flags, fd.as_fd(), offset) 45} 46 47/// `mmap(ptr, len, prot, MAP_ANONYMOUS | flags, -1, 0)`—Create an anonymous 48/// memory mapping. 49/// 50/// For file-backed mappings, see [`mmap`]. 51/// 52/// # Safety 53/// 54/// Raw pointers and lots of special semantics. 55/// 56/// # References 57/// - [POSIX] 58/// - [Linux] 59/// 60/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/mmap.html 61/// [Linux]: https://man7.org/linux/man-pages/man2/mmap.2.html 62#[inline] 63#[doc(alias = "mmap")] 64pub unsafe fn mmap_anonymous( 65 ptr: *mut c_void, 66 len: usize, 67 prot: ProtFlags, 68 flags: MapFlags, 69) -> io::Result<*mut c_void> { 70 backend::mm::syscalls::mmap_anonymous(ptr, len, prot, flags) 71} 72 73/// `munmap(ptr, len)` 74/// 75/// # Safety 76/// 77/// Raw pointers and lots of special semantics. 78/// 79/// # References 80/// - [POSIX] 81/// - [Linux] 82/// 83/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/munmap.html 84/// [Linux]: https://man7.org/linux/man-pages/man2/munmap.2.html 85#[inline] 86pub unsafe fn munmap(ptr: *mut c_void, len: usize) -> io::Result<()> { 87 backend::mm::syscalls::munmap(ptr, len) 88} 89 90/// `mremap(old_address, old_size, new_size, flags)`—Resize, modify, 91/// and/or move a memory mapping. 92/// 93/// For moving a mapping to a fixed address (`MREMAP_FIXED`), see 94/// [`mremap_fixed`]. 95/// 96/// # Safety 97/// 98/// Raw pointers and lots of special semantics. 99/// 100/// # References 101/// - [Linux] 102/// 103/// [Linux]: https://man7.org/linux/man-pages/man2/mremap.2.html 104#[cfg(any(linux_raw, all(libc, target_os = "linux")))] 105#[inline] 106pub unsafe fn mremap( 107 old_address: *mut c_void, 108 old_size: usize, 109 new_size: usize, 110 flags: MremapFlags, 111) -> io::Result<*mut c_void> { 112 backend::mm::syscalls::mremap(old_address, old_size, new_size, flags) 113} 114 115/// `mremap(old_address, old_size, new_size, MREMAP_FIXED | flags)`—Resize, 116/// modify, and/or move a memory mapping to a specific address. 117/// 118/// For `mremap` without moving to a specific address, see [`mremap`]. 119/// [`mremap_fixed`]. 120/// 121/// # Safety 122/// 123/// Raw pointers and lots of special semantics. 124/// 125/// # References 126/// - [Linux] 127/// 128/// [Linux]: https://man7.org/linux/man-pages/man2/mremap.2.html 129#[cfg(any(linux_raw, all(libc, target_os = "linux")))] 130#[inline] 131#[doc(alias = "mremap")] 132pub unsafe fn mremap_fixed( 133 old_address: *mut c_void, 134 old_size: usize, 135 new_size: usize, 136 flags: MremapFlags, 137 new_address: *mut c_void, 138) -> io::Result<*mut c_void> { 139 backend::mm::syscalls::mremap_fixed(old_address, old_size, new_size, flags, new_address) 140} 141 142/// `mprotect(ptr, len, flags)` 143/// 144/// # Safety 145/// 146/// Raw pointers and lots of special semantics. 147/// 148/// # References 149/// - [POSIX] 150/// - [Linux] 151/// 152/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/mprotect.html 153/// [Linux]: https://man7.org/linux/man-pages/man2/mprotect.2.html 154#[inline] 155pub unsafe fn mprotect(ptr: *mut c_void, len: usize, flags: MprotectFlags) -> io::Result<()> { 156 backend::mm::syscalls::mprotect(ptr, len, flags) 157} 158 159/// `mlock(ptr, len)`—Lock memory into RAM. 160/// 161/// # Safety 162/// 163/// This function operates on raw pointers, but it should only be used on 164/// memory which the caller owns. Technically, locking memory shouldn't violate 165/// any invariants, but since unlocking it can violate invariants, this 166/// function is also unsafe for symmetry. 167/// 168/// Some implementations implicitly round the memory region out to the nearest 169/// page boundaries, so this function may lock more memory than explicitly 170/// requested if the memory isn't page-aligned. 171/// 172/// # References 173/// - [POSIX] 174/// - [Linux] 175/// 176/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/mlock.html 177/// [Linux]: https://man7.org/linux/man-pages/man2/mlock.2.html 178#[inline] 179pub unsafe fn mlock(ptr: *mut c_void, len: usize) -> io::Result<()> { 180 backend::mm::syscalls::mlock(ptr, len) 181} 182 183/// `mlock2(ptr, len, flags)`—Lock memory into RAM, with 184/// flags. 185/// 186/// `mlock_with` is the same as [`mlock`] but adds an additional flags operand. 187/// 188/// # Safety 189/// 190/// This function operates on raw pointers, but it should only be used on 191/// memory which the caller owns. Technically, locking memory shouldn't violate 192/// any invariants, but since unlocking it can violate invariants, this 193/// function is also unsafe for symmetry. 194/// 195/// Some implementations implicitly round the memory region out to the nearest 196/// page boundaries, so this function may lock more memory than explicitly 197/// requested if the memory isn't page-aligned. 198/// 199/// # References 200/// - [Linux] 201/// 202/// [Linux]: https://man7.org/linux/man-pages/man2/mlock2.2.html 203#[cfg(any(target_os = "android", target_os = "linux"))] 204#[inline] 205#[doc(alias = "mlock2")] 206pub unsafe fn mlock_with(ptr: *mut c_void, len: usize, flags: MlockFlags) -> io::Result<()> { 207 backend::mm::syscalls::mlock_with(ptr, len, flags) 208} 209 210/// `munlock(ptr, len)`—Unlock memory. 211/// 212/// # Safety 213/// 214/// This function operates on raw pointers, but it should only be used on 215/// memory which the caller owns, to avoid compromising the `mlock` invariants 216/// of other unrelated code in the process. 217/// 218/// Some implementations implicitly round the memory region out to the nearest 219/// page boundaries, so this function may unlock more memory than explicitly 220/// requested if the memory isn't page-aligned. 221/// 222/// # References 223/// - [POSIX] 224/// - [Linux] 225/// 226/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/munlock.html 227/// [Linux]: https://man7.org/linux/man-pages/man2/munlock.2.html 228#[inline] 229pub unsafe fn munlock(ptr: *mut c_void, len: usize) -> io::Result<()> { 230 backend::mm::syscalls::munlock(ptr, len) 231} 232