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.
5 #![deny(unsafe_op_in_unsafe_fn)]
7 use crate::io
::ErrorKind
;
8 use crate::os
::raw
::c_char
;
9 use crate::sync
::atomic
::{AtomicBool, Ordering}
;
16 #[path = "../unix/cmath.rs"]
21 #[path = "../unsupported/fs.rs"]
23 #[path = "../unsupported/io.rs"]
30 #[path = "../unsupported/pipe.rs"]
32 #[path = "../unsupported/process.rs"]
37 pub mod thread_local_key
;
40 pub use crate::sys_common
::os_str_bytes
as os_str
;
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) {
46 args
::init(argc
, argv
);
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() {}
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())
60 pub fn unsupported_err() -> crate::io
::Error
{
61 crate::io
::Error
::new_const(ErrorKind
::Unsupported
, &"operation not supported on SGX yet")
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",
81 pub fn decode_error_kind(code
: i32) -> ErrorKind
{
82 use fortanix_sgx_abi
::Error
;
84 // FIXME: not sure how to make sure all variants of Error are covered
85 if code
== Error
::NotFound
as _
{
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 _
{
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 _
{
113 } else if code
== Error
::WriteZero
as _
{
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
122 ErrorKind
::Uncategorized
126 pub unsafe fn strlen(mut s
: *const c_char
) -> usize {
128 while unsafe { *s }
!= 0 {
130 s
= unsafe { s.offset(1) }
;
135 pub fn abort_internal() -> ! {
136 abi
::usercalls
::exit(true)
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.
143 // NB. used by both libunwind and libpanic_abort
144 pub extern "C" fn __rust_abort() {
149 pub fn rdrand64() -> u64 {
151 let mut ret
: u64 = 0;
153 if crate::arch
::x86_64
::_rdrand64_step(&mut ret
) == 1 {
157 rtabort
!("Failed to obtain random data");
162 pub fn hashmap_random_keys() -> (u64, u64) {
163 (self::rand
::rdrand64(), self::rand
::rdrand64())
166 pub use crate::sys_common
::{AsInner, FromInner, IntoInner}
;
168 pub trait TryIntoInner
<Inner
>: Sized
{
169 fn try_into_inner(self) -> Result
<Inner
, Self>;