diff options
Diffstat (limited to 'vendor/rustix-0.36.5/src/backend/linux_raw/runtime')
3 files changed, 166 insertions, 0 deletions
diff --git a/vendor/rustix-0.36.5/src/backend/linux_raw/runtime/mod.rs b/vendor/rustix-0.36.5/src/backend/linux_raw/runtime/mod.rs new file mode 100644 index 000000000..0b48649ce --- /dev/null +++ b/vendor/rustix-0.36.5/src/backend/linux_raw/runtime/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod syscalls; +pub(crate) mod tls; diff --git a/vendor/rustix-0.36.5/src/backend/linux_raw/runtime/syscalls.rs b/vendor/rustix-0.36.5/src/backend/linux_raw/runtime/syscalls.rs new file mode 100644 index 000000000..a331786f9 --- /dev/null +++ b/vendor/rustix-0.36.5/src/backend/linux_raw/runtime/syscalls.rs @@ -0,0 +1,107 @@ +//! linux_raw syscalls supporting `rustix::runtime`. +//! +//! # Safety +//! +//! See the `rustix::backend` module documentation for details. +#![allow(unsafe_code)] +#![allow(clippy::undocumented_unsafe_blocks)] + +use super::super::c; +#[cfg(target_arch = "x86")] +use super::super::conv::by_mut; +use super::super::conv::{c_int, c_uint, ret, ret_c_uint, ret_error, ret_usize_infallible, zero}; +#[cfg(feature = "fs")] +use crate::fd::BorrowedFd; +use crate::ffi::CStr; +#[cfg(feature = "fs")] +use crate::fs::AtFlags; +use crate::io; +use crate::process::{Pid, RawNonZeroPid}; +use linux_raw_sys::general::{__kernel_pid_t, PR_SET_NAME, SIGCHLD}; +#[cfg(target_arch = "x86_64")] +use {super::super::conv::ret_infallible, linux_raw_sys::general::ARCH_SET_FS}; + +#[inline] +pub(crate) unsafe fn fork() -> io::Result<Option<Pid>> { + let pid = ret_c_uint(syscall_readonly!( + __NR_clone, + c_uint(SIGCHLD), + zero(), + zero(), + zero(), + zero() + ))?; + Ok(Pid::from_raw(pid)) +} + +#[cfg(feature = "fs")] +pub(crate) unsafe fn execveat( + dirfd: BorrowedFd<'_>, + path: &CStr, + args: *const *const u8, + env_vars: *const *const u8, + flags: AtFlags, +) -> io::Errno { + ret_error(syscall_readonly!( + __NR_execveat, + dirfd, + path, + args, + env_vars, + flags + )) +} + +pub(crate) unsafe fn execve( + path: &CStr, + args: *const *const u8, + env_vars: *const *const u8, +) -> io::Errno { + ret_error(syscall_readonly!(__NR_execve, path, args, env_vars)) +} + +pub(crate) mod tls { + #[cfg(target_arch = "x86")] + use super::super::tls::UserDesc; + use super::*; + + #[cfg(target_arch = "x86")] + #[inline] + pub(crate) unsafe fn set_thread_area(u_info: &mut UserDesc) -> io::Result<()> { + ret(syscall!(__NR_set_thread_area, by_mut(u_info))) + } + + #[cfg(target_arch = "arm")] + #[inline] + pub(crate) unsafe fn arm_set_tls(data: *mut c::c_void) -> io::Result<()> { + ret(syscall_readonly!(__ARM_NR_set_tls, data)) + } + + #[cfg(target_arch = "x86_64")] + #[inline] + pub(crate) unsafe fn set_fs(data: *mut c::c_void) { + ret_infallible(syscall_readonly!( + __NR_arch_prctl, + c_uint(ARCH_SET_FS), + data + )) + } + + #[inline] + pub(crate) unsafe fn set_tid_address(data: *mut c::c_void) -> Pid { + let tid: i32 = + ret_usize_infallible(syscall_readonly!(__NR_set_tid_address, data)) as __kernel_pid_t; + debug_assert_ne!(tid, 0); + Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(tid as u32)) + } + + #[inline] + pub(crate) unsafe fn set_thread_name(name: &CStr) -> io::Result<()> { + ret(syscall_readonly!(__NR_prctl, c_uint(PR_SET_NAME), name)) + } + + #[inline] + pub(crate) fn exit_thread(code: c::c_int) -> ! { + unsafe { syscall_noreturn!(__NR_exit, c_int(code)) } + } +} diff --git a/vendor/rustix-0.36.5/src/backend/linux_raw/runtime/tls.rs b/vendor/rustix-0.36.5/src/backend/linux_raw/runtime/tls.rs new file mode 100644 index 000000000..43ed25d7d --- /dev/null +++ b/vendor/rustix-0.36.5/src/backend/linux_raw/runtime/tls.rs @@ -0,0 +1,57 @@ +#![allow(unsafe_code)] + +use super::super::c; +use super::super::elf::*; +use super::super::param::auxv::exe_phdrs_slice; +use core::ptr::null; + +/// For use with [`set_thread_area`]. +/// +/// [`set_thread_area`]: crate::runtime::set_thread_area +#[cfg(target_arch = "x86")] +pub type UserDesc = linux_raw_sys::general::user_desc; + +pub(crate) fn startup_tls_info() -> StartupTlsInfo { + let mut base = null(); + let mut tls_phdr = null(); + let mut stack_size = 0; + + let phdrs = exe_phdrs_slice(); + + // Safety: We assume the phdr array pointer and length the kernel provided + // to the process describe a valid phdr array. + unsafe { + for phdr in phdrs { + match phdr.p_type { + PT_PHDR => base = phdrs.as_ptr().cast::<u8>().offset(-(phdr.p_vaddr as isize)), + PT_TLS => tls_phdr = phdr, + PT_GNU_STACK => stack_size = phdr.p_memsz, + _ => {} + } + } + + StartupTlsInfo { + addr: base.cast::<u8>().add((*tls_phdr).p_vaddr).cast(), + mem_size: (*tls_phdr).p_memsz, + file_size: (*tls_phdr).p_filesz, + align: (*tls_phdr).p_align, + stack_size, + } + } +} + +/// The values returned from [`startup_tls_info`]. +/// +/// [`startup_tls_info`]: crate::runtime::startup_tls_info +pub struct StartupTlsInfo { + /// The base address of the TLS segment. + pub addr: *const c::c_void, + /// The size of the memory region. + pub mem_size: usize, + /// The size beyond which all memory is zero-initialized. + pub file_size: usize, + /// The required alignment for the TLS segment. + pub align: usize, + /// The requested minimum size for stacks. + pub stack_size: usize, +} |