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