std/sys/pal/unix/weak/mod.rs
1//! Support for "weak linkage" to symbols on Unix
2//!
3//! Some I/O operations we do in std require newer versions of OSes but we need
4//! to maintain binary compatibility with older releases for now. In order to
5//! use the new functionality when available we use this module for detection.
6//!
7//! One option to use here is weak linkage, but that is unfortunately only
8//! really workable with ELF. Otherwise, use dlsym to get the symbol value at
9//! runtime. This is also done for compatibility with older versions of glibc,
10//! and to avoid creating dependencies on GLIBC_PRIVATE symbols. It assumes that
11//! we've been dynamically linked to the library the symbol comes from, but that
12//! is currently always the case for things like libpthread/libc.
13//!
14//! A long time ago this used weak linkage for the __pthread_get_minstack
15//! symbol, but that caused Debian to detect an unnecessarily strict versioned
16//! dependency on libc6 (#23628) because it is GLIBC_PRIVATE. We now use `dlsym`
17//! for a runtime lookup of that symbol to avoid the ELF versioned dependency.
18
19#![forbid(unsafe_op_in_unsafe_fn)]
20
21cfg_select! {
22 // On non-ELF targets, use the dlsym approximation of weak linkage.
23 target_vendor = "apple" => {
24 mod dlsym;
25 pub(crate) use dlsym::weak;
26 }
27
28 // Some targets don't need and support weak linkage at all...
29 target_os = "espidf" => {}
30
31 // ... but ELF targets support true weak linkage.
32 _ => {
33 // There are a variety of `#[cfg]`s controlling which targets are involved in
34 // each instance of `weak!`. Rather than trying to unify all of
35 // that, we'll just allow that some unix targets don't use this macro at all.
36 #[cfg_attr(not(target_os = "linux"), allow(unused_macros, dead_code))]
37 mod weak_linkage;
38 #[cfg_attr(not(target_os = "linux"), allow(unused_imports))]
39 pub(crate) use weak_linkage::weak;
40 }
41}
42
43// GNU/Linux needs the `dlsym` variant to avoid linking to private glibc symbols.
44#[cfg(all(target_os = "linux", target_env = "gnu"))]
45mod dlsym;
46#[cfg(all(target_os = "linux", target_env = "gnu"))]
47pub(crate) use dlsym::weak as dlsym;
48
49#[cfg(any(target_os = "android", target_os = "linux"))]
50mod syscall;
51#[cfg(any(target_os = "android", target_os = "linux"))]
52pub(crate) use syscall::syscall;