1 //! System bindings for the Fortanix SGX platform
3 //! This module contains the facade (aka platform-specific) implementations of
4 //! OS level functionality for Fortanix SGX.
6 use crate::io::ErrorKind;
7 use crate::os::raw::c_char;
8 use crate::sync::atomic::{AtomicBool, Ordering};
15 #[cfg(feature = "backtrace")]
32 pub mod stack_overflow;
38 pub use crate::sys_common::os_str_bytes as os_str;
44 /// This function is used to implement functionality that simply doesn't exist.
45 /// Programs relying on this functionality will need to deal with the error.
46 pub fn unsupported<T>() -> crate::io::Result<T> {
47 Err(unsupported_err())
50 pub fn unsupported_err() -> crate::io::Error {
51 crate::io::Error::new(ErrorKind::Other,
52 "operation not supported on SGX yet")
55 /// This function is used to implement various functions that doesn't exist,
56 /// but the lack of which might not be reason for error. If no error is
57 /// returned, the program might very well be able to function normally. This is
58 /// what happens when `SGX_INEFFECTIVE_ERROR` is set to `true`. If it is
59 /// `false`, the behavior is the same as `unsupported`.
60 pub fn sgx_ineffective<T>(v: T) -> crate::io::Result<T> {
61 static SGX_INEFFECTIVE_ERROR: AtomicBool = AtomicBool::new(false);
62 if SGX_INEFFECTIVE_ERROR.load(Ordering::Relaxed) {
63 Err(crate::io::Error::new(ErrorKind::Other,
64 "operation can't be trusted to have any effect on SGX"))
70 pub fn decode_error_kind(code: i32) -> ErrorKind {
71 use fortanix_sgx_abi::Error;
73 // FIXME: not sure how to make sure all variants of Error are covered
74 if code == Error::NotFound as _ {
76 } else if code == Error::PermissionDenied as _ {
77 ErrorKind::PermissionDenied
78 } else if code == Error::ConnectionRefused as _ {
79 ErrorKind::ConnectionRefused
80 } else if code == Error::ConnectionReset as _ {
81 ErrorKind::ConnectionReset
82 } else if code == Error::ConnectionAborted as _ {
83 ErrorKind::ConnectionAborted
84 } else if code == Error::NotConnected as _ {
85 ErrorKind::NotConnected
86 } else if code == Error::AddrInUse as _ {
88 } else if code == Error::AddrNotAvailable as _ {
89 ErrorKind::AddrNotAvailable
90 } else if code == Error::BrokenPipe as _ {
92 } else if code == Error::AlreadyExists as _ {
93 ErrorKind::AlreadyExists
94 } else if code == Error::WouldBlock as _ {
96 } else if code == Error::InvalidInput as _ {
97 ErrorKind::InvalidInput
98 } else if code == Error::InvalidData as _ {
99 ErrorKind::InvalidData
100 } else if code == Error::TimedOut as _ {
102 } else if code == Error::WriteZero as _ {
104 } else if code == Error::Interrupted as _ {
105 ErrorKind::Interrupted
106 } else if code == Error::Other as _ {
108 } else if code == Error::UnexpectedEof as _ {
109 ErrorKind::UnexpectedEof
115 // This enum is used as the storage for a bunch of types which can't actually
117 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
120 pub unsafe fn strlen(mut s: *const c_char) -> usize {
129 pub unsafe fn abort_internal() -> ! {
130 abi::usercalls::exit(true)
133 // This function is needed by the panic runtime. The symbol is named in
134 // pre-link args for the target specification, so keep that in sync.
137 // NB. used by both libunwind and libpanic_abort
138 pub unsafe extern "C" fn __rust_abort() {
142 pub fn hashmap_random_keys() -> (u64, u64) {
143 fn rdrand64() -> u64 {
145 let mut ret: u64 = crate::mem::uninitialized();
147 if crate::arch::x86_64::_rdrand64_step(&mut ret) == 1 {
151 panic!("Failed to obtain random data");
154 (rdrand64(), rdrand64())
157 pub use crate::sys_common::{AsInner, FromInner, IntoInner};
159 pub trait TryIntoInner<Inner>: Sized {
160 fn try_into_inner(self) -> Result<Inner, Self>;