]>
Commit | Line | Data |
---|---|---|
064997fb FG |
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 | ||
487cf647 FG |
9 | use crate::{backend, io}; |
10 | use backend::fd::AsFd; | |
064997fb | 11 | use core::ffi::c_void; |
064997fb FG |
12 | |
13 | #[cfg(any(target_os = "android", target_os = "linux"))] | |
487cf647 | 14 | pub use backend::mm::types::MlockFlags; |
064997fb | 15 | #[cfg(any(linux_raw, all(libc, target_os = "linux")))] |
487cf647 FG |
16 | pub use backend::mm::types::MremapFlags; |
17 | pub use backend::mm::types::{MapFlags, MprotectFlags, ProtFlags}; | |
064997fb FG |
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] | |
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> { | |
487cf647 | 44 | backend::mm::syscalls::mmap(ptr, len, prot, flags, fd.as_fd(), offset) |
064997fb FG |
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")] | |
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> { | |
487cf647 | 70 | backend::mm::syscalls::mmap_anonymous(ptr, len, prot, flags) |
064997fb FG |
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] | |
86 | pub unsafe fn munmap(ptr: *mut c_void, len: usize) -> io::Result<()> { | |
487cf647 | 87 | backend::mm::syscalls::munmap(ptr, len) |
064997fb FG |
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] | |
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> { | |
487cf647 | 112 | backend::mm::syscalls::mremap(old_address, old_size, new_size, flags) |
064997fb FG |
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")] | |
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> { | |
487cf647 | 139 | backend::mm::syscalls::mremap_fixed(old_address, old_size, new_size, flags, new_address) |
064997fb FG |
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] | |
155 | pub unsafe fn mprotect(ptr: *mut c_void, len: usize, flags: MprotectFlags) -> io::Result<()> { | |
487cf647 | 156 | backend::mm::syscalls::mprotect(ptr, len, flags) |
064997fb FG |
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] | |
179 | pub unsafe fn mlock(ptr: *mut c_void, len: usize) -> io::Result<()> { | |
487cf647 | 180 | backend::mm::syscalls::mlock(ptr, len) |
064997fb FG |
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")] | |
206 | pub unsafe fn mlock_with(ptr: *mut c_void, len: usize, flags: MlockFlags) -> io::Result<()> { | |
487cf647 | 207 | backend::mm::syscalls::mlock_with(ptr, len, flags) |
064997fb FG |
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] | |
229 | pub unsafe fn munlock(ptr: *mut c_void, len: usize) -> io::Result<()> { | |
487cf647 | 230 | backend::mm::syscalls::munlock(ptr, len) |
064997fb | 231 | } |