| 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 | |
| 21 | cfg_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" ))] |
| 45 | mod dlsym; |
| 46 | #[cfg (all(target_os = "linux" , target_env = "gnu" ))] |
| 47 | pub(crate) use dlsym::weak as dlsym; |
| 48 | |
| 49 | #[cfg (any(target_os = "android" , target_os = "linux" ))] |
| 50 | mod syscall; |
| 51 | #[cfg (any(target_os = "android" , target_os = "linux" ))] |
| 52 | pub(crate) use syscall::syscall; |
| 53 | |