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