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