Refactor weak symbols in std::sys::unix
This makes a few changes to the weak symbol macros in `sys::unix`:
- `dlsym!` is added to keep the functionality for runtime `dlsym`
lookups, like for `__pthread_get_minstack@GLIBC_PRIVATE` that we don't
want to show up in ELF symbol tables.
- `weak!` now uses `#[linkage = "extern_weak"]` symbols, so its runtime
behavior is just a simple null check. This is also used by `syscall!`.
- On non-ELF targets (macos/ios) where that linkage is not known to
behave, `weak!` is just an alias to `dlsym!` for the old behavior.
- `raw_syscall!` is added to always call `libc::syscall` on linux and
android, for cases like `clone3` that have no known libc wrapper.
The new `weak!` linkage does mean that you'll get versioned symbols if
you build with a newer glibc, like `WEAK DEFAULT UND statx@GLIBC_2.28`.
This might seem problematic, but old non-weak symbols can tie the build
to new versions too, like `dlsym@GLIBC_2.34` from their recent library
unification. If you build with an old glibc like `dist-x86_64-linux`
does, you'll still get unversioned `WEAK DEFAULT UND statx`, which may
be resolved based on the runtime glibc.
I also found a few functions that don't need to be weak anymore:
- Android can directly use `ftruncate64`, `pread64`, and `pwrite64`, as
these were added in API 12, and our baseline is API 14.
- Linux can directly use `splice`, added way back in glibc 2.5 and
similarly old musl. Android only added it in API 21 though.
This commit is contained in:
@@ -7,7 +7,9 @@ use crate::ptr;
|
||||
use crate::sys::{os, stack_overflow};
|
||||
use crate::time::Duration;
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "solaris", target_os = "illumos"))]
|
||||
#[cfg(all(target_os = "linux", target_env = "gnu"))]
|
||||
use crate::sys::weak::dlsym;
|
||||
#[cfg(any(target_os = "solaris", target_os = "illumos"))]
|
||||
use crate::sys::weak::weak;
|
||||
#[cfg(not(any(target_os = "l4re", target_os = "vxworks", target_os = "espidf")))]
|
||||
pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024;
|
||||
@@ -627,10 +629,12 @@ pub mod guard {
|
||||
// We need that information to avoid blowing up when a small stack
|
||||
// is created in an application with big thread-local storage requirements.
|
||||
// See #6233 for rationale and details.
|
||||
#[cfg(target_os = "linux")]
|
||||
#[allow(deprecated)]
|
||||
#[cfg(all(target_os = "linux", target_env = "gnu"))]
|
||||
fn min_stack_size(attr: *const libc::pthread_attr_t) -> usize {
|
||||
weak!(fn __pthread_get_minstack(*const libc::pthread_attr_t) -> libc::size_t);
|
||||
// We use dlsym to avoid an ELF version dependency on GLIBC_PRIVATE. (#23628)
|
||||
// We shouldn't really be using such an internal symbol, but there's currently
|
||||
// no other way to account for the TLS size.
|
||||
dlsym!(fn __pthread_get_minstack(*const libc::pthread_attr_t) -> libc::size_t);
|
||||
|
||||
match __pthread_get_minstack.get() {
|
||||
None => libc::PTHREAD_STACK_MIN,
|
||||
@@ -638,9 +642,8 @@ fn min_stack_size(attr: *const libc::pthread_attr_t) -> usize {
|
||||
}
|
||||
}
|
||||
|
||||
// No point in looking up __pthread_get_minstack() on non-glibc
|
||||
// platforms.
|
||||
#[cfg(all(not(target_os = "linux"), not(target_os = "netbsd")))]
|
||||
// No point in looking up __pthread_get_minstack() on non-glibc platforms.
|
||||
#[cfg(all(not(all(target_os = "linux", target_env = "gnu")), not(target_os = "netbsd")))]
|
||||
fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
|
||||
libc::PTHREAD_STACK_MIN
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user