about summary refs log tree commit diff
path: root/library/std/src/sys
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-03-13 10:27:30 +0000
committerbors <bors@rust-lang.org>2025-03-13 10:27:30 +0000
commita2aba0578ba440130d2ee213fc9dfdaa7095bdb5 (patch)
tree58d1d86e73a6dab6d4eefb07876db427ce9834af /library/std/src/sys
parent961351c76c812e3aeb65bfb542742500a6436aed (diff)
parent3bfce83cb2e880a7f2a601326a56a57abaf6bd8c (diff)
downloadrust-a2aba0578ba440130d2ee213fc9dfdaa7095bdb5.tar.gz
rust-a2aba0578ba440130d2ee213fc9dfdaa7095bdb5.zip
Auto merge of #138448 - matthiaskrgr:rollup-3onhkse, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - #126856 (remove deprecated tool `rls`)
 - #133981 (rustdoc-json: Refractor and document Id's)
 - #136842 (Add libstd support for Trusty targets)
 - #137355 (Implement `read_buf` and vectored read/write for SGX stdio)
 - #138162 (Update the standard library to Rust 2024)
 - #138273 (metadata: Ignore sysroot when doing the manual native lib search in rustc)
 - #138346 (naked functions: on windows emit `.endef` without the symbol name)
 - #138370 (Simulate OOM for the `try_oom_error` test)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'library/std/src/sys')
-rw-r--r--library/std/src/sys/alloc/mod.rs1
-rw-r--r--library/std/src/sys/pal/mod.rs3
-rw-r--r--library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs64
-rw-r--r--library/std/src/sys/pal/sgx/abi/usercalls/mod.rs17
-rw-r--r--library/std/src/sys/pal/sgx/fd.rs2
-rw-r--r--library/std/src/sys/pal/trusty/mod.rs21
-rw-r--r--library/std/src/sys/random/mod.rs3
-rw-r--r--library/std/src/sys/random/trusty.rs7
-rw-r--r--library/std/src/sys/stdio/mod.rs3
-rw-r--r--library/std/src/sys/stdio/sgx.rs33
-rw-r--r--library/std/src/sys/stdio/trusty.rs81
-rw-r--r--library/std/src/sys/thread_local/mod.rs2
12 files changed, 218 insertions, 19 deletions
diff --git a/library/std/src/sys/alloc/mod.rs b/library/std/src/sys/alloc/mod.rs
index 2c0b533a570..8489e17c971 100644
--- a/library/std/src/sys/alloc/mod.rs
+++ b/library/std/src/sys/alloc/mod.rs
@@ -72,6 +72,7 @@ cfg_if::cfg_if! {
         target_family = "unix",
         target_os = "wasi",
         target_os = "teeos",
+        target_os = "trusty",
     ))] {
         mod unix;
     } else if #[cfg(target_os = "windows")] {
diff --git a/library/std/src/sys/pal/mod.rs b/library/std/src/sys/pal/mod.rs
index 9be018c8a53..fbefc62ac88 100644
--- a/library/std/src/sys/pal/mod.rs
+++ b/library/std/src/sys/pal/mod.rs
@@ -37,6 +37,9 @@ cfg_if::cfg_if! {
     } else if #[cfg(target_os = "hermit")] {
         mod hermit;
         pub use self::hermit::*;
+    } else if #[cfg(target_os = "trusty")] {
+        mod trusty;
+        pub use self::trusty::*;
     } else if #[cfg(all(target_os = "wasi", target_env = "p2"))] {
         mod wasip2;
         pub use self::wasip2::*;
diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs
index 301e3299c05..3fe6dee3d6f 100644
--- a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs
+++ b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs
@@ -6,7 +6,7 @@ use super::super::mem::{is_enclave_range, is_user_range};
 use crate::arch::asm;
 use crate::cell::UnsafeCell;
 use crate::convert::TryInto;
-use crate::mem::{self, ManuallyDrop};
+use crate::mem::{self, ManuallyDrop, MaybeUninit};
 use crate::ops::{CoerceUnsized, Deref, DerefMut, Index, IndexMut};
 use crate::pin::PinCoerceUnsized;
 use crate::ptr::{self, NonNull};
@@ -209,6 +209,45 @@ impl<T: ?Sized> NewUserRef<NonNull<T>> for NonNull<UserRef<T>> {
     }
 }
 
+/// A type which can a destination for safely copying from userspace.
+///
+/// # Safety
+///
+/// Requires that `T` and `Self` have identical layouts.
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub unsafe trait UserSafeCopyDestination<T: ?Sized> {
+    /// Returns a pointer for writing to the value.
+    fn as_mut_ptr(&mut self) -> *mut T;
+}
+
+#[unstable(feature = "sgx_platform", issue = "56975")]
+unsafe impl<T> UserSafeCopyDestination<T> for T {
+    fn as_mut_ptr(&mut self) -> *mut T {
+        self as _
+    }
+}
+
+#[unstable(feature = "sgx_platform", issue = "56975")]
+unsafe impl<T> UserSafeCopyDestination<[T]> for [T] {
+    fn as_mut_ptr(&mut self) -> *mut [T] {
+        self as _
+    }
+}
+
+#[unstable(feature = "sgx_platform", issue = "56975")]
+unsafe impl<T> UserSafeCopyDestination<T> for MaybeUninit<T> {
+    fn as_mut_ptr(&mut self) -> *mut T {
+        self as *mut Self as _
+    }
+}
+
+#[unstable(feature = "sgx_platform", issue = "56975")]
+unsafe impl<T> UserSafeCopyDestination<[T]> for [MaybeUninit<T>] {
+    fn as_mut_ptr(&mut self) -> *mut [T] {
+        self as *mut Self as _
+    }
+}
+
 #[unstable(feature = "sgx_platform", issue = "56975")]
 impl<T: ?Sized> User<T>
 where
@@ -544,12 +583,12 @@ where
     /// # Panics
     /// This function panics if the destination doesn't have the same size as
     /// the source. This can happen for dynamically-sized types such as slices.
-    pub fn copy_to_enclave(&self, dest: &mut T) {
+    pub fn copy_to_enclave<U: ?Sized + UserSafeCopyDestination<T>>(&self, dest: &mut U) {
         unsafe {
             assert_eq!(size_of_val(dest), size_of_val(&*self.0.get()));
             copy_from_userspace(
                 self.0.get() as *const T as *const u8,
-                dest as *mut T as *mut u8,
+                dest.as_mut_ptr() as *mut u8,
                 size_of_val(dest),
             );
         }
@@ -639,25 +678,18 @@ where
         unsafe { (*self.0.get()).len() }
     }
 
-    /// Copies the value from user memory and place it into `dest`. Afterwards,
-    /// `dest` will contain exactly `self.len()` elements.
-    ///
-    /// # Panics
-    /// This function panics if the destination doesn't have the same size as
-    /// the source. This can happen for dynamically-sized types such as slices.
-    pub fn copy_to_enclave_vec(&self, dest: &mut Vec<T>) {
-        if let Some(missing) = self.len().checked_sub(dest.capacity()) {
-            dest.reserve(missing)
-        }
+    /// Copies the value from user memory and appends it to `dest`.
+    pub fn append_to_enclave_vec(&self, dest: &mut Vec<T>) {
+        dest.reserve(self.len());
+        self.copy_to_enclave(&mut dest.spare_capacity_mut()[..self.len()]);
         // SAFETY: We reserve enough space above.
-        unsafe { dest.set_len(self.len()) };
-        self.copy_to_enclave(&mut dest[..]);
+        unsafe { dest.set_len(dest.len() + self.len()) };
     }
 
     /// Copies the value from user memory into a vector in enclave memory.
     pub fn to_enclave(&self) -> Vec<T> {
         let mut ret = Vec::with_capacity(self.len());
-        self.copy_to_enclave_vec(&mut ret);
+        self.append_to_enclave_vec(&mut ret);
         ret
     }
 
diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs b/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs
index 90b9b59471a..cbdaf439b28 100644
--- a/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs
+++ b/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs
@@ -1,5 +1,7 @@
 use crate::cmp;
-use crate::io::{Error as IoError, ErrorKind, IoSlice, IoSliceMut, Result as IoResult};
+use crate::io::{
+    BorrowedCursor, Error as IoError, ErrorKind, IoSlice, IoSliceMut, Result as IoResult,
+};
 use crate::random::{DefaultRandomSource, Random};
 use crate::time::{Duration, Instant};
 
@@ -36,6 +38,19 @@ pub fn read(fd: Fd, bufs: &mut [IoSliceMut<'_>]) -> IoResult<usize> {
     }
 }
 
+/// Usercall `read` with an uninitialized buffer. See the ABI documentation for
+/// more information.
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub fn read_buf(fd: Fd, mut buf: BorrowedCursor<'_>) -> IoResult<()> {
+    unsafe {
+        let mut userbuf = alloc::User::<[u8]>::uninitialized(buf.capacity());
+        let len = raw::read(fd, userbuf.as_mut_ptr().cast(), userbuf.len()).from_sgx_result()?;
+        userbuf[..len].copy_to_enclave(&mut buf.as_mut()[..len]);
+        buf.advance_unchecked(len);
+        Ok(())
+    }
+}
+
 /// Usercall `read_alloc`. See the ABI documentation for more information.
 #[unstable(feature = "sgx_platform", issue = "56975")]
 pub fn read_alloc(fd: Fd) -> IoResult<Vec<u8>> {
diff --git a/library/std/src/sys/pal/sgx/fd.rs b/library/std/src/sys/pal/sgx/fd.rs
index 3bb3189a1d1..399f6a16489 100644
--- a/library/std/src/sys/pal/sgx/fd.rs
+++ b/library/std/src/sys/pal/sgx/fd.rs
@@ -29,7 +29,7 @@ impl FileDesc {
     }
 
     pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> {
-        crate::io::default_read_buf(|b| self.read(b), buf)
+        usercalls::read_buf(self.fd, buf)
     }
 
     pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
diff --git a/library/std/src/sys/pal/trusty/mod.rs b/library/std/src/sys/pal/trusty/mod.rs
new file mode 100644
index 00000000000..7034b643d8e
--- /dev/null
+++ b/library/std/src/sys/pal/trusty/mod.rs
@@ -0,0 +1,21 @@
+//! System bindings for the Trusty OS.
+
+#[path = "../unsupported/args.rs"]
+pub mod args;
+#[path = "../unsupported/common.rs"]
+#[deny(unsafe_op_in_unsafe_fn)]
+mod common;
+#[path = "../unsupported/env.rs"]
+pub mod env;
+#[path = "../unsupported/os.rs"]
+pub mod os;
+#[path = "../unsupported/pipe.rs"]
+pub mod pipe;
+#[path = "../unsupported/process.rs"]
+pub mod process;
+#[path = "../unsupported/thread.rs"]
+pub mod thread;
+#[path = "../unsupported/time.rs"]
+pub mod time;
+
+pub use common::*;
diff --git a/library/std/src/sys/random/mod.rs b/library/std/src/sys/random/mod.rs
index f42351deb92..870039602bc 100644
--- a/library/std/src/sys/random/mod.rs
+++ b/library/std/src/sys/random/mod.rs
@@ -60,6 +60,9 @@ cfg_if::cfg_if! {
     } else if #[cfg(target_os = "teeos")] {
         mod teeos;
         pub use teeos::fill_bytes;
+    } else if #[cfg(target_os = "trusty")] {
+        mod trusty;
+        pub use trusty::fill_bytes;
     } else if #[cfg(target_os = "uefi")] {
         mod uefi;
         pub use uefi::fill_bytes;
diff --git a/library/std/src/sys/random/trusty.rs b/library/std/src/sys/random/trusty.rs
new file mode 100644
index 00000000000..da6ca3eea24
--- /dev/null
+++ b/library/std/src/sys/random/trusty.rs
@@ -0,0 +1,7 @@
+extern "C" {
+    fn trusty_rng_secure_rand(randomBuffer: *mut core::ffi::c_void, randomBufferLen: libc::size_t);
+}
+
+pub fn fill_bytes(bytes: &mut [u8]) {
+    unsafe { trusty_rng_secure_rand(bytes.as_mut_ptr().cast(), bytes.len()) }
+}
diff --git a/library/std/src/sys/stdio/mod.rs b/library/std/src/sys/stdio/mod.rs
index 2a9167bfe96..336d4c8527d 100644
--- a/library/std/src/sys/stdio/mod.rs
+++ b/library/std/src/sys/stdio/mod.rs
@@ -19,6 +19,9 @@ cfg_if::cfg_if! {
     } else if #[cfg(target_os = "teeos")] {
         mod teeos;
         pub use teeos::*;
+    } else if #[cfg(target_os = "trusty")] {
+        mod trusty;
+        pub use trusty::*;
     } else if #[cfg(target_os = "uefi")] {
         mod uefi;
         pub use uefi::*;
diff --git a/library/std/src/sys/stdio/sgx.rs b/library/std/src/sys/stdio/sgx.rs
index 03d754cb217..1894c098d18 100644
--- a/library/std/src/sys/stdio/sgx.rs
+++ b/library/std/src/sys/stdio/sgx.rs
@@ -1,6 +1,6 @@
 use fortanix_sgx_abi as abi;
 
-use crate::io;
+use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
 use crate::sys::fd::FileDesc;
 
 pub struct Stdin(());
@@ -24,6 +24,19 @@ impl io::Read for Stdin {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         with_std_fd(abi::FD_STDIN, |fd| fd.read(buf))
     }
+
+    fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> {
+        with_std_fd(abi::FD_STDIN, |fd| fd.read_buf(buf))
+    }
+
+    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+        with_std_fd(abi::FD_STDIN, |fd| fd.read_vectored(bufs))
+    }
+
+    #[inline]
+    fn is_read_vectored(&self) -> bool {
+        true
+    }
 }
 
 impl Stdout {
@@ -40,6 +53,15 @@ impl io::Write for Stdout {
     fn flush(&mut self) -> io::Result<()> {
         with_std_fd(abi::FD_STDOUT, |fd| fd.flush())
     }
+
+    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        with_std_fd(abi::FD_STDOUT, |fd| fd.write_vectored(bufs))
+    }
+
+    #[inline]
+    fn is_write_vectored(&self) -> bool {
+        true
+    }
 }
 
 impl Stderr {
@@ -56,6 +78,15 @@ impl io::Write for Stderr {
     fn flush(&mut self) -> io::Result<()> {
         with_std_fd(abi::FD_STDERR, |fd| fd.flush())
     }
+
+    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        with_std_fd(abi::FD_STDERR, |fd| fd.write_vectored(bufs))
+    }
+
+    #[inline]
+    fn is_write_vectored(&self) -> bool {
+        true
+    }
 }
 
 pub const STDIN_BUF_SIZE: usize = crate::sys::io::DEFAULT_BUF_SIZE;
diff --git a/library/std/src/sys/stdio/trusty.rs b/library/std/src/sys/stdio/trusty.rs
new file mode 100644
index 00000000000..d393e95394d
--- /dev/null
+++ b/library/std/src/sys/stdio/trusty.rs
@@ -0,0 +1,81 @@
+use crate::io;
+
+pub struct Stdin;
+pub struct Stdout;
+pub struct Stderr;
+
+impl Stdin {
+    pub const fn new() -> Stdin {
+        Stdin
+    }
+}
+
+impl io::Read for Stdin {
+    fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
+        Ok(0)
+    }
+}
+
+impl Stdout {
+    pub const fn new() -> Stdout {
+        Stdout
+    }
+}
+
+impl io::Write for Stdout {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        _write(libc::STDOUT_FILENO, buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
+impl Stderr {
+    pub const fn new() -> Stderr {
+        Stderr
+    }
+}
+
+impl io::Write for Stderr {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        _write(libc::STDERR_FILENO, buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
+pub const STDIN_BUF_SIZE: usize = 0;
+
+pub fn is_ebadf(_err: &io::Error) -> bool {
+    true
+}
+
+pub fn panic_output() -> Option<impl io::Write> {
+    Some(Stderr)
+}
+
+fn _write(fd: i32, message: &[u8]) -> io::Result<usize> {
+    let mut iov = libc::iovec { iov_base: message.as_ptr() as *mut _, iov_len: message.len() };
+    loop {
+        // SAFETY: syscall, safe arguments.
+        let ret = unsafe { libc::writev(fd, &iov, 1) };
+        if ret < 0 {
+            return Err(io::Error::last_os_error());
+        }
+        let ret = ret as usize;
+        if ret > iov.iov_len {
+            return Err(io::Error::last_os_error());
+        }
+        if ret == iov.iov_len {
+            return Ok(message.len());
+        }
+        // SAFETY: ret has been checked to be less than the length of
+        // the buffer
+        iov.iov_base = unsafe { iov.iov_base.add(ret) };
+        iov.iov_len -= ret;
+    }
+}
diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs
index f0a13323ec9..1ff13154b7b 100644
--- a/library/std/src/sys/thread_local/mod.rs
+++ b/library/std/src/sys/thread_local/mod.rs
@@ -28,6 +28,7 @@ cfg_if::cfg_if! {
         all(target_family = "wasm", not(target_feature = "atomics")),
         target_os = "uefi",
         target_os = "zkvm",
+        target_os = "trusty",
     ))] {
         mod statik;
         pub use statik::{EagerStorage, LazyStorage, thread_local_inner};
@@ -91,6 +92,7 @@ pub(crate) mod guard {
             )),
             target_os = "uefi",
             target_os = "zkvm",
+            target_os = "trusty",
         ))] {
             pub(crate) fn enable() {
                 // FIXME: Right now there is no concept of "thread exit" on