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;