From f2a90174bb36b9ad528e863ab34c02ebce002b02 Mon Sep 17 00:00:00 2001 From: Valentin Date: Fri, 15 Jun 2018 18:57:24 +0200 Subject: Update for latest nightly 2018-06-09 (#70) * Update for latest nightly 2018-06-09 * We now have a proper horizon os and sys modules in libstd --- ctr-std/src/sys/unix/weak.rs | 79 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 ctr-std/src/sys/unix/weak.rs (limited to 'ctr-std/src/sys/unix/weak.rs') diff --git a/ctr-std/src/sys/unix/weak.rs b/ctr-std/src/sys/unix/weak.rs new file mode 100644 index 0000000..18944be --- /dev/null +++ b/ctr-std/src/sys/unix/weak.rs @@ -0,0 +1,79 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Support for "weak linkage" to symbols on Unix +//! +//! Some I/O operations we do in libstd 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 on Linux. Hence, 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). + +use libc; + +use ffi::CString; +use marker; +use mem; +use sync::atomic::{AtomicUsize, Ordering}; + +macro_rules! weak { + (fn $name:ident($($t:ty),*) -> $ret:ty) => ( + static $name: ::sys::weak::Weak $ret> = + ::sys::weak::Weak::new(stringify!($name)); + ) +} + +pub struct Weak { + name: &'static str, + addr: AtomicUsize, + _marker: marker::PhantomData, +} + +impl Weak { + pub const fn new(name: &'static str) -> Weak { + Weak { + name, + addr: AtomicUsize::new(1), + _marker: marker::PhantomData, + } + } + + pub fn get(&self) -> Option<&F> { + assert_eq!(mem::size_of::(), mem::size_of::()); + unsafe { + if self.addr.load(Ordering::SeqCst) == 1 { + self.addr.store(fetch(self.name), Ordering::SeqCst); + } + if self.addr.load(Ordering::SeqCst) == 0 { + None + } else { + mem::transmute::<&AtomicUsize, Option<&F>>(&self.addr) + } + } + } +} + +unsafe fn fetch(name: &str) -> usize { + let name = match CString::new(name) { + Ok(cstr) => cstr, + Err(..) => return 0, + }; + libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr()) as usize +} -- cgit v1.2.3