mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-13 20:46:48 +00:00
Add std::os::fortanix_sgx
module
This commit is contained in:
parent
38f5c97c33
commit
dcb5db80b2
@ -817,7 +817,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "fortanix-sgx-abi"
|
||||
version = "0.3.1"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"compiler_builtins 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2890,7 +2890,7 @@ dependencies = [
|
||||
"compiler_builtins 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"core 0.0.0",
|
||||
"dlmalloc 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fortanix-sgx-abi 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fortanix-sgx-abi 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"panic_abort 0.0.0",
|
||||
"panic_unwind 0.0.0",
|
||||
@ -3447,7 +3447,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
||||
"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
"checksum fortanix-sgx-abi 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "26105e20b4c3f7a319db1376b54ac9a46e5761e949405553375095d05a0cee4d"
|
||||
"checksum fortanix-sgx-abi 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3f8cbee5e872cf7db61a999a041f9bc4706ca7bf7df4cb914f53fabb1c1bc550"
|
||||
"checksum fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
|
||||
"checksum fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674"
|
||||
"checksum fst 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d94485a00b1827b861dd9d1a2cc9764f9044d4c535514c0760a5a2012ef3399f"
|
||||
|
@ -40,7 +40,7 @@ rustc_tsan = { path = "../librustc_tsan" }
|
||||
dlmalloc = { version = "0.1", features = ['rustc-dep-of-std'] }
|
||||
|
||||
[target.x86_64-fortanix-unknown-sgx.dependencies]
|
||||
fortanix-sgx-abi = { version = "0.3.1", features = ['rustc-dep-of-std'] }
|
||||
fortanix-sgx-abi = { version = "0.3.2", features = ['rustc-dep-of-std'] }
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0"
|
||||
|
@ -314,7 +314,7 @@
|
||||
#![feature(alloc_layout_extra)]
|
||||
#![feature(maybe_uninit)]
|
||||
#![cfg_attr(target_env = "sgx", feature(global_asm, range_contains, slice_index_methods,
|
||||
decl_macro, coerce_unsized))]
|
||||
decl_macro, coerce_unsized, sgx_platform))]
|
||||
|
||||
#![default_lib_allocator]
|
||||
|
||||
|
67
src/libstd/os/fortanix_sgx/mod.rs
Normal file
67
src/libstd/os/fortanix_sgx/mod.rs
Normal file
@ -0,0 +1,67 @@
|
||||
// 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.
|
||||
|
||||
//! Functionality specific to the `x86_64-fortanix-unknown-sgx` target.
|
||||
//!
|
||||
//! This includes functions to deal with memory isolation, usercalls, and the
|
||||
//! SGX instruction set.
|
||||
|
||||
#![deny(missing_docs, missing_debug_implementations)]
|
||||
#![unstable(feature = "sgx_platform", issue = "56975")]
|
||||
|
||||
/// Low-level interfaces to usercalls. See the [ABI documentation] for more
|
||||
/// information.
|
||||
///
|
||||
/// [ABI documentation]: https://docs.rs/fortanix-sgx-abi/
|
||||
pub mod usercalls {
|
||||
pub use sys::abi::usercalls::*;
|
||||
|
||||
/// Primitives for allocating memory in userspace as well as copying data
|
||||
/// to and from user memory.
|
||||
pub mod alloc {
|
||||
pub use sys::abi::usercalls::alloc;
|
||||
}
|
||||
|
||||
/// Lowest-level interfaces to usercalls and usercall ABI type definitions.
|
||||
pub mod raw {
|
||||
use sys::abi::usercalls::raw::invoke_with_usercalls;
|
||||
pub use sys::abi::usercalls::raw::do_usercall;
|
||||
pub use sys::abi::usercalls::raw::{accept_stream, alloc, async_queues, bind_stream, close,
|
||||
connect_stream, exit, flush, free, insecure_time,
|
||||
launch_thread, read, read_alloc, send, wait, write};
|
||||
|
||||
macro_rules! define_usercallnrs {
|
||||
($(fn $f:ident($($n:ident: $t:ty),*) $(-> $r:ty)*; )*) => {
|
||||
/// Usercall numbers as per the ABI.
|
||||
#[repr(C)]
|
||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||
#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum UsercallNrs {
|
||||
$($f,)*
|
||||
}
|
||||
};
|
||||
}
|
||||
invoke_with_usercalls!(define_usercallnrs);
|
||||
|
||||
// fortanix-sgx-abi re-exports
|
||||
pub use sys::abi::usercalls::raw::{ByteBuffer, FifoDescriptor, Return, Usercall};
|
||||
pub use sys::abi::usercalls::raw::Error;
|
||||
pub use sys::abi::usercalls::raw::{EV_RETURNQ_NOT_EMPTY, EV_UNPARK, EV_USERCALLQ_NOT_FULL,
|
||||
FD_STDERR, FD_STDIN, FD_STDOUT, RESULT_SUCCESS,
|
||||
USERCALL_USER_DEFINED, WAIT_INDEFINITE, WAIT_NO};
|
||||
pub use sys::abi::usercalls::raw::{Fd, Result, Tcs};
|
||||
}
|
||||
}
|
||||
|
||||
/// Functions for querying mapping information for pointers.
|
||||
pub mod mem {
|
||||
pub use sys::abi::mem::*;
|
||||
}
|
@ -61,5 +61,6 @@ cfg_if! {
|
||||
#[cfg(target_os = "emscripten")] pub mod emscripten;
|
||||
#[cfg(target_os = "fuchsia")] pub mod fuchsia;
|
||||
#[cfg(target_os = "hermit")] pub mod hermit;
|
||||
#[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] pub mod fortanix_sgx;
|
||||
|
||||
pub mod raw;
|
||||
|
@ -10,13 +10,13 @@
|
||||
|
||||
// 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 +34,8 @@ 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);
|
||||
@ -41,6 +43,8 @@ pub fn is_enclave_range(p: *const u8, len: usize) -> bool {
|
||||
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);
|
||||
|
@ -13,10 +13,10 @@ 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]
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#![allow(unused)]
|
||||
|
||||
use ptr;
|
||||
use ptr::{self, NonNull};
|
||||
use mem;
|
||||
use cell::UnsafeCell;
|
||||
use slice;
|
||||
@ -39,39 +39,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 +122,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 +152,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 +194,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 +225,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 +233,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 +266,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 +288,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 +305,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 +321,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 +337,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 +370,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 +387,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 +421,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 +437,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 +447,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 +465,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 +483,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 +524,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 +533,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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,22 +8,17 @@
|
||||
// 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,14 +28,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(copy_user_buffer(&userbuf))
|
||||
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);
|
||||
@ -48,19 +47,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());
|
||||
@ -75,6 +80,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();
|
||||
@ -92,6 +99,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());
|
||||
@ -111,31 +120,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 {
|
||||
|
@ -10,7 +10,8 @@
|
||||
|
||||
#![allow(unused)]
|
||||
|
||||
use fortanix_sgx_abi::*;
|
||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||
pub use fortanix_sgx_abi::*;
|
||||
|
||||
use ptr::NonNull;
|
||||
|
||||
@ -21,7 +22,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 +179,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 +194,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 +209,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 +223,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 +236,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(
|
||||
|
@ -9,7 +9,7 @@
|
||||
// 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 +22,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);
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ struct Socket {
|
||||
}
|
||||
|
||||
impl Socket {
|
||||
fn new(fd: usercalls::Fd, local_addr: String) -> Socket {
|
||||
fn new(fd: usercalls::raw::Fd, local_addr: String) -> Socket {
|
||||
Socket { inner: Arc::new(FileDesc::new(fd)), local_addr }
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,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
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user