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