]> git.proxmox.com Git - rustc.git/blob - library/std/src/sys/sgx/mod.rs
New upstream version 1.55.0+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 #![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 #[path = "../unix/cmath.rs"]
17 pub mod cmath;
18 pub mod condvar;
19 pub mod env;
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 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 // SAFETY: must be called only once during runtime initialization.
43 // NOTE: this is not guaranteed to run, for example when Rust code is called externally.
44 pub unsafe fn init(argc: isize, argv: *const *const u8) {
45 unsafe {
46 args::init(argc, argv);
47 }
48 }
49
50 // SAFETY: must be called only once during runtime cleanup.
51 // NOTE: this is not guaranteed to run, for example when the program aborts.
52 pub unsafe fn cleanup() {}
53
54 /// This function is used to implement functionality that simply doesn't exist.
55 /// Programs relying on this functionality will need to deal with the error.
56 pub fn unsupported<T>() -> crate::io::Result<T> {
57 Err(unsupported_err())
58 }
59
60 pub fn unsupported_err() -> crate::io::Error {
61 crate::io::Error::new_const(ErrorKind::Unsupported, &"operation not supported on SGX yet")
62 }
63
64 /// This function is used to implement various functions that doesn't exist,
65 /// but the lack of which might not be reason for error. If no error is
66 /// returned, the program might very well be able to function normally. This is
67 /// what happens when `SGX_INEFFECTIVE_ERROR` is set to `true`. If it is
68 /// `false`, the behavior is the same as `unsupported`.
69 pub fn sgx_ineffective<T>(v: T) -> crate::io::Result<T> {
70 static SGX_INEFFECTIVE_ERROR: AtomicBool = AtomicBool::new(false);
71 if SGX_INEFFECTIVE_ERROR.load(Ordering::Relaxed) {
72 Err(crate::io::Error::new_const(
73 ErrorKind::Uncategorized,
74 &"operation can't be trusted to have any effect on SGX",
75 ))
76 } else {
77 Ok(v)
78 }
79 }
80
81 pub fn decode_error_kind(code: i32) -> ErrorKind {
82 use fortanix_sgx_abi::Error;
83
84 // FIXME: not sure how to make sure all variants of Error are covered
85 if code == Error::NotFound as _ {
86 ErrorKind::NotFound
87 } else if code == Error::PermissionDenied as _ {
88 ErrorKind::PermissionDenied
89 } else if code == Error::ConnectionRefused as _ {
90 ErrorKind::ConnectionRefused
91 } else if code == Error::ConnectionReset as _ {
92 ErrorKind::ConnectionReset
93 } else if code == Error::ConnectionAborted as _ {
94 ErrorKind::ConnectionAborted
95 } else if code == Error::NotConnected as _ {
96 ErrorKind::NotConnected
97 } else if code == Error::AddrInUse as _ {
98 ErrorKind::AddrInUse
99 } else if code == Error::AddrNotAvailable as _ {
100 ErrorKind::AddrNotAvailable
101 } else if code == Error::BrokenPipe as _ {
102 ErrorKind::BrokenPipe
103 } else if code == Error::AlreadyExists as _ {
104 ErrorKind::AlreadyExists
105 } else if code == Error::WouldBlock as _ {
106 ErrorKind::WouldBlock
107 } else if code == Error::InvalidInput as _ {
108 ErrorKind::InvalidInput
109 } else if code == Error::InvalidData as _ {
110 ErrorKind::InvalidData
111 } else if code == Error::TimedOut as _ {
112 ErrorKind::TimedOut
113 } else if code == Error::WriteZero as _ {
114 ErrorKind::WriteZero
115 } else if code == Error::Interrupted as _ {
116 ErrorKind::Interrupted
117 } else if code == Error::Other as _ {
118 ErrorKind::Uncategorized
119 } else if code == Error::UnexpectedEof as _ {
120 ErrorKind::UnexpectedEof
121 } else {
122 ErrorKind::Uncategorized
123 }
124 }
125
126 pub unsafe fn strlen(mut s: *const c_char) -> usize {
127 let mut n = 0;
128 while unsafe { *s } != 0 {
129 n += 1;
130 s = unsafe { s.offset(1) };
131 }
132 return n;
133 }
134
135 pub fn abort_internal() -> ! {
136 abi::usercalls::exit(true)
137 }
138
139 // This function is needed by the panic runtime. The symbol is named in
140 // pre-link args for the target specification, so keep that in sync.
141 #[cfg(not(test))]
142 #[no_mangle]
143 // NB. used by both libunwind and libpanic_abort
144 pub extern "C" fn __rust_abort() {
145 abort_internal();
146 }
147
148 pub mod rand {
149 pub fn rdrand64() -> u64 {
150 unsafe {
151 let mut ret: u64 = 0;
152 for _ in 0..10 {
153 if crate::arch::x86_64::_rdrand64_step(&mut ret) == 1 {
154 return ret;
155 }
156 }
157 rtabort!("Failed to obtain random data");
158 }
159 }
160 }
161
162 pub fn hashmap_random_keys() -> (u64, u64) {
163 (self::rand::rdrand64(), self::rand::rdrand64())
164 }
165
166 pub use crate::sys_common::{AsInner, FromInner, IntoInner};
167
168 pub trait TryIntoInner<Inner>: Sized {
169 fn try_into_inner(self) -> Result<Inner, Self>;
170 }