xref: /third_party/rust/crates/rustix/src/mm/mmap.rs (revision b8a62b91)
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