]>
git.proxmox.com Git - rustc.git/blob - src/libstd/sys/unix/weak.rs
1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! Support for "weak linkage" to symbols on Unix
13 //! Some I/O operations we do in libstd require newer versions of OSes but we
14 //! need to maintain binary compatibility with older releases for now. In order
15 //! to use the new functionality when available we use this module for
18 //! One option to use here is weak linkage, but that is unfortunately only
19 //! really workable on Linux. Hence, use dlsym to get the symbol value at
20 //! runtime. This is also done for compatibility with older versions of glibc,
21 //! and to avoid creating dependencies on GLIBC_PRIVATE symbols. It assumes that
22 //! we've been dynamically linked to the library the symbol comes from, but that
23 //! is currently always the case for things like libpthread/libc.
25 //! A long time ago this used weak linkage for the __pthread_get_minstack
26 //! symbol, but that caused Debian to detect an unnecessarily strict versioned
27 //! dependency on libc6 (#23628).
34 use sync
::atomic
::{AtomicUsize, Ordering}
;
37 (fn $name
:ident($
($t
:ty
),*) -> $ret
:ty
) => (
38 static $name
: ::sys
::weak
::Weak
<unsafe extern fn($
($t
),*) -> $ret
> =
39 ::sys
::weak
::Weak
::new(stringify
!($name
));
46 _marker
: marker
::PhantomData
<F
>,
50 pub const fn new(name
: &'
static str) -> Weak
<F
> {
53 addr
: AtomicUsize
::new(1),
54 _marker
: marker
::PhantomData
,
58 pub fn get(&self) -> Option
<&F
> {
59 assert_eq
!(mem
::size_of
::<F
>(), mem
::size_of
::<usize>());
61 if self.addr
.load(Ordering
::SeqCst
) == 1 {
62 self.addr
.store(fetch(self.name
), Ordering
::SeqCst
);
64 if self.addr
.load(Ordering
::SeqCst
) == 0 {
67 mem
::transmute
::<&AtomicUsize
, Option
<&F
>>(&self.addr
)
73 unsafe fn fetch(name
: &str) -> usize {
74 let name
= match CString
::new(name
) {
78 libc
::dlsym(libc
::RTLD_DEFAULT
, name
.as_ptr()) as usize