1 //! System bindings for the Fortanix SGX platform
3 //! This module contains the facade (aka platform-specific) implementations of
4 //! OS level functionality for Fortanix SGX.
6 use crate::io
::ErrorKind
;
7 use crate::os
::raw
::c_char
;
8 use crate::sync
::atomic
::{AtomicBool, Ordering}
;
20 #[path = "../unsupported/fs.rs"]
22 #[path = "../unsupported/io.rs"]
29 #[path = "../unsupported/pipe.rs"]
31 #[path = "../unsupported/process.rs"]
34 pub mod stack_overflow
;
37 pub mod thread_local_key
;
40 pub use crate::sys_common
::os_str_bytes
as os_str
;
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())
51 pub fn unsupported_err() -> crate::io
::Error
{
52 crate::io
::Error
::new(ErrorKind
::Other
, "operation not supported on SGX yet")
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(
65 "operation can't be trusted to have any effect on SGX",
72 pub fn decode_error_kind(code
: i32) -> ErrorKind
{
73 use fortanix_sgx_abi
::Error
;
75 // FIXME: not sure how to make sure all variants of Error are covered
76 if code
== Error
::NotFound
as _
{
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 _
{
90 } else if code
== Error
::AddrNotAvailable
as _
{
91 ErrorKind
::AddrNotAvailable
92 } else if code
== Error
::BrokenPipe
as _
{
94 } else if code
== Error
::AlreadyExists
as _
{
95 ErrorKind
::AlreadyExists
96 } else if code
== Error
::WouldBlock
as _
{
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 _
{
104 } else if code
== Error
::WriteZero
as _
{
106 } else if code
== Error
::Interrupted
as _
{
107 ErrorKind
::Interrupted
108 } else if code
== Error
::Other
as _
{
110 } else if code
== Error
::UnexpectedEof
as _
{
111 ErrorKind
::UnexpectedEof
117 // This enum is used as the storage for a bunch of types which can't actually
119 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
122 pub unsafe fn strlen(mut s
: *const c_char
) -> usize {
131 pub fn abort_internal() -> ! {
132 abi
::usercalls
::exit(true)
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.
139 // NB. used by both libunwind and libpanic_abort
140 pub extern "C" fn __rust_abort() {
145 pub fn rdrand64() -> u64 {
147 let mut ret
: u64 = 0;
149 if crate::arch
::x86_64
::_rdrand64_step(&mut ret
) == 1 {
153 rtabort
!("Failed to obtain random data");
158 pub fn hashmap_random_keys() -> (u64, u64) {
159 (self::rand
::rdrand64(), self::rand
::rdrand64())
162 pub use crate::sys_common
::{AsInner, FromInner, IntoInner}
;
164 pub trait TryIntoInner
<Inner
>: Sized
{
165 fn try_into_inner(self) -> Result
<Inner
, Self>;