diff options
| author | Stein Somers <git@steinsomers.be> | 2019-01-09 15:15:18 +0100 |
|---|---|---|
| committer | Stein Somers <git@steinsomers.be> | 2019-01-09 15:15:18 +0100 |
| commit | ccba43df81d5bda37c9e4d231ad4443e6f3a7e44 (patch) | |
| tree | efe674e2d5ae721f38fa8558385e0a2f12997227 /src/libstd/sys/sgx | |
| parent | f9f71cc32497ee4e3cbc7d9795bcf358a9268c13 (diff) | |
| parent | 664c7797f6bfddf9f5e67474c2fd8017f91d7110 (diff) | |
| download | rust-ccba43df81d5bda37c9e4d231ad4443e6f3a7e44.tar.gz rust-ccba43df81d5bda37c9e4d231ad4443e6f3a7e44.zip | |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'src/libstd/sys/sgx')
37 files changed, 681 insertions, 409 deletions
diff --git a/src/libstd/sys/sgx/abi/entry.S b/src/libstd/sys/sgx/abi/entry.S index 4d5cc02e11e..8dad6ee976f 100644 --- a/src/libstd/sys/sgx/abi/entry.S +++ b/src/libstd/sys/sgx/abi/entry.S @@ -1,13 +1,3 @@ -/* Copyright 2018 The Rust Project Developers. See the COPYRIGHT */ -/* file at the top-level directory of this distribution and at */ -/* http://rust-lang.org/COPYRIGHT. */ -/* */ -/* Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or */ -/* http://www.apache.org/licenses/LICENSE-2.0> or the MIT license */ -/* <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your */ -/* option. This file may not be copied, modified, or distributed */ -/* except according to those terms. */ - /* This symbol is used at runtime to figure out the virtual address that the */ /* enclave is loaded at. */ .section absolute @@ -56,6 +46,14 @@ IMAGE_BASE: globvar CFGDATA_BASE 8 /* Non-zero if debugging is enabled, zero otherwise */ globvar DEBUG 1 + /* The base address (relative to enclave start) of the enclave text section */ + globvar TEXT_BASE 8 + /* The size in bytes of enclacve text section */ + globvar TEXT_SIZE 8 + /* The base address (relative to enclave start) of the enclave EH_FRM_HDR section */ + globvar EH_FRM_HDR_BASE 8 + /* The size in bytes of enclacve EH_FRM_HDR section */ + globvar EH_FRM_HDR_SIZE 8 .Lreentry_panic_msg: .asciz "Re-entered panicked enclave!" diff --git a/src/libstd/sys/sgx/abi/mem.rs b/src/libstd/sys/sgx/abi/mem.rs index bf32c712216..09552d5b4af 100644 --- a/src/libstd/sys/sgx/abi/mem.rs +++ b/src/libstd/sys/sgx/abi/mem.rs @@ -1,22 +1,12 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - // Do not remove inline: will result in relocation failure #[inline(always)] -pub unsafe fn rel_ptr<T>(offset: u64) -> *const T { +pub(crate) unsafe fn rel_ptr<T>(offset: u64) -> *const T { (image_base() + offset) as *const T } // Do not remove inline: will result in relocation failure #[inline(always)] -pub unsafe fn rel_ptr_mut<T>(offset: u64) -> *mut T { +pub(crate) unsafe fn rel_ptr_mut<T>(offset: u64) -> *mut T { (image_base() + offset) as *mut T } @@ -34,6 +24,17 @@ fn image_base() -> u64 { base } +/// Returns `true` if the specified memory range is in the enclave. +#[unstable(feature = "sgx_platform", issue = "56975")] +pub fn is_enclave_range(p: *const u8, len: usize) -> bool { + let start=p as u64; + let end=start + (len as u64); + start >= image_base() && + end <= image_base() + (unsafe { ENCLAVE_SIZE } as u64) // unsafe ok: link-time constant +} + +/// Returns `true` if the specified memory range is in userspace. +#[unstable(feature = "sgx_platform", issue = "56975")] pub fn is_user_range(p: *const u8, len: usize) -> bool { let start=p as u64; let end=start + (len as u64); diff --git a/src/libstd/sys/sgx/abi/mod.rs b/src/libstd/sys/sgx/abi/mod.rs index 069cca3b98e..5ef069aa81c 100644 --- a/src/libstd/sys/sgx/abi/mod.rs +++ b/src/libstd/sys/sgx/abi/mod.rs @@ -1,22 +1,12 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use core::sync::atomic::{AtomicUsize, Ordering}; use io::Write; // runtime features mod reloc; -mod mem; pub(super) mod panic; // library features +pub mod mem; pub mod thread; pub mod tls; #[macro_use] diff --git a/src/libstd/sys/sgx/abi/panic.rs b/src/libstd/sys/sgx/abi/panic.rs index dd9159b9fe2..5ace7fb3368 100644 --- a/src/libstd/sys/sgx/abi/panic.rs +++ b/src/libstd/sys/sgx/abi/panic.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use io::{self, Write}; use slice::from_raw_parts_mut; diff --git a/src/libstd/sys/sgx/abi/reloc.rs b/src/libstd/sys/sgx/abi/reloc.rs index 2d5e14d6ad1..4dd41d70bd7 100644 --- a/src/libstd/sys/sgx/abi/reloc.rs +++ b/src/libstd/sys/sgx/abi/reloc.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use slice::from_raw_parts; use super::mem; diff --git a/src/libstd/sys/sgx/abi/thread.rs b/src/libstd/sys/sgx/abi/thread.rs index 4640b812fea..588fbcd9d43 100644 --- a/src/libstd/sys/sgx/abi/thread.rs +++ b/src/libstd/sys/sgx/abi/thread.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use fortanix_sgx_abi::Tcs; /// Get the ID for the current thread. The ID is guaranteed to be unique among diff --git a/src/libstd/sys/sgx/abi/tls.rs b/src/libstd/sys/sgx/abi/tls.rs index ab7822182a5..aba93db915f 100644 --- a/src/libstd/sys/sgx/abi/tls.rs +++ b/src/libstd/sys/sgx/abi/tls.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; use ptr; use mem; diff --git a/src/libstd/sys/sgx/abi/usercalls/alloc.rs b/src/libstd/sys/sgx/abi/usercalls/alloc.rs index 64968a9970c..8d0013a235a 100644 --- a/src/libstd/sys/sgx/abi/usercalls/alloc.rs +++ b/src/libstd/sys/sgx/abi/usercalls/alloc.rs @@ -1,16 +1,6 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - #![allow(unused)] -use ptr; +use ptr::{self, NonNull}; use mem; use cell::UnsafeCell; use slice; @@ -39,39 +29,78 @@ use super::super::mem::is_user_range; /// as vtable pointers) must not be leaked for confidentiality reasons. /// /// Non-exhaustive list of specific requirements for reading from userspace: -/// * Any bit pattern is valid for this type (no `enum`s). There can be no +/// * **Any bit pattern is valid** for this type (no `enum`s). There can be no /// guarantee that the value correctly adheres to the expectations of the /// type, so any value must be valid for this type. /// /// Non-exhaustive list of specific requirements for writing to userspace: -/// * No pointers to enclave memory. Memory addresses of data in enclave memory -/// must not be leaked for confidentiality reasons. -/// * No internal padding. Padding might contain previously-initialized secret -/// data stored at that memory location and must not be leaked for +/// * **No pointers to enclave memory.** Memory addresses of data in enclave +/// memory must not be leaked for confidentiality reasons. +/// * **No internal padding.** Padding might contain previously-initialized +/// secret data stored at that memory location and must not be leaked for /// confidentiality reasons. +#[unstable(feature = "sgx_platform", issue = "56975")] pub unsafe trait UserSafeSized: Copy + Sized {} +#[unstable(feature = "sgx_platform", issue = "56975")] unsafe impl UserSafeSized for u8 {} +#[unstable(feature = "sgx_platform", issue = "56975")] unsafe impl<T> UserSafeSized for FifoDescriptor<T> {} +#[unstable(feature = "sgx_platform", issue = "56975")] unsafe impl UserSafeSized for ByteBuffer {} +#[unstable(feature = "sgx_platform", issue = "56975")] unsafe impl UserSafeSized for Usercall {} +#[unstable(feature = "sgx_platform", issue = "56975")] unsafe impl UserSafeSized for Return {} +#[unstable(feature = "sgx_platform", issue = "56975")] unsafe impl<T: UserSafeSized> UserSafeSized for [T; 2] {} /// A type that can be represented in memory as one or more `UserSafeSized`s. +#[unstable(feature = "sgx_platform", issue = "56975")] pub unsafe trait UserSafe { - unsafe fn align_of() -> usize; + /// Equivalent to `mem::align_of::<Self>`. + fn align_of() -> usize; + /// Construct a pointer to `Self` given a memory range in user space. + /// /// NB. This takes a size, not a length! - unsafe fn from_raw_sized_unchecked(ptr: *const u8, size: usize) -> *const Self; + /// + /// # Safety + /// The caller must ensure the memory range is in user memory, is the + /// correct size and is correctly aligned and points to the right type. + unsafe fn from_raw_sized_unchecked(ptr: *mut u8, size: usize) -> *mut Self; + /// Construct a pointer to `Self` given a memory range. + /// /// NB. This takes a size, not a length! - unsafe fn from_raw_sized(ptr: *const u8, size: usize) -> *const Self { + /// + /// # Safety + /// The caller must ensure the memory range points to the correct type. + /// + /// # Panics + /// This function panics if: + /// + /// * The pointer is not aligned + /// * The pointer is null + /// * The pointed-to range is not in user memory + unsafe fn from_raw_sized(ptr: *mut u8, size: usize) -> NonNull<Self> { let ret = Self::from_raw_sized_unchecked(ptr, size); Self::check_ptr(ret); - ret + NonNull::new_unchecked(ret as _) } + /// Check if a pointer may point to Self in user memory. + /// + /// # Safety + /// The caller must ensure the memory range points to the correct type and + /// length (if this is a slice). + /// + /// # Panics + /// This function panics if: + /// + /// * The pointer is not aligned + /// * The pointer is null + /// * The pointed-to range is not in user memory unsafe fn check_ptr(ptr: *const Self) { let is_aligned = |p| -> bool { 0 == (p as usize) & (Self::align_of() - 1) @@ -83,27 +112,29 @@ pub unsafe trait UserSafe { } } +#[unstable(feature = "sgx_platform", issue = "56975")] unsafe impl<T: UserSafeSized> UserSafe for T { - unsafe fn align_of() -> usize { + fn align_of() -> usize { mem::align_of::<T>() } - unsafe fn from_raw_sized_unchecked(ptr: *const u8, size: usize) -> *const Self { + unsafe fn from_raw_sized_unchecked(ptr: *mut u8, size: usize) -> *mut Self { assert_eq!(size, mem::size_of::<T>()); ptr as _ } } +#[unstable(feature = "sgx_platform", issue = "56975")] unsafe impl<T: UserSafeSized> UserSafe for [T] { - unsafe fn align_of() -> usize { + fn align_of() -> usize { mem::align_of::<T>() } - unsafe fn from_raw_sized_unchecked(ptr: *const u8, size: usize) -> *const Self { + unsafe fn from_raw_sized_unchecked(ptr: *mut u8, size: usize) -> *mut Self { let elem_size = mem::size_of::<T>(); assert_eq!(size % elem_size, 0); let len = size / elem_size; - slice::from_raw_parts(ptr as _, len) + slice::from_raw_parts_mut(ptr as _, len) } } @@ -111,14 +142,40 @@ unsafe impl<T: UserSafeSized> UserSafe for [T] { /// to `&T` in enclave memory. Access to the memory is only allowed by copying /// to avoid TOCTTOU issues. After copying, code should make sure to completely /// check the value before use. +/// +/// It is also possible to obtain a mutable reference `&mut UserRef<T>`. Unlike +/// regular mutable references, these are not exclusive. Userspace may always +/// write to the backing memory at any time, so it can't be assumed that there +/// the pointed-to memory is uniquely borrowed. The two different refence types +/// are used solely to indicate intent: a mutable reference is for writing to +/// user memory, an immutable reference for reading from user memory. +#[unstable(feature = "sgx_platform", issue = "56975")] pub struct UserRef<T: ?Sized>(UnsafeCell<T>); /// An owned type in userspace memory. `User<T>` is equivalent to `Box<T>` in /// enclave memory. Access to the memory is only allowed by copying to avoid /// TOCTTOU issues. The user memory will be freed when the value is dropped. /// After copying, code should make sure to completely check the value before /// use. -pub struct User<T: UserSafe + ?Sized>(*mut UserRef<T>); +#[unstable(feature = "sgx_platform", issue = "56975")] +pub struct User<T: UserSafe + ?Sized>(NonNull<UserRef<T>>); + +trait NewUserRef<T: ?Sized> { + unsafe fn new_userref(v: T) -> Self; +} + +impl<T: ?Sized> NewUserRef<*mut T> for NonNull<UserRef<T>> { + unsafe fn new_userref(v: *mut T) -> Self { + NonNull::new_unchecked(v as _) + } +} +impl<T: ?Sized> NewUserRef<NonNull<T>> for NonNull<UserRef<T>> { + unsafe fn new_userref(v: NonNull<T>) -> Self { + NonNull::new_userref(v.as_ptr()) + } +} + +#[unstable(feature = "sgx_platform", issue = "56975")] impl<T: ?Sized> User<T> where T: UserSafe { // This function returns memory that is practically uninitialized, but is // not considered "unspecified" or "undefined" for purposes of an @@ -127,24 +184,28 @@ impl<T: ?Sized> User<T> where T: UserSafe { fn new_uninit_bytes(size: usize) -> Self { unsafe { let ptr = super::alloc(size, T::align_of()).expect("User memory allocation failed"); - User(T::from_raw_sized(ptr as _, size) as _) + User(NonNull::new_userref(T::from_raw_sized(ptr as _, size))) } } + /// Copy `val` into freshly allocated space in user memory. pub fn new_from_enclave(val: &T) -> Self { unsafe { let ret = Self::new_uninit_bytes(mem::size_of_val(val)); ptr::copy( val as *const T as *const u8, - ret.0 as *mut T as *mut u8, + ret.0.as_ptr() as *mut u8, mem::size_of_val(val) ); ret } } - /// Create an owned `User<T>` from a raw pointer. The pointer should be - /// freeable with the `free` usercall and the alignment of `T`. + /// Create an owned `User<T>` from a raw pointer. + /// + /// # Safety + /// The caller must ensure `ptr` points to `T`, is freeable with the `free` + /// usercall and the alignment of `T`, and is uniquely owned. /// /// # Panics /// This function panics if: @@ -154,7 +215,7 @@ impl<T: ?Sized> User<T> where T: UserSafe { /// * The pointed-to range is not in user memory pub unsafe fn from_raw(ptr: *mut T) -> Self { T::check_ptr(ptr); - User(ptr as _) + User(NonNull::new_userref(ptr)) } /// Convert this value into a raw pointer. The value will no longer be @@ -162,24 +223,31 @@ impl<T: ?Sized> User<T> where T: UserSafe { pub fn into_raw(self) -> *mut T { let ret = self.0; mem::forget(self); - ret as _ + ret.as_ptr() as _ } } +#[unstable(feature = "sgx_platform", issue = "56975")] impl<T> User<T> where T: UserSafe { + /// Allocate space for `T` in user memory. pub fn uninitialized() -> Self { Self::new_uninit_bytes(mem::size_of::<T>()) } } +#[unstable(feature = "sgx_platform", issue = "56975")] impl<T> User<[T]> where [T]: UserSafe { + /// Allocate space for a `[T]` of `n` elements in user memory. pub fn uninitialized(n: usize) -> Self { Self::new_uninit_bytes(n * mem::size_of::<T>()) } /// Create an owned `User<[T]>` from a raw thin pointer and a slice length. - /// The pointer should be freeable with the `free` usercall and the - /// alignment of `T`. + /// + /// # Safety + /// The caller must ensure `ptr` points to `len` elements of `T`, is + /// freeable with the `free` usercall and the alignment of `T`, and is + /// uniquely owned. /// /// # Panics /// This function panics if: @@ -188,13 +256,17 @@ impl<T> User<[T]> where [T]: UserSafe { /// * The pointer is null /// * The pointed-to range is not in user memory pub unsafe fn from_raw_parts(ptr: *mut T, len: usize) -> Self { - User(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()) as _) + User(NonNull::new_userref(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()))) } } +#[unstable(feature = "sgx_platform", issue = "56975")] impl<T: ?Sized> UserRef<T> where T: UserSafe { /// Create a `&UserRef<[T]>` from a raw pointer. /// + /// # Safety + /// The caller must ensure `ptr` points to `T`. + /// /// # Panics /// This function panics if: /// @@ -206,7 +278,11 @@ impl<T: ?Sized> UserRef<T> where T: UserSafe { &*(ptr as *const Self) } - /// Create a `&mut UserRef<[T]>` from a raw pointer. + /// Create a `&mut UserRef<[T]>` from a raw pointer. See the struct + /// documentation for the nuances regarding a `&mut UserRef<T>`. + /// + /// # Safety + /// The caller must ensure `ptr` points to `T`. /// /// # Panics /// This function panics if: @@ -219,6 +295,8 @@ impl<T: ?Sized> UserRef<T> where T: UserSafe { &mut*(ptr as *mut Self) } + /// Copy `val` into user memory. + /// /// # Panics /// This function panics if the destination doesn't have the same size as /// the source. This can happen for dynamically-sized types such as slices. @@ -233,6 +311,8 @@ impl<T: ?Sized> UserRef<T> where T: UserSafe { } } + /// Copy the value from user memory and place it into `dest`. + /// /// # Panics /// This function panics if the destination doesn't have the same size as /// the source. This can happen for dynamically-sized types such as slices. @@ -247,24 +327,32 @@ impl<T: ?Sized> UserRef<T> where T: UserSafe { } } + /// Obtain a raw pointer from this reference. pub fn as_raw_ptr(&self) -> *const T { self as *const _ as _ } + /// Obtain a raw pointer from this reference. pub fn as_raw_mut_ptr(&mut self) -> *mut T { self as *mut _ as _ } } +#[unstable(feature = "sgx_platform", issue = "56975")] impl<T> UserRef<T> where T: UserSafe { + /// Copy the value from user memory into enclave memory. pub fn to_enclave(&self) -> T { unsafe { ptr::read(self.0.get()) } } } +#[unstable(feature = "sgx_platform", issue = "56975")] impl<T> UserRef<[T]> where [T]: UserSafe { /// Create a `&UserRef<[T]>` from a raw thin pointer and a slice length. /// + /// # Safety + /// The caller must ensure `ptr` points to `n` elements of `T`. + /// /// # Panics /// This function panics if: /// @@ -272,10 +360,15 @@ impl<T> UserRef<[T]> where [T]: UserSafe { /// * The pointer is null /// * The pointed-to range is not in user memory pub unsafe fn from_raw_parts<'a>(ptr: *const T, len: usize) -> &'a Self { - &*(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()) as *const Self) + &*(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()).as_ptr() as *const Self) } /// Create a `&mut UserRef<[T]>` from a raw thin pointer and a slice length. + /// See the struct documentation for the nuances regarding a + /// `&mut UserRef<T>`. + /// + /// # Safety + /// The caller must ensure `ptr` points to `n` elements of `T`. /// /// # Panics /// This function panics if: @@ -284,21 +377,30 @@ impl<T> UserRef<[T]> where [T]: UserSafe { /// * The pointer is null /// * The pointed-to range is not in user memory pub unsafe fn from_raw_parts_mut<'a>(ptr: *mut T, len: usize) -> &'a mut Self { - &mut*(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()) as *mut Self) + &mut*(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()).as_ptr() as *mut Self) } + /// Obtain a raw pointer to the first element of this user slice. pub fn as_ptr(&self) -> *const T { self.0.get() as _ } + /// Obtain a raw pointer to the first element of this user slice. pub fn as_mut_ptr(&mut self) -> *mut T { self.0.get() as _ } + /// Obtain the number of elements in this user slice. pub fn len(&self) -> usize { unsafe { (*self.0.get()).len() } } + /// Copy the value from user memory and place it into `dest`. Afterwards, + /// `dest` will contain exactly `self.len()` elements. + /// + /// # Panics + /// This function panics if the destination doesn't have the same size as + /// the source. This can happen for dynamically-sized types such as slices. pub fn copy_to_enclave_vec(&self, dest: &mut Vec<T>) { unsafe { if let Some(missing) = self.len().checked_sub(dest.capacity()) { @@ -309,12 +411,14 @@ impl<T> UserRef<[T]> where [T]: UserSafe { } } + /// Copy the value from user memory into a vector in enclave memory. pub fn to_enclave(&self) -> Vec<T> { let mut ret = Vec::with_capacity(self.len()); self.copy_to_enclave_vec(&mut ret); ret } + /// Returns an iterator over the slice. pub fn iter(&self) -> Iter<T> where T: UserSafe // FIXME: should be implied by [T]: UserSafe? { @@ -323,6 +427,7 @@ impl<T> UserRef<[T]> where [T]: UserSafe { } } + /// Returns an iterator that allows modifying each value. pub fn iter_mut(&mut self) -> IterMut<T> where T: UserSafe // FIXME: should be implied by [T]: UserSafe? { @@ -332,8 +437,13 @@ impl<T> UserRef<[T]> where [T]: UserSafe { } } +/// Immutable user slice iterator +/// +/// This struct is created by the `iter` method on `UserRef<[T]>`. +#[unstable(feature = "sgx_platform", issue = "56975")] pub struct Iter<'a, T: 'a + UserSafe>(slice::Iter<'a, T>); +#[unstable(feature = "sgx_platform", issue = "56975")] impl<'a, T: UserSafe> Iterator for Iter<'a, T> { type Item = &'a UserRef<T>; @@ -345,8 +455,13 @@ impl<'a, T: UserSafe> Iterator for Iter<'a, T> { } } +/// Mutable user slice iterator +/// +/// This struct is created by the `iter_mut` method on `UserRef<[T]>`. +#[unstable(feature = "sgx_platform", issue = "56975")] pub struct IterMut<'a, T: 'a + UserSafe>(slice::IterMut<'a, T>); +#[unstable(feature = "sgx_platform", issue = "56975")] impl<'a, T: UserSafe> Iterator for IterMut<'a, T> { type Item = &'a mut UserRef<T>; @@ -358,31 +473,36 @@ impl<'a, T: UserSafe> Iterator for IterMut<'a, T> { } } +#[unstable(feature = "sgx_platform", issue = "56975")] impl<T: ?Sized> Deref for User<T> where T: UserSafe { type Target = UserRef<T>; fn deref(&self) -> &Self::Target { - unsafe { &*self.0 } + unsafe { &*self.0.as_ptr() } } } +#[unstable(feature = "sgx_platform", issue = "56975")] impl<T: ?Sized> DerefMut for User<T> where T: UserSafe { fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { &mut*self.0 } + unsafe { &mut*self.0.as_ptr() } } } +#[unstable(feature = "sgx_platform", issue = "56975")] impl<T: ?Sized> Drop for User<T> where T: UserSafe { fn drop(&mut self) { unsafe { - let ptr = (*self.0).0.get(); + let ptr = (*self.0.as_ptr()).0.get(); super::free(ptr as _, mem::size_of_val(&mut*ptr), T::align_of()); } } } +#[unstable(feature = "sgx_platform", issue = "56975")] impl<T: CoerceUnsized<U>, U> CoerceUnsized<UserRef<U>> for UserRef<T> {} +#[unstable(feature = "sgx_platform", issue = "56975")] impl<T, I: SliceIndex<[T]>> Index<I> for UserRef<[T]> where [T]: UserSafe, I::Output: UserSafe { type Output = UserRef<I::Output>; @@ -394,6 +514,7 @@ impl<T, I: SliceIndex<[T]>> Index<I> for UserRef<[T]> where [T]: UserSafe, I::Ou } } +#[unstable(feature = "sgx_platform", issue = "56975")] impl<T, I: SliceIndex<[T]>> IndexMut<I> for UserRef<[T]> where [T]: UserSafe, I::Output: UserSafe { #[inline] fn index_mut(&mut self, index: I) -> &mut UserRef<I::Output> { @@ -402,3 +523,21 @@ impl<T, I: SliceIndex<[T]>> IndexMut<I> for UserRef<[T]> where [T]: UserSafe, I: } } } + +#[unstable(feature = "sgx_platform", issue = "56975")] +impl UserRef<super::raw::ByteBuffer> { + /// Copy the user memory range pointed to by the user `ByteBuffer` to + /// enclave memory. + /// + /// # Panics + /// This function panics if: + /// + /// * The pointer in the user `ByteBuffer` is null + /// * The pointed-to range in the user `ByteBuffer` is not in user memory + pub fn copy_user_buffer(&self) -> Vec<u8> { + unsafe { + let buf = self.to_enclave(); + User::from_raw_parts(buf.data as _, buf.len).to_enclave() + } + } +} diff --git a/src/libstd/sys/sgx/abi/usercalls/mod.rs b/src/libstd/sys/sgx/abi/usercalls/mod.rs index d1d180e4825..58903761ebe 100644 --- a/src/libstd/sys/sgx/abi/usercalls/mod.rs +++ b/src/libstd/sys/sgx/abi/usercalls/mod.rs @@ -1,29 +1,14 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -pub use fortanix_sgx_abi::*; - use io::{Error as IoError, Result as IoResult}; use time::Duration; -pub mod alloc; +pub(crate) mod alloc; #[macro_use] -mod raw; +pub(crate) mod raw; -pub(crate) fn copy_user_buffer(buf: &alloc::UserRef<ByteBuffer>) -> Vec<u8> { - unsafe { - let buf = buf.to_enclave(); - alloc::User::from_raw_parts(buf.data as _, buf.len).to_enclave() - } -} +use self::raw::*; +/// Usercall `read`. See the ABI documentation for more information. +#[unstable(feature = "sgx_platform", issue = "56975")] pub fn read(fd: Fd, buf: &mut [u8]) -> IoResult<usize> { unsafe { let mut userbuf = alloc::User::<[u8]>::uninitialized(buf.len()); @@ -33,6 +18,18 @@ pub fn read(fd: Fd, buf: &mut [u8]) -> IoResult<usize> { } } +/// Usercall `read_alloc`. See the ABI documentation for more information. +#[unstable(feature = "sgx_platform", issue = "56975")] +pub fn read_alloc(fd: Fd) -> IoResult<Vec<u8>> { + unsafe { + let mut userbuf = alloc::User::<ByteBuffer>::uninitialized(); + raw::read_alloc(fd, userbuf.as_raw_mut_ptr()).from_sgx_result()?; + Ok(userbuf.copy_user_buffer()) + } +} + +/// Usercall `write`. See the ABI documentation for more information. +#[unstable(feature = "sgx_platform", issue = "56975")] pub fn write(fd: Fd, buf: &[u8]) -> IoResult<usize> { unsafe { let userbuf = alloc::User::new_from_enclave(buf); @@ -40,19 +37,25 @@ pub fn write(fd: Fd, buf: &[u8]) -> IoResult<usize> { } } +/// Usercall `flush`. See the ABI documentation for more information. +#[unstable(feature = "sgx_platform", issue = "56975")] pub fn flush(fd: Fd) -> IoResult<()> { unsafe { raw::flush(fd).from_sgx_result() } } +/// Usercall `close`. See the ABI documentation for more information. +#[unstable(feature = "sgx_platform", issue = "56975")] pub fn close(fd: Fd) { unsafe { raw::close(fd) } } fn string_from_bytebuffer(buf: &alloc::UserRef<ByteBuffer>, usercall: &str, arg: &str) -> String { - String::from_utf8(copy_user_buffer(buf)) + String::from_utf8(buf.copy_user_buffer()) .unwrap_or_else(|_| panic!("Usercall {}: expected {} to be valid UTF-8", usercall, arg)) } +/// Usercall `bind_stream`. See the ABI documentation for more information. +#[unstable(feature = "sgx_platform", issue = "56975")] pub fn bind_stream(addr: &str) -> IoResult<(Fd, String)> { unsafe { let addr_user = alloc::User::new_from_enclave(addr.as_bytes()); @@ -67,6 +70,8 @@ pub fn bind_stream(addr: &str) -> IoResult<(Fd, String)> { } } +/// Usercall `accept_stream`. See the ABI documentation for more information. +#[unstable(feature = "sgx_platform", issue = "56975")] pub fn accept_stream(fd: Fd) -> IoResult<(Fd, String, String)> { unsafe { let mut bufs = alloc::User::<[ByteBuffer; 2]>::uninitialized(); @@ -84,6 +89,8 @@ pub fn accept_stream(fd: Fd) -> IoResult<(Fd, String, String)> { } } +/// Usercall `connect_stream`. See the ABI documentation for more information. +#[unstable(feature = "sgx_platform", issue = "56975")] pub fn connect_stream(addr: &str) -> IoResult<(Fd, String, String)> { unsafe { let addr_user = alloc::User::new_from_enclave(addr.as_bytes()); @@ -103,31 +110,45 @@ pub fn connect_stream(addr: &str) -> IoResult<(Fd, String, String)> { } } -pub fn launch_thread() -> IoResult<()> { - unsafe { raw::launch_thread().from_sgx_result() } +/// Usercall `launch_thread`. See the ABI documentation for more information. +#[unstable(feature = "sgx_platform", issue = "56975")] +pub unsafe fn launch_thread() -> IoResult<()> { + raw::launch_thread().from_sgx_result() } +/// Usercall `exit`. See the ABI documentation for more information. +#[unstable(feature = "sgx_platform", issue = "56975")] pub fn exit(panic: bool) -> ! { unsafe { raw::exit(panic) } } +/// Usercall `wait`. See the ABI documentation for more information. +#[unstable(feature = "sgx_platform", issue = "56975")] pub fn wait(event_mask: u64, timeout: u64) -> IoResult<u64> { unsafe { raw::wait(event_mask, timeout).from_sgx_result() } } +/// Usercall `send`. See the ABI documentation for more information. +#[unstable(feature = "sgx_platform", issue = "56975")] pub fn send(event_set: u64, tcs: Option<Tcs>) -> IoResult<()> { unsafe { raw::send(event_set, tcs).from_sgx_result() } } +/// Usercall `insecure_time`. See the ABI documentation for more information. +#[unstable(feature = "sgx_platform", issue = "56975")] pub fn insecure_time() -> Duration { let t = unsafe { raw::insecure_time() }; Duration::new(t / 1_000_000_000, (t % 1_000_000_000) as _) } +/// Usercall `alloc`. See the ABI documentation for more information. +#[unstable(feature = "sgx_platform", issue = "56975")] pub fn alloc(size: usize, alignment: usize) -> IoResult<*mut u8> { unsafe { raw::alloc(size, alignment).from_sgx_result() } } +#[unstable(feature = "sgx_platform", issue = "56975")] +#[doc(inline)] pub use self::raw::free; fn check_os_error(err: Result) -> i32 { diff --git a/src/libstd/sys/sgx/abi/usercalls/raw.rs b/src/libstd/sys/sgx/abi/usercalls/raw.rs index a28d41c1b74..27aca7c0903 100644 --- a/src/libstd/sys/sgx/abi/usercalls/raw.rs +++ b/src/libstd/sys/sgx/abi/usercalls/raw.rs @@ -1,16 +1,7 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - #![allow(unused)] -use fortanix_sgx_abi::*; +#[unstable(feature = "sgx_platform", issue = "56975")] +pub use fortanix_sgx_abi::*; use ptr::NonNull; @@ -21,7 +12,16 @@ extern "C" { fn usercall(nr: u64, p1: u64, p2: u64, _ignore: u64, p3: u64, p4: u64) -> UsercallReturn; } -unsafe fn do_usercall(nr: u64, p1: u64, p2: u64, p3: u64, p4: u64) -> (u64, u64) { +/// Perform the raw usercall operation as defined in the ABI calling convention. +/// +/// # Safety +/// The caller must ensure to pass parameters appropriate for the usercall `nr` +/// and to observe all requirements specified in the ABI. +/// +/// # Panics +/// Panics if `nr` is 0. +#[unstable(feature = "sgx_platform", issue = "56975")] +pub unsafe fn do_usercall(nr: u64, p1: u64, p2: u64, p3: u64, p4: u64) -> (u64, u64) { if nr==0 { panic!("Invalid usercall number {}",nr) } let UsercallReturn(a, b) = usercall(nr,p1,p2,0,p3,p4); (a, b) @@ -169,6 +169,9 @@ impl<T: RegisterArgument, U: RegisterArgument> ReturnValue for (T, U) { macro_rules! enclave_usercalls_internal_define_usercalls { (def fn $f:ident($n1:ident: $t1:ty, $n2:ident: $t2:ty, $n3:ident: $t3:ty, $n4:ident: $t4:ty) -> $r:ty) => ( + /// This is the raw function definition, see the ABI documentation for + /// more information. + #[unstable(feature = "sgx_platform", issue = "56975")] #[inline(always)] pub unsafe fn $f($n1: $t1, $n2: $t2, $n3: $t3, $n4: $t4) -> $r { ReturnValue::from_registers(stringify!($f), do_usercall( @@ -181,6 +184,9 @@ macro_rules! enclave_usercalls_internal_define_usercalls { } ); (def fn $f:ident($n1:ident: $t1:ty, $n2:ident: $t2:ty, $n3:ident: $t3:ty) -> $r:ty) => ( + /// This is the raw function definition, see the ABI documentation for + /// more information. + #[unstable(feature = "sgx_platform", issue = "56975")] #[inline(always)] pub unsafe fn $f($n1: $t1, $n2: $t2, $n3: $t3) -> $r { ReturnValue::from_registers(stringify!($f), do_usercall( @@ -193,6 +199,9 @@ macro_rules! enclave_usercalls_internal_define_usercalls { } ); (def fn $f:ident($n1:ident: $t1:ty, $n2:ident: $t2:ty) -> $r:ty) => ( + /// This is the raw function definition, see the ABI documentation for + /// more information. + #[unstable(feature = "sgx_platform", issue = "56975")] #[inline(always)] pub unsafe fn $f($n1: $t1, $n2: $t2) -> $r { ReturnValue::from_registers(stringify!($f), do_usercall( @@ -204,6 +213,9 @@ macro_rules! enclave_usercalls_internal_define_usercalls { } ); (def fn $f:ident($n1:ident: $t1:ty) -> $r:ty) => ( + /// This is the raw function definition, see the ABI documentation for + /// more information. + #[unstable(feature = "sgx_platform", issue = "56975")] #[inline(always)] pub unsafe fn $f($n1: $t1) -> $r { ReturnValue::from_registers(stringify!($f), do_usercall( @@ -214,6 +226,9 @@ macro_rules! enclave_usercalls_internal_define_usercalls { } ); (def fn $f:ident() -> $r:ty) => ( + /// This is the raw function definition, see the ABI documentation for + /// more information. + #[unstable(feature = "sgx_platform", issue = "56975")] #[inline(always)] pub unsafe fn $f() -> $r { ReturnValue::from_registers(stringify!($f), do_usercall( diff --git a/src/libstd/sys/sgx/alloc.rs b/src/libstd/sys/sgx/alloc.rs index 83c20ace89b..95284190bdd 100644 --- a/src/libstd/sys/sgx/alloc.rs +++ b/src/libstd/sys/sgx/alloc.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - extern crate dlmalloc; use alloc::{GlobalAlloc, Layout, System}; diff --git a/src/libstd/sys/sgx/args.rs b/src/libstd/sys/sgx/args.rs index 8fb35d7ef98..bc138a64019 100644 --- a/src/libstd/sys/sgx/args.rs +++ b/src/libstd/sys/sgx/args.rs @@ -1,15 +1,5 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use ffi::OsString; -use super::abi::usercalls::{copy_user_buffer, alloc, ByteBuffer}; +use super::abi::usercalls::{alloc, raw::ByteBuffer}; use sync::atomic::{AtomicUsize, Ordering}; use sys::os_str::Buf; use sys_common::FromInner; @@ -22,7 +12,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) { if argc != 0 { let args = alloc::User::<[ByteBuffer]>::from_raw_parts(argv as _, argc as _); let args = args.iter() - .map( |a| OsString::from_inner(Buf { inner: copy_user_buffer(a) }) ) + .map( |a| OsString::from_inner(Buf { inner: a.copy_user_buffer() }) ) .collect::<ArgsStore>(); ARGS.store(Box::into_raw(Box::new(args)) as _, Ordering::Relaxed); } diff --git a/src/libstd/sys/sgx/backtrace.rs b/src/libstd/sys/sgx/backtrace.rs index ca4a7c9561c..52d4a63bb63 100644 --- a/src/libstd/sys/sgx/backtrace.rs +++ b/src/libstd/sys/sgx/backtrace.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use io; use sys::unsupported; use sys_common::backtrace::Frame; diff --git a/src/libstd/sys/sgx/cmath.rs b/src/libstd/sys/sgx/cmath.rs index 0c1300f61f8..5aabdc1c8d3 100644 --- a/src/libstd/sys/sgx/cmath.rs +++ b/src/libstd/sys/sgx/cmath.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - #![cfg(not(test))] // These symbols are all defined in `compiler-builtins` diff --git a/src/libstd/sys/sgx/condvar.rs b/src/libstd/sys/sgx/condvar.rs index 940f50f25b8..b42e5490c72 100644 --- a/src/libstd/sys/sgx/condvar.rs +++ b/src/libstd/sys/sgx/condvar.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use sys::mutex::Mutex; use time::Duration; diff --git a/src/libstd/sys/sgx/env.rs b/src/libstd/sys/sgx/env.rs index 146ce02754b..6fa0ed7bcf4 100644 --- a/src/libstd/sys/sgx/env.rs +++ b/src/libstd/sys/sgx/env.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - pub mod os { pub const FAMILY: &'static str = ""; pub const OS: &'static str = ""; diff --git a/src/libstd/sys/sgx/ext/arch.rs b/src/libstd/sys/sgx/ext/arch.rs new file mode 100644 index 00000000000..ba6f9e622ad --- /dev/null +++ b/src/libstd/sys/sgx/ext/arch.rs @@ -0,0 +1,74 @@ +//! SGX-specific access to architectural features. +//! +//! The functionality in this module is further documented in the Intel +//! Software Developer's Manual, Volume 3, Chapter 40. +#![unstable(feature = "sgx_platform", issue = "56975")] + +use mem::MaybeUninit; + +/// Wrapper struct to force 16-byte alignment. +#[repr(align(16))] +#[unstable(feature = "sgx_platform", issue = "56975")] +pub struct Align16<T>(pub T); + +/// Wrapper struct to force 128-byte alignment. +#[repr(align(128))] +#[unstable(feature = "sgx_platform", issue = "56975")] +pub struct Align128<T>(pub T); + +/// Wrapper struct to force 512-byte alignment. +#[repr(align(512))] +#[unstable(feature = "sgx_platform", issue = "56975")] +pub struct Align512<T>(pub T); + +const ENCLU_EREPORT: u32 = 0; +const ENCLU_EGETKEY: u32 = 1; + +/// Call the `EGETKEY` instruction to obtain a 128-bit secret key. +#[unstable(feature = "sgx_platform", issue = "56975")] +pub fn egetkey(request: &Align512<[u8; 512]>) -> Result<Align16<[u8; 16]>, u32> { + unsafe { + let mut out = MaybeUninit::uninitialized(); + let error; + + asm!( + "enclu" + : "={eax}"(error) + : "{eax}"(ENCLU_EGETKEY), + "{rbx}"(request), + "{rcx}"(out.get_mut()) + : "flags" + ); + + match error { + 0 => Ok(out.into_inner()), + err => Err(err), + } + } +} + +/// Call the `EREPORT` instruction. +/// +/// This creates a cryptographic report describing the contents of the current +/// enclave. The report may be verified by the enclave described in +/// `targetinfo`. +#[unstable(feature = "sgx_platform", issue = "56975")] +pub fn ereport( + targetinfo: &Align512<[u8; 512]>, + reportdata: &Align128<[u8; 64]>, +) -> Align512<[u8; 432]> { + unsafe { + let mut report = MaybeUninit::uninitialized(); + + asm!( + "enclu" + : /* no output registers */ + : "{eax}"(ENCLU_EREPORT), + "{rbx}"(targetinfo), + "{rcx}"(reportdata), + "{rdx}"(report.get_mut()) + ); + + report.into_inner() + } +} diff --git a/src/libstd/sys/sgx/ext/io.rs b/src/libstd/sys/sgx/ext/io.rs new file mode 100644 index 00000000000..1eb269783c5 --- /dev/null +++ b/src/libstd/sys/sgx/ext/io.rs @@ -0,0 +1,109 @@ +//! SGX-specific extensions to general I/O primitives +//! +//! SGX file descriptors behave differently from Unix file descriptors. See the +//! description of [`TryIntoRawFd`](trait.TryIntoRawFd.html) for more details. +#![unstable(feature = "sgx_platform", issue = "56975")] + +pub use sys::abi::usercalls::raw::Fd as RawFd; +use net; +use sys::{self, AsInner, FromInner, IntoInner, TryIntoInner}; + +/// A trait to extract the raw SGX file descriptor from an underlying +/// object. +#[unstable(feature = "sgx_platform", issue = "56975")] +pub trait AsRawFd { + /// Extracts the raw file descriptor. + /// + /// This method does **not** pass ownership of the raw file descriptor + /// to the caller. The descriptor is only guaranteed to be valid while + /// the original object has not yet been destroyed. + #[unstable(feature = "sgx_platform", issue = "56975")] + fn as_raw_fd(&self) -> RawFd; +} + +/// A trait to express the ability to construct an object from a raw file +/// descriptor. +#[unstable(feature = "sgx_platform", issue = "56975")] +pub trait FromRawFd { + /// Constructs a new instance of `Self` from the given raw file + /// descriptor. + /// + /// This function **consumes ownership** of the specified file + /// descriptor. The returned object will take responsibility for closing + /// it when the object goes out of scope. + /// + /// This function is also unsafe as the primitives currently returned + /// have the contract that they are the sole owner of the file + /// descriptor they are wrapping. Usage of this function could + /// accidentally allow violating this contract which can cause memory + /// unsafety in code that relies on it being true. + #[unstable(feature = "sgx_platform", issue = "56975")] + unsafe fn from_raw_fd(fd: RawFd) -> Self; +} + +/// A trait to express the ability to consume an object and acquire ownership of +/// its raw file descriptor. +#[unstable(feature = "sgx_platform", issue = "56975")] +pub trait TryIntoRawFd: Sized { + /// Consumes this object, returning the raw underlying file descriptor, if + /// this object is not cloned. + /// + /// This function **transfers ownership** of the underlying file descriptor + /// to the caller. Callers are then the unique owners of the file descriptor + /// and must close the descriptor once it's no longer needed. + /// + /// Unlike other platforms, on SGX, the file descriptor is shared between + /// all clones of an object. To avoid race conditions, this function will + /// only return `Ok` when called on the final clone. + #[unstable(feature = "sgx_platform", issue = "56975")] + fn try_into_raw_fd(self) -> Result<RawFd, Self>; +} + +impl AsRawFd for net::TcpStream { + fn as_raw_fd(&self) -> RawFd { *self.as_inner().as_inner().as_inner().as_inner() } +} + +impl AsRawFd for net::TcpListener { + fn as_raw_fd(&self) -> RawFd { *self.as_inner().as_inner().as_inner().as_inner() } +} + +impl FromRawFd for net::TcpStream { + unsafe fn from_raw_fd(fd: RawFd) -> net::TcpStream { + let fd = sys::fd::FileDesc::from_inner(fd); + let socket = sys::net::Socket::from_inner(fd); + net::TcpStream::from_inner(sys::net::TcpStream::from_inner((socket, None))) + } +} + +impl FromRawFd for net::TcpListener { + unsafe fn from_raw_fd(fd: RawFd) -> net::TcpListener { + let fd = sys::fd::FileDesc::from_inner(fd); + let socket = sys::net::Socket::from_inner(fd); + net::TcpListener::from_inner(sys::net::TcpListener::from_inner(socket)) + } +} + +impl TryIntoRawFd for net::TcpStream { + fn try_into_raw_fd(self) -> Result<RawFd, Self> { + let (socket, peer_addr) = self.into_inner().into_inner(); + match socket.try_into_inner() { + Ok(fd) => Ok(fd.into_inner()), + Err(socket) => { + let sys = sys::net::TcpStream::from_inner((socket, peer_addr)); + Err(net::TcpStream::from_inner(sys)) + } + } + } +} + +impl TryIntoRawFd for net::TcpListener { + fn try_into_raw_fd(self) -> Result<RawFd, Self> { + match self.into_inner().into_inner().try_into_inner() { + Ok(fd) => Ok(fd.into_inner()), + Err(socket) => { + let sys = sys::net::TcpListener::from_inner(socket); + Err(net::TcpListener::from_inner(sys)) + } + } + } +} diff --git a/src/libstd/sys/sgx/ext/mod.rs b/src/libstd/sys/sgx/ext/mod.rs new file mode 100644 index 00000000000..5489f6f5694 --- /dev/null +++ b/src/libstd/sys/sgx/ext/mod.rs @@ -0,0 +1,4 @@ +#![unstable(feature = "sgx_platform", issue = "56975")] + +pub mod arch; +pub mod io; diff --git a/src/libstd/sys/sgx/fd.rs b/src/libstd/sys/sgx/fd.rs index 31c4199c6cd..69077728b1a 100644 --- a/src/libstd/sys/sgx/fd.rs +++ b/src/libstd/sys/sgx/fd.rs @@ -1,18 +1,8 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use fortanix_sgx_abi::Fd; use io; use mem; -use sys_common::AsInner; +use sys::{AsInner, FromInner, IntoInner}; use super::abi::usercalls; #[derive(Debug)] @@ -51,6 +41,20 @@ impl AsInner<Fd> for FileDesc { fn as_inner(&self) -> &Fd { &self.fd } } +impl IntoInner<Fd> for FileDesc { + fn into_inner(self) -> Fd { + let fd = self.fd; + mem::forget(self); + fd + } +} + +impl FromInner<Fd> for FileDesc { + fn from_inner(fd: Fd) -> FileDesc { + FileDesc { fd } + } +} + impl Drop for FileDesc { fn drop(&mut self) { usercalls::close(self.fd) diff --git a/src/libstd/sys/sgx/fs.rs b/src/libstd/sys/sgx/fs.rs index 1dcea3e8eac..8b1c4476bc4 100644 --- a/src/libstd/sys/sgx/fs.rs +++ b/src/libstd/sys/sgx/fs.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use ffi::OsString; use fmt; use hash::{Hash, Hasher}; diff --git a/src/libstd/sys/sgx/memchr.rs b/src/libstd/sys/sgx/memchr.rs index 0998bc5db4c..9967482197e 100644 --- a/src/libstd/sys/sgx/memchr.rs +++ b/src/libstd/sys/sgx/memchr.rs @@ -1,11 +1 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - pub use core::slice::memchr::{memchr, memrchr}; diff --git a/src/libstd/sys/sgx/mod.rs b/src/libstd/sys/sgx/mod.rs index dd6862e908e..7f8550490a1 100644 --- a/src/libstd/sys/sgx/mod.rs +++ b/src/libstd/sys/sgx/mod.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - //! System bindings for the Fortanix SGX platform //! //! This module contains the facade (aka platform-specific) implementations of @@ -27,6 +17,7 @@ pub mod backtrace; pub mod cmath; pub mod condvar; pub mod env; +pub mod ext; pub mod fd; pub mod fs; pub mod memchr; @@ -151,3 +142,9 @@ pub fn hashmap_random_keys() -> (u64, u64) { } (rdrand64(), rdrand64()) } + +pub use sys_common::{AsInner, FromInner, IntoInner}; + +pub trait TryIntoInner<Inner>: Sized { + fn try_into_inner(self) -> Result<Inner, Self>; +} diff --git a/src/libstd/sys/sgx/mutex.rs b/src/libstd/sys/sgx/mutex.rs index 994cf91eea0..f325fb1dd58 100644 --- a/src/libstd/sys/sgx/mutex.rs +++ b/src/libstd/sys/sgx/mutex.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use fortanix_sgx_abi::Tcs; use super::abi::thread; diff --git a/src/libstd/sys/sgx/net.rs b/src/libstd/sys/sgx/net.rs index 176d230846d..6e86b06b286 100644 --- a/src/libstd/sys/sgx/net.rs +++ b/src/libstd/sys/sgx/net.rs @@ -1,18 +1,8 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use fmt; use io; use net::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr, ToSocketAddrs}; use time::Duration; -use sys::{unsupported, Void, sgx_ineffective}; +use sys::{unsupported, Void, sgx_ineffective, AsInner, FromInner, IntoInner, TryIntoInner}; use sys::fd::FileDesc; use convert::TryFrom; use error; @@ -23,21 +13,38 @@ use super::abi::usercalls; const DEFAULT_FAKE_TTL: u32 = 64; #[derive(Debug, Clone)] -struct Socket { +pub struct Socket { inner: Arc<FileDesc>, - local_addr: String, + local_addr: Option<String>, } impl Socket { - fn new(fd: usercalls::Fd, local_addr: String) -> Socket { - Socket { inner: Arc::new(FileDesc::new(fd)), local_addr } + fn new(fd: usercalls::raw::Fd, local_addr: String) -> Socket { + Socket { inner: Arc::new(FileDesc::new(fd)), local_addr: Some(local_addr) } + } +} + +impl AsInner<FileDesc> for Socket { + fn as_inner(&self) -> &FileDesc { &self.inner } +} + +impl TryIntoInner<FileDesc> for Socket { + fn try_into_inner(self) -> Result<FileDesc, Socket> { + let Socket { inner, local_addr } = self; + Arc::try_unwrap(inner).map_err(|inner| Socket { inner, local_addr } ) + } +} + +impl FromInner<FileDesc> for Socket { + fn from_inner(inner: FileDesc) -> Socket { + Socket { inner: Arc::new(inner), local_addr: None } } } #[derive(Debug, Clone)] pub struct TcpStream { inner: Socket, - peer_addr: String, + peer_addr: Option<String>, } fn io_err_to_addr(result: io::Result<&SocketAddr>) -> io::Result<String> { @@ -53,16 +60,19 @@ fn io_err_to_addr(result: io::Result<&SocketAddr>) -> io::Result<String> { } } -fn addr_to_sockaddr(addr: &str) -> io::Result<SocketAddr> { - // unwrap OK: if an iterator is returned, we're guaranteed to get exactly one entry - addr.to_socket_addrs().map(|mut it| it.next().unwrap()) +fn addr_to_sockaddr(addr: &Option<String>) -> io::Result<SocketAddr> { + addr.as_ref() + .ok_or(io::ErrorKind::AddrNotAvailable)? + .to_socket_addrs() + // unwrap OK: if an iterator is returned, we're guaranteed to get exactly one entry + .map(|mut it| it.next().unwrap()) } impl TcpStream { pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> { let addr = io_err_to_addr(addr)?; let (fd, local_addr, peer_addr) = usercalls::connect_stream(&addr)?; - Ok(TcpStream { inner: Socket::new(fd, local_addr), peer_addr }) + Ok(TcpStream { inner: Socket::new(fd, local_addr), peer_addr: Some(peer_addr) }) } pub fn connect_timeout(addr: &SocketAddr, _: Duration) -> io::Result<TcpStream> { @@ -138,6 +148,24 @@ impl TcpStream { } } +impl AsInner<Socket> for TcpStream { + fn as_inner(&self) -> &Socket { &self.inner } +} + +// `Inner` includes `peer_addr` so that a `TcpStream` maybe correctly +// reconstructed if `Socket::try_into_inner` fails. +impl IntoInner<(Socket, Option<String>)> for TcpStream { + fn into_inner(self) -> (Socket, Option<String>) { + (self.inner, self.peer_addr) + } +} + +impl FromInner<(Socket, Option<String>)> for TcpStream { + fn from_inner((inner, peer_addr): (Socket, Option<String>)) -> TcpStream { + TcpStream { inner, peer_addr } + } +} + #[derive(Debug, Clone)] pub struct TcpListener { inner: Socket, @@ -156,6 +184,7 @@ impl TcpListener { pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { let (fd, local_addr, peer_addr) = usercalls::accept_stream(self.inner.inner.raw())?; + let peer_addr = Some(peer_addr); let ret_peer = addr_to_sockaddr(&peer_addr).unwrap_or_else(|_| ([0; 4], 0).into()); Ok((TcpStream { inner: Socket::new(fd, local_addr), peer_addr }, ret_peer)) } @@ -189,6 +218,22 @@ impl TcpListener { } } +impl AsInner<Socket> for TcpListener { + fn as_inner(&self) -> &Socket { &self.inner } +} + +impl IntoInner<Socket> for TcpListener { + fn into_inner(self) -> Socket { + self.inner + } +} + +impl FromInner<Socket> for TcpListener { + fn from_inner(inner: Socket) -> TcpListener { + TcpListener { inner } + } +} + pub struct UdpSocket(Void); impl UdpSocket { diff --git a/src/libstd/sys/sgx/os.rs b/src/libstd/sys/sgx/os.rs index 79ebafe73f9..b1e4d371a67 100644 --- a/src/libstd/sys/sgx/os.rs +++ b/src/libstd/sys/sgx/os.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use fortanix_sgx_abi::{Error, RESULT_SUCCESS}; use error::Error as StdError; diff --git a/src/libstd/sys/sgx/os_str.rs b/src/libstd/sys/sgx/os_str.rs index 9bfb84db209..9d5e084feb2 100644 --- a/src/libstd/sys/sgx/os_str.rs +++ b/src/libstd/sys/sgx/os_str.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - /// The underlying OsString/OsStr implementation on Unix systems: just /// a `Vec<u8>`/`[u8]`. diff --git a/src/libstd/sys/sgx/path.rs b/src/libstd/sys/sgx/path.rs index afe0c490426..90b1fa7c97b 100644 --- a/src/libstd/sys/sgx/path.rs +++ b/src/libstd/sys/sgx/path.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use path::Prefix; use ffi::OsStr; diff --git a/src/libstd/sys/sgx/pipe.rs b/src/libstd/sys/sgx/pipe.rs index 6c6cbc14a8a..ac48a6dc033 100644 --- a/src/libstd/sys/sgx/pipe.rs +++ b/src/libstd/sys/sgx/pipe.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use io; use sys::Void; diff --git a/src/libstd/sys/sgx/process.rs b/src/libstd/sys/sgx/process.rs index 01a12fba043..5357d931c73 100644 --- a/src/libstd/sys/sgx/process.rs +++ b/src/libstd/sys/sgx/process.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use ffi::OsStr; use fmt; use io; diff --git a/src/libstd/sys/sgx/rwlock.rs b/src/libstd/sys/sgx/rwlock.rs index a1551dbb53b..47874158ed9 100644 --- a/src/libstd/sys/sgx/rwlock.rs +++ b/src/libstd/sys/sgx/rwlock.rs @@ -1,22 +1,23 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use num::NonZeroUsize; +use slice; +use str; -use super::waitqueue::{WaitVariable, WaitQueue, SpinMutex, NotifiedTcs, try_lock_or_false}; +use super::waitqueue::{ + try_lock_or_false, NotifiedTcs, SpinMutex, SpinMutexGuard, WaitQueue, WaitVariable, +}; +use mem; pub struct RWLock { readers: SpinMutex<WaitVariable<Option<NonZeroUsize>>>, writer: SpinMutex<WaitVariable<bool>>, } +// Below is to check at compile time, that RWLock has size of 128 bytes. +#[allow(dead_code)] +unsafe fn rw_lock_size_assert(r: RWLock) { + mem::transmute::<RWLock, [u8; 128]>(r); +} + //unsafe impl Send for RWLock {} //unsafe impl Sync for RWLock {} // FIXME @@ -24,7 +25,7 @@ impl RWLock { pub const fn new() -> RWLock { RWLock { readers: SpinMutex::new(WaitVariable::new(None)), - writer: SpinMutex::new(WaitVariable::new(false)) + writer: SpinMutex::new(WaitVariable::new(false)), } } @@ -89,9 +90,11 @@ impl RWLock { } #[inline] - pub unsafe fn read_unlock(&self) { - let mut rguard = self.readers.lock(); - let wguard = self.writer.lock(); + unsafe fn __read_unlock( + &self, + mut rguard: SpinMutexGuard<WaitVariable<Option<NonZeroUsize>>>, + wguard: SpinMutexGuard<WaitVariable<bool>>, + ) { *rguard.lock_var_mut() = NonZeroUsize::new(rguard.lock_var().unwrap().get() - 1); if rguard.lock_var().is_some() { // There are other active readers @@ -107,9 +110,18 @@ impl RWLock { } #[inline] - pub unsafe fn write_unlock(&self) { + pub unsafe fn read_unlock(&self) { let rguard = self.readers.lock(); let wguard = self.writer.lock(); + self.__read_unlock(rguard, wguard); + } + + #[inline] + unsafe fn __write_unlock( + &self, + rguard: SpinMutexGuard<WaitVariable<Option<NonZeroUsize>>>, + wguard: SpinMutexGuard<WaitVariable<bool>>, + ) { if let Err(mut wguard) = WaitQueue::notify_one(wguard) { // No writers waiting, release the write lock *wguard.lock_var_mut() = false; @@ -129,5 +141,108 @@ impl RWLock { } #[inline] + pub unsafe fn write_unlock(&self) { + let rguard = self.readers.lock(); + let wguard = self.writer.lock(); + self.__write_unlock(rguard, wguard); + } + + #[inline] + unsafe fn unlock(&self) { + let rguard = self.readers.lock(); + let wguard = self.writer.lock(); + if *wguard.lock_var() == true { + self.__write_unlock(rguard, wguard); + } else { + self.__read_unlock(rguard, wguard); + } + } + + #[inline] pub unsafe fn destroy(&self) {} } + +const EINVAL: i32 = 22; + +#[no_mangle] +pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RWLock) -> i32 { + if p.is_null() { + return EINVAL; + } + (*p).read(); + return 0; +} + +#[no_mangle] +pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RWLock) -> i32 { + if p.is_null() { + return EINVAL; + } + (*p).write(); + return 0; +} +#[no_mangle] +pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RWLock) -> i32 { + if p.is_null() { + return EINVAL; + } + (*p).unlock(); + return 0; +} + +#[no_mangle] +pub unsafe extern "C" fn __rust_print_err(m: *mut u8, s: i32) { + if s < 0 { + return; + } + let buf = slice::from_raw_parts(m as *const u8, s as _); + if let Ok(s) = str::from_utf8(&buf[..buf.iter().position(|&b| b == 0).unwrap_or(buf.len())]) { + eprint!("{}", s); + } +} + +#[no_mangle] +pub unsafe extern "C" fn __rust_abort() { + ::sys::abort_internal(); +} + +#[cfg(test)] +mod tests { + + use super::*; + use core::array::FixedSizeArray; + use mem::MaybeUninit; + use {mem, ptr}; + + // The below test verifies that the bytes of initialized RWLock are the ones + // we use in libunwind. + // If they change we need to update src/UnwindRustSgx.h in libunwind. + #[test] + fn test_c_rwlock_initializer() { + const RWLOCK_INIT: &[u8] = &[ + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + ]; + + let mut init = MaybeUninit::<RWLock>::zeroed(); + init.set(RWLock::new()); + assert_eq!( + mem::transmute::<_, [u8; 128]>(init.into_inner()).as_slice(), + RWLOCK_INIT + ); + } +} diff --git a/src/libstd/sys/sgx/stack_overflow.rs b/src/libstd/sys/sgx/stack_overflow.rs index 0176b748a87..c0e7c824615 100644 --- a/src/libstd/sys/sgx/stack_overflow.rs +++ b/src/libstd/sys/sgx/stack_overflow.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - pub struct Handler; impl Handler { diff --git a/src/libstd/sys/sgx/stdio.rs b/src/libstd/sys/sgx/stdio.rs index 13c91195569..6f206cd9a51 100644 --- a/src/libstd/sys/sgx/stdio.rs +++ b/src/libstd/sys/sgx/stdio.rs @@ -1,13 +1,3 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use fortanix_sgx_abi as abi; use io; diff --git a/src/libstd/sys/sgx/thread.rs b/src/libstd/sys/sgx/thread.rs index 9f3c4536cb5..b4bdb03e61a 100644 --- a/src/libstd/sys/sgx/thread.rs +++ b/src/libstd/sys/sgx/thread.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use boxed::FnBox; use ffi::CStr; use io; @@ -75,7 +65,7 @@ impl Thread { pub fn yield_now() { assert_eq!( - usercalls::wait(0, usercalls::WAIT_NO).unwrap_err().kind(), + usercalls::wait(0, usercalls::raw::WAIT_NO).unwrap_err().kind(), io::ErrorKind::WouldBlock ); } diff --git a/src/libstd/sys/sgx/thread_local.rs b/src/libstd/sys/sgx/thread_local.rs index 3b628bae4fb..e0d0fe76957 100644 --- a/src/libstd/sys/sgx/thread_local.rs +++ b/src/libstd/sys/sgx/thread_local.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use super::abi::tls::{Tls, Key as AbiKey}; pub type Key = usize; diff --git a/src/libstd/sys/sgx/time.rs b/src/libstd/sys/sgx/time.rs index 196e1a97fc4..10fe72d5f68 100644 --- a/src/libstd/sys/sgx/time.rs +++ b/src/libstd/sys/sgx/time.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - use time::Duration; use super::abi::usercalls; diff --git a/src/libstd/sys/sgx/waitqueue.rs b/src/libstd/sys/sgx/waitqueue.rs index ef0def13eee..a4738208778 100644 --- a/src/libstd/sys/sgx/waitqueue.rs +++ b/src/libstd/sys/sgx/waitqueue.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - /// A simple queue implementation for synchronization primitives. /// /// This queue is used to implement condition variable and mutexes. |
