]> git.proxmox.com Git - rustc.git/blame - vendor/rustix-0.36.5/src/backend/libc/mm/syscalls.rs
New upstream version 1.70.0+dfsg2
[rustc.git] / vendor / rustix-0.36.5 / src / backend / libc / mm / syscalls.rs
CommitLineData
353b0b11
FG
1//! libc syscalls supporting `rustix::mm`.
2
3use super::super::c;
4#[cfg(any(target_os = "android", target_os = "linux"))]
5use super::super::conv::syscall_ret_owned_fd;
6use super::super::conv::{borrowed_fd, no_fd, ret};
7use super::super::offset::libc_mmap;
8#[cfg(not(target_os = "redox"))]
9use super::types::Advice;
10#[cfg(target_os = "linux")]
11use super::types::MremapFlags;
12use super::types::{MapFlags, MprotectFlags, MsyncFlags, ProtFlags};
13#[cfg(any(target_os = "android", target_os = "linux"))]
14use super::types::{MlockFlags, UserfaultfdFlags};
15use crate::fd::BorrowedFd;
16#[cfg(any(target_os = "android", target_os = "linux"))]
17use crate::fd::OwnedFd;
18use crate::io;
19
20#[cfg(not(target_os = "redox"))]
21pub(crate) fn madvise(addr: *mut c::c_void, len: usize, advice: Advice) -> io::Result<()> {
22 // On Linux platforms, `MADV_DONTNEED` has the same value as
23 // `POSIX_MADV_DONTNEED` but different behavior. We remap it to a different
24 // value, and check for it here.
25 #[cfg(target_os = "linux")]
26 if let Advice::LinuxDontNeed = advice {
27 return unsafe { ret(c::madvise(addr, len, c::MADV_DONTNEED)) };
28 }
29
30 #[cfg(not(target_os = "android"))]
31 {
32 let err = unsafe { c::posix_madvise(addr, len, advice as c::c_int) };
33
34 // `posix_madvise` returns its error status rather than using `errno`.
35 if err == 0 {
36 Ok(())
37 } else {
38 Err(io::Errno(err))
39 }
40 }
41
42 #[cfg(target_os = "android")]
43 {
44 if let Advice::DontNeed = advice {
45 // Do nothing. Linux's `MADV_DONTNEED` isn't the same as
46 // `POSIX_MADV_DONTNEED`, so just discard `MADV_DONTNEED`.
47 Ok(())
48 } else {
49 unsafe { ret(c::madvise(addr, len, advice as c::c_int)) }
50 }
51 }
52}
53
54pub(crate) unsafe fn msync(addr: *mut c::c_void, len: usize, flags: MsyncFlags) -> io::Result<()> {
55 let err = c::msync(addr, len, flags.bits());
56
57 // `msync` returns its error status rather than using `errno`.
58 if err == 0 {
59 Ok(())
60 } else {
61 Err(io::Errno(err))
62 }
63}
64
65/// # Safety
66///
67/// `mmap` is primarily unsafe due to the `addr` parameter, as anything working
68/// with memory pointed to by raw pointers is unsafe.
69pub(crate) unsafe fn mmap(
70 ptr: *mut c::c_void,
71 len: usize,
72 prot: ProtFlags,
73 flags: MapFlags,
74 fd: BorrowedFd<'_>,
75 offset: u64,
76) -> io::Result<*mut c::c_void> {
77 let res = libc_mmap(
78 ptr,
79 len,
80 prot.bits(),
81 flags.bits(),
82 borrowed_fd(fd),
83 offset as i64,
84 );
85 if res == c::MAP_FAILED {
86 Err(io::Errno::last_os_error())
87 } else {
88 Ok(res)
89 }
90}
91
92/// # Safety
93///
94/// `mmap` is primarily unsafe due to the `addr` parameter, as anything working
95/// with memory pointed to by raw pointers is unsafe.
96pub(crate) unsafe fn mmap_anonymous(
97 ptr: *mut c::c_void,
98 len: usize,
99 prot: ProtFlags,
100 flags: MapFlags,
101) -> io::Result<*mut c::c_void> {
102 let res = libc_mmap(
103 ptr,
104 len,
105 prot.bits(),
106 flags.bits() | c::MAP_ANONYMOUS,
107 no_fd(),
108 0,
109 );
110 if res == c::MAP_FAILED {
111 Err(io::Errno::last_os_error())
112 } else {
113 Ok(res)
114 }
115}
116
117pub(crate) unsafe fn mprotect(
118 ptr: *mut c::c_void,
119 len: usize,
120 flags: MprotectFlags,
121) -> io::Result<()> {
122 ret(c::mprotect(ptr, len, flags.bits()))
123}
124
125pub(crate) unsafe fn munmap(ptr: *mut c::c_void, len: usize) -> io::Result<()> {
126 ret(c::munmap(ptr, len))
127}
128
129/// # Safety
130///
131/// `mremap` is primarily unsafe due to the `old_address` parameter, as
132/// anything working with memory pointed to by raw pointers is unsafe.
133#[cfg(target_os = "linux")]
134pub(crate) unsafe fn mremap(
135 old_address: *mut c::c_void,
136 old_size: usize,
137 new_size: usize,
138 flags: MremapFlags,
139) -> io::Result<*mut c::c_void> {
140 let res = c::mremap(old_address, old_size, new_size, flags.bits());
141 if res == c::MAP_FAILED {
142 Err(io::Errno::last_os_error())
143 } else {
144 Ok(res)
145 }
146}
147
148/// # Safety
149///
150/// `mremap_fixed` is primarily unsafe due to the `old_address` and
151/// `new_address` parameters, as anything working with memory pointed to by raw
152/// pointers is unsafe.
153#[cfg(target_os = "linux")]
154pub(crate) unsafe fn mremap_fixed(
155 old_address: *mut c::c_void,
156 old_size: usize,
157 new_size: usize,
158 flags: MremapFlags,
159 new_address: *mut c::c_void,
160) -> io::Result<*mut c::c_void> {
161 let res = c::mremap(
162 old_address,
163 old_size,
164 new_size,
165 flags.bits() | c::MAP_FIXED,
166 new_address,
167 );
168 if res == c::MAP_FAILED {
169 Err(io::Errno::last_os_error())
170 } else {
171 Ok(res)
172 }
173}
174
175/// # Safety
176///
177/// `mlock` operates on raw pointers and may round out to the nearest page
178/// boundaries.
179#[inline]
180pub(crate) unsafe fn mlock(addr: *mut c::c_void, length: usize) -> io::Result<()> {
181 ret(c::mlock(addr, length))
182}
183
184/// # Safety
185///
186/// `mlock_with` operates on raw pointers and may round out to the nearest page
187/// boundaries.
188#[cfg(any(target_os = "android", target_os = "linux"))]
189#[inline]
190pub(crate) unsafe fn mlock_with(
191 addr: *mut c::c_void,
192 length: usize,
193 flags: MlockFlags,
194) -> io::Result<()> {
195 weak_or_syscall! {
196 fn mlock2(
197 addr: *const c::c_void,
198 len: c::size_t,
199 flags: c::c_int
200 ) via SYS_mlock2 -> c::c_int
201 }
202
203 ret(mlock2(addr, length, flags.bits()))
204}
205
206/// # Safety
207///
208/// `munlock` operates on raw pointers and may round out to the nearest page
209/// boundaries.
210#[inline]
211pub(crate) unsafe fn munlock(addr: *mut c::c_void, length: usize) -> io::Result<()> {
212 ret(c::munlock(addr, length))
213}
214
215#[cfg(any(target_os = "android", target_os = "linux"))]
216pub(crate) unsafe fn userfaultfd(flags: UserfaultfdFlags) -> io::Result<OwnedFd> {
217 syscall_ret_owned_fd(c::syscall(c::SYS_userfaultfd, flags.bits()))
218}