blob: be53f148fc664fd57ce57f8f2ea993800744aa64 [file] [log] [blame]
//! Support for "weak linkage" to symbols on Unix
//!
//! Some I/O operations we do in std require newer versions of OSes but we need
//! to maintain binary compatibility with older releases for now. In order to
//! use the new functionality when available we use this module for detection.
//!
//! One option to use here is weak linkage, but that is unfortunately only
//! really workable with ELF. Otherwise, use dlsym to get the symbol value at
//! runtime. This is also done for compatibility with older versions of glibc,
//! and to avoid creating dependencies on GLIBC_PRIVATE symbols. It assumes that
//! we've been dynamically linked to the library the symbol comes from, but that
//! is currently always the case for things like libpthread/libc.
//!
//! A long time ago this used weak linkage for the __pthread_get_minstack
//! symbol, but that caused Debian to detect an unnecessarily strict versioned
//! dependency on libc6 (#23628) because it is GLIBC_PRIVATE. We now use `dlsym`
//! for a runtime lookup of that symbol to avoid the ELF versioned dependency.
#![forbid(unsafe_op_in_unsafe_fn)]
cfg_select! {
// On non-ELF targets, use the dlsym approximation of weak linkage.
target_vendor = "apple" => {
mod dlsym;
pub(crate) use dlsym::weak;
}
// Some targets don't need and support weak linkage at all...
target_os = "espidf" => {}
// ... but ELF targets support true weak linkage.
_ => {
// There are a variety of `#[cfg]`s controlling which targets are involved in
// each instance of `weak!`. Rather than trying to unify all of
// that, we'll just allow that some unix targets don't use this macro at all.
#[cfg_attr(not(target_os = "linux"), allow(unused_macros, dead_code))]
mod weak_linkage;
#[cfg_attr(not(target_os = "linux"), allow(unused_imports))]
pub(crate) use weak_linkage::weak;
}
}
// GNU/Linux needs the `dlsym` variant to avoid linking to private glibc symbols.
#[cfg(all(target_os = "linux", target_env = "gnu"))]
mod dlsym;
#[cfg(all(target_os = "linux", target_env = "gnu"))]
pub(crate) use dlsym::weak as dlsym;
#[cfg(any(target_os = "android", target_os = "linux"))]
mod syscall;
#[cfg(any(target_os = "android", target_os = "linux"))]
pub(crate) use syscall::syscall;