about summary refs log tree commit diff
path: root/library/std/src/sys/sgx/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/std/src/sys/sgx/mod.rs')
-rw-r--r--library/std/src/sys/sgx/mod.rs162
1 files changed, 162 insertions, 0 deletions
diff --git a/library/std/src/sys/sgx/mod.rs b/library/std/src/sys/sgx/mod.rs
new file mode 100644
index 00000000000..1d32eb25424
--- /dev/null
+++ b/library/std/src/sys/sgx/mod.rs
@@ -0,0 +1,162 @@
+//! System bindings for the Fortanix SGX platform
+//!
+//! This module contains the facade (aka platform-specific) implementations of
+//! OS level functionality for Fortanix SGX.
+
+use crate::io::ErrorKind;
+use crate::os::raw::c_char;
+use crate::sync::atomic::{AtomicBool, Ordering};
+
+pub mod abi;
+mod waitqueue;
+
+pub mod alloc;
+pub mod args;
+pub mod cmath;
+pub mod condvar;
+pub mod env;
+pub mod ext;
+pub mod fd;
+pub mod fs;
+pub mod io;
+pub mod memchr;
+pub mod mutex;
+pub mod net;
+pub mod os;
+pub mod path;
+pub mod pipe;
+pub mod process;
+pub mod rwlock;
+pub mod stack_overflow;
+pub mod stdio;
+pub mod thread;
+pub mod thread_local_key;
+pub mod time;
+
+pub use crate::sys_common::os_str_bytes as os_str;
+
+#[cfg(not(test))]
+pub fn init() {}
+
+/// This function is used to implement functionality that simply doesn't exist.
+/// Programs relying on this functionality will need to deal with the error.
+pub fn unsupported<T>() -> crate::io::Result<T> {
+    Err(unsupported_err())
+}
+
+pub fn unsupported_err() -> crate::io::Error {
+    crate::io::Error::new(ErrorKind::Other, "operation not supported on SGX yet")
+}
+
+/// This function is used to implement various functions that doesn't exist,
+/// but the lack of which might not be reason for error. If no error is
+/// returned, the program might very well be able to function normally. This is
+/// what happens when `SGX_INEFFECTIVE_ERROR` is set to `true`. If it is
+/// `false`, the behavior is the same as `unsupported`.
+pub fn sgx_ineffective<T>(v: T) -> crate::io::Result<T> {
+    static SGX_INEFFECTIVE_ERROR: AtomicBool = AtomicBool::new(false);
+    if SGX_INEFFECTIVE_ERROR.load(Ordering::Relaxed) {
+        Err(crate::io::Error::new(
+            ErrorKind::Other,
+            "operation can't be trusted to have any effect on SGX",
+        ))
+    } else {
+        Ok(v)
+    }
+}
+
+pub fn decode_error_kind(code: i32) -> ErrorKind {
+    use fortanix_sgx_abi::Error;
+
+    // FIXME: not sure how to make sure all variants of Error are covered
+    if code == Error::NotFound as _ {
+        ErrorKind::NotFound
+    } else if code == Error::PermissionDenied as _ {
+        ErrorKind::PermissionDenied
+    } else if code == Error::ConnectionRefused as _ {
+        ErrorKind::ConnectionRefused
+    } else if code == Error::ConnectionReset as _ {
+        ErrorKind::ConnectionReset
+    } else if code == Error::ConnectionAborted as _ {
+        ErrorKind::ConnectionAborted
+    } else if code == Error::NotConnected as _ {
+        ErrorKind::NotConnected
+    } else if code == Error::AddrInUse as _ {
+        ErrorKind::AddrInUse
+    } else if code == Error::AddrNotAvailable as _ {
+        ErrorKind::AddrNotAvailable
+    } else if code == Error::BrokenPipe as _ {
+        ErrorKind::BrokenPipe
+    } else if code == Error::AlreadyExists as _ {
+        ErrorKind::AlreadyExists
+    } else if code == Error::WouldBlock as _ {
+        ErrorKind::WouldBlock
+    } else if code == Error::InvalidInput as _ {
+        ErrorKind::InvalidInput
+    } else if code == Error::InvalidData as _ {
+        ErrorKind::InvalidData
+    } else if code == Error::TimedOut as _ {
+        ErrorKind::TimedOut
+    } else if code == Error::WriteZero as _ {
+        ErrorKind::WriteZero
+    } else if code == Error::Interrupted as _ {
+        ErrorKind::Interrupted
+    } else if code == Error::Other as _ {
+        ErrorKind::Other
+    } else if code == Error::UnexpectedEof as _ {
+        ErrorKind::UnexpectedEof
+    } else {
+        ErrorKind::Other
+    }
+}
+
+// This enum is used as the storage for a bunch of types which can't actually
+// exist.
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+pub enum Void {}
+
+pub unsafe fn strlen(mut s: *const c_char) -> usize {
+    let mut n = 0;
+    while *s != 0 {
+        n += 1;
+        s = s.offset(1);
+    }
+    return n;
+}
+
+pub fn abort_internal() -> ! {
+    abi::usercalls::exit(true)
+}
+
+// This function is needed by the panic runtime. The symbol is named in
+// pre-link args for the target specification, so keep that in sync.
+#[cfg(not(test))]
+#[no_mangle]
+// NB. used by both libunwind and libpanic_abort
+pub extern "C" fn __rust_abort() {
+    abort_internal();
+}
+
+pub mod rand {
+    pub fn rdrand64() -> u64 {
+        unsafe {
+            let mut ret: u64 = 0;
+            for _ in 0..10 {
+                if crate::arch::x86_64::_rdrand64_step(&mut ret) == 1 {
+                    return ret;
+                }
+            }
+            rtabort!("Failed to obtain random data");
+        }
+    }
+}
+
+pub fn hashmap_random_keys() -> (u64, u64) {
+    (self::rand::rdrand64(), self::rand::rdrand64())
+}
+
+pub use crate::sys_common::{AsInner, FromInner, IntoInner};
+
+pub trait TryIntoInner<Inner>: Sized {
+    fn try_into_inner(self) -> Result<Inner, Self>;
+}