diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:18:32 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:18:32 +0000 |
commit | 4547b622d8d29df964fa2914213088b148c498fc (patch) | |
tree | 9fc6b25f3c3add6b745be9a2400a6e96140046e9 /vendor/rustix/src/backend/libc/mm | |
parent | Releasing progress-linux version 1.66.0+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-4547b622d8d29df964fa2914213088b148c498fc.tar.xz rustc-4547b622d8d29df964fa2914213088b148c498fc.zip |
Merging upstream version 1.67.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/rustix/src/backend/libc/mm')
-rw-r--r-- | vendor/rustix/src/backend/libc/mm/mod.rs | 2 | ||||
-rw-r--r-- | vendor/rustix/src/backend/libc/mm/syscalls.rs | 218 | ||||
-rw-r--r-- | vendor/rustix/src/backend/libc/mm/types.rs | 428 |
3 files changed, 648 insertions, 0 deletions
diff --git a/vendor/rustix/src/backend/libc/mm/mod.rs b/vendor/rustix/src/backend/libc/mm/mod.rs new file mode 100644 index 000000000..1e0181a99 --- /dev/null +++ b/vendor/rustix/src/backend/libc/mm/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod syscalls; +pub(crate) mod types; diff --git a/vendor/rustix/src/backend/libc/mm/syscalls.rs b/vendor/rustix/src/backend/libc/mm/syscalls.rs new file mode 100644 index 000000000..a1d2df1af --- /dev/null +++ b/vendor/rustix/src/backend/libc/mm/syscalls.rs @@ -0,0 +1,218 @@ +//! libc syscalls supporting `rustix::mm`. + +use super::super::c; +#[cfg(any(target_os = "android", target_os = "linux"))] +use super::super::conv::syscall_ret_owned_fd; +use super::super::conv::{borrowed_fd, no_fd, ret}; +use super::super::offset::libc_mmap; +#[cfg(not(target_os = "redox"))] +use super::types::Advice; +#[cfg(target_os = "linux")] +use super::types::MremapFlags; +use super::types::{MapFlags, MprotectFlags, MsyncFlags, ProtFlags}; +#[cfg(any(target_os = "android", target_os = "linux"))] +use super::types::{MlockFlags, UserfaultfdFlags}; +use crate::fd::BorrowedFd; +#[cfg(any(target_os = "android", target_os = "linux"))] +use crate::fd::OwnedFd; +use crate::io; + +#[cfg(not(target_os = "redox"))] +pub(crate) fn madvise(addr: *mut c::c_void, len: usize, advice: Advice) -> io::Result<()> { + // On Linux platforms, `MADV_DONTNEED` has the same value as + // `POSIX_MADV_DONTNEED` but different behavior. We remap it to a different + // value, and check for it here. + #[cfg(target_os = "linux")] + if let Advice::LinuxDontNeed = advice { + return unsafe { ret(c::madvise(addr, len, c::MADV_DONTNEED)) }; + } + + #[cfg(not(target_os = "android"))] + { + let err = unsafe { c::posix_madvise(addr, len, advice as c::c_int) }; + + // `posix_madvise` returns its error status rather than using `errno`. + if err == 0 { + Ok(()) + } else { + Err(io::Errno(err)) + } + } + + #[cfg(target_os = "android")] + { + if let Advice::DontNeed = advice { + // Do nothing. Linux's `MADV_DONTNEED` isn't the same as + // `POSIX_MADV_DONTNEED`, so just discard `MADV_DONTNEED`. + Ok(()) + } else { + unsafe { ret(c::madvise(addr, len, advice as c::c_int)) } + } + } +} + +pub(crate) unsafe fn msync(addr: *mut c::c_void, len: usize, flags: MsyncFlags) -> io::Result<()> { + let err = c::msync(addr, len, flags.bits()); + + // `msync` returns its error status rather than using `errno`. + if err == 0 { + Ok(()) + } else { + Err(io::Errno(err)) + } +} + +/// # Safety +/// +/// `mmap` is primarily unsafe due to the `addr` parameter, as anything working +/// with memory pointed to by raw pointers is unsafe. +pub(crate) unsafe fn mmap( + ptr: *mut c::c_void, + len: usize, + prot: ProtFlags, + flags: MapFlags, + fd: BorrowedFd<'_>, + offset: u64, +) -> io::Result<*mut c::c_void> { + let res = libc_mmap( + ptr, + len, + prot.bits(), + flags.bits(), + borrowed_fd(fd), + offset as i64, + ); + if res == c::MAP_FAILED { + Err(io::Errno::last_os_error()) + } else { + Ok(res) + } +} + +/// # Safety +/// +/// `mmap` is primarily unsafe due to the `addr` parameter, as anything working +/// with memory pointed to by raw pointers is unsafe. +pub(crate) unsafe fn mmap_anonymous( + ptr: *mut c::c_void, + len: usize, + prot: ProtFlags, + flags: MapFlags, +) -> io::Result<*mut c::c_void> { + let res = libc_mmap( + ptr, + len, + prot.bits(), + flags.bits() | c::MAP_ANONYMOUS, + no_fd(), + 0, + ); + if res == c::MAP_FAILED { + Err(io::Errno::last_os_error()) + } else { + Ok(res) + } +} + +pub(crate) unsafe fn mprotect( + ptr: *mut c::c_void, + len: usize, + flags: MprotectFlags, +) -> io::Result<()> { + ret(c::mprotect(ptr, len, flags.bits())) +} + +pub(crate) unsafe fn munmap(ptr: *mut c::c_void, len: usize) -> io::Result<()> { + ret(c::munmap(ptr, len)) +} + +/// # Safety +/// +/// `mremap` is primarily unsafe due to the `old_address` parameter, as +/// anything working with memory pointed to by raw pointers is unsafe. +#[cfg(target_os = "linux")] +pub(crate) unsafe fn mremap( + old_address: *mut c::c_void, + old_size: usize, + new_size: usize, + flags: MremapFlags, +) -> io::Result<*mut c::c_void> { + let res = c::mremap(old_address, old_size, new_size, flags.bits()); + if res == c::MAP_FAILED { + Err(io::Errno::last_os_error()) + } else { + Ok(res) + } +} + +/// # Safety +/// +/// `mremap_fixed` is primarily unsafe due to the `old_address` and +/// `new_address` parameters, as anything working with memory pointed to by raw +/// pointers is unsafe. +#[cfg(target_os = "linux")] +pub(crate) unsafe fn mremap_fixed( + old_address: *mut c::c_void, + old_size: usize, + new_size: usize, + flags: MremapFlags, + new_address: *mut c::c_void, +) -> io::Result<*mut c::c_void> { + let res = c::mremap( + old_address, + old_size, + new_size, + flags.bits() | c::MAP_FIXED, + new_address, + ); + if res == c::MAP_FAILED { + Err(io::Errno::last_os_error()) + } else { + Ok(res) + } +} + +/// # Safety +/// +/// `mlock` operates on raw pointers and may round out to the nearest page +/// boundaries. +#[inline] +pub(crate) unsafe fn mlock(addr: *mut c::c_void, length: usize) -> io::Result<()> { + ret(c::mlock(addr, length)) +} + +/// # Safety +/// +/// `mlock_with` operates on raw pointers and may round out to the nearest page +/// boundaries. +#[cfg(any(target_os = "android", target_os = "linux"))] +#[inline] +pub(crate) unsafe fn mlock_with( + addr: *mut c::c_void, + length: usize, + flags: MlockFlags, +) -> io::Result<()> { + weak_or_syscall! { + fn mlock2( + addr: *const c::c_void, + len: c::size_t, + flags: c::c_int + ) via SYS_mlock2 -> c::c_int + } + + ret(mlock2(addr, length, flags.bits())) +} + +/// # Safety +/// +/// `munlock` operates on raw pointers and may round out to the nearest page +/// boundaries. +#[inline] +pub(crate) unsafe fn munlock(addr: *mut c::c_void, length: usize) -> io::Result<()> { + ret(c::munlock(addr, length)) +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +pub(crate) unsafe fn userfaultfd(flags: UserfaultfdFlags) -> io::Result<OwnedFd> { + syscall_ret_owned_fd(c::syscall(c::SYS_userfaultfd, flags.bits())) +} diff --git a/vendor/rustix/src/backend/libc/mm/types.rs b/vendor/rustix/src/backend/libc/mm/types.rs new file mode 100644 index 000000000..11ab708cf --- /dev/null +++ b/vendor/rustix/src/backend/libc/mm/types.rs @@ -0,0 +1,428 @@ +use super::super::c; +use bitflags::bitflags; + +bitflags! { + /// `PROT_*` flags for use with [`mmap`]. + /// + /// For `PROT_NONE`, use `ProtFlags::empty()`. + /// + /// [`mmap`]: crate::io::mmap + pub struct ProtFlags: c::c_int { + /// `PROT_READ` + const READ = c::PROT_READ; + /// `PROT_WRITE` + const WRITE = c::PROT_WRITE; + /// `PROT_EXEC` + const EXEC = c::PROT_EXEC; + } +} + +bitflags! { + /// `PROT_*` flags for use with [`mprotect`]. + /// + /// For `PROT_NONE`, use `MprotectFlags::empty()`. + /// + /// [`mprotect`]: crate::io::mprotect + pub struct MprotectFlags: c::c_int { + /// `PROT_READ` + const READ = c::PROT_READ; + /// `PROT_WRITE` + const WRITE = c::PROT_WRITE; + /// `PROT_EXEC` + const EXEC = c::PROT_EXEC; + /// `PROT_GROWSUP` + #[cfg(any(target_os = "android", target_os = "linux"))] + const GROWSUP = c::PROT_GROWSUP; + /// `PROT_GROWSDOWN` + #[cfg(any(target_os = "android", target_os = "linux"))] + const GROWSDOWN = c::PROT_GROWSDOWN; + } +} + +bitflags! { + /// `MAP_*` flags for use with [`mmap`]. + /// + /// For `MAP_ANONYMOUS` (aka `MAP_ANON`), see [`mmap_anonymous`]. + /// + /// [`mmap`]: crate::io::mmap + /// [`mmap_anonymous`]: crates::io::mmap_anonymous + pub struct MapFlags: c::c_int { + /// `MAP_SHARED` + const SHARED = c::MAP_SHARED; + /// `MAP_SHARED_VALIDATE` + #[cfg(not(any( + target_os = "android", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + )))] + const SHARED_VALIDATE = c::MAP_SHARED_VALIDATE; + /// `MAP_PRIVATE` + const PRIVATE = c::MAP_PRIVATE; + /// `MAP_DENYWRITE` + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + )))] + const DENYWRITE = c::MAP_DENYWRITE; + /// `MAP_FIXED` + const FIXED = c::MAP_FIXED; + /// `MAP_FIXED_NOREPLACE` + #[cfg(not(any( + target_os = "android", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + )))] + const FIXED_NOREPLACE = c::MAP_FIXED_NOREPLACE; + /// `MAP_GROWSDOWN` + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + )))] + const GROWSDOWN = c::MAP_GROWSDOWN; + /// `MAP_HUGETLB` + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + )))] + const HUGETLB = c::MAP_HUGETLB; + /// `MAP_HUGE_2MB` + #[cfg(not(any( + target_os = "android", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + )))] + const HUGE_2MB = c::MAP_HUGE_2MB; + /// `MAP_HUGE_1GB` + #[cfg(not(any( + target_os = "android", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + )))] + const HUGE_1GB = c::MAP_HUGE_1GB; + /// `MAP_LOCKED` + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + )))] + const LOCKED = c::MAP_LOCKED; + /// `MAP_NOCORE` + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + const NOCORE = c::MAP_NOCORE; + /// `MAP_NORESERVE` + #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd", target_os = "redox")))] + const NORESERVE = c::MAP_NORESERVE; + /// `MAP_NOSYNC` + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + const NOSYNC = c::MAP_NOSYNC; + /// `MAP_POPULATE` + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + )))] + const POPULATE = c::MAP_POPULATE; + /// `MAP_STACK` + #[cfg(not(any( + target_os = "dragonfly", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "redox", + target_os = "solaris", + )))] + const STACK = c::MAP_STACK; + /// `MAP_PREFAULT_READ` + #[cfg(target_os = "freebsd")] + const PREFAULT_READ = c::MAP_PREFAULT_READ; + /// `MAP_SYNC` + #[cfg(not(any( + target_os = "android", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + all( + any(target_os = "android", target_os = "linux"), + any(target_arch = "mips", target_arch = "mips64"), + ) + )))] + const SYNC = c::MAP_SYNC; + /// `MAP_UNINITIALIZED` + #[cfg(any())] + const UNINITIALIZED = c::MAP_UNINITIALIZED; + } +} + +#[cfg(target_os = "linux")] +bitflags! { + /// `MREMAP_*` flags for use with [`mremap`]. + /// + /// For `MREMAP_FIXED`, see [`mremap_fixed`]. + /// + /// [`mremap`]: crate::io::mremap + /// [`mremap_fixed`]: crate::io::mremap_fixed + pub struct MremapFlags: i32 { + /// `MREMAP_MAYMOVE` + const MAYMOVE = c::MREMAP_MAYMOVE; + } +} + +bitflags! { + /// `MS_*` flags for use with [`msync`]. + /// + /// [`msync`]: crate::io::msync + pub struct MsyncFlags: i32 { + /// `MS_SYNC`—Requests an update and waits for it to complete. + const SYNC = c::MS_SYNC; + /// `MS_ASYNC`—Specifies that an update be scheduled, but the call + /// returns immediately. + const ASYNC = c::MS_ASYNC; + /// `MS_INVALIDATE`—Asks to invalidate other mappings of the same + /// file (so that they can be updated with the fresh values just + /// written). + const INVALIDATE = c::MS_INVALIDATE; + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +bitflags! { + /// `MLOCK_*` flags for use with [`mlock_with`]. + /// + /// [`mlock_with`]: crate::io::mlock_with + pub struct MlockFlags: i32 { + /// `MLOCK_ONFAULT` + const ONFAULT = c::MLOCK_ONFAULT as _; + } +} + +/// `POSIX_MADV_*` constants for use with [`madvise`]. +/// +/// [`madvise`]: crate::mm::madvise +#[cfg(not(target_os = "redox"))] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[repr(i32)] +#[non_exhaustive] +pub enum Advice { + /// `POSIX_MADV_NORMAL` + #[cfg(not(any(target_os = "android", target_os = "haiku")))] + Normal = c::POSIX_MADV_NORMAL, + + /// `POSIX_MADV_NORMAL` + #[cfg(any(target_os = "android", target_os = "haiku"))] + Normal = c::MADV_NORMAL, + + /// `POSIX_MADV_SEQUENTIAL` + #[cfg(not(any(target_os = "android", target_os = "haiku")))] + Sequential = c::POSIX_MADV_SEQUENTIAL, + + /// `POSIX_MADV_SEQUENTIAL` + #[cfg(any(target_os = "android", target_os = "haiku"))] + Sequential = c::MADV_SEQUENTIAL, + + /// `POSIX_MADV_RANDOM` + #[cfg(not(any(target_os = "android", target_os = "haiku")))] + Random = c::POSIX_MADV_RANDOM, + + /// `POSIX_MADV_RANDOM` + #[cfg(any(target_os = "android", target_os = "haiku"))] + Random = c::MADV_RANDOM, + + /// `POSIX_MADV_WILLNEED` + #[cfg(not(any(target_os = "android", target_os = "haiku")))] + WillNeed = c::POSIX_MADV_WILLNEED, + + /// `POSIX_MADV_WILLNEED` + #[cfg(any(target_os = "android", target_os = "haiku"))] + WillNeed = c::MADV_WILLNEED, + + /// `POSIX_MADV_DONTNEED` + #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "haiku")))] + DontNeed = c::POSIX_MADV_DONTNEED, + + /// `POSIX_MADV_DONTNEED` + #[cfg(any(target_os = "android", target_os = "haiku"))] + DontNeed = i32::MAX - 1, + + /// `MADV_DONTNEED` + // `MADV_DONTNEED` has the same value as `POSIX_MADV_DONTNEED`. We don't + // have a separate `posix_madvise` from `madvise`, so we expose a special + // value which we special-case. + #[cfg(target_os = "linux")] + LinuxDontNeed = i32::MAX, + + /// `MADV_DONTNEED` + #[cfg(target_os = "android")] + LinuxDontNeed = c::MADV_DONTNEED, + /// `MADV_FREE` + #[cfg(any(target_os = "android", target_os = "linux"))] + LinuxFree = c::MADV_FREE, + /// `MADV_REMOVE` + #[cfg(any(target_os = "android", target_os = "linux"))] + LinuxRemove = c::MADV_REMOVE, + /// `MADV_DONTFORK` + #[cfg(any(target_os = "android", target_os = "linux"))] + LinuxDontFork = c::MADV_DONTFORK, + /// `MADV_DOFORK` + #[cfg(any(target_os = "android", target_os = "linux"))] + LinuxDoFork = c::MADV_DOFORK, + /// `MADV_HWPOISON` + #[cfg(any(target_os = "android", target_os = "linux"))] + LinuxHwPoison = c::MADV_HWPOISON, + /// `MADV_SOFT_OFFLINE` + #[cfg(all( + any(target_os = "android", target_os = "linux"), + not(any(target_arch = "mips", target_arch = "mips64")), + ))] + LinuxSoftOffline = c::MADV_SOFT_OFFLINE, + /// `MADV_MERGEABLE` + #[cfg(any(target_os = "android", target_os = "linux"))] + LinuxMergeable = c::MADV_MERGEABLE, + /// `MADV_UNMERGEABLE` + #[cfg(any(target_os = "android", target_os = "linux"))] + LinuxUnmergeable = c::MADV_UNMERGEABLE, + /// `MADV_HUGEPAGE` (since Linux 2.6.38) + #[cfg(any(target_os = "android", target_os = "linux"))] + LinuxHugepage = c::MADV_HUGEPAGE, + /// `MADV_NOHUGEPAGE` (since Linux 2.6.38) + #[cfg(any(target_os = "android", target_os = "linux"))] + LinuxNoHugepage = c::MADV_NOHUGEPAGE, + /// `MADV_DONTDUMP` (since Linux 3.4) + #[cfg(any(target_os = "android", target_os = "linux"))] + LinuxDontDump = c::MADV_DONTDUMP, + /// `MADV_DODUMP` (since Linux 3.4) + #[cfg(any(target_os = "android", target_os = "linux"))] + LinuxDoDump = c::MADV_DODUMP, + /// `MADV_WIPEONFORK` (since Linux 4.14) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(feature = "mm")] + LinuxWipeOnFork = linux_raw_sys::general::MADV_WIPEONFORK as i32, + /// `MADV_KEEPONFORK` (since Linux 4.14) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(feature = "mm")] + LinuxKeepOnFork = linux_raw_sys::general::MADV_KEEPONFORK as i32, + /// `MADV_COLD` (since Linux 5.4) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(feature = "mm")] + LinuxCold = linux_raw_sys::general::MADV_COLD as i32, + /// `MADV_PAGEOUT` (since Linux 5.4) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(feature = "mm")] + LinuxPageOut = linux_raw_sys::general::MADV_PAGEOUT as i32, + /// `MADV_POPULATE_READ` (since Linux 5.14) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(feature = "mm")] + LinuxPopulateRead = linux_raw_sys::general::MADV_POPULATE_READ as i32, + /// `MADV_POPULATE_WRITE` (since Linux 5.14) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(feature = "mm")] + LinuxPopulateWrite = linux_raw_sys::general::MADV_POPULATE_WRITE as i32, +} + +#[cfg(target_os = "emscripten")] +impl Advice { + /// `POSIX_MADV_DONTNEED` + #[allow(non_upper_case_globals)] + pub const DontNeed: Self = Self::Normal; +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +bitflags! { + /// `O_*` flags for use with [`userfaultfd`]. + /// + /// [`userfaultfd`]: crate::io::userfaultfd + pub struct UserfaultfdFlags: c::c_int { + /// `O_CLOEXEC` + const CLOEXEC = c::O_CLOEXEC; + /// `O_NONBLOCK` + const NONBLOCK = c::O_NONBLOCK; + } +} |