| //! 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; |