about summary refs log tree commit diff
path: root/src/libstd/sys
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd/sys')
-rw-r--r--src/libstd/sys/cloudabi/io.rs1
-rw-r--r--src/libstd/sys/cloudabi/mutex.rs8
-rw-r--r--src/libstd/sys/cloudabi/stack_overflow.rs8
-rw-r--r--src/libstd/sys/cloudabi/thread.rs15
-rw-r--r--src/libstd/sys/hermit/io.rs1
-rw-r--r--src/libstd/sys/hermit/mod.rs4
-rw-r--r--src/libstd/sys/hermit/mutex.rs6
-rw-r--r--src/libstd/sys/hermit/net.rs239
-rw-r--r--src/libstd/sys/hermit/stack_overflow.rs8
-rw-r--r--src/libstd/sys/hermit/thread.rs19
-rw-r--r--src/libstd/sys/sgx/abi/mem.rs2
-rw-r--r--src/libstd/sys/sgx/abi/usercalls/alloc.rs2
-rw-r--r--src/libstd/sys/sgx/ext/arch.rs4
-rw-r--r--src/libstd/sys/sgx/io.rs1
-rw-r--r--src/libstd/sys/sgx/mutex.rs2
-rw-r--r--src/libstd/sys/sgx/stack_overflow.rs8
-rw-r--r--src/libstd/sys/unix/io.rs1
-rw-r--r--src/libstd/sys/unix/mod.rs2
-rw-r--r--src/libstd/sys/unix/mutex.rs4
-rw-r--r--src/libstd/sys/unix/process/process_common.rs4
-rw-r--r--src/libstd/sys/unix/process/process_unix.rs2
-rw-r--r--src/libstd/sys/unix/rand.rs37
-rw-r--r--src/libstd/sys/unix/stack_overflow.rs51
-rw-r--r--src/libstd/sys/unix/thread.rs21
-rw-r--r--src/libstd/sys/vxworks/io.rs1
-rw-r--r--src/libstd/sys/vxworks/mod.rs2
-rw-r--r--src/libstd/sys/vxworks/mutex.rs4
-rw-r--r--src/libstd/sys/vxworks/thread.rs21
-rw-r--r--src/libstd/sys/wasi/alloc.rs2
-rw-r--r--src/libstd/sys/wasi/io.rs1
-rw-r--r--src/libstd/sys/wasm/io.rs1
-rw-r--r--src/libstd/sys/wasm/mutex.rs4
-rw-r--r--src/libstd/sys/wasm/mutex_atomics.rs4
-rw-r--r--src/libstd/sys/wasm/stack_overflow.rs8
-rw-r--r--src/libstd/sys/windows/c.rs7
-rw-r--r--src/libstd/sys/windows/handle.rs5
-rw-r--r--src/libstd/sys/windows/io.rs1
-rw-r--r--src/libstd/sys/windows/mod.rs2
-rw-r--r--src/libstd/sys/windows/mutex.rs6
-rw-r--r--src/libstd/sys/windows/os.rs2
-rw-r--r--src/libstd/sys/windows/os_str.rs42
-rw-r--r--src/libstd/sys/windows/process.rs9
-rw-r--r--src/libstd/sys/windows/thread.rs17
-rw-r--r--src/libstd/sys/windows/time.rs2
44 files changed, 384 insertions, 207 deletions
diff --git a/src/libstd/sys/cloudabi/io.rs b/src/libstd/sys/cloudabi/io.rs
index 976e122463d..d5f475b4310 100644
--- a/src/libstd/sys/cloudabi/io.rs
+++ b/src/libstd/sys/cloudabi/io.rs
@@ -1,5 +1,6 @@
 use crate::mem;
 
+#[derive(Copy, Clone)]
 pub struct IoSlice<'a>(&'a [u8]);
 
 impl<'a> IoSlice<'a> {
diff --git a/src/libstd/sys/cloudabi/mutex.rs b/src/libstd/sys/cloudabi/mutex.rs
index 4aa25e25052..580ab0e8ad8 100644
--- a/src/libstd/sys/cloudabi/mutex.rs
+++ b/src/libstd/sys/cloudabi/mutex.rs
@@ -53,16 +53,16 @@ pub struct ReentrantMutex {
 }
 
 impl ReentrantMutex {
-    pub unsafe fn uninitialized() -> ReentrantMutex {
+    pub const unsafe fn uninitialized() -> ReentrantMutex {
         ReentrantMutex {
             lock: UnsafeCell::new(MaybeUninit::uninit()),
             recursion: UnsafeCell::new(MaybeUninit::uninit()),
         }
     }
 
-    pub unsafe fn init(&mut self) {
-        self.lock = UnsafeCell::new(MaybeUninit::new(AtomicU32::new(abi::LOCK_UNLOCKED.0)));
-        self.recursion = UnsafeCell::new(MaybeUninit::new(0));
+    pub unsafe fn init(&self) {
+        *self.lock.get() = MaybeUninit::new(AtomicU32::new(abi::LOCK_UNLOCKED.0));
+        *self.recursion.get() = MaybeUninit::new(0);
     }
 
     pub unsafe fn try_lock(&self) -> bool {
diff --git a/src/libstd/sys/cloudabi/stack_overflow.rs b/src/libstd/sys/cloudabi/stack_overflow.rs
index e97831b2c28..9339b143731 100644
--- a/src/libstd/sys/cloudabi/stack_overflow.rs
+++ b/src/libstd/sys/cloudabi/stack_overflow.rs
@@ -1,13 +1,5 @@
 #![cfg_attr(test, allow(dead_code))]
 
-pub struct Handler;
-
-impl Handler {
-    pub unsafe fn new() -> Handler {
-        Handler
-    }
-}
-
 pub unsafe fn init() {}
 
 pub unsafe fn cleanup() {}
diff --git a/src/libstd/sys/cloudabi/thread.rs b/src/libstd/sys/cloudabi/thread.rs
index 3afcae7ae75..a15dc8653e8 100644
--- a/src/libstd/sys/cloudabi/thread.rs
+++ b/src/libstd/sys/cloudabi/thread.rs
@@ -5,7 +5,6 @@ use crate::mem;
 use crate::ptr;
 use crate::sys::cloudabi::abi;
 use crate::sys::time::checked_dur2intervals;
-use crate::sys_common::thread::*;
 use crate::time::Duration;
 
 pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024;
@@ -22,7 +21,7 @@ unsafe impl Sync for Thread {}
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
     pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
-        let p = box p;
+        let p = Box::into_raw(box p);
         let mut native: libc::pthread_t = mem::zeroed();
         let mut attr: libc::pthread_attr_t = mem::zeroed();
         assert_eq!(libc::pthread_attr_init(&mut attr), 0);
@@ -30,19 +29,25 @@ impl Thread {
         let stack_size = cmp::max(stack, min_stack_size(&attr));
         assert_eq!(libc::pthread_attr_setstacksize(&mut attr, stack_size), 0);
 
-        let ret = libc::pthread_create(&mut native, &attr, thread_start, &*p as *const _ as *mut _);
+        let ret = libc::pthread_create(&mut native, &attr, thread_start, p as *mut _);
+        // Note: if the thread creation fails and this assert fails, then p will
+        // be leaked. However, an alternative design could cause double-free
+        // which is clearly worse.
         assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
 
         return if ret != 0 {
+            // The thread failed to start and as a result p was not consumed. Therefore, it is
+            // safe to reconstruct the box so that it gets deallocated.
+            drop(Box::from_raw(p));
             Err(io::Error::from_raw_os_error(ret))
         } else {
-            mem::forget(p); // ownership passed to pthread_create
             Ok(Thread { id: native })
         };
 
         extern "C" fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
             unsafe {
-                start_thread(main as *mut u8);
+                // Let's run some code.
+                Box::from_raw(main as *mut Box<dyn FnOnce()>)();
             }
             ptr::null_mut()
         }
diff --git a/src/libstd/sys/hermit/io.rs b/src/libstd/sys/hermit/io.rs
index 976e122463d..d5f475b4310 100644
--- a/src/libstd/sys/hermit/io.rs
+++ b/src/libstd/sys/hermit/io.rs
@@ -1,5 +1,6 @@
 use crate::mem;
 
+#[derive(Copy, Clone)]
 pub struct IoSlice<'a>(&'a [u8]);
 
 impl<'a> IoSlice<'a> {
diff --git a/src/libstd/sys/hermit/mod.rs b/src/libstd/sys/hermit/mod.rs
index 1e4a53abdc7..958532b8fc4 100644
--- a/src/libstd/sys/hermit/mod.rs
+++ b/src/libstd/sys/hermit/mod.rs
@@ -93,9 +93,7 @@ pub unsafe extern "C" fn __rust_abort() {
 
 #[cfg(not(test))]
 pub fn init() {
-    unsafe {
-        let _ = net::init();
-    }
+    let _ = net::init();
 }
 
 #[cfg(not(test))]
diff --git a/src/libstd/sys/hermit/mutex.rs b/src/libstd/sys/hermit/mutex.rs
index b5c75f738d2..3d4813209cb 100644
--- a/src/libstd/sys/hermit/mutex.rs
+++ b/src/libstd/sys/hermit/mutex.rs
@@ -46,13 +46,13 @@ pub struct ReentrantMutex {
 }
 
 impl ReentrantMutex {
-    pub unsafe fn uninitialized() -> ReentrantMutex {
+    pub const unsafe fn uninitialized() -> ReentrantMutex {
         ReentrantMutex { inner: ptr::null() }
     }
 
     #[inline]
-    pub unsafe fn init(&mut self) {
-        let _ = abi::recmutex_init(&mut self.inner as *mut *const c_void);
+    pub unsafe fn init(&self) {
+        let _ = abi::recmutex_init(&self.inner as *const *const c_void as *mut _);
     }
 
     #[inline]
diff --git a/src/libstd/sys/hermit/net.rs b/src/libstd/sys/hermit/net.rs
index 82917e71be1..377c3132c5a 100644
--- a/src/libstd/sys/hermit/net.rs
+++ b/src/libstd/sys/hermit/net.rs
@@ -1,291 +1,362 @@
 use crate::convert::TryFrom;
 use crate::fmt;
-use crate::io::{self, IoSlice, IoSliceMut};
+use crate::io::{self, ErrorKind, IoSlice, IoSliceMut};
 use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
 use crate::str;
+use crate::sys::hermit::abi;
 use crate::sys::{unsupported, Void};
 use crate::time::Duration;
 
-//// Iinitializes HermitCore's network stack
-pub unsafe fn init() -> io::Result<()> {
+/// Checks whether the HermitCore's socket interface has been started already, and
+/// if not, starts it.
+pub fn init() -> io::Result<()> {
+    if abi::network_init() < 0 {
+        return Err(io::Error::new(ErrorKind::Other, "Unable to initialize network interface"));
+    }
+
     Ok(())
 }
 
-pub struct TcpStream(Void);
+pub struct TcpStream(abi::Handle);
 
 impl TcpStream {
-    pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
-        unsupported()
+    pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
+        let addr = addr?;
+
+        match abi::tcpstream::connect(addr.ip().to_string().as_bytes(), addr.port(), None) {
+            Ok(handle) => Ok(TcpStream(handle)),
+            _ => {
+                Err(io::Error::new(ErrorKind::Other, "Unable to initiate a connection on a socket"))
+            }
+        }
     }
 
-    pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
-        unsupported()
+    pub fn connect_timeout(saddr: &SocketAddr, duration: Duration) -> io::Result<TcpStream> {
+        match abi::tcpstream::connect(
+            saddr.ip().to_string().as_bytes(),
+            saddr.port(),
+            Some(duration.as_millis() as u64),
+        ) {
+            Ok(handle) => Ok(TcpStream(handle)),
+            _ => {
+                Err(io::Error::new(ErrorKind::Other, "Unable to initiate a connection on a socket"))
+            }
+        }
     }
 
-    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
-        match self.0 {}
+    pub fn set_read_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
+        abi::tcpstream::set_read_timeout(self.0, duration.map(|d| d.as_millis() as u64))
+            .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to set timeout value"))
     }
 
-    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
-        match self.0 {}
+    pub fn set_write_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
+        abi::tcpstream::set_write_timeout(self.0, duration.map(|d| d.as_millis() as u64))
+            .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to set timeout value"))
     }
 
     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
-        match self.0 {}
+        let duration = abi::tcpstream::get_read_timeout(self.0)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to determine timeout value"))?;
+
+        Ok(duration.map(|d| Duration::from_millis(d)))
     }
 
     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
-        match self.0 {}
+        let duration = abi::tcpstream::get_write_timeout(self.0)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to determine timeout value"))?;
+
+        Ok(duration.map(|d| Duration::from_millis(d)))
     }
 
-    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
-        match self.0 {}
+    pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
+        abi::tcpstream::peek(self.0, buf)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "set_nodelay failed"))
     }
 
-    pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
-        match self.0 {}
+    pub fn read(&self, buffer: &mut [u8]) -> io::Result<usize> {
+        self.read_vectored(&mut [IoSliceMut::new(buffer)])
     }
 
-    pub fn read_vectored(&self, _: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
-        match self.0 {}
+    pub fn read_vectored(&self, ioslice: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+        let mut size: usize = 0;
+
+        for i in ioslice.iter_mut() {
+            let mut pos: usize = 0;
+
+            while pos < i.len() {
+                let ret = abi::tcpstream::read(self.0, &mut i[pos..])
+                    .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to read on socket"))?;
+
+                if ret == 0 {
+                    return Ok(size);
+                } else {
+                    size += ret;
+                    pos += ret;
+                }
+            }
+        }
+
+        Ok(size)
     }
 
-    pub fn write(&self, _: &[u8]) -> io::Result<usize> {
-        match self.0 {}
+    pub fn write(&self, buffer: &[u8]) -> io::Result<usize> {
+        self.write_vectored(&[IoSlice::new(buffer)])
     }
 
-    pub fn write_vectored(&self, _: &[IoSlice<'_>]) -> io::Result<usize> {
-        match self.0 {}
+    pub fn write_vectored(&self, ioslice: &[IoSlice<'_>]) -> io::Result<usize> {
+        let mut size: usize = 0;
+
+        for i in ioslice.iter() {
+            size += abi::tcpstream::write(self.0, i)
+                .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to write on socket"))?;
+        }
+
+        Ok(size)
     }
 
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "peer_addr isn't supported"))
     }
 
     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "socket_addr isn't supported"))
     }
 
-    pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
-        match self.0 {}
+    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
+        abi::tcpstream::shutdown(self.0, how as i32)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "unable to shutdown socket"))
     }
 
     pub fn duplicate(&self) -> io::Result<TcpStream> {
-        match self.0 {}
+        let handle = abi::tcpstream::duplicate(self.0)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "unable to duplicate stream"))?;
+
+        Ok(TcpStream(handle))
     }
 
-    pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+    pub fn set_nodelay(&self, mode: bool) -> io::Result<()> {
+        abi::tcpstream::set_nodelay(self.0, mode)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "set_nodelay failed"))
     }
 
     pub fn nodelay(&self) -> io::Result<bool> {
-        match self.0 {}
+        abi::tcpstream::nodelay(self.0)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "nodelay failed"))
     }
 
-    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
-        match self.0 {}
+    pub fn set_ttl(&self, tll: u32) -> io::Result<()> {
+        abi::tcpstream::set_tll(self.0, tll)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "unable to set TTL"))
     }
 
     pub fn ttl(&self) -> io::Result<u32> {
-        match self.0 {}
+        abi::tcpstream::get_tll(self.0)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "unable to get TTL"))
     }
 
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "take_error isn't supported"))
     }
 
-    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+    pub fn set_nonblocking(&self, mode: bool) -> io::Result<()> {
+        abi::tcpstream::set_nonblocking(self.0, mode)
+            .map_err(|_| io::Error::new(ErrorKind::Other, "unable to set blocking mode"))
+    }
+}
+
+impl Drop for TcpStream {
+    fn drop(&mut self) {
+        let _ = abi::tcpstream::close(self.0);
     }
 }
 
 impl fmt::Debug for TcpStream {
     fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.0 {}
+        Ok(())
     }
 }
 
-pub struct TcpListener(Void);
+pub struct TcpListener(abi::Handle);
 
 impl TcpListener {
     pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
-        unsupported()
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn duplicate(&self) -> io::Result<TcpListener> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_ttl(&self, _: u32) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn ttl(&self) -> io::Result<u32> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn only_v6(&self) -> io::Result<bool> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 }
 
 impl fmt::Debug for TcpListener {
     fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.0 {}
+        Ok(())
     }
 }
 
-pub struct UdpSocket(Void);
+pub struct UdpSocket(abi::Handle);
 
 impl UdpSocket {
     pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
-        unsupported()
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn duplicate(&self) -> io::Result<UdpSocket> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn broadcast(&self) -> io::Result<bool> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn multicast_loop_v4(&self) -> io::Result<bool> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn multicast_loop_v6(&self) -> io::Result<bool> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_ttl(&self, _: u32) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn ttl(&self) -> io::Result<u32> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn send(&self, _: &[u8]) -> io::Result<usize> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 
     pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
-        match self.0 {}
+        Err(io::Error::new(ErrorKind::Other, "not supported"))
     }
 }
 
 impl fmt::Debug for UdpSocket {
     fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.0 {}
+        Ok(())
     }
 }
 
diff --git a/src/libstd/sys/hermit/stack_overflow.rs b/src/libstd/sys/hermit/stack_overflow.rs
index 65a1b17acce..121fe42011d 100644
--- a/src/libstd/sys/hermit/stack_overflow.rs
+++ b/src/libstd/sys/hermit/stack_overflow.rs
@@ -1,11 +1,3 @@
-pub struct Handler;
-
-impl Handler {
-    pub unsafe fn new() -> Handler {
-        Handler
-    }
-}
-
 #[inline]
 pub unsafe fn init() {}
 
diff --git a/src/libstd/sys/hermit/thread.rs b/src/libstd/sys/hermit/thread.rs
index c3c29c93826..c7bea168f34 100644
--- a/src/libstd/sys/hermit/thread.rs
+++ b/src/libstd/sys/hermit/thread.rs
@@ -8,8 +8,6 @@ use crate::sys::hermit::abi;
 use crate::time::Duration;
 use core::u32;
 
-use crate::sys_common::thread::*;
-
 pub type Tid = abi::Tid;
 
 /// Priority of a task
@@ -49,26 +47,29 @@ impl Thread {
         p: Box<dyn FnOnce()>,
         core_id: isize,
     ) -> io::Result<Thread> {
-        let p = box p;
+        let p = Box::into_raw(box p);
         let mut tid: Tid = u32::MAX;
         let ret = abi::spawn(
             &mut tid as *mut Tid,
             thread_start,
-            &*p as *const _ as *const u8 as usize,
+            p as usize,
             Priority::into(NORMAL_PRIO),
             core_id,
         );
 
-        return if ret == 0 {
-            mem::forget(p); // ownership passed to pthread_create
-            Ok(Thread { tid: tid })
-        } else {
+        return if ret != 0 {
+            // The thread failed to start and as a result p was not consumed. Therefore, it is
+            // safe to reconstruct the box so that it gets deallocated.
+            drop(Box::from_raw(p));
             Err(io::Error::new(io::ErrorKind::Other, "Unable to create thread!"))
+        } else {
+            Ok(Thread { tid: tid })
         };
 
         extern "C" fn thread_start(main: usize) {
             unsafe {
-                start_thread(main as *mut u8);
+                // Finally, let's run some code.
+                Box::from_raw(main as *mut Box<dyn FnOnce()>)();
             }
         }
     }
diff --git a/src/libstd/sys/sgx/abi/mem.rs b/src/libstd/sys/sgx/abi/mem.rs
index 500e62b1cb5..57fd7efdd49 100644
--- a/src/libstd/sys/sgx/abi/mem.rs
+++ b/src/libstd/sys/sgx/abi/mem.rs
@@ -22,7 +22,7 @@ extern "C" {
 #[unstable(feature = "sgx_platform", issue = "56975")]
 pub fn image_base() -> u64 {
     let base;
-    unsafe { asm!("lea IMAGE_BASE(%rip),$0":"=r"(base)) };
+    unsafe { llvm_asm!("lea IMAGE_BASE(%rip),$0":"=r"(base)) };
     base
 }
 
diff --git a/src/libstd/sys/sgx/abi/usercalls/alloc.rs b/src/libstd/sys/sgx/abi/usercalls/alloc.rs
index b54c115a2b6..76a9b427b39 100644
--- a/src/libstd/sys/sgx/abi/usercalls/alloc.rs
+++ b/src/libstd/sys/sgx/abi/usercalls/alloc.rs
@@ -151,7 +151,7 @@ unsafe impl<T: UserSafeSized> UserSafe for [T] {
 /// It is also possible to obtain a mutable reference `&mut UserRef<T>`. Unlike
 /// regular mutable references, these are not exclusive. Userspace may always
 /// write to the backing memory at any time, so it can't be assumed that there
-/// the pointed-to memory is uniquely borrowed. The two different refence types
+/// the pointed-to memory is uniquely borrowed. The two different reference types
 /// are used solely to indicate intent: a mutable reference is for writing to
 /// user memory, an immutable reference for reading from user memory.
 #[unstable(feature = "sgx_platform", issue = "56975")]
diff --git a/src/libstd/sys/sgx/ext/arch.rs b/src/libstd/sys/sgx/ext/arch.rs
index 5056e388112..0c97a87e2e4 100644
--- a/src/libstd/sys/sgx/ext/arch.rs
+++ b/src/libstd/sys/sgx/ext/arch.rs
@@ -31,7 +31,7 @@ pub fn egetkey(request: &Align512<[u8; 512]>) -> Result<Align16<[u8; 16]>, u32>
         let mut out = MaybeUninit::uninit();
         let error;
 
-        asm!(
+        llvm_asm!(
             "enclu"
             : "={eax}"(error)
             : "{eax}"(ENCLU_EGETKEY),
@@ -60,7 +60,7 @@ pub fn ereport(
     unsafe {
         let mut report = MaybeUninit::uninit();
 
-        asm!(
+        llvm_asm!(
             "enclu"
             : /* no output registers */
             : "{eax}"(ENCLU_EREPORT),
diff --git a/src/libstd/sys/sgx/io.rs b/src/libstd/sys/sgx/io.rs
index 976e122463d..d5f475b4310 100644
--- a/src/libstd/sys/sgx/io.rs
+++ b/src/libstd/sys/sgx/io.rs
@@ -1,5 +1,6 @@
 use crate::mem;
 
+#[derive(Copy, Clone)]
 pub struct IoSlice<'a>(&'a [u8]);
 
 impl<'a> IoSlice<'a> {
diff --git a/src/libstd/sys/sgx/mutex.rs b/src/libstd/sys/sgx/mutex.rs
index eebbea1b285..4911c2f5387 100644
--- a/src/libstd/sys/sgx/mutex.rs
+++ b/src/libstd/sys/sgx/mutex.rs
@@ -75,7 +75,7 @@ impl ReentrantMutex {
     }
 
     #[inline]
-    pub unsafe fn init(&mut self) {}
+    pub unsafe fn init(&self) {}
 
     #[inline]
     pub unsafe fn lock(&self) {
diff --git a/src/libstd/sys/sgx/stack_overflow.rs b/src/libstd/sys/sgx/stack_overflow.rs
index a2d13d11849..b96652a8330 100644
--- a/src/libstd/sys/sgx/stack_overflow.rs
+++ b/src/libstd/sys/sgx/stack_overflow.rs
@@ -1,11 +1,3 @@
-pub struct Handler;
-
-impl Handler {
-    pub unsafe fn new() -> Handler {
-        Handler
-    }
-}
-
 #[cfg_attr(test, allow(dead_code))]
 pub unsafe fn init() {}
 
diff --git a/src/libstd/sys/unix/io.rs b/src/libstd/sys/unix/io.rs
index b4a64e93c84..deb5ee76bd0 100644
--- a/src/libstd/sys/unix/io.rs
+++ b/src/libstd/sys/unix/io.rs
@@ -3,6 +3,7 @@ use crate::slice;
 
 use libc::{c_void, iovec};
 
+#[derive(Copy, Clone)]
 #[repr(transparent)]
 pub struct IoSlice<'a> {
     vec: iovec,
diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs
index 06876cb0614..fbcb006ecdf 100644
--- a/src/libstd/sys/unix/mod.rs
+++ b/src/libstd/sys/unix/mod.rs
@@ -156,7 +156,7 @@ where
 
 // On Unix-like platforms, libc::abort will unregister signal handlers
 // including the SIGABRT handler, preventing the abort from being blocked, and
-// fclose streams, with the side effect of flushing them so libc bufferred
+// fclose streams, with the side effect of flushing them so libc buffered
 // output will be printed.  Additionally the shell will generally print a more
 // understandable error message like "Abort trap" rather than "Illegal
 // instruction" that intrinsics::abort would cause, as intrinsics::abort is
diff --git a/src/libstd/sys/unix/mutex.rs b/src/libstd/sys/unix/mutex.rs
index b38375a2e03..103d87e3d2f 100644
--- a/src/libstd/sys/unix/mutex.rs
+++ b/src/libstd/sys/unix/mutex.rs
@@ -92,11 +92,11 @@ unsafe impl Send for ReentrantMutex {}
 unsafe impl Sync for ReentrantMutex {}
 
 impl ReentrantMutex {
-    pub unsafe fn uninitialized() -> ReentrantMutex {
+    pub const unsafe fn uninitialized() -> ReentrantMutex {
         ReentrantMutex { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) }
     }
 
-    pub unsafe fn init(&mut self) {
+    pub unsafe fn init(&self) {
         let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
         let result = libc::pthread_mutexattr_init(attr.as_mut_ptr());
         debug_assert_eq!(result, 0);
diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs
index 83f052c898b..859da691ad2 100644
--- a/src/libstd/sys/unix/process/process_common.rs
+++ b/src/libstd/sys/unix/process/process_common.rs
@@ -19,9 +19,9 @@ cfg_if::cfg_if! {
     if #[cfg(target_os = "fuchsia")] {
         // fuchsia doesn't have /dev/null
     } else if #[cfg(target_os = "redox")] {
-        const DEV_NULL: &'static str = "null:\0";
+        const DEV_NULL: &str = "null:\0";
     } else {
-        const DEV_NULL: &'static str = "/dev/null\0";
+        const DEV_NULL: &str = "/dev/null\0";
     }
 }
 
diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs
index 07d0fbf61fe..f389c60615f 100644
--- a/src/libstd/sys/unix/process/process_unix.rs
+++ b/src/libstd/sys/unix/process/process_unix.rs
@@ -72,7 +72,7 @@ impl Command {
             }
         };
 
-        let mut p = Process { pid: pid, status: None };
+        let mut p = Process { pid, status: None };
         drop(output);
         let mut bytes = [0; 8];
 
diff --git a/src/libstd/sys/unix/rand.rs b/src/libstd/sys/unix/rand.rs
index 9ce5f3d014c..eed6fbf13b7 100644
--- a/src/libstd/sys/unix/rand.rs
+++ b/src/libstd/sys/unix/rand.rs
@@ -12,6 +12,7 @@ pub fn hashmap_random_keys() -> (u64, u64) {
 
 #[cfg(all(
     unix,
+    not(target_os = "macos"),
     not(target_os = "ios"),
     not(target_os = "openbsd"),
     not(target_os = "freebsd"),
@@ -92,6 +93,42 @@ mod imp {
     }
 }
 
+#[cfg(target_os = "macos")]
+mod imp {
+    use crate::fs::File;
+    use crate::io::Read;
+    use crate::sys::os::errno;
+    use libc::{c_int, c_void, size_t};
+
+    fn getentropy_fill_bytes(v: &mut [u8]) -> bool {
+        weak!(fn getentropy(*mut c_void, size_t) -> c_int);
+
+        getentropy
+            .get()
+            .map(|f| {
+                // getentropy(2) permits a maximum buffer size of 256 bytes
+                for s in v.chunks_mut(256) {
+                    let ret = unsafe { f(s.as_mut_ptr() as *mut c_void, s.len()) };
+                    if ret == -1 {
+                        panic!("unexpected getentropy error: {}", errno());
+                    }
+                }
+                true
+            })
+            .unwrap_or(false)
+    }
+
+    pub fn fill_bytes(v: &mut [u8]) {
+        if getentropy_fill_bytes(v) {
+            return;
+        }
+
+        // for older macos which doesn't support getentropy
+        let mut file = File::open("/dev/urandom").expect("failed to open /dev/urandom");
+        file.read_exact(v).expect("failed to read /dev/urandom")
+    }
+}
+
 #[cfg(target_os = "openbsd")]
 mod imp {
     use crate::sys::os::errno;
diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs
index 528fe321efb..2626ca37cf8 100644
--- a/src/libstd/sys/unix/stack_overflow.rs
+++ b/src/libstd/sys/unix/stack_overflow.rs
@@ -13,6 +13,10 @@ impl Handler {
     pub unsafe fn new() -> Handler {
         make_handler()
     }
+
+    fn null() -> Handler {
+        Handler { _data: crate::ptr::null_mut() }
+    }
 }
 
 impl Drop for Handler {
@@ -41,8 +45,9 @@ mod imp {
     use libc::{mmap, munmap};
     use libc::{sigaction, sighandler_t, SA_ONSTACK, SA_SIGINFO, SIGBUS, SIG_DFL};
     use libc::{sigaltstack, SIGSTKSZ, SS_DISABLE};
-    use libc::{MAP_ANON, MAP_PRIVATE, PROT_READ, PROT_WRITE, SIGSEGV};
+    use libc::{MAP_ANON, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE, SIGSEGV};
 
+    use crate::sys::unix::os::page_size;
     use crate::sys_common::thread_info;
 
     #[cfg(any(target_os = "linux", target_os = "android"))]
@@ -108,13 +113,20 @@ mod imp {
     }
 
     static mut MAIN_ALTSTACK: *mut libc::c_void = ptr::null_mut();
+    static mut NEED_ALTSTACK: bool = false;
 
     pub unsafe fn init() {
         let mut action: sigaction = mem::zeroed();
-        action.sa_flags = SA_SIGINFO | SA_ONSTACK;
-        action.sa_sigaction = signal_handler as sighandler_t;
-        sigaction(SIGSEGV, &action, ptr::null_mut());
-        sigaction(SIGBUS, &action, ptr::null_mut());
+        for &signal in &[SIGSEGV, SIGBUS] {
+            sigaction(signal, ptr::null_mut(), &mut action);
+            // Configure our signal handler if one is not already set.
+            if action.sa_sigaction == SIG_DFL {
+                action.sa_flags = SA_SIGINFO | SA_ONSTACK;
+                action.sa_sigaction = signal_handler as sighandler_t;
+                sigaction(signal, &action, ptr::null_mut());
+                NEED_ALTSTACK = true;
+            }
+        }
 
         let handler = make_handler();
         MAIN_ALTSTACK = handler._data;
@@ -126,12 +138,22 @@ mod imp {
     }
 
     unsafe fn get_stackp() -> *mut libc::c_void {
-        let stackp =
-            mmap(ptr::null_mut(), SIGSTKSZ, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
+        let stackp = mmap(
+            ptr::null_mut(),
+            SIGSTKSZ + page_size(),
+            PROT_READ | PROT_WRITE,
+            MAP_PRIVATE | MAP_ANON,
+            -1,
+            0,
+        );
         if stackp == MAP_FAILED {
             panic!("failed to allocate an alternative stack");
         }
-        stackp
+        let guard_result = libc::mprotect(stackp, page_size(), PROT_NONE);
+        if guard_result != 0 {
+            panic!("failed to set up alternative stack guard page");
+        }
+        stackp.add(page_size())
     }
 
     #[cfg(any(
@@ -152,6 +174,9 @@ mod imp {
     }
 
     pub unsafe fn make_handler() -> Handler {
+        if !NEED_ALTSTACK {
+            return Handler::null();
+        }
         let mut stack = mem::zeroed();
         sigaltstack(ptr::null(), &mut stack);
         // Configure alternate signal stack, if one is not already set.
@@ -160,7 +185,7 @@ mod imp {
             sigaltstack(&stack, ptr::null_mut());
             Handler { _data: stack.ss_sp as *mut libc::c_void }
         } else {
-            Handler { _data: ptr::null_mut() }
+            Handler::null()
         }
     }
 
@@ -176,7 +201,9 @@ mod imp {
                 ss_size: SIGSTKSZ,
             };
             sigaltstack(&stack, ptr::null_mut());
-            munmap(handler._data, SIGSTKSZ);
+            // We know from `get_stackp` that the alternate stack we installed is part of a mapping
+            // that started one page earlier, so walk back a page and unmap from there.
+            munmap(handler._data.sub(page_size()), SIGSTKSZ + page_size());
         }
     }
 }
@@ -191,14 +218,12 @@ mod imp {
     target_os = "openbsd"
 )))]
 mod imp {
-    use crate::ptr;
-
     pub unsafe fn init() {}
 
     pub unsafe fn cleanup() {}
 
     pub unsafe fn make_handler() -> super::Handler {
-        super::Handler { _data: ptr::null_mut() }
+        super::Handler::null()
     }
 
     pub unsafe fn drop_handler(_handler: &mut super::Handler) {}
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index 674d4c71138..aab5a92a7ad 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -3,11 +3,9 @@ use crate::ffi::CStr;
 use crate::io;
 use crate::mem;
 use crate::ptr;
-use crate::sys::os;
+use crate::sys::{os, stack_overflow};
 use crate::time::Duration;
 
-use crate::sys_common::thread::*;
-
 #[cfg(not(target_os = "l4re"))]
 pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024;
 #[cfg(target_os = "l4re")]
@@ -43,7 +41,7 @@ unsafe fn pthread_attr_setstacksize(
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
     pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
-        let p = box p;
+        let p = Box::into_raw(box p);
         let mut native: libc::pthread_t = mem::zeroed();
         let mut attr: libc::pthread_attr_t = mem::zeroed();
         assert_eq!(libc::pthread_attr_init(&mut attr), 0);
@@ -65,19 +63,28 @@ impl Thread {
             }
         };
 
-        let ret = libc::pthread_create(&mut native, &attr, thread_start, &*p as *const _ as *mut _);
+        let ret = libc::pthread_create(&mut native, &attr, thread_start, p as *mut _);
+        // Note: if the thread creation fails and this assert fails, then p will
+        // be leaked. However, an alternative design could cause double-free
+        // which is clearly worse.
         assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
 
         return if ret != 0 {
+            // The thread failed to start and as a result p was not consumed. Therefore, it is
+            // safe to reconstruct the box so that it gets deallocated.
+            drop(Box::from_raw(p));
             Err(io::Error::from_raw_os_error(ret))
         } else {
-            mem::forget(p); // ownership passed to pthread_create
             Ok(Thread { id: native })
         };
 
         extern "C" fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
             unsafe {
-                start_thread(main as *mut u8);
+                // Next, set up our stack overflow handler which may get triggered if we run
+                // out of stack.
+                let _handler = stack_overflow::Handler::new();
+                // Finally, let's run some code.
+                Box::from_raw(main as *mut Box<dyn FnOnce()>)();
             }
             ptr::null_mut()
         }
diff --git a/src/libstd/sys/vxworks/io.rs b/src/libstd/sys/vxworks/io.rs
index f1a2c8446ff..0f68ebf8da9 100644
--- a/src/libstd/sys/vxworks/io.rs
+++ b/src/libstd/sys/vxworks/io.rs
@@ -3,6 +3,7 @@ use crate::slice;
 
 use libc::{c_void, iovec};
 
+#[derive(Copy, Clone)]
 #[repr(transparent)]
 pub struct IoSlice<'a> {
     vec: iovec,
diff --git a/src/libstd/sys/vxworks/mod.rs b/src/libstd/sys/vxworks/mod.rs
index 12bbfa1d4e1..e23191c9431 100644
--- a/src/libstd/sys/vxworks/mod.rs
+++ b/src/libstd/sys/vxworks/mod.rs
@@ -103,7 +103,7 @@ where
 
 // On Unix-like platforms, libc::abort will unregister signal handlers
 // including the SIGABRT handler, preventing the abort from being blocked, and
-// fclose streams, with the side effect of flushing them so libc bufferred
+// fclose streams, with the side effect of flushing them so libc buffered
 // output will be printed.  Additionally the shell will generally print a more
 // understandable error message like "Abort trap" rather than "Illegal
 // instruction" that intrinsics::abort would cause, as intrinsics::abort is
diff --git a/src/libstd/sys/vxworks/mutex.rs b/src/libstd/sys/vxworks/mutex.rs
index b38375a2e03..103d87e3d2f 100644
--- a/src/libstd/sys/vxworks/mutex.rs
+++ b/src/libstd/sys/vxworks/mutex.rs
@@ -92,11 +92,11 @@ unsafe impl Send for ReentrantMutex {}
 unsafe impl Sync for ReentrantMutex {}
 
 impl ReentrantMutex {
-    pub unsafe fn uninitialized() -> ReentrantMutex {
+    pub const unsafe fn uninitialized() -> ReentrantMutex {
         ReentrantMutex { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) }
     }
 
-    pub unsafe fn init(&mut self) {
+    pub unsafe fn init(&self) {
         let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
         let result = libc::pthread_mutexattr_init(attr.as_mut_ptr());
         debug_assert_eq!(result, 0);
diff --git a/src/libstd/sys/vxworks/thread.rs b/src/libstd/sys/vxworks/thread.rs
index e0d104b5f3e..4d0196e4b4d 100644
--- a/src/libstd/sys/vxworks/thread.rs
+++ b/src/libstd/sys/vxworks/thread.rs
@@ -3,11 +3,9 @@ use crate::ffi::CStr;
 use crate::io;
 use crate::mem;
 use crate::ptr;
-use crate::sys::os;
+use crate::sys::{os, stack_overflow};
 use crate::time::Duration;
 
-use crate::sys_common::thread::*;
-
 pub const DEFAULT_MIN_STACK_SIZE: usize = 0x40000; // 256K
 
 pub struct Thread {
@@ -31,7 +29,7 @@ unsafe fn pthread_attr_setstacksize(
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
     pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
-        let p = box p;
+        let p = Box::into_raw(box p);
         let mut native: libc::pthread_t = mem::zeroed();
         let mut attr: libc::pthread_attr_t = mem::zeroed();
         assert_eq!(libc::pthread_attr_init(&mut attr), 0);
@@ -53,19 +51,28 @@ impl Thread {
             }
         };
 
-        let ret = libc::pthread_create(&mut native, &attr, thread_start, &*p as *const _ as *mut _);
+        let ret = libc::pthread_create(&mut native, &attr, thread_start, p as *mut _);
+        // Note: if the thread creation fails and this assert fails, then p will
+        // be leaked. However, an alternative design could cause double-free
+        // which is clearly worse.
         assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
 
         return if ret != 0 {
+            // The thread failed to start and as a result p was not consumed. Therefore, it is
+            // safe to reconstruct the box so that it gets deallocated.
+            drop(Box::from_raw(p));
             Err(io::Error::from_raw_os_error(ret))
         } else {
-            mem::forget(p); // ownership passed to pthread_create
             Ok(Thread { id: native })
         };
 
         extern "C" fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
             unsafe {
-                start_thread(main as *mut u8);
+                // Next, set up our stack overflow handler which may get triggered if we run
+                // out of stack.
+                let _handler = stack_overflow::Handler::new();
+                // Finally, let's run some code.
+                Box::from_raw(main as *mut Box<dyn FnOnce()>)();
             }
             ptr::null_mut()
         }
diff --git a/src/libstd/sys/wasi/alloc.rs b/src/libstd/sys/wasi/alloc.rs
index e9760d050e1..bc614162784 100644
--- a/src/libstd/sys/wasi/alloc.rs
+++ b/src/libstd/sys/wasi/alloc.rs
@@ -10,7 +10,7 @@ unsafe impl GlobalAlloc for System {
         if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
             libc::malloc(layout.size()) as *mut u8
         } else {
-            libc::aligned_alloc(layout.size(), layout.align()) as *mut u8
+            libc::aligned_alloc(layout.align(), layout.size()) as *mut u8
         }
     }
 
diff --git a/src/libstd/sys/wasi/io.rs b/src/libstd/sys/wasi/io.rs
index ee20ea6dab8..0ad2e152855 100644
--- a/src/libstd/sys/wasi/io.rs
+++ b/src/libstd/sys/wasi/io.rs
@@ -1,6 +1,7 @@
 use crate::marker::PhantomData;
 use crate::slice;
 
+#[derive(Copy, Clone)]
 #[repr(transparent)]
 pub struct IoSlice<'a> {
     vec: wasi::Ciovec,
diff --git a/src/libstd/sys/wasm/io.rs b/src/libstd/sys/wasm/io.rs
index 976e122463d..d5f475b4310 100644
--- a/src/libstd/sys/wasm/io.rs
+++ b/src/libstd/sys/wasm/io.rs
@@ -1,5 +1,6 @@
 use crate::mem;
 
+#[derive(Copy, Clone)]
 pub struct IoSlice<'a>(&'a [u8]);
 
 impl<'a> IoSlice<'a> {
diff --git a/src/libstd/sys/wasm/mutex.rs b/src/libstd/sys/wasm/mutex.rs
index 07238d08730..7aaf1b3a343 100644
--- a/src/libstd/sys/wasm/mutex.rs
+++ b/src/libstd/sys/wasm/mutex.rs
@@ -47,11 +47,11 @@ impl Mutex {
 pub struct ReentrantMutex {}
 
 impl ReentrantMutex {
-    pub unsafe fn uninitialized() -> ReentrantMutex {
+    pub const unsafe fn uninitialized() -> ReentrantMutex {
         ReentrantMutex {}
     }
 
-    pub unsafe fn init(&mut self) {}
+    pub unsafe fn init(&self) {}
 
     pub unsafe fn lock(&self) {}
 
diff --git a/src/libstd/sys/wasm/mutex_atomics.rs b/src/libstd/sys/wasm/mutex_atomics.rs
index 90c628a19c2..268a53bb564 100644
--- a/src/libstd/sys/wasm/mutex_atomics.rs
+++ b/src/libstd/sys/wasm/mutex_atomics.rs
@@ -80,11 +80,11 @@ unsafe impl Sync for ReentrantMutex {}
 // released when this recursion counter reaches 0.
 
 impl ReentrantMutex {
-    pub unsafe fn uninitialized() -> ReentrantMutex {
+    pub const unsafe fn uninitialized() -> ReentrantMutex {
         ReentrantMutex { owner: AtomicU32::new(0), recursions: UnsafeCell::new(0) }
     }
 
-    pub unsafe fn init(&mut self) {
+    pub unsafe fn init(&self) {
         // nothing to do...
     }
 
diff --git a/src/libstd/sys/wasm/stack_overflow.rs b/src/libstd/sys/wasm/stack_overflow.rs
index cbf62b6e5b7..32555394cd5 100644
--- a/src/libstd/sys/wasm/stack_overflow.rs
+++ b/src/libstd/sys/wasm/stack_overflow.rs
@@ -1,11 +1,3 @@
-pub struct Handler;
-
-impl Handler {
-    pub unsafe fn new() -> Handler {
-        Handler
-    }
-}
-
 pub unsafe fn init() {}
 
 pub unsafe fn cleanup() {}
diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs
index 4d377341be3..134f508dfab 100644
--- a/src/libstd/sys/windows/c.rs
+++ b/src/libstd/sys/windows/c.rs
@@ -295,6 +295,7 @@ pub struct WSADATA {
     pub szSystemStatus: [u8; WSASYS_STATUS_LEN + 1],
 }
 
+#[derive(Copy, Clone)]
 #[repr(C)]
 pub struct WSABUF {
     pub len: ULONG,
@@ -777,7 +778,7 @@ extern "system" {
     pub fn ioctlsocket(s: SOCKET, cmd: c_long, argp: *mut c_ulong) -> c_int;
     pub fn InitializeCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
     pub fn EnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
-    pub fn TryEnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION) -> BOOLEAN;
+    pub fn TryEnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION) -> BOOL;
     pub fn LeaveCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
     pub fn DeleteCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
 
@@ -1044,6 +1045,10 @@ compat_fn! {
                     _dwBufferSize: DWORD) -> BOOL {
         SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
     }
+    pub fn GetSystemTimePreciseAsFileTime(lpSystemTimeAsFileTime: LPFILETIME)
+                                          -> () {
+        GetSystemTimeAsFileTime(lpSystemTimeAsFileTime)
+    }
     pub fn SleepConditionVariableSRW(ConditionVariable: PCONDITION_VARIABLE,
                                      SRWLock: PSRWLOCK,
                                      dwMilliseconds: DWORD,
diff --git a/src/libstd/sys/windows/handle.rs b/src/libstd/sys/windows/handle.rs
index f2ad057b6b6..d00381792e3 100644
--- a/src/libstd/sys/windows/handle.rs
+++ b/src/libstd/sys/windows/handle.rs
@@ -115,8 +115,7 @@ impl RawHandle {
     ) -> io::Result<Option<usize>> {
         let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
         let mut amt = 0;
-        let res =
-            cvt({ c::ReadFile(self.0, buf.as_ptr() as c::LPVOID, len, &mut amt, overlapped) });
+        let res = cvt(c::ReadFile(self.0, buf.as_ptr() as c::LPVOID, len, &mut amt, overlapped));
         match res {
             Ok(_) => Ok(Some(amt as usize)),
             Err(e) => {
@@ -139,7 +138,7 @@ impl RawHandle {
         unsafe {
             let mut bytes = 0;
             let wait = if wait { c::TRUE } else { c::FALSE };
-            let res = cvt({ c::GetOverlappedResult(self.raw(), overlapped, &mut bytes, wait) });
+            let res = cvt(c::GetOverlappedResult(self.raw(), overlapped, &mut bytes, wait));
             match res {
                 Ok(_) => Ok(bytes as usize),
                 Err(e) => {
diff --git a/src/libstd/sys/windows/io.rs b/src/libstd/sys/windows/io.rs
index 9d8018fd5e8..5525d283252 100644
--- a/src/libstd/sys/windows/io.rs
+++ b/src/libstd/sys/windows/io.rs
@@ -2,6 +2,7 @@ use crate::marker::PhantomData;
 use crate::slice;
 use crate::sys::c;
 
+#[derive(Copy, Clone)]
 #[repr(transparent)]
 pub struct IoSlice<'a> {
     vec: c::WSABUF,
diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs
index b004cd19020..74dd41fd501 100644
--- a/src/libstd/sys/windows/mod.rs
+++ b/src/libstd/sys/windows/mod.rs
@@ -267,7 +267,7 @@ pub fn dur2timeout(dur: Duration) -> c::DWORD {
 pub unsafe fn abort_internal() -> ! {
     #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
     {
-        asm!("int $$0x29" :: "{ecx}"(7) ::: volatile); // 7 is FAST_FAIL_FATAL_APP_EXIT
+        llvm_asm!("int $$0x29" :: "{ecx}"(7) ::: volatile); // 7 is FAST_FAIL_FATAL_APP_EXIT
         crate::intrinsics::unreachable();
     }
     crate::intrinsics::abort();
diff --git a/src/libstd/sys/windows/mutex.rs b/src/libstd/sys/windows/mutex.rs
index 281eb294c65..63dfc640908 100644
--- a/src/libstd/sys/windows/mutex.rs
+++ b/src/libstd/sys/windows/mutex.rs
@@ -109,7 +109,7 @@ impl Mutex {
             0 => {}
             n => return n as *mut _,
         }
-        let mut re = box ReentrantMutex::uninitialized();
+        let re = box ReentrantMutex::uninitialized();
         re.init();
         let re = Box::into_raw(re);
         match self.lock.compare_and_swap(0, re as usize, Ordering::SeqCst) {
@@ -157,11 +157,11 @@ unsafe impl Send for ReentrantMutex {}
 unsafe impl Sync for ReentrantMutex {}
 
 impl ReentrantMutex {
-    pub fn uninitialized() -> ReentrantMutex {
+    pub const fn uninitialized() -> ReentrantMutex {
         ReentrantMutex { inner: UnsafeCell::new(MaybeUninit::uninit()) }
     }
 
-    pub unsafe fn init(&mut self) {
+    pub unsafe fn init(&self) {
         c::InitializeCriticalSection((&mut *self.inner.get()).as_mut_ptr());
     }
 
diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs
index cc4ae405906..a0da2498bb7 100644
--- a/src/libstd/sys/windows/os.rs
+++ b/src/libstd/sys/windows/os.rs
@@ -94,7 +94,7 @@ impl Iterator for Env {
                 if *self.cur == 0 {
                     return None;
                 }
-                let p = &*self.cur as *const u16;
+                let p = self.cur as *const u16;
                 let mut len = 0;
                 while *p.offset(len) != 0 {
                     len += 1;
diff --git a/src/libstd/sys/windows/os_str.rs b/src/libstd/sys/windows/os_str.rs
index ef260f9c5d2..6aab028873e 100644
--- a/src/libstd/sys/windows/os_str.rs
+++ b/src/libstd/sys/windows/os_str.rs
@@ -77,9 +77,21 @@ impl Buf {
     }
 
     pub fn as_slice(&self) -> &Slice {
+        // Safety: Slice is just a wrapper for Wtf8,
+        // and self.inner.as_slice() returns &Wtf8.
+        // Therefore, transmuting &Wtf8 to &Slice is safe.
         unsafe { mem::transmute(self.inner.as_slice()) }
     }
 
+    pub fn as_mut_slice(&mut self) -> &mut Slice {
+        // Safety: Slice is just a wrapper for Wtf8,
+        // and self.inner.as_mut_slice() returns &mut Wtf8.
+        // Therefore, transmuting &mut Wtf8 to &mut Slice is safe.
+        // Additionally, care should be taken to ensure the slice
+        // is always valid Wtf8.
+        unsafe { mem::transmute(self.inner.as_mut_slice()) }
+    }
+
     pub fn into_string(self) -> Result<String, Buf> {
         self.inner.into_string().map_err(|buf| Buf { inner: buf })
     }
@@ -167,4 +179,34 @@ impl Slice {
         let rc = self.inner.into_rc();
         unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
     }
+
+    #[inline]
+    pub fn make_ascii_lowercase(&mut self) {
+        self.inner.make_ascii_lowercase()
+    }
+
+    #[inline]
+    pub fn make_ascii_uppercase(&mut self) {
+        self.inner.make_ascii_uppercase()
+    }
+
+    #[inline]
+    pub fn to_ascii_lowercase(&self) -> Buf {
+        Buf { inner: self.inner.to_ascii_lowercase() }
+    }
+
+    #[inline]
+    pub fn to_ascii_uppercase(&self) -> Buf {
+        Buf { inner: self.inner.to_ascii_uppercase() }
+    }
+
+    #[inline]
+    pub fn is_ascii(&self) -> bool {
+        self.inner.is_ascii()
+    }
+
+    #[inline]
+    pub fn eq_ignore_ascii_case(&self, other: &Self) -> bool {
+        self.inner.eq_ignore_ascii_case(&other.inner)
+    }
 }
diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs
index a62a637393e..77f9a5c9dc7 100644
--- a/src/libstd/sys/windows/process.rs
+++ b/src/libstd/sys/windows/process.rs
@@ -20,7 +20,7 @@ use crate::sys::mutex::Mutex;
 use crate::sys::pipe::{self, AnonPipe};
 use crate::sys::stdio;
 use crate::sys_common::process::CommandEnv;
-use crate::sys_common::{AsInner, FromInner, IntoInner};
+use crate::sys_common::AsInner;
 
 use libc::{c_void, EXIT_FAILURE, EXIT_SUCCESS};
 
@@ -33,10 +33,9 @@ use libc::{c_void, EXIT_FAILURE, EXIT_SUCCESS};
 pub struct EnvKey(OsString);
 
 impl From<OsString> for EnvKey {
-    fn from(k: OsString) -> Self {
-        let mut buf = k.into_inner().into_inner();
-        buf.make_ascii_uppercase();
-        EnvKey(FromInner::from_inner(FromInner::from_inner(buf)))
+    fn from(mut k: OsString) -> Self {
+        k.make_ascii_uppercase();
+        EnvKey(k)
     }
 }
 
diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs
index c828243a59b..38839ea5e90 100644
--- a/src/libstd/sys/windows/thread.rs
+++ b/src/libstd/sys/windows/thread.rs
@@ -1,10 +1,9 @@
 use crate::ffi::CStr;
 use crate::io;
-use crate::mem;
 use crate::ptr;
 use crate::sys::c;
 use crate::sys::handle::Handle;
-use crate::sys_common::thread::*;
+use crate::sys::stack_overflow;
 use crate::time::Duration;
 
 use libc::c_void;
@@ -20,7 +19,7 @@ pub struct Thread {
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
     pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
-        let p = box p;
+        let p = Box::into_raw(box p);
 
         // FIXME On UNIX, we guard against stack sizes that are too small but
         // that's because pthreads enforces that stacks are at least
@@ -34,21 +33,27 @@ impl Thread {
             ptr::null_mut(),
             stack_size,
             thread_start,
-            &*p as *const _ as *mut _,
+            p as *mut _,
             c::STACK_SIZE_PARAM_IS_A_RESERVATION,
             ptr::null_mut(),
         );
 
         return if ret as usize == 0 {
+            // The thread failed to start and as a result p was not consumed. Therefore, it is
+            // safe to reconstruct the box so that it gets deallocated.
+            drop(Box::from_raw(p));
             Err(io::Error::last_os_error())
         } else {
-            mem::forget(p); // ownership passed to CreateThread
             Ok(Thread { handle: Handle::new(ret) })
         };
 
         extern "system" fn thread_start(main: *mut c_void) -> c::DWORD {
             unsafe {
-                start_thread(main as *mut u8);
+                // Next, set up our stack overflow handler which may get triggered if we run
+                // out of stack.
+                let _handler = stack_overflow::Handler::new();
+                // Finally, let's run some code.
+                Box::from_raw(main as *mut Box<dyn FnOnce()>)();
             }
             0
         }
diff --git a/src/libstd/sys/windows/time.rs b/src/libstd/sys/windows/time.rs
index 86667ca7ab2..900260169c7 100644
--- a/src/libstd/sys/windows/time.rs
+++ b/src/libstd/sys/windows/time.rs
@@ -74,7 +74,7 @@ impl SystemTime {
     pub fn now() -> SystemTime {
         unsafe {
             let mut t: SystemTime = mem::zeroed();
-            c::GetSystemTimeAsFileTime(&mut t.t);
+            c::GetSystemTimePreciseAsFileTime(&mut t.t);
             t
         }
     }