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.
8 use sync::atomic::{AtomicBool, Ordering};
15 #[cfg(feature = "backtrace")]
31 pub mod stack_overflow;
41 /// This function is used to implement functionality that simply doesn't exist.
42 /// Programs relying on this functionality will need to deal with the error.
43 pub fn unsupported<T>() -> io::Result<T> {
44 Err(unsupported_err())
47 pub fn unsupported_err() -> io::Error {
48 io::Error::new(io::ErrorKind::Other,
49 "operation not supported on SGX yet")
52 /// This function is used to implement various functions that doesn't exist,
53 /// but the lack of which might not be reason for error. If no error is
54 /// returned, the program might very well be able to function normally. This is
55 /// what happens when `SGX_INEFFECTIVE_ERROR` is set to `true`. If it is
56 /// `false`, the behavior is the same as `unsupported`.
57 pub fn sgx_ineffective<T>(v: T) -> io::Result<T> {
58 static SGX_INEFFECTIVE_ERROR: AtomicBool = AtomicBool::new(false);
59 if SGX_INEFFECTIVE_ERROR.load(Ordering::Relaxed) {
60 Err(io::Error::new(io::ErrorKind::Other,
61 "operation can't be trusted to have any effect on SGX"))
67 pub fn decode_error_kind(code: i32) -> io::ErrorKind {
68 use fortanix_sgx_abi::Error;
70 // FIXME: not sure how to make sure all variants of Error are covered
71 if code == Error::NotFound as _ {
72 io::ErrorKind::NotFound
73 } else if code == Error::PermissionDenied as _ {
74 io::ErrorKind::PermissionDenied
75 } else if code == Error::ConnectionRefused as _ {
76 io::ErrorKind::ConnectionRefused
77 } else if code == Error::ConnectionReset as _ {
78 io::ErrorKind::ConnectionReset
79 } else if code == Error::ConnectionAborted as _ {
80 io::ErrorKind::ConnectionAborted
81 } else if code == Error::NotConnected as _ {
82 io::ErrorKind::NotConnected
83 } else if code == Error::AddrInUse as _ {
84 io::ErrorKind::AddrInUse
85 } else if code == Error::AddrNotAvailable as _ {
86 io::ErrorKind::AddrNotAvailable
87 } else if code == Error::BrokenPipe as _ {
88 io::ErrorKind::BrokenPipe
89 } else if code == Error::AlreadyExists as _ {
90 io::ErrorKind::AlreadyExists
91 } else if code == Error::WouldBlock as _ {
92 io::ErrorKind::WouldBlock
93 } else if code == Error::InvalidInput as _ {
94 io::ErrorKind::InvalidInput
95 } else if code == Error::InvalidData as _ {
96 io::ErrorKind::InvalidData
97 } else if code == Error::TimedOut as _ {
98 io::ErrorKind::TimedOut
99 } else if code == Error::WriteZero as _ {
100 io::ErrorKind::WriteZero
101 } else if code == Error::Interrupted as _ {
102 io::ErrorKind::Interrupted
103 } else if code == Error::Other as _ {
105 } else if code == Error::UnexpectedEof as _ {
106 io::ErrorKind::UnexpectedEof
112 // This enum is used as the storage for a bunch of types which can't actually
114 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
117 pub unsafe fn strlen(mut s: *const c_char) -> usize {
126 pub unsafe fn abort_internal() -> ! {
127 abi::panic::panic_exit()
130 pub fn hashmap_random_keys() -> (u64, u64) {
131 fn rdrand64() -> u64 {
133 let mut ret: u64 = ::mem::uninitialized();
135 if ::arch::x86_64::_rdrand64_step(&mut ret) == 1 {
139 panic!("Failed to obtain random data");
142 (rdrand64(), rdrand64())