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