Skip to content

Commit e9048cf

Browse files
authored
Introduce unstable-errno feature (#110)
This will help with integrating the musl dynamic linker until a rust replacement is written.
1 parent 52cef87 commit e9048cf

3 files changed

Lines changed: 32 additions & 1 deletion

File tree

Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,12 @@ fini-array = []
121121
# needed to support statically-linked PIE executables.
122122
experimental-relocate = ["rustix/mm", "rustix/runtime"]
123123

124+
# Enable unstable support for storing C errno values in the TLS header. This
125+
# will likely be removed in the future and only exists to make it easier to
126+
# possibly integrate a dynamic linker written in C in the near future before
127+
# until a dynamic linker is written in Rust.
128+
unstable-errno = ["thread"]
129+
124130
[package.metadata.docs.rs]
125131
features = ["origin-thread", "origin-signal", "origin-start"]
126132
rustdoc-args = ["--cfg", "doc_cfg"]

src/thread/libc.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Thread startup and shutdown.
22
33
use alloc::boxed::Box;
4-
use core::ffi::c_void;
4+
use core::ffi::{c_int, c_void};
55
use core::mem::{size_of, transmute, zeroed};
66
use core::ptr::{from_exposed_addr_mut, null_mut, without_provenance_mut, NonNull};
77
use core::slice;
@@ -16,6 +16,7 @@ extern "C" {
1616
obj: *mut c_void,
1717
_dso_symbol: *mut c_void,
1818
) -> libc::c_int;
19+
fn __errno_location() -> *mut c_int;
1920
fn __tls_get_addr(p: &[usize; 2]) -> *mut c_void;
2021

2122
static __dso_handle: *const c_void;
@@ -203,6 +204,15 @@ pub unsafe fn set_current_id_after_a_fork(tid: ThreadId) {
203204
let _ = tid;
204205
}
205206

207+
/// Return the address of the thread-local `errno` state.
208+
///
209+
/// This is equivalent to `__errno_location()` in glibc and musl.
210+
#[cfg(feature = "unstable-errno")]
211+
#[inline]
212+
pub fn errno_location() -> *mut i32 {
213+
unsafe { __errno_location() }
214+
}
215+
206216
/// Return the TLS address for the given `offset` for the current thread.
207217
#[inline]
208218
#[must_use]

src/thread/linux_raw.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ use crate::arch::{
1212
};
1313
#[cfg(feature = "alloc")]
1414
use alloc::boxed::Box;
15+
#[cfg(feature = "unstable-errno")]
16+
use core::cell::Cell;
1517
use core::cmp::max;
1618
use core::ffi::c_void;
1719
use core::mem::{align_of, size_of};
@@ -76,6 +78,8 @@ impl Thread {
7678
/// This is not `repr(C)` and not ABI-exposed.
7779
struct ThreadData {
7880
thread_id: AtomicI32,
81+
#[cfg(feature = "unstable-errno")]
82+
errno_val: Cell<i32>,
7983
detached: AtomicU8,
8084
stack_addr: *mut c_void,
8185
stack_size: usize,
@@ -104,6 +108,8 @@ impl ThreadData {
104108
) -> Self {
105109
Self {
106110
thread_id: AtomicI32::new(ThreadId::as_raw(tid)),
111+
#[cfg(feature = "unstable-errno")]
112+
errno_val: Cell::new(0),
107113
detached: AtomicU8::new(INITIAL),
108114
stack_addr,
109115
stack_size,
@@ -1006,6 +1012,15 @@ pub unsafe fn set_current_id_after_a_fork(tid: ThreadId) {
10061012
.store(tid.as_raw_nonzero().get(), SeqCst);
10071013
}
10081014

1015+
/// Return the address of the thread-local `errno` state.
1016+
///
1017+
/// This is equivalent to `__errno_location()` in glibc and musl.
1018+
#[cfg(feature = "unstable-errno")]
1019+
#[inline]
1020+
pub fn errno_location() -> *mut i32 {
1021+
unsafe { core::ptr::addr_of_mut!((*current_metadata()).thread.errno_val).cast::<i32>() }
1022+
}
1023+
10091024
/// Return the TLS address for the given `offset` for the current thread.
10101025
#[inline]
10111026
#[must_use]

0 commit comments

Comments
 (0)