about summary refs log tree commit diff
path: root/src/libstd/sys/windows
diff options
context:
space:
mode:
authorOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2017-12-06 09:25:29 +0100
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2017-12-06 09:25:29 +0100
commitacdf83f2288e1b80259dafeca4a0cee9a42973c3 (patch)
treeef7ffe46fee2f0b9f331a206af4a71d23fabe0a1 /src/libstd/sys/windows
parentd4c442d65c150b99d18202a5cce4a2cbdbd4dc83 (diff)
Update miri to rustc changes
Diffstat (limited to 'src/libstd/sys/windows')
-rw-r--r--src/libstd/sys/windows/backtrace/mod.rs4
-rw-r--r--src/libstd/sys/windows/backtrace/printing/msvc.rs6
-rw-r--r--src/libstd/sys/windows/c.rs33
-rw-r--r--src/libstd/sys/windows/cmath.rs103
-rw-r--r--src/libstd/sys/windows/ext/ffi.rs56
-rw-r--r--src/libstd/sys/windows/ext/fs.rs6
-rw-r--r--src/libstd/sys/windows/fs.rs8
-rw-r--r--src/libstd/sys/windows/mod.rs6
-rw-r--r--src/libstd/sys/windows/os.rs4
-rw-r--r--src/libstd/sys/windows/os_str.rs24
-rw-r--r--src/libstd/sys/windows/path.rs2
-rw-r--r--src/libstd/sys/windows/pipe.rs18
-rw-r--r--src/libstd/sys/windows/process.rs2
-rw-r--r--src/libstd/sys/windows/rand.rs70
-rw-r--r--src/libstd/sys/windows/stdio.rs5
-rw-r--r--src/libstd/sys/windows/thread.rs2
-rw-r--r--src/libstd/sys/windows/thread_local.rs3
17 files changed, 254 insertions, 98 deletions
diff --git a/src/libstd/sys/windows/backtrace/mod.rs b/src/libstd/sys/windows/backtrace/mod.rs
index 26b4cb90e0a..176891fff23 100644
--- a/src/libstd/sys/windows/backtrace/mod.rs
+++ b/src/libstd/sys/windows/backtrace/mod.rs
@@ -95,8 +95,8 @@ pub fn unwind_backtrace(frames: &mut [Frame])
                frame.AddrReturn.Offset == 0 { break }
 
             frames[i] = Frame {
-                symbol_addr: (addr - 1) as *const c_void,
-                exact_position: (addr - 1) as *const c_void,
+                symbol_addr: (addr - 1) as *const u8,
+                exact_position: (addr - 1) as *const u8,
             };
             i += 1;
         }
diff --git a/src/libstd/sys/windows/backtrace/printing/msvc.rs b/src/libstd/sys/windows/backtrace/printing/msvc.rs
index 3107d784324..5a49b77af8e 100644
--- a/src/libstd/sys/windows/backtrace/printing/msvc.rs
+++ b/src/libstd/sys/windows/backtrace/printing/msvc.rs
@@ -10,7 +10,7 @@
 
 use ffi::CStr;
 use io;
-use libc::{c_ulong, c_int, c_char};
+use libc::{c_ulong, c_char};
 use mem;
 use sys::c;
 use sys::backtrace::BacktraceContext;
@@ -59,7 +59,7 @@ pub fn foreach_symbol_fileline<F>(frame: Frame,
                                   mut f: F,
                                   context: &BacktraceContext)
     -> io::Result<bool>
-    where F: FnMut(&[u8], c_int) -> io::Result<()>
+    where F: FnMut(&[u8], u32) -> io::Result<()>
 {
     let SymGetLineFromAddr64 = sym!(&context.dbghelp,
                                     "SymGetLineFromAddr64",
@@ -76,7 +76,7 @@ pub fn foreach_symbol_fileline<F>(frame: Frame,
                                        &mut line);
         if ret == c::TRUE {
             let name = CStr::from_ptr(line.Filename).to_bytes();
-            f(name, line.LineNumber as c_int)?;
+            f(name, line.LineNumber as u32)?;
         }
         Ok(false)
     }
diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs
index 9535ddfe5ca..6e0cccff001 100644
--- a/src/libstd/sys/windows/c.rs
+++ b/src/libstd/sys/windows/c.rs
@@ -37,7 +37,6 @@ pub type BOOL = c_int;
 pub type BYTE = u8;
 pub type BOOLEAN = BYTE;
 pub type GROUP = c_uint;
-pub type LONG_PTR = isize;
 pub type LARGE_INTEGER = c_longlong;
 pub type LONG = c_long;
 pub type UINT = c_uint;
@@ -46,7 +45,6 @@ pub type USHORT = c_ushort;
 pub type SIZE_T = usize;
 pub type WORD = u16;
 pub type CHAR = c_char;
-pub type HCRYPTPROV = LONG_PTR;
 pub type ULONG_PTR = usize;
 pub type ULONG = c_ulong;
 #[cfg(target_arch = "x86_64")]
@@ -279,16 +277,15 @@ pub const WAIT_TIMEOUT: DWORD = 258;
 pub const WAIT_FAILED: DWORD = 0xFFFFFFFF;
 
 #[cfg(target_env = "msvc")]
+#[cfg(feature = "backtrace")]
 pub const MAX_SYM_NAME: usize = 2000;
 #[cfg(target_arch = "x86")]
+#[cfg(feature = "backtrace")]
 pub const IMAGE_FILE_MACHINE_I386: DWORD = 0x014c;
 #[cfg(target_arch = "x86_64")]
+#[cfg(feature = "backtrace")]
 pub const IMAGE_FILE_MACHINE_AMD64: DWORD = 0x8664;
 
-pub const PROV_RSA_FULL: DWORD = 1;
-pub const CRYPT_SILENT: DWORD = 64;
-pub const CRYPT_VERIFYCONTEXT: DWORD = 0xF0000000;
-
 pub const EXCEPTION_CONTINUE_SEARCH: LONG = 0;
 pub const EXCEPTION_STACK_OVERFLOW: DWORD = 0xc00000fd;
 pub const EXCEPTION_MAXIMUM_PARAMETERS: usize = 15;
@@ -575,6 +572,7 @@ pub struct OVERLAPPED {
 
 #[repr(C)]
 #[cfg(target_env = "msvc")]
+#[cfg(feature = "backtrace")]
 pub struct SYMBOL_INFO {
     pub SizeOfStruct: c_ulong,
     pub TypeIndex: c_ulong,
@@ -598,6 +596,7 @@ pub struct SYMBOL_INFO {
 
 #[repr(C)]
 #[cfg(target_env = "msvc")]
+#[cfg(feature = "backtrace")]
 pub struct IMAGEHLP_LINE64 {
     pub SizeOfStruct: u32,
     pub Key: *const c_void,
@@ -616,6 +615,7 @@ pub enum ADDRESS_MODE {
 }
 
 #[repr(C)]
+#[cfg(feature = "backtrace")]
 pub struct ADDRESS64 {
     pub Offset: u64,
     pub Segment: u16,
@@ -623,6 +623,7 @@ pub struct ADDRESS64 {
 }
 
 #[repr(C)]
+#[cfg(feature = "backtrace")]
 pub struct STACKFRAME64 {
     pub AddrPC: ADDRESS64,
     pub AddrReturn: ADDRESS64,
@@ -638,6 +639,7 @@ pub struct STACKFRAME64 {
 }
 
 #[repr(C)]
+#[cfg(feature = "backtrace")]
 pub struct KDHELP64 {
     pub Thread: u64,
     pub ThCallbackStack: DWORD,
@@ -1089,6 +1091,7 @@ extern "system" {
     pub fn FindNextFileW(findFile: HANDLE, findFileData: LPWIN32_FIND_DATAW)
                          -> BOOL;
     pub fn FindClose(findFile: HANDLE) -> BOOL;
+    #[cfg(feature = "backtrace")]
     pub fn RtlCaptureContext(ctx: *mut CONTEXT);
     pub fn getsockopt(s: SOCKET,
                       level: c_int,
@@ -1120,20 +1123,13 @@ extern "system" {
                        res: *mut *mut ADDRINFOA) -> c_int;
     pub fn freeaddrinfo(res: *mut ADDRINFOA);
 
+    #[cfg(feature = "backtrace")]
     pub fn LoadLibraryW(name: LPCWSTR) -> HMODULE;
+    #[cfg(feature = "backtrace")]
     pub fn FreeLibrary(handle: HMODULE) -> BOOL;
     pub fn GetProcAddress(handle: HMODULE,
                           name: LPCSTR) -> *mut c_void;
     pub fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
-    pub fn CryptAcquireContextA(phProv: *mut HCRYPTPROV,
-                                pszContainer: LPCSTR,
-                                pszProvider: LPCSTR,
-                                dwProvType: DWORD,
-                                dwFlags: DWORD) -> BOOL;
-    pub fn CryptGenRandom(hProv: HCRYPTPROV,
-                          dwLen: DWORD,
-                          pbBuffer: *mut BYTE) -> BOOL;
-    pub fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) -> BOOL;
 
     pub fn GetSystemTimeAsFileTime(lpSystemTimeAsFileTime: LPFILETIME);
 
@@ -1164,6 +1160,9 @@ extern "system" {
                   writefds: *mut fd_set,
                   exceptfds: *mut fd_set,
                   timeout: *const timeval) -> c_int;
+
+    #[link_name = "SystemFunction036"]
+    pub fn RtlGenRandom(RandomBuffer: *mut u8, RandomBufferLength: ULONG) -> BOOLEAN;
 }
 
 // Functions that aren't available on every version of Windows that we support,
@@ -1229,7 +1228,7 @@ compat_fn! {
     }
 }
 
-#[cfg(target_env = "gnu")]
+#[cfg(all(target_env = "gnu", feature = "backtrace"))]
 mod gnu {
     use super::*;
 
@@ -1257,5 +1256,5 @@ mod gnu {
     }
 }
 
-#[cfg(target_env = "gnu")]
+#[cfg(all(target_env = "gnu", feature = "backtrace"))]
 pub use self::gnu::*;
diff --git a/src/libstd/sys/windows/cmath.rs b/src/libstd/sys/windows/cmath.rs
new file mode 100644
index 00000000000..b665a2c9ba4
--- /dev/null
+++ b/src/libstd/sys/windows/cmath.rs
@@ -0,0 +1,103 @@
+// Copyright 2017 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![cfg(not(test))]
+
+use libc::{c_float, c_double};
+
+#[link_name = "m"]
+extern {
+    pub fn acos(n: c_double) -> c_double;
+    pub fn asin(n: c_double) -> c_double;
+    pub fn atan(n: c_double) -> c_double;
+    pub fn atan2(a: c_double, b: c_double) -> c_double;
+    pub fn cbrt(n: c_double) -> c_double;
+    pub fn cbrtf(n: c_float) -> c_float;
+    pub fn cosh(n: c_double) -> c_double;
+    pub fn expm1(n: c_double) -> c_double;
+    pub fn expm1f(n: c_float) -> c_float;
+    pub fn fdim(a: c_double, b: c_double) -> c_double;
+    pub fn fdimf(a: c_float, b: c_float) -> c_float;
+    #[cfg_attr(target_env = "msvc", link_name = "_hypot")]
+    pub fn hypot(x: c_double, y: c_double) -> c_double;
+    #[cfg_attr(target_env = "msvc", link_name = "_hypotf")]
+    pub fn hypotf(x: c_float, y: c_float) -> c_float;
+    pub fn log1p(n: c_double) -> c_double;
+    pub fn log1pf(n: c_float) -> c_float;
+    pub fn sinh(n: c_double) -> c_double;
+    pub fn tan(n: c_double) -> c_double;
+    pub fn tanh(n: c_double) -> c_double;
+}
+
+pub use self::shims::*;
+
+#[cfg(not(target_env = "msvc"))]
+mod shims {
+    use libc::c_float;
+
+    extern {
+        pub fn acosf(n: c_float) -> c_float;
+        pub fn asinf(n: c_float) -> c_float;
+        pub fn atan2f(a: c_float, b: c_float) -> c_float;
+        pub fn atanf(n: c_float) -> c_float;
+        pub fn coshf(n: c_float) -> c_float;
+        pub fn sinhf(n: c_float) -> c_float;
+        pub fn tanf(n: c_float) -> c_float;
+        pub fn tanhf(n: c_float) -> c_float;
+    }
+}
+
+// On MSVC these functions aren't defined, so we just define shims which promote
+// everything fo f64, perform the calculation, and then demote back to f32.
+// While not precisely correct should be "correct enough" for now.
+#[cfg(target_env = "msvc")]
+mod shims {
+    use libc::c_float;
+
+    #[inline]
+    pub unsafe fn acosf(n: c_float) -> c_float {
+        f64::acos(n as f64) as c_float
+    }
+
+    #[inline]
+    pub unsafe fn asinf(n: c_float) -> c_float {
+        f64::asin(n as f64) as c_float
+    }
+
+    #[inline]
+    pub unsafe fn atan2f(n: c_float, b: c_float) -> c_float {
+        f64::atan2(n as f64, b as f64) as c_float
+    }
+
+    #[inline]
+    pub unsafe fn atanf(n: c_float) -> c_float {
+        f64::atan(n as f64) as c_float
+    }
+
+    #[inline]
+    pub unsafe fn coshf(n: c_float) -> c_float {
+        f64::cosh(n as f64) as c_float
+    }
+
+    #[inline]
+    pub unsafe fn sinhf(n: c_float) -> c_float {
+        f64::sinh(n as f64) as c_float
+    }
+
+    #[inline]
+    pub unsafe fn tanf(n: c_float) -> c_float {
+        f64::tan(n as f64) as c_float
+    }
+
+    #[inline]
+    pub unsafe fn tanhf(n: c_float) -> c_float {
+        f64::tanh(n as f64) as c_float
+    }
+}
diff --git a/src/libstd/sys/windows/ext/ffi.rs b/src/libstd/sys/windows/ext/ffi.rs
index 3f6c2827a3f..d6b8896ac09 100644
--- a/src/libstd/sys/windows/ext/ffi.rs
+++ b/src/libstd/sys/windows/ext/ffi.rs
@@ -9,6 +9,62 @@
 // except according to those terms.
 
 //! Windows-specific extensions to the primitives in the `std::ffi` module.
+//!
+//! # Overview
+//!
+//! For historical reasons, the Windows API uses a form of potentially
+//! ill-formed UTF-16 encoding for strings.  Specifically, the 16-bit
+//! code units in Windows strings may contain [isolated surrogate code
+//! points which are not paired together][ill-formed-utf-16].  The
+//! Unicode standard requires that surrogate code points (those in the
+//! range U+D800 to U+DFFF) always be *paired*, because in the UTF-16
+//! encoding a *surrogate code unit pair* is used to encode a single
+//! character.  For compatibility with code that does not enforce
+//! these pairings, Windows does not enforce them, either.
+//!
+//! While it is not always possible to convert such a string losslessly into
+//! a valid UTF-16 string (or even UTF-8), it is often desirable to be
+//! able to round-trip such a string from and to Windows APIs
+//! losslessly.  For example, some Rust code may be "bridging" some
+//! Windows APIs together, just passing `WCHAR` strings among those
+//! APIs without ever really looking into the strings.
+//!
+//! If Rust code *does* need to look into those strings, it can
+//! convert them to valid UTF-8, possibly lossily, by substituting
+//! invalid sequences with U+FFFD REPLACEMENT CHARACTER, as is
+//! conventionally done in other Rust APIs that deal with string
+//! encodings.
+//!
+//! # `OsStringExt` and `OsStrExt`
+//!
+//! [`OsString`] is the Rust wrapper for owned strings in the
+//! preferred representation of the operating system.  On Windows,
+//! this struct gets augmented with an implementation of the
+//! [`OsStringExt`] trait, which has a [`from_wide`] method.  This
+//! lets you create an [`OsString`] from a `&[u16]` slice; presumably
+//! you get such a slice out of a `WCHAR` Windows API.
+//!
+//! Similarly, [`OsStr`] is the Rust wrapper for borrowed strings from
+//! preferred representation of the operating system.  On Windows, the
+//! [`OsStrExt`] trait provides the [`encode_wide`] method, which
+//! outputs an [`EncodeWide`] iterator.  You can [`collect`] this
+//! iterator, for example, to obtain a `Vec<u16>`; you can later get a
+//! pointer to this vector's contents and feed it to Windows APIs.
+//!
+//! These traits, along with [`OsString`] and [`OsStr`], work in
+//! conjunction so that it is possible to **round-trip** strings from
+//! Windows and back, with no loss of data, even if the strings are
+//! ill-formed UTF-16.
+//!
+//! [ill-formed-utf-16]: https://simonsapin.github.io/wtf-8/#ill-formed-utf-16
+//! [`OsString`]: ../../../ffi/struct.OsString.html
+//! [`OsStr`]: ../../../ffi/struct.OsStr.html
+//! [`OsStringExt`]: trait.OsStringExt.html
+//! [`OsStrExt`]: trait.OsStrExt.html
+//! [`EncodeWide`]: struct.EncodeWide.html
+//! [`from_wide`]: trait.OsStringExt.html#tymethod.from_wide
+//! [`encode_wide`]: trait.OsStrExt.html#tymethod.encode_wide
+//! [`collect`]: ../../../iter/trait.Iterator.html#method.collect
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs
index d58a3505154..24c41046f26 100644
--- a/src/libstd/sys/windows/ext/fs.rs
+++ b/src/libstd/sys/windows/ext/fs.rs
@@ -32,7 +32,7 @@ pub trait FileExt {
     /// function, it is set to the end of the read.
     ///
     /// Reading beyond the end of the file will always return with a length of
-    /// 0.
+    /// 0\.
     ///
     /// Note that similar to `File::read`, it is not an error to return with a
     /// short read. When returning from such a short read, the file pointer is
@@ -393,8 +393,8 @@ pub trait MetadataExt {
     /// to. For a directory, the structure specifies when the directory was
     /// created.
     ///
-    /// If the underlying filesystem does not support the last write time
-    /// time, the returned value is 0.
+    /// If the underlying filesystem does not support the last write time,
+    /// the returned value is 0.
     ///
     /// # Examples
     ///
diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs
index f2487c1b0bd..ae9535139d9 100644
--- a/src/libstd/sys/windows/fs.rs
+++ b/src/libstd/sys/windows/fs.rs
@@ -722,16 +722,16 @@ pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
 pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
     unsafe extern "system" fn callback(
         _TotalFileSize: c::LARGE_INTEGER,
-        TotalBytesTransferred: c::LARGE_INTEGER,
+        _TotalBytesTransferred: c::LARGE_INTEGER,
         _StreamSize: c::LARGE_INTEGER,
-        _StreamBytesTransferred: c::LARGE_INTEGER,
-        _dwStreamNumber: c::DWORD,
+        StreamBytesTransferred: c::LARGE_INTEGER,
+        dwStreamNumber: c::DWORD,
         _dwCallbackReason: c::DWORD,
         _hSourceFile: c::HANDLE,
         _hDestinationFile: c::HANDLE,
         lpData: c::LPVOID,
     ) -> c::DWORD {
-        *(lpData as *mut i64) = TotalBytesTransferred;
+        if dwStreamNumber == 1 {*(lpData as *mut i64) = StreamBytesTransferred;}
         c::PROGRESS_CONTINUE
     }
     let pfrom = to_u16s(from)?;
diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs
index ee58efc5144..0d12ecf8fe3 100644
--- a/src/libstd/sys/windows/mod.rs
+++ b/src/libstd/sys/windows/mod.rs
@@ -17,12 +17,18 @@ use os::windows::ffi::{OsStrExt, OsStringExt};
 use path::PathBuf;
 use time::Duration;
 
+pub use libc::strlen;
+pub use self::rand::hashmap_random_keys;
+
 #[macro_use] pub mod compat;
 
 pub mod args;
+#[cfg(feature = "backtrace")]
 pub mod backtrace;
 pub mod c;
+pub mod cmath;
 pub mod condvar;
+#[cfg(feature = "backtrace")]
 pub mod dynamic_lib;
 pub mod env;
 pub mod ext;
diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs
index a51b458451e..b9448243559 100644
--- a/src/libstd/sys/windows/os.rs
+++ b/src/libstd/sys/windows/os.rs
@@ -318,6 +318,10 @@ pub fn exit(code: i32) -> ! {
     unsafe { c::ExitProcess(code as c::UINT) }
 }
 
+pub fn getpid() -> u32 {
+    unsafe { c::GetCurrentProcessId() as u32 }
+}
+
 #[cfg(test)]
 mod tests {
     use io::Error;
diff --git a/src/libstd/sys/windows/os_str.rs b/src/libstd/sys/windows/os_str.rs
index 3eb4582718b..b8d2f7bc53c 100644
--- a/src/libstd/sys/windows/os_str.rs
+++ b/src/libstd/sys/windows/os_str.rs
@@ -15,6 +15,8 @@ use borrow::Cow;
 use fmt;
 use sys_common::wtf8::{Wtf8, Wtf8Buf};
 use mem;
+use rc::Rc;
+use sync::Arc;
 use sys_common::{AsInner, IntoInner};
 
 #[derive(Clone, Hash)]
@@ -115,6 +117,16 @@ impl Buf {
         let inner: Box<Wtf8> = unsafe { mem::transmute(boxed) };
         Buf { inner: Wtf8Buf::from_box(inner) }
     }
+
+    #[inline]
+    pub fn into_arc(&self) -> Arc<Slice> {
+        self.as_slice().into_arc()
+    }
+
+    #[inline]
+    pub fn into_rc(&self) -> Rc<Slice> {
+        self.as_slice().into_rc()
+    }
 }
 
 impl Slice {
@@ -144,4 +156,16 @@ impl Slice {
     pub fn empty_box() -> Box<Slice> {
         unsafe { mem::transmute(Wtf8::empty_box()) }
     }
+
+    #[inline]
+    pub fn into_arc(&self) -> Arc<Slice> {
+        let arc = self.inner.into_arc();
+        unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) }
+    }
+
+    #[inline]
+    pub fn into_rc(&self) -> Rc<Slice> {
+        let rc = self.inner.into_rc();
+        unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
+    }
 }
diff --git a/src/libstd/sys/windows/path.rs b/src/libstd/sys/windows/path.rs
index 2b47808451b..98d62a0c953 100644
--- a/src/libstd/sys/windows/path.rs
+++ b/src/libstd/sys/windows/path.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use ascii::*;
-
 use path::Prefix;
 use ffi::OsStr;
 use mem;
diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs
index 452d720ce59..f3b1185c6ea 100644
--- a/src/libstd/sys/windows/pipe.rs
+++ b/src/libstd/sys/windows/pipe.rs
@@ -15,11 +15,13 @@ use io;
 use mem;
 use path::Path;
 use ptr;
-use rand::{self, Rng};
 use slice;
+use sync::atomic::Ordering::SeqCst;
+use sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT};
 use sys::c;
 use sys::fs::{File, OpenOptions};
 use sys::handle::Handle;
+use sys::hashmap_random_keys;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Anonymous pipes
@@ -71,10 +73,9 @@ pub fn anon_pipe(ours_readable: bool) -> io::Result<Pipes> {
         let mut reject_remote_clients_flag = c::PIPE_REJECT_REMOTE_CLIENTS;
         loop {
             tries += 1;
-            let key: u64 = rand::thread_rng().gen();
             name = format!(r"\\.\pipe\__rust_anonymous_pipe1__.{}.{}",
                            c::GetCurrentProcessId(),
-                           key);
+                           random_number());
             let wide_name = OsStr::new(&name)
                                   .encode_wide()
                                   .chain(Some(0))
@@ -156,6 +157,17 @@ pub fn anon_pipe(ours_readable: bool) -> io::Result<Pipes> {
     }
 }
 
+fn random_number() -> usize {
+    static N: AtomicUsize = ATOMIC_USIZE_INIT;
+    loop {
+        if N.load(SeqCst) != 0 {
+            return N.fetch_add(1, SeqCst)
+        }
+
+        N.store(hashmap_random_keys().0 as usize, SeqCst);
+    }
+}
+
 impl AnonPipe {
     pub fn handle(&self) -> &Handle { &self.inner }
     pub fn into_handle(self) -> Handle { self.inner }
diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs
index 0d1766d5aec..631d69b05e1 100644
--- a/src/libstd/sys/windows/process.rs
+++ b/src/libstd/sys/windows/process.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use ascii::*;
+use ascii::AsciiExt;
 use collections::HashMap;
 use collections;
 use env::split_paths;
diff --git a/src/libstd/sys/windows/rand.rs b/src/libstd/sys/windows/rand.rs
index 10e3d45f9d5..262323656aa 100644
--- a/src/libstd/sys/windows/rand.rs
+++ b/src/libstd/sys/windows/rand.rs
@@ -8,69 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
 use io;
 use mem;
-use rand::Rng;
 use sys::c;
 
-pub struct OsRng {
-    hcryptprov: c::HCRYPTPROV
-}
-
-impl OsRng {
-    /// Create a new `OsRng`.
-    pub fn new() -> io::Result<OsRng> {
-        let mut hcp = 0;
-        let ret = unsafe {
-            c::CryptAcquireContextA(&mut hcp, 0 as c::LPCSTR, 0 as c::LPCSTR,
-                                    c::PROV_RSA_FULL,
-                                    c::CRYPT_VERIFYCONTEXT | c::CRYPT_SILENT)
-        };
-
-        if ret == 0 {
-            Err(io::Error::last_os_error())
-        } else {
-            Ok(OsRng { hcryptprov: hcp })
-        }
-    }
-}
-
-impl Rng for OsRng {
-    fn next_u32(&mut self) -> u32 {
-        let mut v = [0; 4];
-        self.fill_bytes(&mut v);
-        unsafe { mem::transmute(v) }
-    }
-    fn next_u64(&mut self) -> u64 {
-        let mut v = [0; 8];
-        self.fill_bytes(&mut v);
-        unsafe { mem::transmute(v) }
-    }
-    fn fill_bytes(&mut self, v: &mut [u8]) {
-        // CryptGenRandom takes a DWORD (u32) for the length so we need to
-        // split up the buffer.
-        for slice in v.chunks_mut(<c::DWORD>::max_value() as usize) {
-            let ret = unsafe {
-                c::CryptGenRandom(self.hcryptprov, slice.len() as c::DWORD,
-                                  slice.as_mut_ptr())
-            };
-            if ret == 0 {
-                panic!("couldn't generate random bytes: {}",
-                       io::Error::last_os_error());
-            }
-        }
-    }
-}
-
-impl Drop for OsRng {
-    fn drop(&mut self) {
-        let ret = unsafe {
-            c::CryptReleaseContext(self.hcryptprov, 0)
-        };
-        if ret == 0 {
-            panic!("couldn't release context: {}",
-                   io::Error::last_os_error());
-        }
+pub fn hashmap_random_keys() -> (u64, u64) {
+    let mut v = (0, 0);
+    let ret = unsafe {
+        c::RtlGenRandom(&mut v as *mut _ as *mut u8,
+                        mem::size_of_val(&v) as c::ULONG)
+    };
+    if ret == 0 {
+        panic!("couldn't generate random bytes: {}",
+               io::Error::last_os_error());
     }
+    return v
 }
diff --git a/src/libstd/sys/windows/stdio.rs b/src/libstd/sys/windows/stdio.rs
index b5e5b5760f2..b43df20bddd 100644
--- a/src/libstd/sys/windows/stdio.rs
+++ b/src/libstd/sys/windows/stdio.rs
@@ -218,7 +218,10 @@ fn readconsole_input_control(wakeup_mask: c::ULONG) -> c::CONSOLE_READCONSOLE_CO
 const CTRL_Z: u8 = 0x1A;
 const CTRL_Z_MASK: c::ULONG = 0x4000000; //1 << 0x1A
 
-pub const EBADF_ERR: i32 = ::sys::c::ERROR_INVALID_HANDLE as i32;
+pub fn is_ebadf(err: &io::Error) -> bool {
+    err.raw_os_error() == Some(c::ERROR_INVALID_HANDLE as i32)
+}
+
 // The default buffer capacity is 64k, but apparently windows
 // doesn't like 64k reads on stdin. See #13304 for details, but the
 // idea is that on windows we use a slightly smaller buffer that's
diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs
index c47baaa2434..74786d09285 100644
--- a/src/libstd/sys/windows/thread.rs
+++ b/src/libstd/sys/windows/thread.rs
@@ -52,7 +52,7 @@ impl Thread {
         };
 
         extern "system" fn thread_start(main: *mut c_void) -> c::DWORD {
-            unsafe { start_thread(main); }
+            unsafe { start_thread(main as *mut u8); }
             0
         }
     }
diff --git a/src/libstd/sys/windows/thread_local.rs b/src/libstd/sys/windows/thread_local.rs
index 7ae9ed917bd..cdad320e122 100644
--- a/src/libstd/sys/windows/thread_local.rs
+++ b/src/libstd/sys/windows/thread_local.rs
@@ -200,8 +200,9 @@ unsafe fn register_dtor(key: Key, dtor: Dtor) {
 // the address of the symbol to ensure it sticks around.
 
 #[link_section = ".CRT$XLB"]
-#[linkage = "external"]
 #[allow(dead_code, unused_variables)]
+#[used] // we don't want LLVM eliminating this symbol for any reason, and
+        // when the symbol makes it to the linker the linker will take over
 pub static p_thread_callback: unsafe extern "system" fn(c::LPVOID, c::DWORD,
                                                         c::LPVOID) =
         on_tls_callback;