]>
Commit | Line | Data |
---|---|---|
0731742a XL |
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. | |
29967ef6 | 5 | #![deny(unsafe_op_in_unsafe_fn)] |
0731742a | 6 | |
532ac7d7 | 7 | use crate::io::ErrorKind; |
532ac7d7 | 8 | use crate::sync::atomic::{AtomicBool, Ordering}; |
0731742a XL |
9 | |
10 | pub mod abi; | |
11 | mod waitqueue; | |
12 | ||
13 | pub mod alloc; | |
14 | pub mod args; | |
cdc7bbd5 | 15 | #[path = "../unix/cmath.rs"] |
0731742a | 16 | pub mod cmath; |
0731742a | 17 | pub mod env; |
0731742a | 18 | pub mod fd; |
1b1a35ee | 19 | #[path = "../unsupported/fs.rs"] |
0731742a | 20 | pub mod fs; |
1b1a35ee | 21 | #[path = "../unsupported/io.rs"] |
9fa01778 | 22 | pub mod io; |
0731742a | 23 | pub mod memchr; |
0731742a XL |
24 | pub mod net; |
25 | pub mod os; | |
94222f64 XL |
26 | #[path = "../unix/os_str.rs"] |
27 | pub mod os_str; | |
0731742a | 28 | pub mod path; |
1b1a35ee | 29 | #[path = "../unsupported/pipe.rs"] |
0731742a | 30 | pub mod pipe; |
1b1a35ee | 31 | #[path = "../unsupported/process.rs"] |
0731742a | 32 | pub mod process; |
dfeec247 | 33 | pub mod stdio; |
0731742a | 34 | pub mod thread; |
3dfed10e | 35 | pub mod thread_local_key; |
0731742a | 36 | pub mod time; |
0731742a | 37 | |
5e7ed085 FG |
38 | mod condvar; |
39 | mod mutex; | |
40 | mod rwlock; | |
41 | ||
42 | pub mod locks { | |
43 | pub use super::condvar::*; | |
44 | pub use super::mutex::*; | |
45 | pub use super::rwlock::*; | |
46 | } | |
47 | ||
cdc7bbd5 XL |
48 | // SAFETY: must be called only once during runtime initialization. |
49 | // NOTE: this is not guaranteed to run, for example when Rust code is called externally. | |
50 | pub unsafe fn init(argc: isize, argv: *const *const u8) { | |
51 | unsafe { | |
52 | args::init(argc, argv); | |
53 | } | |
54 | } | |
55 | ||
56 | // SAFETY: must be called only once during runtime cleanup. | |
57 | // NOTE: this is not guaranteed to run, for example when the program aborts. | |
58 | pub unsafe fn cleanup() {} | |
0731742a XL |
59 | |
60 | /// This function is used to implement functionality that simply doesn't exist. | |
61 | /// Programs relying on this functionality will need to deal with the error. | |
532ac7d7 | 62 | pub fn unsupported<T>() -> crate::io::Result<T> { |
0731742a XL |
63 | Err(unsupported_err()) |
64 | } | |
65 | ||
532ac7d7 | 66 | pub fn unsupported_err() -> crate::io::Error { |
5099ac24 | 67 | crate::io::const_io_error!(ErrorKind::Unsupported, "operation not supported on SGX yet") |
0731742a XL |
68 | } |
69 | ||
70 | /// This function is used to implement various functions that doesn't exist, | |
71 | /// but the lack of which might not be reason for error. If no error is | |
72 | /// returned, the program might very well be able to function normally. This is | |
73 | /// what happens when `SGX_INEFFECTIVE_ERROR` is set to `true`. If it is | |
74 | /// `false`, the behavior is the same as `unsupported`. | |
532ac7d7 | 75 | pub fn sgx_ineffective<T>(v: T) -> crate::io::Result<T> { |
0731742a XL |
76 | static SGX_INEFFECTIVE_ERROR: AtomicBool = AtomicBool::new(false); |
77 | if SGX_INEFFECTIVE_ERROR.load(Ordering::Relaxed) { | |
5099ac24 | 78 | Err(crate::io::const_io_error!( |
136023e0 | 79 | ErrorKind::Uncategorized, |
5099ac24 | 80 | "operation can't be trusted to have any effect on SGX", |
dfeec247 | 81 | )) |
0731742a XL |
82 | } else { |
83 | Ok(v) | |
84 | } | |
85 | } | |
86 | ||
532ac7d7 | 87 | pub fn decode_error_kind(code: i32) -> ErrorKind { |
0731742a XL |
88 | use fortanix_sgx_abi::Error; |
89 | ||
90 | // FIXME: not sure how to make sure all variants of Error are covered | |
91 | if code == Error::NotFound as _ { | |
532ac7d7 | 92 | ErrorKind::NotFound |
0731742a | 93 | } else if code == Error::PermissionDenied as _ { |
532ac7d7 | 94 | ErrorKind::PermissionDenied |
0731742a | 95 | } else if code == Error::ConnectionRefused as _ { |
532ac7d7 | 96 | ErrorKind::ConnectionRefused |
0731742a | 97 | } else if code == Error::ConnectionReset as _ { |
532ac7d7 | 98 | ErrorKind::ConnectionReset |
0731742a | 99 | } else if code == Error::ConnectionAborted as _ { |
532ac7d7 | 100 | ErrorKind::ConnectionAborted |
0731742a | 101 | } else if code == Error::NotConnected as _ { |
532ac7d7 | 102 | ErrorKind::NotConnected |
0731742a | 103 | } else if code == Error::AddrInUse as _ { |
532ac7d7 | 104 | ErrorKind::AddrInUse |
0731742a | 105 | } else if code == Error::AddrNotAvailable as _ { |
532ac7d7 | 106 | ErrorKind::AddrNotAvailable |
0731742a | 107 | } else if code == Error::BrokenPipe as _ { |
532ac7d7 | 108 | ErrorKind::BrokenPipe |
0731742a | 109 | } else if code == Error::AlreadyExists as _ { |
532ac7d7 | 110 | ErrorKind::AlreadyExists |
0731742a | 111 | } else if code == Error::WouldBlock as _ { |
532ac7d7 | 112 | ErrorKind::WouldBlock |
0731742a | 113 | } else if code == Error::InvalidInput as _ { |
532ac7d7 | 114 | ErrorKind::InvalidInput |
0731742a | 115 | } else if code == Error::InvalidData as _ { |
532ac7d7 | 116 | ErrorKind::InvalidData |
0731742a | 117 | } else if code == Error::TimedOut as _ { |
532ac7d7 | 118 | ErrorKind::TimedOut |
0731742a | 119 | } else if code == Error::WriteZero as _ { |
532ac7d7 | 120 | ErrorKind::WriteZero |
0731742a | 121 | } else if code == Error::Interrupted as _ { |
532ac7d7 | 122 | ErrorKind::Interrupted |
0731742a | 123 | } else if code == Error::Other as _ { |
136023e0 | 124 | ErrorKind::Uncategorized |
0731742a | 125 | } else if code == Error::UnexpectedEof as _ { |
532ac7d7 | 126 | ErrorKind::UnexpectedEof |
0731742a | 127 | } else { |
136023e0 | 128 | ErrorKind::Uncategorized |
0731742a XL |
129 | } |
130 | } | |
131 | ||
f9f354fc | 132 | pub fn abort_internal() -> ! { |
9fa01778 | 133 | abi::usercalls::exit(true) |
0731742a XL |
134 | } |
135 | ||
532ac7d7 XL |
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 | |
f9f354fc | 141 | pub extern "C" fn __rust_abort() { |
532ac7d7 XL |
142 | abort_internal(); |
143 | } | |
144 | ||
3dfed10e XL |
145 | pub mod rand { |
146 | pub fn rdrand64() -> u64 { | |
0731742a | 147 | unsafe { |
416331ca | 148 | let mut ret: u64 = 0; |
0731742a | 149 | for _ in 0..10 { |
532ac7d7 | 150 | if crate::arch::x86_64::_rdrand64_step(&mut ret) == 1 { |
0731742a XL |
151 | return ret; |
152 | } | |
153 | } | |
532ac7d7 | 154 | rtabort!("Failed to obtain random data"); |
0731742a XL |
155 | } |
156 | } | |
3dfed10e XL |
157 | } |
158 | ||
159 | pub fn hashmap_random_keys() -> (u64, u64) { | |
160 | (self::rand::rdrand64(), self::rand::rdrand64()) | |
0731742a XL |
161 | } |
162 | ||
532ac7d7 | 163 | pub use crate::sys_common::{AsInner, FromInner, IntoInner}; |
0731742a XL |
164 | |
165 | pub trait TryIntoInner<Inner>: Sized { | |
166 | fn try_into_inner(self) -> Result<Inner, Self>; | |
167 | } |