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
9 use crate::{backend, io};
10 use backend::fd::AsFd;
11 use core::ffi::c_void;
12
13 #[cfg(any(target_os = "android", target_os = "linux"))]
14 pub use backend::mm::types::MlockFlags;
15 #[cfg(any(linux_raw, all(libc, target_os = "linux")))]
16 pub use backend::mm::types::MremapFlags;
17 pub 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]
mmap<Fd: AsFd>( ptr: *mut c_void, len: usize, prot: ProtFlags, flags: MapFlags, fd: Fd, offset: u64, ) -> io::Result<*mut c_void>36 pub 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")]
mmap_anonymous( ptr: *mut c_void, len: usize, prot: ProtFlags, flags: MapFlags, ) -> io::Result<*mut c_void>64 pub 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]
munmap(ptr: *mut c_void, len: usize) -> io::Result<()>86 pub 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]
mremap( old_address: *mut c_void, old_size: usize, new_size: usize, flags: MremapFlags, ) -> io::Result<*mut c_void>106 pub 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")]
mremap_fixed( old_address: *mut c_void, old_size: usize, new_size: usize, flags: MremapFlags, new_address: *mut c_void, ) -> io::Result<*mut c_void>132 pub 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]
mprotect(ptr: *mut c_void, len: usize, flags: MprotectFlags) -> io::Result<()>155 pub 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]
mlock(ptr: *mut c_void, len: usize) -> io::Result<()>179 pub 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")]
mlock_with(ptr: *mut c_void, len: usize, flags: MlockFlags) -> io::Result<()>206 pub 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]
munlock(ptr: *mut c_void, len: usize) -> io::Result<()>229 pub unsafe fn munlock(ptr: *mut c_void, len: usize) -> io::Result<()> {
230 backend::mm::syscalls::munlock(ptr, len)
231 }
232