1 // Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! System bindings for the Fortanix SGX platform
13 //! This module contains the facade (aka platform-specific) implementations of
14 //! OS level functionality for Fortanix SGX.
18 use sync::atomic::{AtomicBool, Ordering};
25 #[cfg(feature = "backtrace")]
40 pub mod stack_overflow;
50 /// This function is used to implement functionality that simply doesn't exist.
51 /// Programs relying on this functionality will need to deal with the error.
52 pub fn unsupported<T>() -> io::Result<T> {
53 Err(unsupported_err())
56 pub fn unsupported_err() -> io::Error {
57 io::Error::new(io::ErrorKind::Other,
58 "operation not supported on SGX yet")
61 /// This function is used to implement various functions that doesn't exist,
62 /// but the lack of which might not be reason for error. If no error is
63 /// returned, the program might very well be able to function normally. This is
64 /// what happens when `SGX_INEFFECTIVE_ERROR` is set to `true`. If it is
65 /// `false`, the behavior is the same as `unsupported`.
66 pub fn sgx_ineffective<T>(v: T) -> io::Result<T> {
67 static SGX_INEFFECTIVE_ERROR: AtomicBool = AtomicBool::new(false);
68 if SGX_INEFFECTIVE_ERROR.load(Ordering::Relaxed) {
69 Err(io::Error::new(io::ErrorKind::Other,
70 "operation can't be trusted to have any effect on SGX"))
76 pub fn decode_error_kind(code: i32) -> io::ErrorKind {
77 use fortanix_sgx_abi::Error;
79 // FIXME: not sure how to make sure all variants of Error are covered
80 if code == Error::NotFound as _ {
81 io::ErrorKind::NotFound
82 } else if code == Error::PermissionDenied as _ {
83 io::ErrorKind::PermissionDenied
84 } else if code == Error::ConnectionRefused as _ {
85 io::ErrorKind::ConnectionRefused
86 } else if code == Error::ConnectionReset as _ {
87 io::ErrorKind::ConnectionReset
88 } else if code == Error::ConnectionAborted as _ {
89 io::ErrorKind::ConnectionAborted
90 } else if code == Error::NotConnected as _ {
91 io::ErrorKind::NotConnected
92 } else if code == Error::AddrInUse as _ {
93 io::ErrorKind::AddrInUse
94 } else if code == Error::AddrNotAvailable as _ {
95 io::ErrorKind::AddrNotAvailable
96 } else if code == Error::BrokenPipe as _ {
97 io::ErrorKind::BrokenPipe
98 } else if code == Error::AlreadyExists as _ {
99 io::ErrorKind::AlreadyExists
100 } else if code == Error::WouldBlock as _ {
101 io::ErrorKind::WouldBlock
102 } else if code == Error::InvalidInput as _ {
103 io::ErrorKind::InvalidInput
104 } else if code == Error::InvalidData as _ {
105 io::ErrorKind::InvalidData
106 } else if code == Error::TimedOut as _ {
107 io::ErrorKind::TimedOut
108 } else if code == Error::WriteZero as _ {
109 io::ErrorKind::WriteZero
110 } else if code == Error::Interrupted as _ {
111 io::ErrorKind::Interrupted
112 } else if code == Error::Other as _ {
114 } else if code == Error::UnexpectedEof as _ {
115 io::ErrorKind::UnexpectedEof
121 // This enum is used as the storage for a bunch of types which can't actually
123 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
126 pub unsafe fn strlen(mut s: *const c_char) -> usize {
135 pub unsafe fn abort_internal() -> ! {
136 abi::panic::panic_exit()
139 pub fn hashmap_random_keys() -> (u64, u64) {
140 fn rdrand64() -> u64 {
142 let mut ret: u64 = ::mem::uninitialized();
144 if ::arch::x86_64::_rdrand64_step(&mut ret) == 1 {
148 panic!("Failed to obtain random data");
151 (rdrand64(), rdrand64())