1b8a62b91Sopenharmony_ci//! Low-level implementation details for libc-like runtime libraries such as 2b8a62b91Sopenharmony_ci//! [origin]. 3b8a62b91Sopenharmony_ci//! 4b8a62b91Sopenharmony_ci//! These functions are for implementing thread-local storage (TLS), managing 5b8a62b91Sopenharmony_ci//! threads, loaded libraries, and other process-wide resources. Most of 6b8a62b91Sopenharmony_ci//! `rustix` doesn't care about what other libraries are linked into the 7b8a62b91Sopenharmony_ci//! program or what they're doing, but the features in this module generally 8b8a62b91Sopenharmony_ci//! can only be used by one entity within a process. 9b8a62b91Sopenharmony_ci//! 10b8a62b91Sopenharmony_ci//! The API for these functions is not stable, and this module is 11b8a62b91Sopenharmony_ci//! `doc(hidden)`. 12b8a62b91Sopenharmony_ci//! 13b8a62b91Sopenharmony_ci//! [origin]: https://github.com/sunfishcode/mustang/tree/main/origin 14b8a62b91Sopenharmony_ci//! 15b8a62b91Sopenharmony_ci//! # Safety 16b8a62b91Sopenharmony_ci//! 17b8a62b91Sopenharmony_ci//! This module is intended to be used for implementing a runtime library such 18b8a62b91Sopenharmony_ci//! as libc. Use of these features for any other purpose is likely to create 19b8a62b91Sopenharmony_ci//! serious problems. 20b8a62b91Sopenharmony_ci#![allow(unsafe_code)] 21b8a62b91Sopenharmony_ci 22b8a62b91Sopenharmony_ciuse crate::backend; 23b8a62b91Sopenharmony_ci#[cfg(linux_raw)] 24b8a62b91Sopenharmony_ciuse crate::ffi::CStr; 25b8a62b91Sopenharmony_ci#[cfg(linux_raw)] 26b8a62b91Sopenharmony_ci#[cfg(feature = "fs")] 27b8a62b91Sopenharmony_ciuse crate::fs::AtFlags; 28b8a62b91Sopenharmony_ci#[cfg(linux_raw)] 29b8a62b91Sopenharmony_ciuse crate::io; 30b8a62b91Sopenharmony_ci#[cfg(linux_raw)] 31b8a62b91Sopenharmony_ciuse crate::process::Pid; 32b8a62b91Sopenharmony_ci#[cfg(linux_raw)] 33b8a62b91Sopenharmony_ci#[cfg(feature = "fs")] 34b8a62b91Sopenharmony_ciuse backend::fd::AsFd; 35b8a62b91Sopenharmony_ci#[cfg(linux_raw)] 36b8a62b91Sopenharmony_ciuse core::ffi::c_void; 37b8a62b91Sopenharmony_ci 38b8a62b91Sopenharmony_ci#[cfg(linux_raw)] 39b8a62b91Sopenharmony_ci#[cfg(target_arch = "x86")] 40b8a62b91Sopenharmony_ci#[inline] 41b8a62b91Sopenharmony_cipub unsafe fn set_thread_area(u_info: &mut UserDesc) -> io::Result<()> { 42b8a62b91Sopenharmony_ci backend::runtime::syscalls::tls::set_thread_area(u_info) 43b8a62b91Sopenharmony_ci} 44b8a62b91Sopenharmony_ci 45b8a62b91Sopenharmony_ci#[cfg(linux_raw)] 46b8a62b91Sopenharmony_ci#[cfg(target_arch = "arm")] 47b8a62b91Sopenharmony_ci#[inline] 48b8a62b91Sopenharmony_cipub unsafe fn arm_set_tls(data: *mut c_void) -> io::Result<()> { 49b8a62b91Sopenharmony_ci backend::runtime::syscalls::tls::arm_set_tls(data) 50b8a62b91Sopenharmony_ci} 51b8a62b91Sopenharmony_ci 52b8a62b91Sopenharmony_ci#[cfg(linux_raw)] 53b8a62b91Sopenharmony_ci#[cfg(target_arch = "x86_64")] 54b8a62b91Sopenharmony_ci#[inline] 55b8a62b91Sopenharmony_cipub unsafe fn set_fs(data: *mut c_void) { 56b8a62b91Sopenharmony_ci backend::runtime::syscalls::tls::set_fs(data) 57b8a62b91Sopenharmony_ci} 58b8a62b91Sopenharmony_ci 59b8a62b91Sopenharmony_ci#[cfg(linux_raw)] 60b8a62b91Sopenharmony_ci#[inline] 61b8a62b91Sopenharmony_cipub unsafe fn set_tid_address(data: *mut c_void) -> Pid { 62b8a62b91Sopenharmony_ci backend::runtime::syscalls::tls::set_tid_address(data) 63b8a62b91Sopenharmony_ci} 64b8a62b91Sopenharmony_ci 65b8a62b91Sopenharmony_ci/// `prctl(PR_SET_NAME, name)` 66b8a62b91Sopenharmony_ci/// 67b8a62b91Sopenharmony_ci/// # References 68b8a62b91Sopenharmony_ci/// - [Linux]: https://man7.org/linux/man-pages/man2/prctl.2.html 69b8a62b91Sopenharmony_ci/// 70b8a62b91Sopenharmony_ci/// # Safety 71b8a62b91Sopenharmony_ci/// 72b8a62b91Sopenharmony_ci/// This is a very low-level feature for implementing threading libraries. 73b8a62b91Sopenharmony_ci/// See the references links above. 74b8a62b91Sopenharmony_ci/// 75b8a62b91Sopenharmony_ci/// [Linux]: https://man7.org/linux/man-pages/man2/prctl.2.html 76b8a62b91Sopenharmony_ci#[cfg(linux_raw)] 77b8a62b91Sopenharmony_ci#[inline] 78b8a62b91Sopenharmony_cipub unsafe fn set_thread_name(name: &CStr) -> io::Result<()> { 79b8a62b91Sopenharmony_ci backend::runtime::syscalls::tls::set_thread_name(name) 80b8a62b91Sopenharmony_ci} 81b8a62b91Sopenharmony_ci 82b8a62b91Sopenharmony_ci#[cfg(linux_raw)] 83b8a62b91Sopenharmony_ci#[cfg(target_arch = "x86")] 84b8a62b91Sopenharmony_cipub use backend::runtime::tls::UserDesc; 85b8a62b91Sopenharmony_ci 86b8a62b91Sopenharmony_ci/// `syscall(SYS_exit, status)`—Exit the current thread. 87b8a62b91Sopenharmony_ci/// 88b8a62b91Sopenharmony_ci/// # Safety 89b8a62b91Sopenharmony_ci/// 90b8a62b91Sopenharmony_ci/// This is a very low-level feature for implementing threading libraries. 91b8a62b91Sopenharmony_ci#[cfg(linux_raw)] 92b8a62b91Sopenharmony_ci#[inline] 93b8a62b91Sopenharmony_cipub unsafe fn exit_thread(status: i32) -> ! { 94b8a62b91Sopenharmony_ci backend::runtime::syscalls::tls::exit_thread(status) 95b8a62b91Sopenharmony_ci} 96b8a62b91Sopenharmony_ci 97b8a62b91Sopenharmony_ci/// Exit all the threads in the current process' thread group. 98b8a62b91Sopenharmony_ci/// 99b8a62b91Sopenharmony_ci/// This is equivalent to `_exit` and `_Exit` in libc. 100b8a62b91Sopenharmony_ci/// 101b8a62b91Sopenharmony_ci/// This does not all any `__cxa_atexit`, `atexit`, or any other destructors. 102b8a62b91Sopenharmony_ci/// Most programs should use [`std::process::exit`] instead of calling this 103b8a62b91Sopenharmony_ci/// directly. 104b8a62b91Sopenharmony_ci/// 105b8a62b91Sopenharmony_ci/// # References 106b8a62b91Sopenharmony_ci/// - [POSIX `_Exit`] 107b8a62b91Sopenharmony_ci/// - [Linux `exit_group`] 108b8a62b91Sopenharmony_ci/// - [Linux `_Exit`] 109b8a62b91Sopenharmony_ci/// 110b8a62b91Sopenharmony_ci/// [POSIX `_Exit`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/_Exit.html 111b8a62b91Sopenharmony_ci/// [Linux `exit_group`]: https://man7.org/linux/man-pages/man2/exit_group.2.html 112b8a62b91Sopenharmony_ci/// [Linux `_Exit`]: https://man7.org/linux/man-pages/man2/exit.2.html 113b8a62b91Sopenharmony_ci#[doc(alias = "_exit")] 114b8a62b91Sopenharmony_ci#[doc(alias = "_Exit")] 115b8a62b91Sopenharmony_ci#[inline] 116b8a62b91Sopenharmony_cipub fn exit_group(status: i32) -> ! { 117b8a62b91Sopenharmony_ci backend::process::syscalls::exit_group(status) 118b8a62b91Sopenharmony_ci} 119b8a62b91Sopenharmony_ci 120b8a62b91Sopenharmony_ci/// Return fields from the main executable segment headers ("phdrs") relevant 121b8a62b91Sopenharmony_ci/// to initializing TLS provided to the program at startup. 122b8a62b91Sopenharmony_ci#[cfg(linux_raw)] 123b8a62b91Sopenharmony_ci#[inline] 124b8a62b91Sopenharmony_cipub fn startup_tls_info() -> StartupTlsInfo { 125b8a62b91Sopenharmony_ci backend::runtime::tls::startup_tls_info() 126b8a62b91Sopenharmony_ci} 127b8a62b91Sopenharmony_ci 128b8a62b91Sopenharmony_ci/// `(getauxval(AT_PHDR), getauxval(AT_PHNUM))`—Returns the address and 129b8a62b91Sopenharmony_ci/// number of ELF segment headers for the main executable. 130b8a62b91Sopenharmony_ci/// 131b8a62b91Sopenharmony_ci/// # References 132b8a62b91Sopenharmony_ci/// - [Linux] 133b8a62b91Sopenharmony_ci/// 134b8a62b91Sopenharmony_ci/// [Linux]: https://man7.org/linux/man-pages/man3/getauxval.3.html 135b8a62b91Sopenharmony_ci#[cfg(linux_raw)] 136b8a62b91Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))] 137b8a62b91Sopenharmony_ci#[inline] 138b8a62b91Sopenharmony_cipub fn exe_phdrs() -> (*const c_void, usize) { 139b8a62b91Sopenharmony_ci backend::param::auxv::exe_phdrs() 140b8a62b91Sopenharmony_ci} 141b8a62b91Sopenharmony_ci 142b8a62b91Sopenharmony_ci#[cfg(linux_raw)] 143b8a62b91Sopenharmony_cipub use backend::runtime::tls::StartupTlsInfo; 144b8a62b91Sopenharmony_ci 145b8a62b91Sopenharmony_ci/// `fork()`—Creates a new process by duplicating the calling process. 146b8a62b91Sopenharmony_ci/// 147b8a62b91Sopenharmony_ci/// On success, the pid of the child process is returned in the parent, and 148b8a62b91Sopenharmony_ci/// `None` is returned in the child. 149b8a62b91Sopenharmony_ci/// 150b8a62b91Sopenharmony_ci/// Unlike its POSIX and libc counterparts, this `fork` does not invoke any 151b8a62b91Sopenharmony_ci/// handlers (such as those registered with `pthread_atfork`). 152b8a62b91Sopenharmony_ci/// 153b8a62b91Sopenharmony_ci/// The program environment in the child after a `fork` and before an `execve` 154b8a62b91Sopenharmony_ci/// is very special. All code that executes in this environment must avoid: 155b8a62b91Sopenharmony_ci/// 156b8a62b91Sopenharmony_ci/// - Acquiring any other locks that are held in other threads on the parent 157b8a62b91Sopenharmony_ci/// at the time of the `fork`, as the child only contains one thread, and 158b8a62b91Sopenharmony_ci/// attempting to acquire such locks will deadlock (though this is [not 159b8a62b91Sopenharmony_ci/// considered unsafe]). 160b8a62b91Sopenharmony_ci/// 161b8a62b91Sopenharmony_ci/// - Performing any dynamic allocation using the global allocator, since 162b8a62b91Sopenharmony_ci/// global allocators may use locks to ensure thread safety, and their locks 163b8a62b91Sopenharmony_ci/// may not be released in the child process, so attempts to allocate may 164b8a62b91Sopenharmony_ci/// deadlock (as described in the previous point). 165b8a62b91Sopenharmony_ci/// 166b8a62b91Sopenharmony_ci/// - Accessing any external state which the parent assumes it has exclusive 167b8a62b91Sopenharmony_ci/// access to, such as a file protected by a file lock, as this could 168b8a62b91Sopenharmony_ci/// corrupt the external state. 169b8a62b91Sopenharmony_ci/// 170b8a62b91Sopenharmony_ci/// - Accessing any random-number-generator state inherited from the parent, 171b8a62b91Sopenharmony_ci/// as the parent may have the same state and generate the same random 172b8a62b91Sopenharmony_ci/// numbers, which may violate security invariants. 173b8a62b91Sopenharmony_ci/// 174b8a62b91Sopenharmony_ci/// - Accessing any thread runtime state, since this function does not update 175b8a62b91Sopenharmony_ci/// the thread id in the thread runtime, so thread runtime functions could 176b8a62b91Sopenharmony_ci/// cause undefined behavior. 177b8a62b91Sopenharmony_ci/// 178b8a62b91Sopenharmony_ci/// - Accessing any memory shared with the parent, such as a [`MAP_SHARED`] 179b8a62b91Sopenharmony_ci/// mapping, even with anonymous or [`memfd_create`] mappings, as this could 180b8a62b91Sopenharmony_ci/// cause undefined behavior. 181b8a62b91Sopenharmony_ci/// 182b8a62b91Sopenharmony_ci/// - Calling any C function which isn't known to be [async-signal-safe], as 183b8a62b91Sopenharmony_ci/// that could cause undefined behavior. The extent to which this also 184b8a62b91Sopenharmony_ci/// applies to Rust functions is unclear at this time. 185b8a62b91Sopenharmony_ci/// 186b8a62b91Sopenharmony_ci/// # Safety 187b8a62b91Sopenharmony_ci/// 188b8a62b91Sopenharmony_ci/// The child must avoid accessing any memory shared with the parent in a 189b8a62b91Sopenharmony_ci/// way that invokes undefined behavior. It must avoid accessing any threading 190b8a62b91Sopenharmony_ci/// runtime functions in a way that invokes undefined behavior. And it must 191b8a62b91Sopenharmony_ci/// avoid invoking any undefined behavior through any function that is not 192b8a62b91Sopenharmony_ci/// guaranteed to be async-signal-safe. 193b8a62b91Sopenharmony_ci/// 194b8a62b91Sopenharmony_ci/// # References 195b8a62b91Sopenharmony_ci/// - [POSIX] 196b8a62b91Sopenharmony_ci/// - [Linux] 197b8a62b91Sopenharmony_ci/// 198b8a62b91Sopenharmony_ci/// # Literary interlude 199b8a62b91Sopenharmony_ci/// 200b8a62b91Sopenharmony_ci/// > Do not jump on ancient uncles. 201b8a62b91Sopenharmony_ci/// > Do not yell at average mice. 202b8a62b91Sopenharmony_ci/// > Do not wear a broom to breakfast. 203b8a62b91Sopenharmony_ci/// > Do not ask a snake’s advice. 204b8a62b91Sopenharmony_ci/// > Do not bathe in chocolate pudding. 205b8a62b91Sopenharmony_ci/// > Do not talk to bearded bears. 206b8a62b91Sopenharmony_ci/// > Do not smoke cigars on sofas. 207b8a62b91Sopenharmony_ci/// > Do not dance on velvet chairs. 208b8a62b91Sopenharmony_ci/// > Do not take a whale to visit 209b8a62b91Sopenharmony_ci/// > Russell’s mother’s cousin’s yacht. 210b8a62b91Sopenharmony_ci/// > And whatever else you do do 211b8a62b91Sopenharmony_ci/// > It is better you 212b8a62b91Sopenharmony_ci/// > Do not. 213b8a62b91Sopenharmony_ci/// 214b8a62b91Sopenharmony_ci/// - "Rules", by Karla Kuskin 215b8a62b91Sopenharmony_ci/// 216b8a62b91Sopenharmony_ci/// [`MAP_SHARED`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/mmap.html 217b8a62b91Sopenharmony_ci/// [not considered unsafe]: https://doc.rust-lang.org/reference/behavior-not-considered-unsafe.html#deadlocks 218b8a62b91Sopenharmony_ci/// [`memfd_create`]: https://man7.org/linux/man-pages/man2/memfd_create.2.html 219b8a62b91Sopenharmony_ci/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html 220b8a62b91Sopenharmony_ci/// [Linux]: https://man7.org/linux/man-pages/man2/fork.2.html 221b8a62b91Sopenharmony_ci/// [async-signal-safe]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03 222b8a62b91Sopenharmony_ci#[cfg(linux_raw)] 223b8a62b91Sopenharmony_cipub unsafe fn fork() -> io::Result<Option<Pid>> { 224b8a62b91Sopenharmony_ci backend::runtime::syscalls::fork() 225b8a62b91Sopenharmony_ci} 226b8a62b91Sopenharmony_ci 227b8a62b91Sopenharmony_ci/// `execveat(dirfd, path.as_c_str(), argv, envp, flags)`—Execute a new 228b8a62b91Sopenharmony_ci/// command using the current process. 229b8a62b91Sopenharmony_ci/// 230b8a62b91Sopenharmony_ci/// # Safety 231b8a62b91Sopenharmony_ci/// 232b8a62b91Sopenharmony_ci/// The `argv` and `envp` pointers must point to NUL-terminated arrays, and 233b8a62b91Sopenharmony_ci/// their contents must be pointers to NUL-terminated byte arrays. 234b8a62b91Sopenharmony_ci/// 235b8a62b91Sopenharmony_ci/// # References 236b8a62b91Sopenharmony_ci/// - [Linux] 237b8a62b91Sopenharmony_ci/// 238b8a62b91Sopenharmony_ci/// [Linux]: https://man7.org/linux/man-pages/man2/execveat.2.html 239b8a62b91Sopenharmony_ci#[cfg(linux_raw)] 240b8a62b91Sopenharmony_ci#[inline] 241b8a62b91Sopenharmony_ci#[cfg(feature = "fs")] 242b8a62b91Sopenharmony_ci#[cfg_attr(doc_cfg, doc(cfg(feature = "fs")))] 243b8a62b91Sopenharmony_cipub unsafe fn execveat<Fd: AsFd>( 244b8a62b91Sopenharmony_ci dirfd: Fd, 245b8a62b91Sopenharmony_ci path: &CStr, 246b8a62b91Sopenharmony_ci argv: *const *const u8, 247b8a62b91Sopenharmony_ci envp: *const *const u8, 248b8a62b91Sopenharmony_ci flags: AtFlags, 249b8a62b91Sopenharmony_ci) -> io::Errno { 250b8a62b91Sopenharmony_ci backend::runtime::syscalls::execveat(dirfd.as_fd(), path, argv, envp, flags) 251b8a62b91Sopenharmony_ci} 252b8a62b91Sopenharmony_ci 253b8a62b91Sopenharmony_ci/// `execve(path.as_c_str(), argv, envp)`—Execute a new command using the 254b8a62b91Sopenharmony_ci/// current process. 255b8a62b91Sopenharmony_ci/// 256b8a62b91Sopenharmony_ci/// # Safety 257b8a62b91Sopenharmony_ci/// 258b8a62b91Sopenharmony_ci/// The `argv` and `envp` pointers must point to NUL-terminated arrays, and 259b8a62b91Sopenharmony_ci/// their contents must be pointers to NUL-terminated byte arrays. 260b8a62b91Sopenharmony_ci/// 261b8a62b91Sopenharmony_ci/// # References 262b8a62b91Sopenharmony_ci/// - [Linux] 263b8a62b91Sopenharmony_ci/// 264b8a62b91Sopenharmony_ci/// [Linux]: https://man7.org/linux/man-pages/man2/execve.2.html 265b8a62b91Sopenharmony_ci#[cfg(linux_raw)] 266b8a62b91Sopenharmony_ci#[inline] 267b8a62b91Sopenharmony_cipub unsafe fn execve(path: &CStr, argv: *const *const u8, envp: *const *const u8) -> io::Errno { 268b8a62b91Sopenharmony_ci backend::runtime::syscalls::execve(path, argv, envp) 269b8a62b91Sopenharmony_ci} 270