]> git.lizzy.rs Git - rust.git/blob - src/libstd/sys/sgx/mod.rs
SGX target: simplify usercall internals
[rust.git] / src / libstd / sys / sgx / mod.rs
1 //! System bindings for the Fortanix SGX platform
2 //!
3 //! This module contains the facade (aka platform-specific) implementations of
4 //! OS level functionality for Fortanix SGX.
5
6 use io;
7 use os::raw::c_char;
8 use sync::atomic::{AtomicBool, Ordering};
9
10 pub mod abi;
11 mod waitqueue;
12
13 pub mod alloc;
14 pub mod args;
15 #[cfg(feature = "backtrace")]
16 pub mod backtrace;
17 pub mod cmath;
18 pub mod condvar;
19 pub mod env;
20 pub mod ext;
21 pub mod fd;
22 pub mod fs;
23 pub mod memchr;
24 pub mod mutex;
25 pub mod net;
26 pub mod os;
27 pub mod os_str;
28 pub mod path;
29 pub mod pipe;
30 pub mod process;
31 pub mod rwlock;
32 pub mod stack_overflow;
33 pub mod thread;
34 pub mod thread_local;
35 pub mod time;
36 pub mod stdio;
37
38 #[cfg(not(test))]
39 pub fn init() {
40 }
41
42 /// This function is used to implement functionality that simply doesn't exist.
43 /// Programs relying on this functionality will need to deal with the error.
44 pub fn unsupported<T>() -> io::Result<T> {
45     Err(unsupported_err())
46 }
47
48 pub fn unsupported_err() -> io::Error {
49     io::Error::new(io::ErrorKind::Other,
50                    "operation not supported on SGX yet")
51 }
52
53 /// This function is used to implement various functions that doesn't exist,
54 /// but the lack of which might not be reason for error. If no error is
55 /// returned, the program might very well be able to function normally. This is
56 /// what happens when `SGX_INEFFECTIVE_ERROR` is set to `true`. If it is
57 /// `false`, the behavior is the same as `unsupported`.
58 pub fn sgx_ineffective<T>(v: T) -> io::Result<T> {
59     static SGX_INEFFECTIVE_ERROR: AtomicBool = AtomicBool::new(false);
60     if SGX_INEFFECTIVE_ERROR.load(Ordering::Relaxed) {
61         Err(io::Error::new(io::ErrorKind::Other,
62                        "operation can't be trusted to have any effect on SGX"))
63     } else {
64         Ok(v)
65     }
66 }
67
68 pub fn decode_error_kind(code: i32) -> io::ErrorKind {
69     use fortanix_sgx_abi::Error;
70
71     // FIXME: not sure how to make sure all variants of Error are covered
72     if code == Error::NotFound as _ {
73         io::ErrorKind::NotFound
74     } else if code == Error::PermissionDenied as _ {
75         io::ErrorKind::PermissionDenied
76     } else if code == Error::ConnectionRefused as _ {
77         io::ErrorKind::ConnectionRefused
78     } else if code == Error::ConnectionReset as _ {
79         io::ErrorKind::ConnectionReset
80     } else if code == Error::ConnectionAborted as _ {
81         io::ErrorKind::ConnectionAborted
82     } else if code == Error::NotConnected as _ {
83         io::ErrorKind::NotConnected
84     } else if code == Error::AddrInUse as _ {
85         io::ErrorKind::AddrInUse
86     } else if code == Error::AddrNotAvailable as _ {
87         io::ErrorKind::AddrNotAvailable
88     } else if code == Error::BrokenPipe as _ {
89         io::ErrorKind::BrokenPipe
90     } else if code == Error::AlreadyExists as _ {
91         io::ErrorKind::AlreadyExists
92     } else if code == Error::WouldBlock as _ {
93         io::ErrorKind::WouldBlock
94     } else if code == Error::InvalidInput as _ {
95         io::ErrorKind::InvalidInput
96     } else if code == Error::InvalidData as _ {
97         io::ErrorKind::InvalidData
98     } else if code == Error::TimedOut as _ {
99         io::ErrorKind::TimedOut
100     } else if code == Error::WriteZero as _ {
101         io::ErrorKind::WriteZero
102     } else if code == Error::Interrupted as _ {
103         io::ErrorKind::Interrupted
104     } else if code == Error::Other as _ {
105         io::ErrorKind::Other
106     } else if code == Error::UnexpectedEof as _ {
107         io::ErrorKind::UnexpectedEof
108     } else {
109         io::ErrorKind::Other
110     }
111 }
112
113 // This enum is used as the storage for a bunch of types which can't actually
114 // exist.
115 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
116 pub enum Void {}
117
118 pub unsafe fn strlen(mut s: *const c_char) -> usize {
119     let mut n = 0;
120     while *s != 0 {
121         n += 1;
122         s = s.offset(1);
123     }
124     return n
125 }
126
127 pub unsafe fn abort_internal() -> ! {
128     abi::usercalls::exit(true)
129 }
130
131 pub fn hashmap_random_keys() -> (u64, u64) {
132     fn rdrand64() -> u64 {
133         unsafe {
134             let mut ret: u64 = ::mem::uninitialized();
135             for _ in 0..10 {
136                 if ::arch::x86_64::_rdrand64_step(&mut ret) == 1 {
137                     return ret;
138                 }
139             }
140             panic!("Failed to obtain random data");
141         }
142     }
143     (rdrand64(), rdrand64())
144 }
145
146 pub use sys_common::{AsInner, FromInner, IntoInner};
147
148 pub trait TryIntoInner<Inner>: Sized {
149     fn try_into_inner(self) -> Result<Inner, Self>;
150 }