| From 219ec2c5f5b1138e702e6e736736dde6571beecf Mon Sep 17 00:00:00 2001 |
| From: David LeGare <legare@google.com> |
| Date: Thu, 12 May 2022 20:46:00 +0000 |
| Subject: [PATCH 05/14] Add Trusty OS support to Rust std |
| |
| Updated 2024-06-26 for Rust 1.78.0 |
| |
| Updated 2024-12-14 for Rust 1.82.0 |
| |
| Change-Id: I1bc9b9d80ee9bfde9892b480890228887e1c62a0 |
| --- |
| library/core/src/ffi/mod.rs | 1 + |
| library/std/build.rs | 1 + |
| library/std/src/sys/alloc/mod.rs | 1 + |
| library/std/src/sys/pal/mod.rs | 3 + |
| library/std/src/sys/pal/trusty/mod.rs | 28 +++++++ |
| library/std/src/sys/pal/trusty/stdio.rs | 82 +++++++++++++++++++ |
| library/std/src/sys/random/mod.rs | 3 + |
| library/std/src/sys/random/trusty.rs | 7 ++ |
| .../std/src/sys/thread_local/key/trusty.rs | 30 +++++++ |
| library/std/src/sys/thread_local/mod.rs | 9 ++ |
| 10 files changed, 165 insertions(+) |
| create mode 100644 library/std/src/sys/pal/trusty/mod.rs |
| create mode 100644 library/std/src/sys/pal/trusty/stdio.rs |
| create mode 100644 library/std/src/sys/random/trusty.rs |
| create mode 100644 library/std/src/sys/thread_local/key/trusty.rs |
| |
| diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs |
| index dc107c5d22..195bccadc7 100644 |
| --- a/library/core/src/ffi/mod.rs |
| +++ b/library/core/src/ffi/mod.rs |
| @@ -134,20 +134,21 @@ mod c_char_definition { |
| target_arch = "aarch64", |
| target_arch = "arm", |
| target_arch = "powerpc64", |
| target_arch = "powerpc" |
| ) |
| ), |
| all( |
| target_os = "fuchsia", |
| any(target_arch = "aarch64", target_arch = "riscv64") |
| ), |
| + all(target_os = "trusty", any(target_arch = "aarch64", target_arch = "arm")), |
| all(target_os = "nto", target_arch = "aarch64"), |
| target_os = "horizon", |
| target_os = "aix", |
| ))] { |
| pub type c_char = u8; |
| } else { |
| // On every other target, c_char is signed. |
| pub type c_char = i8; |
| } |
| } |
| diff --git a/library/std/build.rs b/library/std/build.rs |
| index 032326556b..45b7007bcc 100644 |
| --- a/library/std/build.rs |
| +++ b/library/std/build.rs |
| @@ -30,20 +30,21 @@ fn main() { |
| || target_os == "illumos" |
| || target_os == "macos" |
| || target_os == "ios" |
| || target_os == "tvos" |
| || target_os == "watchos" |
| || target_os == "visionos" |
| || target_os == "windows" |
| || target_os == "fuchsia" |
| || (target_vendor == "fortanix" && target_env == "sgx") |
| || target_os == "hermit" |
| + || target_os == ("trusty") |
| || target_os == "l4re" |
| || target_os == "redox" |
| || target_os == "haiku" |
| || target_os == "vxworks" |
| || target_arch == "wasm32" |
| || target_arch == "wasm64" |
| || target_os == "espidf" |
| || target_os.starts_with("solid") |
| || (target_vendor == "nintendo" && target_env == "newlib") |
| || target_os == "vita" |
| diff --git a/library/std/src/sys/alloc/mod.rs b/library/std/src/sys/alloc/mod.rs |
| index 2c0b533a57..8489e17c97 100644 |
| --- a/library/std/src/sys/alloc/mod.rs |
| +++ b/library/std/src/sys/alloc/mod.rs |
| @@ -65,20 +65,21 @@ unsafe fn realloc_fallback( |
| |
| new_ptr |
| } |
| } |
| |
| cfg_if::cfg_if! { |
| if #[cfg(any( |
| target_family = "unix", |
| target_os = "wasi", |
| target_os = "teeos", |
| + target_os = "trusty", |
| ))] { |
| mod unix; |
| } else if #[cfg(target_os = "windows")] { |
| mod windows; |
| } else if #[cfg(target_os = "hermit")] { |
| mod hermit; |
| } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { |
| mod sgx; |
| } else if #[cfg(target_os = "solid_asp3")] { |
| mod solid; |
| diff --git a/library/std/src/sys/pal/mod.rs b/library/std/src/sys/pal/mod.rs |
| index 9be018c8a5..fbefc62ac8 100644 |
| --- a/library/std/src/sys/pal/mod.rs |
| +++ b/library/std/src/sys/pal/mod.rs |
| @@ -30,20 +30,23 @@ cfg_if::cfg_if! { |
| pub use self::unix::*; |
| } else if #[cfg(windows)] { |
| mod windows; |
| pub use self::windows::*; |
| } else if #[cfg(target_os = "solid_asp3")] { |
| mod solid; |
| pub use self::solid::*; |
| } 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::*; |
| } else if #[cfg(target_os = "wasi")] { |
| mod wasi; |
| pub use self::wasi::*; |
| } else if #[cfg(target_family = "wasm")] { |
| mod wasm; |
| pub use self::wasm::*; |
| } else if #[cfg(target_os = "xous")] { |
| 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 0000000000..41005205c8 |
| --- /dev/null |
| +++ b/library/std/src/sys/pal/trusty/mod.rs |
| @@ -0,0 +1,28 @@ |
| +//! System bindings for the Trusty OS. |
| + |
| +#[path = "../unsupported/args.rs"] |
| +pub mod args; |
| +#[path = "../unsupported/env.rs"] |
| +pub mod env; |
| +#[path = "../unsupported/fs.rs"] |
| +pub mod fs; |
| +#[path = "../unsupported/io.rs"] |
| +pub mod io; |
| +#[path = "../unsupported/net.rs"] |
| +pub mod net; |
| +#[path = "../unsupported/os.rs"] |
| +pub mod os; |
| +#[path = "../unsupported/pipe.rs"] |
| +pub mod pipe; |
| +#[path = "../unsupported/process.rs"] |
| +pub mod process; |
| +pub mod stdio; |
| +#[path = "../unsupported/time.rs"] |
| +pub mod time; |
| +#[path = "../unsupported/thread.rs"] |
| +pub mod thread; |
| +#[path = "../unsupported/common.rs"] |
| +#[deny(unsafe_op_in_unsafe_fn)] |
| +mod common; |
| + |
| +pub use common::*; |
| diff --git a/library/std/src/sys/pal/trusty/stdio.rs b/library/std/src/sys/pal/trusty/stdio.rs |
| new file mode 100644 |
| index 0000000000..3f7c9f76e7 |
| --- /dev/null |
| +++ b/library/std/src/sys/pal/trusty/stdio.rs |
| @@ -0,0 +1,82 @@ |
| +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/random/mod.rs b/library/std/src/sys/random/mod.rs |
| index d625814d15..3443d7dd6a 100644 |
| --- a/library/std/src/sys/random/mod.rs |
| +++ b/library/std/src/sys/random/mod.rs |
| @@ -51,20 +51,23 @@ cfg_if::cfg_if! { |
| pub use redox::fill_bytes; |
| } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { |
| mod sgx; |
| pub use sgx::fill_bytes; |
| } else if #[cfg(target_os = "solid_asp3")] { |
| mod solid; |
| pub use solid::fill_bytes; |
| } 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; |
| } else if #[cfg(target_os = "vxworks")] { |
| mod vxworks; |
| pub use vxworks::fill_bytes; |
| } else if #[cfg(target_os = "wasi")] { |
| mod wasi; |
| pub use wasi::fill_bytes; |
| } else if #[cfg(target_os = "zkvm")] { |
| diff --git a/library/std/src/sys/random/trusty.rs b/library/std/src/sys/random/trusty.rs |
| new file mode 100644 |
| index 0000000000..da6ca3eea2 |
| --- /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/thread_local/key/trusty.rs b/library/std/src/sys/thread_local/key/trusty.rs |
| new file mode 100644 |
| index 0000000000..894091d2d8 |
| --- /dev/null |
| +++ b/library/std/src/sys/thread_local/key/trusty.rs |
| @@ -0,0 +1,30 @@ |
| +use crate::ptr; |
| + |
| +pub type Key = usize; |
| +type Dtor = unsafe extern "C" fn(*mut u8); |
| + |
| +static mut STORAGE: crate::vec::Vec<(*mut u8, Option<Dtor>)> = Vec::new(); |
| + |
| +#[inline] |
| +pub fn create(dtor: Option<Dtor>) -> Key { |
| + unsafe { |
| + #[allow(static_mut_refs)] |
| + let key = STORAGE.len(); |
| + #[allow(static_mut_refs)] |
| + STORAGE.push((ptr::null_mut(), dtor)); |
| + key |
| + } |
| +} |
| + |
| +#[inline] |
| +pub unsafe fn set(key: Key, value: *mut u8) { |
| + unsafe { STORAGE[key].0 = value }; |
| +} |
| + |
| +#[inline] |
| +pub unsafe fn get(key: Key) -> *mut u8 { |
| + unsafe { STORAGE[key].0 } |
| +} |
| + |
| +#[inline] |
| +pub fn destroy(_key: Key) {} |
| diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs |
| index 31d3b43906..3146581d86 100644 |
| --- a/library/std/src/sys/thread_local/mod.rs |
| +++ b/library/std/src/sys/thread_local/mod.rs |
| @@ -160,20 +160,29 @@ pub(crate) mod key { |
| use sgx::{create, destroy}; |
| } else if #[cfg(target_os = "xous")] { |
| mod racy; |
| #[cfg(test)] |
| mod tests; |
| mod xous; |
| pub(super) use racy::LazyKey; |
| pub(crate) use xous::destroy_tls; |
| pub(super) use xous::{Key, get, set}; |
| use xous::{create, destroy}; |
| + } else if #[cfg(target_os = "trusty")] { |
| + #[allow(unused_unsafe)] |
| + mod racy; |
| + #[cfg(test)] |
| + mod tests; |
| + mod trusty; |
| + pub(super) use racy::LazyKey; |
| + pub(super) use trusty::{Key, get, set}; |
| + use trusty::{create, destroy}; |
| } |
| } |
| } |
| |
| /// Run a callback in a scenario which must not unwind (such as a `extern "C" |
| /// fn` declared in a user crate). If the callback unwinds anyway, then |
| /// `rtabort` with a message about thread local panicking on drop. |
| #[inline] |
| #[allow(dead_code)] |
| fn abort_on_dtor_unwind(f: impl FnOnce()) { |
| -- |
| 2.48.1.362.g079036d154-goog |
| |