]>
Commit | Line | Data |
---|---|---|
064997fb FG |
1 | //! linux_raw syscalls supporting `rustix::io`. |
2 | //! | |
3 | //! # Safety | |
4 | //! | |
5 | //! See the `rustix::imp` module documentation for details. | |
6 | #![allow(unsafe_code)] | |
7 | #![allow(clippy::undocumented_unsafe_blocks)] | |
8 | ||
9 | use super::super::c; | |
10 | #[cfg(target_pointer_width = "64")] | |
11 | use super::super::conv::loff_t_from_u64; | |
12 | use super::super::conv::{c_uint, no_fd, pass_usize, ret, ret_owned_fd, ret_void_star}; | |
13 | use super::types::{ | |
14 | Advice, MapFlags, MlockFlags, MprotectFlags, MremapFlags, MsyncFlags, ProtFlags, | |
15 | UserfaultfdFlags, | |
16 | }; | |
17 | use crate::fd::BorrowedFd; | |
18 | use crate::io::{self, OwnedFd}; | |
19 | #[cfg(target_pointer_width = "32")] | |
20 | use core::convert::TryInto; | |
21 | use linux_raw_sys::general::MAP_ANONYMOUS; | |
22 | ||
23 | #[inline] | |
24 | pub(crate) fn madvise(addr: *mut c::c_void, len: usize, advice: Advice) -> io::Result<()> { | |
25 | unsafe { | |
26 | ret(syscall!( | |
27 | __NR_madvise, | |
28 | addr, | |
29 | pass_usize(len), | |
30 | c_uint(advice as c::c_uint) | |
31 | )) | |
32 | } | |
33 | } | |
34 | ||
35 | #[inline] | |
36 | pub(crate) unsafe fn msync(addr: *mut c::c_void, len: usize, flags: MsyncFlags) -> io::Result<()> { | |
37 | ret(syscall!(__NR_msync, addr, pass_usize(len), flags)) | |
38 | } | |
39 | ||
40 | /// # Safety | |
41 | /// | |
42 | /// `mmap` is primarily unsafe due to the `addr` parameter, as anything working | |
43 | /// with memory pointed to by raw pointers is unsafe. | |
44 | #[inline] | |
45 | pub(crate) unsafe fn mmap( | |
46 | addr: *mut c::c_void, | |
47 | length: usize, | |
48 | prot: ProtFlags, | |
49 | flags: MapFlags, | |
50 | fd: BorrowedFd<'_>, | |
51 | offset: u64, | |
52 | ) -> io::Result<*mut c::c_void> { | |
53 | #[cfg(target_pointer_width = "32")] | |
54 | { | |
55 | ret_void_star(syscall!( | |
56 | __NR_mmap2, | |
57 | addr, | |
58 | pass_usize(length), | |
59 | prot, | |
60 | flags, | |
61 | fd, | |
62 | (offset / 4096) | |
63 | .try_into() | |
64 | .map(|scaled_offset| pass_usize(scaled_offset)) | |
65 | .map_err(|_| io::Errno::INVAL)? | |
66 | )) | |
67 | } | |
68 | #[cfg(target_pointer_width = "64")] | |
69 | { | |
70 | ret_void_star(syscall!( | |
71 | __NR_mmap, | |
72 | addr, | |
73 | pass_usize(length), | |
74 | prot, | |
75 | flags, | |
76 | fd, | |
77 | loff_t_from_u64(offset) | |
78 | )) | |
79 | } | |
80 | } | |
81 | ||
82 | /// # Safety | |
83 | /// | |
84 | /// `mmap` is primarily unsafe due to the `addr` parameter, as anything working | |
85 | /// with memory pointed to by raw pointers is unsafe. | |
86 | #[inline] | |
87 | pub(crate) unsafe fn mmap_anonymous( | |
88 | addr: *mut c::c_void, | |
89 | length: usize, | |
90 | prot: ProtFlags, | |
91 | flags: MapFlags, | |
92 | ) -> io::Result<*mut c::c_void> { | |
93 | #[cfg(target_pointer_width = "32")] | |
94 | { | |
95 | ret_void_star(syscall!( | |
96 | __NR_mmap2, | |
97 | addr, | |
98 | pass_usize(length), | |
99 | prot, | |
100 | c_uint(flags.bits() | MAP_ANONYMOUS), | |
101 | no_fd(), | |
102 | pass_usize(0) | |
103 | )) | |
104 | } | |
105 | #[cfg(target_pointer_width = "64")] | |
106 | { | |
107 | ret_void_star(syscall!( | |
108 | __NR_mmap, | |
109 | addr, | |
110 | pass_usize(length), | |
111 | prot, | |
112 | c_uint(flags.bits() | MAP_ANONYMOUS), | |
113 | no_fd(), | |
114 | loff_t_from_u64(0) | |
115 | )) | |
116 | } | |
117 | } | |
118 | ||
119 | #[inline] | |
120 | pub(crate) unsafe fn mprotect( | |
121 | ptr: *mut c::c_void, | |
122 | len: usize, | |
123 | flags: MprotectFlags, | |
124 | ) -> io::Result<()> { | |
125 | ret(syscall!(__NR_mprotect, ptr, pass_usize(len), flags)) | |
126 | } | |
127 | ||
128 | /// # Safety | |
129 | /// | |
130 | /// `munmap` is primarily unsafe due to the `addr` parameter, as anything | |
131 | /// working with memory pointed to by raw pointers is unsafe. | |
132 | #[inline] | |
133 | pub(crate) unsafe fn munmap(addr: *mut c::c_void, length: usize) -> io::Result<()> { | |
134 | ret(syscall!(__NR_munmap, addr, pass_usize(length))) | |
135 | } | |
136 | ||
137 | /// # Safety | |
138 | /// | |
139 | /// `mremap` is primarily unsafe due to the `old_address` parameter, as | |
140 | /// anything working with memory pointed to by raw pointers is unsafe. | |
141 | #[inline] | |
142 | pub(crate) unsafe fn mremap( | |
143 | old_address: *mut c::c_void, | |
144 | old_size: usize, | |
145 | new_size: usize, | |
146 | flags: MremapFlags, | |
147 | ) -> io::Result<*mut c::c_void> { | |
148 | ret_void_star(syscall!( | |
149 | __NR_mremap, | |
150 | old_address, | |
151 | pass_usize(old_size), | |
152 | pass_usize(new_size), | |
153 | flags | |
154 | )) | |
155 | } | |
156 | ||
157 | /// # Safety | |
158 | /// | |
159 | /// `mremap_fixed` is primarily unsafe due to the `old_address` and | |
160 | /// `new_address` parameters, as anything working with memory pointed to by raw | |
161 | /// pointers is unsafe. | |
162 | #[inline] | |
163 | pub(crate) unsafe fn mremap_fixed( | |
164 | old_address: *mut c::c_void, | |
165 | old_size: usize, | |
166 | new_size: usize, | |
167 | flags: MremapFlags, | |
168 | new_address: *mut c::c_void, | |
169 | ) -> io::Result<*mut c::c_void> { | |
170 | ret_void_star(syscall!( | |
171 | __NR_mremap, | |
172 | old_address, | |
173 | pass_usize(old_size), | |
174 | pass_usize(new_size), | |
175 | flags, | |
176 | new_address | |
177 | )) | |
178 | } | |
179 | ||
180 | /// # Safety | |
181 | /// | |
182 | /// `mlock` operates on raw pointers and may round out to the nearest page | |
183 | /// boundaries. | |
184 | #[inline] | |
185 | pub(crate) unsafe fn mlock(addr: *mut c::c_void, length: usize) -> io::Result<()> { | |
186 | ret(syscall!(__NR_mlock, addr, pass_usize(length))) | |
187 | } | |
188 | ||
189 | /// # Safety | |
190 | /// | |
191 | /// `mlock_with` operates on raw pointers and may round out to the nearest page | |
192 | /// boundaries. | |
193 | #[inline] | |
194 | pub(crate) unsafe fn mlock_with( | |
195 | addr: *mut c::c_void, | |
196 | length: usize, | |
197 | flags: MlockFlags, | |
198 | ) -> io::Result<()> { | |
199 | ret(syscall!(__NR_mlock2, addr, pass_usize(length), flags)) | |
200 | } | |
201 | ||
202 | /// # Safety | |
203 | /// | |
204 | /// `munlock` operates on raw pointers and may round out to the nearest page | |
205 | /// boundaries. | |
206 | #[inline] | |
207 | pub(crate) unsafe fn munlock(addr: *mut c::c_void, length: usize) -> io::Result<()> { | |
208 | ret(syscall!(__NR_munlock, addr, pass_usize(length))) | |
209 | } | |
210 | ||
211 | #[inline] | |
212 | pub(crate) unsafe fn userfaultfd(flags: UserfaultfdFlags) -> io::Result<OwnedFd> { | |
213 | ret_owned_fd(syscall_readonly!(__NR_userfaultfd, flags)) | |
214 | } |