mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-13 20:46:48 +00:00
Add x86_64-fortanix-unknown-sgx target to libstd and dependencies
The files src/libstd/sys/sgx/*.rs are mostly copied/adapted from the wasm target. This also updates the dlmalloc submodule to the very latest version.
This commit is contained in:
parent
c559216ad0
commit
4a3505682e
4
.gitmodules
vendored
4
.gitmodules
vendored
@ -61,10 +61,12 @@
|
||||
path = src/tools/clang
|
||||
url = https://github.com/rust-lang-nursery/clang.git
|
||||
branch = rust-release-80-v2
|
||||
|
||||
[submodule "src/doc/rustc-guide"]
|
||||
path = src/doc/rustc-guide
|
||||
url = https://github.com/rust-lang/rustc-guide.git
|
||||
[submodule "src/doc/edition-guide"]
|
||||
path = src/doc/edition-guide
|
||||
url = https://github.com/rust-lang-nursery/edition-guide
|
||||
[submodule "src/rust-sgx"]
|
||||
path = src/rust-sgx
|
||||
url = https://github.com/fortanix/rust-sgx
|
||||
|
@ -797,6 +797,14 @@ name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "fortanix-sgx-abi"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"compiler_builtins 0.0.0",
|
||||
"core 0.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fs2"
|
||||
version = "0.4.3"
|
||||
@ -2773,6 +2781,7 @@ dependencies = [
|
||||
"compiler_builtins 0.0.0",
|
||||
"core 0.0.0",
|
||||
"dlmalloc 0.0.0",
|
||||
"fortanix-sgx-abi 0.0.0",
|
||||
"libc 0.0.0",
|
||||
"panic_abort 0.0.0",
|
||||
"panic_unwind 0.0.0",
|
||||
|
@ -874,6 +874,7 @@ impl Step for Src {
|
||||
"src/rustc/compiler_builtins_shim",
|
||||
"src/rustc/libc_shim",
|
||||
"src/rustc/dlmalloc_shim",
|
||||
"src/rustc/fortanix-sgx-abi_shim",
|
||||
"src/libtest",
|
||||
"src/libterm",
|
||||
"src/libprofiler_builtins",
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit c99638dc2ecfc750cc1656f6edb2bd062c1e0981
|
||||
Subproject commit de99f4b0c886f5916cd1a146464276d65bef61b8
|
@ -1 +1 @@
|
||||
Subproject commit c75ca6465a139704e00295be355b1f067af2f535
|
||||
Subproject commit 5b403753da9ec8ff501adf34cb6d63b319b4a3ae
|
@ -66,6 +66,12 @@ pub unsafe extern fn __rust_start_panic(_payload: usize) -> u32 {
|
||||
unsafe fn abort() -> ! {
|
||||
core::intrinsics::abort();
|
||||
}
|
||||
|
||||
#[cfg(target_env="sgx")]
|
||||
unsafe fn abort() -> ! {
|
||||
extern "C" { pub fn panic_exit() -> !; }
|
||||
panic_exit();
|
||||
}
|
||||
}
|
||||
|
||||
// This... is a bit of an oddity. The tl;dr; is that this is required to link
|
||||
|
@ -62,7 +62,7 @@ cfg_if! {
|
||||
if #[cfg(target_os = "emscripten")] {
|
||||
#[path = "emcc.rs"]
|
||||
mod imp;
|
||||
} else if #[cfg(target_arch = "wasm32")] {
|
||||
} else if #[cfg(any(target_arch = "wasm32", target_env = "sgx"))] {
|
||||
#[path = "dummy.rs"]
|
||||
mod imp;
|
||||
} else if #[cfg(all(target_env = "msvc", target_arch = "aarch64"))] {
|
||||
|
@ -35,9 +35,12 @@ rustc_lsan = { path = "../librustc_lsan" }
|
||||
rustc_msan = { path = "../librustc_msan" }
|
||||
rustc_tsan = { path = "../librustc_tsan" }
|
||||
|
||||
[target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies]
|
||||
[target.'cfg(any(all(target_arch = "wasm32", not(target_os = "emscripten")), target_env = "sgx"))'.dependencies]
|
||||
dlmalloc = { path = '../rustc/dlmalloc_shim' }
|
||||
|
||||
[target.x86_64-fortanix-unknown-sgx.dependencies]
|
||||
fortanix-sgx-abi = { path = "../rustc/fortanix-sgx-abi_shim" }
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0"
|
||||
build_helper = { path = "../build_helper" }
|
||||
|
@ -184,7 +184,7 @@ pub enum ErrorKind {
|
||||
}
|
||||
|
||||
impl ErrorKind {
|
||||
fn as_str(&self) -> &'static str {
|
||||
pub(crate) fn as_str(&self) -> &'static str {
|
||||
match *self {
|
||||
ErrorKind::NotFound => "entity not found",
|
||||
ErrorKind::PermissionDenied => "permission denied",
|
||||
|
@ -312,6 +312,7 @@
|
||||
#![feature(non_exhaustive)]
|
||||
#![feature(alloc_layout_extra)]
|
||||
#![feature(maybe_uninit)]
|
||||
#![cfg_attr(target_env = "sgx", feature(global_asm, range_contains))]
|
||||
|
||||
#![default_lib_allocator]
|
||||
|
||||
@ -354,6 +355,12 @@ extern crate unwind;
|
||||
// testing gives test-std access to real-std lang items and globals. See #2912
|
||||
#[cfg(test)] extern crate std as realstd;
|
||||
|
||||
#[cfg(target_env = "sgx")]
|
||||
#[macro_use]
|
||||
#[allow(unused_imports)] // FIXME: without `#[macro_use]`, get error: “cannot
|
||||
// determine resolution for the macro `usercalls_asm`”
|
||||
extern crate fortanix_sgx_abi;
|
||||
|
||||
// The standard macros that are not built-in to the compiler.
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
@ -48,6 +48,9 @@ cfg_if! {
|
||||
} else if #[cfg(target_arch = "wasm32")] {
|
||||
mod wasm;
|
||||
pub use self::wasm::*;
|
||||
} else if #[cfg(target_env = "sgx")] {
|
||||
mod sgx;
|
||||
pub use self::sgx::*;
|
||||
} else {
|
||||
compile_error!("libstd doesn't compile for this platform yet");
|
||||
}
|
||||
|
327
src/libstd/sys/sgx/abi/entry.S
Normal file
327
src/libstd/sys/sgx/abi/entry.S
Normal file
@ -0,0 +1,327 @@
|
||||
/* 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
|
||||
.global IMAGE_BASE
|
||||
IMAGE_BASE:
|
||||
|
||||
.section .rodata
|
||||
/* The XSAVE area needs to be a large chunk of readable memory, but since we are */
|
||||
/* going to restore everything to its initial state (XSTATE_BV=0), only certain */
|
||||
/* parts need to have a defined value. In particular: */
|
||||
/* */
|
||||
/* * MXCSR in the legacy area. This register is always restored if RFBM[1] or */
|
||||
/* RFBM[2] is set, regardless of the value of XSTATE_BV */
|
||||
/* * XSAVE header */
|
||||
.align 64
|
||||
.Lxsave_clear:
|
||||
.org .+24
|
||||
.Lxsave_mxcsr:
|
||||
.int 0
|
||||
|
||||
/* We can store a bunch of data in the gap between MXCSR and the XSAVE header */
|
||||
|
||||
/* The following symbols point at read-only data that will be filled in by the */
|
||||
/* post-linker. */
|
||||
|
||||
/* When using this macro, don't forget to adjust the linker version script! */
|
||||
.macro globvar name:req size:req
|
||||
.global \name
|
||||
.protected \name
|
||||
.align \size
|
||||
.size \name , \size
|
||||
\name :
|
||||
.org .+\size
|
||||
.endm
|
||||
/* The base address (relative to enclave start) of the heap area */
|
||||
globvar HEAP_BASE 8
|
||||
/* The heap size in bytes */
|
||||
globvar HEAP_SIZE 8
|
||||
/* Value of the RELA entry in the dynamic table */
|
||||
globvar RELA 8
|
||||
/* Value of the RELACOUNT entry in the dynamic table */
|
||||
globvar RELACOUNT 8
|
||||
/* The enclave size in bytes */
|
||||
globvar ENCLAVE_SIZE 8
|
||||
/* The base address (relative to enclave start) of the enclave configuration area */
|
||||
globvar CFGDATA_BASE 8
|
||||
/* Non-zero if debugging is enabled, zero otherwise */
|
||||
globvar DEBUG 1
|
||||
|
||||
.Lreentry_panic_msg:
|
||||
.asciz "Re-entered panicked enclave!"
|
||||
.Lreentry_panic_msg_end:
|
||||
|
||||
.Lusercall_panic_msg:
|
||||
.asciz "Invalid usercall#!"
|
||||
.Lusercall_panic_msg_end:
|
||||
|
||||
.org .Lxsave_clear+512
|
||||
.Lxsave_header:
|
||||
.int 0, 0 /* XSTATE_BV */
|
||||
.int 0, 0 /* XCOMP_BV */
|
||||
.org .+48 /* reserved bits */
|
||||
|
||||
.data
|
||||
.Lpanicked:
|
||||
.byte 0
|
||||
|
||||
/* TCS local storage section */
|
||||
.equ tcsls_tos, 0x00 /* initialized by loader to *offset* from image base to TOS */
|
||||
.equ tcsls_flags, 0x08 /* initialized by loader */
|
||||
.equ tcsls_flag_secondary, 0 /* initialized by loader; 0 = standard TCS, 1 = secondary TCS */
|
||||
.equ tcsls_flag_init_once, 1 /* initialized by loader to 0 */
|
||||
/* 14 unused bits */
|
||||
.equ tcsls_user_fcw, 0x0a
|
||||
.equ tcsls_user_mxcsr, 0x0c
|
||||
.equ tcsls_last_rsp, 0x10 /* initialized by loader to 0 */
|
||||
.equ tcsls_panic_last_rsp, 0x18 /* initialized by loader to 0 */
|
||||
.equ tcsls_debug_panic_buf_ptr, 0x20 /* initialized by loader to 0 */
|
||||
.equ tcsls_user_rsp, 0x28
|
||||
.equ tcsls_user_retip, 0x30
|
||||
.equ tcsls_user_rbp, 0x38
|
||||
.equ tcsls_user_r12, 0x40
|
||||
.equ tcsls_user_r13, 0x48
|
||||
.equ tcsls_user_r14, 0x50
|
||||
.equ tcsls_user_r15, 0x58
|
||||
.equ tcsls_tls_ptr, 0x60
|
||||
.equ tcsls_tcs_addr, 0x68
|
||||
|
||||
.macro load_tcsls_flag_secondary_bool reg:req comments:vararg
|
||||
.ifne tcsls_flag_secondary /* to convert to a bool, must be the first bit */
|
||||
.abort
|
||||
.endif
|
||||
mov $(1<<tcsls_flag_secondary),%e\reg
|
||||
and %gs:tcsls_flags,%\reg
|
||||
.endm
|
||||
|
||||
.text
|
||||
.global sgx_entry
|
||||
.type sgx_entry,function
|
||||
sgx_entry:
|
||||
/* save user registers */
|
||||
mov %rcx,%gs:tcsls_user_retip
|
||||
mov %rsp,%gs:tcsls_user_rsp
|
||||
mov %rbp,%gs:tcsls_user_rbp
|
||||
mov %r12,%gs:tcsls_user_r12
|
||||
mov %r13,%gs:tcsls_user_r13
|
||||
mov %r14,%gs:tcsls_user_r14
|
||||
mov %r15,%gs:tcsls_user_r15
|
||||
mov %rbx,%gs:tcsls_tcs_addr
|
||||
stmxcsr %gs:tcsls_user_mxcsr
|
||||
fnstcw %gs:tcsls_user_fcw
|
||||
/* reset user state */
|
||||
cld /* x86-64 ABI requires DF to be unset at function entry/exit */
|
||||
/* check for debug buffer pointer */
|
||||
testb $0xff,DEBUG(%rip)
|
||||
jz .Lskip_debug_init
|
||||
mov %r10,%gs:tcsls_debug_panic_buf_ptr
|
||||
.Lskip_debug_init:
|
||||
/* check if returning from usercall */
|
||||
mov %gs:tcsls_last_rsp,%r11
|
||||
test %r11,%r11
|
||||
jnz .Lusercall_ret
|
||||
/* setup stack */
|
||||
mov %gs:tcsls_tos,%rsp /* initially, RSP is not set to the correct value */
|
||||
/* here. This is fixed below under "adjust stack". */
|
||||
/* check for thread init */
|
||||
bts $tcsls_flag_init_once,%gs:tcsls_flags
|
||||
jc .Lskip_init
|
||||
/* adjust stack */
|
||||
lea IMAGE_BASE(%rip),%rax
|
||||
add %rax,%rsp
|
||||
mov %rsp,%gs:tcsls_tos
|
||||
/* call tcs_init */
|
||||
/* store caller-saved registers in callee-saved registers */
|
||||
mov %rdi,%rbx
|
||||
mov %rsi,%r12
|
||||
mov %rdx,%r13
|
||||
mov %r8,%r14
|
||||
mov %r9,%r15
|
||||
load_tcsls_flag_secondary_bool di /* RDI = tcs_init() argument: secondary: bool */
|
||||
call tcs_init
|
||||
/* reload caller-saved registers */
|
||||
mov %rbx,%rdi
|
||||
mov %r12,%rsi
|
||||
mov %r13,%rdx
|
||||
mov %r14,%r8
|
||||
mov %r15,%r9
|
||||
.Lskip_init:
|
||||
/* check for panic */
|
||||
bt $0,.Lpanicked(%rip)
|
||||
jc .Lreentry_panic
|
||||
/* call into main entry point */
|
||||
load_tcsls_flag_secondary_bool cx /* RCX = entry() argument: secondary: bool */
|
||||
call entry /* RDI, RSI, RDX, R8, R9 passed in from userspace */
|
||||
mov %rax,%rsi /* RSI = return value */
|
||||
/* NOP: mov %rdx,%rdx */ /* RDX = return value */
|
||||
xor %rdi,%rdi /* RDI = normal exit */
|
||||
.Lexit:
|
||||
/* clear general purpose register state */
|
||||
/* RAX overwritten by ENCLU */
|
||||
/* RBX set later */
|
||||
/* RCX overwritten by ENCLU */
|
||||
/* RDX contains return value */
|
||||
/* RSP set later */
|
||||
/* RBP set later */
|
||||
/* RDI contains exit mode */
|
||||
/* RSI contains return value */
|
||||
xor %r8,%r8
|
||||
xor %r9,%r9
|
||||
xor %r10,%r10
|
||||
xor %r11,%r11
|
||||
/* R12 ~ R15 set by sgx_exit */
|
||||
.Lsgx_exit:
|
||||
/* clear extended register state */
|
||||
mov %rdx, %rcx /* save RDX */
|
||||
mov $-1, %rax
|
||||
mov %rax, %rdx
|
||||
xrstor .Lxsave_clear(%rip)
|
||||
mov %rcx, %rdx /* restore RDX */
|
||||
/* clear flags */
|
||||
pushq $0
|
||||
popfq
|
||||
/* restore user registers */
|
||||
mov %gs:tcsls_user_r12,%r12
|
||||
mov %gs:tcsls_user_r13,%r13
|
||||
mov %gs:tcsls_user_r14,%r14
|
||||
mov %gs:tcsls_user_r15,%r15
|
||||
mov %gs:tcsls_user_retip,%rbx
|
||||
mov %gs:tcsls_user_rsp,%rsp
|
||||
mov %gs:tcsls_user_rbp,%rbp
|
||||
fldcw %gs:tcsls_user_fcw
|
||||
ldmxcsr %gs:tcsls_user_mxcsr
|
||||
/* exit enclave */
|
||||
mov $0x4,%eax /* EEXIT */
|
||||
enclu
|
||||
/* end sgx_entry */
|
||||
|
||||
.Lreentry_panic:
|
||||
lea .Lreentry_panic_msg(%rip),%rdi
|
||||
mov $.Lreentry_panic_msg_end-.Lreentry_panic_msg,%esi
|
||||
orq $8,%rsp
|
||||
jmp panic_msg
|
||||
|
||||
.Lusercall_panic:
|
||||
lea .Lusercall_panic_msg(%rip),%rdi
|
||||
mov $.Lusercall_panic_msg_end-.Lusercall_panic_msg,%esi
|
||||
orq $8,%rsp
|
||||
jmp panic_msg
|
||||
|
||||
.macro push_callee_saved_registers
|
||||
push %r15
|
||||
push %r14
|
||||
push %r13
|
||||
push %r12
|
||||
push %rbp
|
||||
push %rbx
|
||||
sub $8, %rsp
|
||||
fstcw 4(%rsp)
|
||||
stmxcsr (%rsp)
|
||||
.endm
|
||||
|
||||
.global panic_exit
|
||||
panic_exit:
|
||||
/* save registers in DEBUG mode, so that debugger can reconstruct the stack */
|
||||
testb $0xff,DEBUG(%rip)
|
||||
jz .Lskip_save_registers
|
||||
push_callee_saved_registers
|
||||
movq %rsp,%gs:tcsls_panic_last_rsp
|
||||
.Lskip_save_registers:
|
||||
/* set panicked bit */
|
||||
movb $1,.Lpanicked(%rip)
|
||||
/* call usercall exit(true) */
|
||||
mov $1,%esi /* RSI = usercall() argument: panic = true */
|
||||
xor %rdx,%rdx /* RDX cleared */
|
||||
movq $usercall_nr_exit,%rdi /* RDI = usercall exit */
|
||||
jmp .Lexit
|
||||
|
||||
/* This *MUST* be called with 6 parameters, otherwise register information */
|
||||
/* might leak! */
|
||||
.global usercall
|
||||
usercall:
|
||||
test %rdi,%rdi
|
||||
jle .Lusercall_panic
|
||||
/* save callee-saved state */
|
||||
push_callee_saved_registers
|
||||
movq %rsp,%gs:tcsls_last_rsp
|
||||
/* clear general purpose register state */
|
||||
/* RAX overwritten by ENCLU */
|
||||
/* RBX set by sgx_exit */
|
||||
/* RCX overwritten by ENCLU */
|
||||
/* RDX contains parameter */
|
||||
/* RSP set by sgx_exit */
|
||||
/* RBP set by sgx_exit */
|
||||
/* RDI contains parameter */
|
||||
/* RSI contains parameter */
|
||||
/* R8 contains parameter */
|
||||
/* R9 contains parameter */
|
||||
xor %r10,%r10
|
||||
xor %r11,%r11
|
||||
/* R12 ~ R15 set by sgx_exit */
|
||||
/* extended registers/flags cleared by sgx_exit */
|
||||
/* exit */
|
||||
jmp .Lsgx_exit
|
||||
.Lusercall_ret:
|
||||
movq $0,%gs:tcsls_last_rsp
|
||||
/* restore callee-saved state, cf. push_callee_saved_registers */
|
||||
mov %r11,%rsp
|
||||
ldmxcsr (%rsp)
|
||||
fldcw 4(%rsp)
|
||||
add $8, %rsp
|
||||
pop %rbx
|
||||
pop %rbp
|
||||
pop %r12
|
||||
pop %r13
|
||||
pop %r14
|
||||
pop %r15
|
||||
/* return */
|
||||
mov %rsi,%rax /* RAX = return value */
|
||||
/* NOP: mov %rdx,%rdx */ /* RDX = return value */
|
||||
ret
|
||||
|
||||
/*
|
||||
The following functions need to be defined externally:
|
||||
```
|
||||
// Called by entry code when it needs to panic
|
||||
extern "C" fn panic_msg(msg: &'static str) -> ! {
|
||||
panic!(msg)
|
||||
}
|
||||
|
||||
// Called once when a TCS is first entered
|
||||
extern "C" fn tcs_init(secondary: bool);
|
||||
|
||||
// Standard TCS entrypoint
|
||||
extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64) -> (u64, u64);
|
||||
```
|
||||
*/
|
||||
|
||||
.global get_tcs_addr
|
||||
get_tcs_addr:
|
||||
mov %gs:tcsls_tcs_addr,%rax
|
||||
ret
|
||||
|
||||
.global get_tls_ptr
|
||||
get_tls_ptr:
|
||||
mov %gs:tcsls_tls_ptr,%rax
|
||||
ret
|
||||
|
||||
.global set_tls_ptr
|
||||
set_tls_ptr:
|
||||
mov %rdi,%gs:tcsls_tls_ptr
|
||||
ret
|
||||
|
||||
.global take_debug_panic_buf_ptr
|
||||
take_debug_panic_buf_ptr:
|
||||
xor %rax,%rax
|
||||
xchg %gs:tcsls_debug_panic_buf_ptr,%rax
|
||||
ret
|
31
src/libstd/sys/sgx/abi/mem.rs
Normal file
31
src/libstd/sys/sgx/abi/mem.rs
Normal file
@ -0,0 +1,31 @@
|
||||
// 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 {
|
||||
(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 {
|
||||
(image_base()+offset) as *mut T
|
||||
}
|
||||
|
||||
// Do not remove inline: will result in relocation failure
|
||||
// For the same reason we use inline ASM here instead of an extern static to
|
||||
// locate the base
|
||||
#[inline(always)]
|
||||
fn image_base() -> u64 {
|
||||
let base;
|
||||
unsafe{asm!("lea IMAGE_BASE(%rip),$0":"=r"(base))};
|
||||
base
|
||||
}
|
94
src/libstd/sys/sgx/abi/mod.rs
Normal file
94
src/libstd/sys/sgx/abi/mod.rs
Normal file
@ -0,0 +1,94 @@
|
||||
// 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
|
||||
#[macro_use]
|
||||
mod usercalls;
|
||||
|
||||
global_asm!(concat!(usercalls_asm!(), include_str!("entry.S")));
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn tcs_init(secondary: bool) {
|
||||
// Be very careful when changing this code: it runs before the binary has been
|
||||
// relocated. Any indirect accesses to symbols will likely fail.
|
||||
const UNINIT: usize = 0;
|
||||
const BUSY: usize = 1;
|
||||
const DONE: usize = 2;
|
||||
// Three-state spin-lock
|
||||
static RELOC_STATE: AtomicUsize = AtomicUsize::new(UNINIT);
|
||||
|
||||
if secondary && RELOC_STATE.load(Ordering::Relaxed) != DONE {
|
||||
panic::panic_msg("Entered secondary TCS before main TCS!")
|
||||
}
|
||||
|
||||
// Try to atomically swap UNINIT with BUSY. The returned state can be:
|
||||
match RELOC_STATE.compare_and_swap(UNINIT, BUSY, Ordering::Acquire) {
|
||||
// This thread just obtained the lock and other threads will observe BUSY
|
||||
UNINIT => {
|
||||
reloc::relocate_elf_rela();
|
||||
RELOC_STATE.store(DONE, Ordering::Release);
|
||||
},
|
||||
// We need to wait until the initialization is done.
|
||||
BUSY => while RELOC_STATE.load(Ordering::Acquire) == BUSY {
|
||||
::core::arch::x86_64::_mm_pause()
|
||||
},
|
||||
// Initialization is done.
|
||||
DONE => {},
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: this item should only exist if this is linked into an executable
|
||||
// (main function exists). If this is a library, the crate author should be
|
||||
// able to specify this
|
||||
#[no_mangle]
|
||||
#[allow(unreachable_code)]
|
||||
extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64) -> (u64, u64) {
|
||||
if secondary {
|
||||
unimplemented!("thread entrypoint");
|
||||
|
||||
(0, 0)
|
||||
} else {
|
||||
extern "C" {
|
||||
fn main(argc: isize, argv: *const *const u8) -> isize;
|
||||
}
|
||||
|
||||
// check entry is being called according to ABI
|
||||
assert_eq!(p3, 0);
|
||||
assert_eq!(p4, 0);
|
||||
assert_eq!(p5, 0);
|
||||
|
||||
unsafe {
|
||||
// The actual types of these arguments are `p1: *const Arg, p2:
|
||||
// usize`. We can't currently customize the argument list of Rust's
|
||||
// main function, so we pass these in as the standard pointer-sized
|
||||
// values in `argc` and `argv`.
|
||||
let ret = main(p2 as _, p1 as _);
|
||||
exit_with_code(ret)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn exit_with_code(code: isize) -> ! {
|
||||
if code != 0 {
|
||||
if let Some(mut out) = panic::SgxPanicOutput::new() {
|
||||
let _ = write!(out, "Exited with status code {}", code);
|
||||
}
|
||||
}
|
||||
unsafe { usercalls::raw::exit(code != 0) };
|
||||
}
|
58
src/libstd/sys/sgx/abi/panic.rs
Normal file
58
src/libstd/sys/sgx/abi/panic.rs
Normal file
@ -0,0 +1,58 @@
|
||||
// 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;
|
||||
|
||||
extern "C" {
|
||||
fn take_debug_panic_buf_ptr() -> *mut u8;
|
||||
static DEBUG: u8;
|
||||
}
|
||||
|
||||
pub(crate) struct SgxPanicOutput(Option<&'static mut [u8]>);
|
||||
|
||||
impl SgxPanicOutput {
|
||||
pub(crate) fn new() -> Option<Self> {
|
||||
if unsafe { DEBUG == 0 } {
|
||||
None
|
||||
} else {
|
||||
Some(SgxPanicOutput(None))
|
||||
}
|
||||
}
|
||||
|
||||
fn init(&mut self) -> &mut &'static mut [u8] {
|
||||
self.0.get_or_insert_with(|| unsafe {
|
||||
let ptr = take_debug_panic_buf_ptr();
|
||||
if ptr.is_null() {
|
||||
&mut []
|
||||
} else {
|
||||
from_raw_parts_mut(ptr, 1024)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for SgxPanicOutput {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.init().write(buf)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.init().flush()
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn panic_msg(msg: &str) -> ! {
|
||||
let _ = SgxPanicOutput::new().map(|mut out| out.write(msg.as_bytes()));
|
||||
unsafe { panic_exit(); }
|
||||
}
|
||||
|
||||
extern "C" { pub fn panic_exit() -> !; }
|
40
src/libstd/sys/sgx/abi/reloc.rs
Normal file
40
src/libstd/sys/sgx/abi/reloc.rs
Normal file
@ -0,0 +1,40 @@
|
||||
// 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;
|
||||
|
||||
const R_X86_64_RELATIVE: u32 = 8;
|
||||
|
||||
#[repr(packed)]
|
||||
struct Rela<T> {
|
||||
offset: T,
|
||||
info: T,
|
||||
addend: T,
|
||||
}
|
||||
|
||||
pub fn relocate_elf_rela() {
|
||||
extern {
|
||||
static RELA: u64;
|
||||
static RELACOUNT: usize;
|
||||
}
|
||||
|
||||
if unsafe { RELACOUNT } == 0 { return } // unsafe ok: link-time constant
|
||||
|
||||
let relas = unsafe {
|
||||
from_raw_parts::<Rela<u64>>(mem::rel_ptr(RELA), RELACOUNT) // unsafe ok: link-time constant
|
||||
};
|
||||
for rela in relas {
|
||||
if rela.info != (/*0 << 32 |*/ R_X86_64_RELATIVE as u64) {
|
||||
panic!("Invalid relocation");
|
||||
}
|
||||
unsafe { *mem::rel_ptr_mut::<*const ()>(rela.offset) = mem::rel_ptr(rela.addend) };
|
||||
}
|
||||
}
|
12
src/libstd/sys/sgx/abi/usercalls/mod.rs
Normal file
12
src/libstd/sys/sgx/abi/usercalls/mod.rs
Normal file
@ -0,0 +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.
|
||||
|
||||
#[macro_use]
|
||||
pub mod raw;
|
231
src/libstd/sys/sgx/abi/usercalls/raw.rs
Normal file
231
src/libstd/sys/sgx/abi/usercalls/raw.rs
Normal file
@ -0,0 +1,231 @@
|
||||
// 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::*;
|
||||
|
||||
use ptr::NonNull;
|
||||
|
||||
#[repr(C)]
|
||||
struct UsercallReturn(u64, u64);
|
||||
|
||||
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) {
|
||||
if nr==0 { panic!("Invalid usercall number {}",nr) }
|
||||
let UsercallReturn(a, b) = usercall(nr,p1,p2,0,p3,p4);
|
||||
(a, b)
|
||||
}
|
||||
|
||||
type Register = u64;
|
||||
|
||||
trait RegisterArgument {
|
||||
fn from_register(Register) -> Self;
|
||||
fn into_register(self) -> Register;
|
||||
}
|
||||
|
||||
trait ReturnValue {
|
||||
fn from_registers(call: &'static str, regs: (Register, Register)) -> Self;
|
||||
}
|
||||
|
||||
macro_rules! define_usercalls {
|
||||
// Using `$r:tt` because `$r:ty` doesn't match ! in `clobber_diverging`
|
||||
($(fn $f:ident($($n:ident: $t:ty),*) $(-> $r:tt)*; )*) => {
|
||||
#[repr(C)]
|
||||
#[allow(non_camel_case_types)]
|
||||
enum Usercalls {
|
||||
__enclave_usercalls_invalid,
|
||||
$($f,)*
|
||||
}
|
||||
|
||||
$(enclave_usercalls_internal_define_usercalls!(def fn $f($($n: $t),*) $(-> $r)*);)*
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! define_usercalls_asm {
|
||||
($(fn $f:ident($($n:ident: $t:ty),*) $(-> $r:ty)*; )*) => {
|
||||
macro_rules! usercalls_asm {
|
||||
() => {
|
||||
concat!(
|
||||
".equ usercall_nr_LAST, 0\n",
|
||||
$(
|
||||
".equ usercall_nr_", stringify!($f), ", usercall_nr_LAST+1\n",
|
||||
".equ usercall_nr_LAST, usercall_nr_", stringify!($f), "\n"
|
||||
),*
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! define_ra {
|
||||
(< $i:ident > $t:ty) => {
|
||||
impl<$i> RegisterArgument for $t {
|
||||
fn from_register(a: Register) -> Self {
|
||||
a as _
|
||||
}
|
||||
fn into_register(self) -> Register {
|
||||
self as _
|
||||
}
|
||||
}
|
||||
};
|
||||
($i:ty as $t:ty) => {
|
||||
impl RegisterArgument for $t {
|
||||
fn from_register(a: Register) -> Self {
|
||||
a as $i as _
|
||||
}
|
||||
fn into_register(self) -> Register {
|
||||
self as $i as _
|
||||
}
|
||||
}
|
||||
};
|
||||
($t:ty) => {
|
||||
impl RegisterArgument for $t {
|
||||
fn from_register(a: Register) -> Self {
|
||||
a as _
|
||||
}
|
||||
fn into_register(self) -> Register {
|
||||
self as _
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
define_ra!(Register);
|
||||
define_ra!(i64);
|
||||
define_ra!(u32);
|
||||
define_ra!(u32 as i32);
|
||||
define_ra!(u16);
|
||||
define_ra!(u16 as i16);
|
||||
define_ra!(u8);
|
||||
define_ra!(u8 as i8);
|
||||
define_ra!(usize);
|
||||
define_ra!(usize as isize);
|
||||
define_ra!(<T> *const T);
|
||||
define_ra!(<T> *mut T);
|
||||
|
||||
impl RegisterArgument for bool {
|
||||
fn from_register(a: Register) -> bool {
|
||||
if a != 0 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
fn into_register(self) -> Register {
|
||||
self as _
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RegisterArgument> RegisterArgument for Option<NonNull<T>> {
|
||||
fn from_register(a: Register) -> Option<NonNull<T>> {
|
||||
NonNull::new(a as _)
|
||||
}
|
||||
fn into_register(self) -> Register {
|
||||
self.map_or(0 as _, NonNull::as_ptr) as _
|
||||
}
|
||||
}
|
||||
|
||||
impl ReturnValue for ! {
|
||||
fn from_registers(call: &'static str, _regs: (Register, Register)) -> Self {
|
||||
panic!("Usercall {}: did not expect to be re-entered", call);
|
||||
}
|
||||
}
|
||||
|
||||
impl ReturnValue for () {
|
||||
fn from_registers(call: &'static str, regs: (Register, Register)) -> Self {
|
||||
assert_eq!(regs.0, 0, "Usercall {}: expected {} return value to be 0", call, "1st");
|
||||
assert_eq!(regs.1, 0, "Usercall {}: expected {} return value to be 0", call, "2nd");
|
||||
()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RegisterArgument> ReturnValue for T {
|
||||
fn from_registers(call: &'static str, regs: (Register, Register)) -> Self {
|
||||
assert_eq!(regs.1, 0, "Usercall {}: expected {} return value to be 0", call, "2nd");
|
||||
T::from_register(regs.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RegisterArgument, U: RegisterArgument> ReturnValue for (T, U) {
|
||||
fn from_registers(_call: &'static str, regs: (Register, Register)) -> Self {
|
||||
(
|
||||
T::from_register(regs.0),
|
||||
U::from_register(regs.1)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
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) => (
|
||||
#[inline(always)]
|
||||
pub unsafe fn $f($n1: $t1, $n2: $t2, $n3: $t3, $n4: $t4) -> $r {
|
||||
ReturnValue::from_registers(stringify!($f), do_usercall(
|
||||
Usercalls::$f as Register,
|
||||
RegisterArgument::into_register($n1),
|
||||
RegisterArgument::into_register($n2),
|
||||
RegisterArgument::into_register($n3),
|
||||
RegisterArgument::into_register($n4),
|
||||
))
|
||||
}
|
||||
);
|
||||
(def fn $f:ident($n1:ident: $t1:ty, $n2:ident: $t2:ty, $n3:ident: $t3:ty) -> $r:ty) => (
|
||||
#[inline(always)]
|
||||
pub unsafe fn $f($n1: $t1, $n2: $t2, $n3: $t3) -> $r {
|
||||
ReturnValue::from_registers(stringify!($f), do_usercall(
|
||||
Usercalls::$f as Register,
|
||||
RegisterArgument::into_register($n1),
|
||||
RegisterArgument::into_register($n2),
|
||||
RegisterArgument::into_register($n3),
|
||||
0
|
||||
))
|
||||
}
|
||||
);
|
||||
(def fn $f:ident($n1:ident: $t1:ty, $n2:ident: $t2:ty) -> $r:ty) => (
|
||||
#[inline(always)]
|
||||
pub unsafe fn $f($n1: $t1, $n2: $t2) -> $r {
|
||||
ReturnValue::from_registers(stringify!($f), do_usercall(
|
||||
Usercalls::$f as Register,
|
||||
RegisterArgument::into_register($n1),
|
||||
RegisterArgument::into_register($n2),
|
||||
0,0
|
||||
))
|
||||
}
|
||||
);
|
||||
(def fn $f:ident($n1:ident: $t1:ty) -> $r:ty) => (
|
||||
#[inline(always)]
|
||||
pub unsafe fn $f($n1: $t1) -> $r {
|
||||
ReturnValue::from_registers(stringify!($f), do_usercall(
|
||||
Usercalls::$f as Register,
|
||||
RegisterArgument::into_register($n1),
|
||||
0,0,0
|
||||
))
|
||||
}
|
||||
);
|
||||
(def fn $f:ident() -> $r:ty) => (
|
||||
#[inline(always)]
|
||||
pub unsafe fn $f() -> $r {
|
||||
ReturnValue::from_registers(stringify!($f), do_usercall(
|
||||
Usercalls::$f as Register,
|
||||
0,0,0,0
|
||||
))
|
||||
}
|
||||
);
|
||||
(def fn $f:ident($($n:ident: $t:ty),*)) => (
|
||||
enclave_usercalls_internal_define_usercalls!(def fn $f($($n: $t),*) -> ());
|
||||
);
|
||||
}
|
||||
|
||||
invoke_with_usercalls!(define_usercalls);
|
||||
invoke_with_usercalls!(define_usercalls_asm);
|
39
src/libstd/sys/sgx/alloc.rs
Normal file
39
src/libstd/sys/sgx/alloc.rs
Normal file
@ -0,0 +1,39 @@
|
||||
// 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};
|
||||
|
||||
// FIXME: protect this value for concurrent access
|
||||
static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::DLMALLOC_INIT;
|
||||
|
||||
#[stable(feature = "alloc_system_type", since = "1.28.0")]
|
||||
unsafe impl GlobalAlloc for System {
|
||||
#[inline]
|
||||
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
||||
DLMALLOC.malloc(layout.size(), layout.align())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
|
||||
DLMALLOC.calloc(layout.size(), layout.align())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
|
||||
DLMALLOC.free(ptr, layout.size(), layout.align())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
|
||||
DLMALLOC.realloc(ptr, layout.size(), layout.align(), new_size)
|
||||
}
|
||||
}
|
57
src/libstd/sys/sgx/args.rs
Normal file
57
src/libstd/sys/sgx/args.rs
Normal file
@ -0,0 +1,57 @@
|
||||
// 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 fortanix_sgx_abi::ByteBuffer;
|
||||
|
||||
pub unsafe fn init(argc: isize, argv: *const *const u8) {
|
||||
// See ABI
|
||||
let _len: usize = argc as _;
|
||||
let _args: *const ByteBuffer = argv as _;
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
pub unsafe fn cleanup() {
|
||||
}
|
||||
|
||||
pub fn args() -> Args {
|
||||
Args
|
||||
}
|
||||
|
||||
pub struct Args;
|
||||
|
||||
impl Args {
|
||||
pub fn inner_debug(&self) -> &[OsString] {
|
||||
&[]
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for Args {
|
||||
type Item = OsString;
|
||||
fn next(&mut self) -> Option<OsString> {
|
||||
None
|
||||
}
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
(0, Some(0))
|
||||
}
|
||||
}
|
||||
|
||||
impl ExactSizeIterator for Args {
|
||||
fn len(&self) -> usize {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
impl DoubleEndedIterator for Args {
|
||||
fn next_back(&mut self) -> Option<OsString> {
|
||||
None
|
||||
}
|
||||
}
|
37
src/libstd/sys/sgx/backtrace.rs
Normal file
37
src/libstd/sys/sgx/backtrace.rs
Normal file
@ -0,0 +1,37 @@
|
||||
// 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;
|
||||
|
||||
pub struct BacktraceContext;
|
||||
|
||||
pub fn unwind_backtrace(_frames: &mut [Frame])
|
||||
-> io::Result<(usize, BacktraceContext)>
|
||||
{
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn resolve_symname<F>(_frame: Frame,
|
||||
_callback: F,
|
||||
_: &BacktraceContext) -> io::Result<()>
|
||||
where F: FnOnce(Option<&str>) -> io::Result<()>
|
||||
{
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn foreach_symbol_fileline<F>(_: Frame,
|
||||
_: F,
|
||||
_: &BacktraceContext) -> io::Result<bool>
|
||||
where F: FnMut(&[u8], u32) -> io::Result<()>
|
||||
{
|
||||
unsupported()
|
||||
}
|
41
src/libstd/sys/sgx/cmath.rs
Normal file
41
src/libstd/sys/sgx/cmath.rs
Normal file
@ -0,0 +1,41 @@
|
||||
// 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`
|
||||
extern {
|
||||
pub fn acos(n: f64) -> f64;
|
||||
pub fn acosf(n: f32) -> f32;
|
||||
pub fn asin(n: f64) -> f64;
|
||||
pub fn asinf(n: f32) -> f32;
|
||||
pub fn atan(n: f64) -> f64;
|
||||
pub fn atan2(a: f64, b: f64) -> f64;
|
||||
pub fn atan2f(a: f32, b: f32) -> f32;
|
||||
pub fn atanf(n: f32) -> f32;
|
||||
pub fn cbrt(n: f64) -> f64;
|
||||
pub fn cbrtf(n: f32) -> f32;
|
||||
pub fn cosh(n: f64) -> f64;
|
||||
pub fn coshf(n: f32) -> f32;
|
||||
pub fn expm1(n: f64) -> f64;
|
||||
pub fn expm1f(n: f32) -> f32;
|
||||
pub fn fdim(a: f64, b: f64) -> f64;
|
||||
pub fn fdimf(a: f32, b: f32) -> f32;
|
||||
pub fn hypot(x: f64, y: f64) -> f64;
|
||||
pub fn hypotf(x: f32, y: f32) -> f32;
|
||||
pub fn log1p(n: f64) -> f64;
|
||||
pub fn log1pf(n: f32) -> f32;
|
||||
pub fn sinh(n: f64) -> f64;
|
||||
pub fn sinhf(n: f32) -> f32;
|
||||
pub fn tan(n: f64) -> f64;
|
||||
pub fn tanf(n: f32) -> f32;
|
||||
pub fn tanh(n: f64) -> f64;
|
||||
pub fn tanhf(n: f32) -> f32;
|
||||
}
|
43
src/libstd/sys/sgx/condvar.rs
Normal file
43
src/libstd/sys/sgx/condvar.rs
Normal file
@ -0,0 +1,43 @@
|
||||
// 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;
|
||||
|
||||
pub struct Condvar { }
|
||||
|
||||
impl Condvar {
|
||||
pub const fn new() -> Condvar {
|
||||
Condvar { }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn init(&mut self) {}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn notify_one(&self) {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn notify_all(&self) {
|
||||
}
|
||||
|
||||
pub unsafe fn wait(&self, _mutex: &Mutex) {
|
||||
panic!("can't block with web assembly")
|
||||
}
|
||||
|
||||
pub unsafe fn wait_timeout(&self, _mutex: &Mutex, _dur: Duration) -> bool {
|
||||
panic!("can't block with web assembly");
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn destroy(&self) {
|
||||
}
|
||||
}
|
19
src/libstd/sys/sgx/env.rs
Normal file
19
src/libstd/sys/sgx/env.rs
Normal file
@ -0,0 +1,19 @@
|
||||
// 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 = "";
|
||||
pub const DLL_PREFIX: &'static str = "";
|
||||
pub const DLL_SUFFIX: &'static str = ".sgxs";
|
||||
pub const DLL_EXTENSION: &'static str = "sgxs";
|
||||
pub const EXE_SUFFIX: &'static str = ".sgxs";
|
||||
pub const EXE_EXTENSION: &'static str = "sgxs";
|
||||
}
|
304
src/libstd/sys/sgx/fs.rs
Normal file
304
src/libstd/sys/sgx/fs.rs
Normal file
@ -0,0 +1,304 @@
|
||||
// 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};
|
||||
use io::{self, SeekFrom};
|
||||
use path::{Path, PathBuf};
|
||||
use sys::time::SystemTime;
|
||||
use sys::{unsupported, Void};
|
||||
|
||||
pub struct File(Void);
|
||||
|
||||
pub struct FileAttr(Void);
|
||||
|
||||
pub struct ReadDir(Void);
|
||||
|
||||
pub struct DirEntry(Void);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct OpenOptions { }
|
||||
|
||||
pub struct FilePermissions(Void);
|
||||
|
||||
pub struct FileType(Void);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DirBuilder { }
|
||||
|
||||
impl FileAttr {
|
||||
pub fn size(&self) -> u64 {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn perm(&self) -> FilePermissions {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn file_type(&self) -> FileType {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn modified(&self) -> io::Result<SystemTime> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn accessed(&self) -> io::Result<SystemTime> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn created(&self) -> io::Result<SystemTime> {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for FileAttr {
|
||||
fn clone(&self) -> FileAttr {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl FilePermissions {
|
||||
pub fn readonly(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn set_readonly(&mut self, _readonly: bool) {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for FilePermissions {
|
||||
fn clone(&self) -> FilePermissions {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for FilePermissions {
|
||||
fn eq(&self, _other: &FilePermissions) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for FilePermissions {
|
||||
}
|
||||
|
||||
impl fmt::Debug for FilePermissions {
|
||||
fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl FileType {
|
||||
pub fn is_dir(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn is_file(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn is_symlink(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for FileType {
|
||||
fn clone(&self) -> FileType {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl Copy for FileType {}
|
||||
|
||||
impl PartialEq for FileType {
|
||||
fn eq(&self, _other: &FileType) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for FileType {
|
||||
}
|
||||
|
||||
impl Hash for FileType {
|
||||
fn hash<H: Hasher>(&self, _h: &mut H) {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for FileType {
|
||||
fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ReadDir {
|
||||
fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for ReadDir {
|
||||
type Item = io::Result<DirEntry>;
|
||||
|
||||
fn next(&mut self) -> Option<io::Result<DirEntry>> {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl DirEntry {
|
||||
pub fn path(&self) -> PathBuf {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn file_name(&self) -> OsString {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn metadata(&self) -> io::Result<FileAttr> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn file_type(&self) -> io::Result<FileType> {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl OpenOptions {
|
||||
pub fn new() -> OpenOptions {
|
||||
OpenOptions { }
|
||||
}
|
||||
|
||||
pub fn read(&mut self, _read: bool) { }
|
||||
pub fn write(&mut self, _write: bool) { }
|
||||
pub fn append(&mut self, _append: bool) { }
|
||||
pub fn truncate(&mut self, _truncate: bool) { }
|
||||
pub fn create(&mut self, _create: bool) { }
|
||||
pub fn create_new(&mut self, _create_new: bool) { }
|
||||
}
|
||||
|
||||
impl File {
|
||||
pub fn open(_path: &Path, _opts: &OpenOptions) -> io::Result<File> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn file_attr(&self) -> io::Result<FileAttr> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn fsync(&self) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn datasync(&self) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn truncate(&self, _size: u64) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn read(&self, _buf: &mut [u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn flush(&self) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn seek(&self, _pos: SeekFrom) -> io::Result<u64> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn duplicate(&self) -> io::Result<File> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn set_permissions(&self, _perm: FilePermissions) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn diverge(&self) -> ! {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl DirBuilder {
|
||||
pub fn new() -> DirBuilder {
|
||||
DirBuilder { }
|
||||
}
|
||||
|
||||
pub fn mkdir(&self, _p: &Path) -> io::Result<()> {
|
||||
unsupported()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for File {
|
||||
fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn readdir(_p: &Path) -> io::Result<ReadDir> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn unlink(_p: &Path) -> io::Result<()> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn rename(_old: &Path, _new: &Path) -> io::Result<()> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn set_perm(_p: &Path, perm: FilePermissions) -> io::Result<()> {
|
||||
match perm.0 {}
|
||||
}
|
||||
|
||||
pub fn rmdir(_p: &Path) -> io::Result<()> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn remove_dir_all(_path: &Path) -> io::Result<()> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn readlink(_p: &Path) -> io::Result<PathBuf> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn symlink(_src: &Path, _dst: &Path) -> io::Result<()> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn stat(_p: &Path) -> io::Result<FileAttr> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn lstat(_p: &Path) -> io::Result<FileAttr> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn canonicalize(_p: &Path) -> io::Result<PathBuf> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn copy(_from: &Path, _to: &Path) -> io::Result<u64> {
|
||||
unsupported()
|
||||
}
|
11
src/libstd/sys/sgx/memchr.rs
Normal file
11
src/libstd/sys/sgx/memchr.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// 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};
|
151
src/libstd/sys/sgx/mod.rs
Normal file
151
src/libstd/sys/sgx/mod.rs
Normal file
@ -0,0 +1,151 @@
|
||||
// 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
|
||||
//! OS level functionality for Fortanix SGX.
|
||||
|
||||
use io;
|
||||
use os::raw::c_char;
|
||||
use sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
pub mod abi;
|
||||
|
||||
pub mod alloc;
|
||||
pub mod args;
|
||||
#[cfg(feature = "backtrace")]
|
||||
pub mod backtrace;
|
||||
pub mod cmath;
|
||||
pub mod condvar;
|
||||
pub mod env;
|
||||
pub mod fs;
|
||||
pub mod memchr;
|
||||
pub mod mutex;
|
||||
pub mod net;
|
||||
pub mod os;
|
||||
pub mod os_str;
|
||||
pub mod path;
|
||||
pub mod pipe;
|
||||
pub mod process;
|
||||
pub mod rwlock;
|
||||
pub mod stack_overflow;
|
||||
pub mod thread;
|
||||
pub mod thread_local;
|
||||
pub mod time;
|
||||
pub mod stdio;
|
||||
|
||||
#[cfg(not(test))]
|
||||
pub fn init() {
|
||||
}
|
||||
|
||||
/// This function is used to implement functionality that simply doesn't exist.
|
||||
/// Programs relying on this functionality will need to deal with the error.
|
||||
pub fn unsupported<T>() -> io::Result<T> {
|
||||
Err(unsupported_err())
|
||||
}
|
||||
|
||||
pub fn unsupported_err() -> io::Error {
|
||||
io::Error::new(io::ErrorKind::Other,
|
||||
"operation not supported on SGX yet")
|
||||
}
|
||||
|
||||
/// This function is used to implement various functions that doesn't exist,
|
||||
/// but the lack of which might not be reason for error. If no error is
|
||||
/// returned, the program might very well be able to function normally. This is
|
||||
/// what happens when `SGX_INEFFECTIVE_ERROR` is set to `true`. If it is
|
||||
/// `false`, the behavior is the same as `unsupported`.
|
||||
pub fn sgx_ineffective<T>(v: T) -> io::Result<T> {
|
||||
static SGX_INEFFECTIVE_ERROR: AtomicBool = AtomicBool::new(false);
|
||||
if SGX_INEFFECTIVE_ERROR.load(Ordering::Relaxed) {
|
||||
Err(io::Error::new(io::ErrorKind::Other,
|
||||
"operation can't be trusted to have any effect on SGX"))
|
||||
} else {
|
||||
Ok(v)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decode_error_kind(code: i32) -> io::ErrorKind {
|
||||
use fortanix_sgx_abi::Error;
|
||||
|
||||
// FIXME: not sure how to make sure all variants of Error are covered
|
||||
if code == Error::NotFound as _ {
|
||||
io::ErrorKind::NotFound
|
||||
} else if code == Error::PermissionDenied as _ {
|
||||
io::ErrorKind::PermissionDenied
|
||||
} else if code == Error::ConnectionRefused as _ {
|
||||
io::ErrorKind::ConnectionRefused
|
||||
} else if code == Error::ConnectionReset as _ {
|
||||
io::ErrorKind::ConnectionReset
|
||||
} else if code == Error::ConnectionAborted as _ {
|
||||
io::ErrorKind::ConnectionAborted
|
||||
} else if code == Error::NotConnected as _ {
|
||||
io::ErrorKind::NotConnected
|
||||
} else if code == Error::AddrInUse as _ {
|
||||
io::ErrorKind::AddrInUse
|
||||
} else if code == Error::AddrNotAvailable as _ {
|
||||
io::ErrorKind::AddrNotAvailable
|
||||
} else if code == Error::BrokenPipe as _ {
|
||||
io::ErrorKind::BrokenPipe
|
||||
} else if code == Error::AlreadyExists as _ {
|
||||
io::ErrorKind::AlreadyExists
|
||||
} else if code == Error::WouldBlock as _ {
|
||||
io::ErrorKind::WouldBlock
|
||||
} else if code == Error::InvalidInput as _ {
|
||||
io::ErrorKind::InvalidInput
|
||||
} else if code == Error::InvalidData as _ {
|
||||
io::ErrorKind::InvalidData
|
||||
} else if code == Error::TimedOut as _ {
|
||||
io::ErrorKind::TimedOut
|
||||
} else if code == Error::WriteZero as _ {
|
||||
io::ErrorKind::WriteZero
|
||||
} else if code == Error::Interrupted as _ {
|
||||
io::ErrorKind::Interrupted
|
||||
} else if code == Error::Other as _ {
|
||||
io::ErrorKind::Other
|
||||
} else if code == Error::UnexpectedEof as _ {
|
||||
io::ErrorKind::UnexpectedEof
|
||||
} else {
|
||||
io::ErrorKind::Other
|
||||
}
|
||||
}
|
||||
|
||||
// This enum is used as the storage for a bunch of types which can't actually
|
||||
// exist.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
|
||||
pub enum Void {}
|
||||
|
||||
pub unsafe fn strlen(mut s: *const c_char) -> usize {
|
||||
let mut n = 0;
|
||||
while *s != 0 {
|
||||
n += 1;
|
||||
s = s.offset(1);
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
pub unsafe fn abort_internal() -> ! {
|
||||
abi::panic::panic_exit()
|
||||
}
|
||||
|
||||
pub fn hashmap_random_keys() -> (u64, u64) {
|
||||
fn rdrand64() -> u64 {
|
||||
unsafe {
|
||||
let mut ret: u64 = ::mem::uninitialized();
|
||||
for _ in 0..10 {
|
||||
if ::arch::x86_64::_rdrand64_step(&mut ret) == 1 {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
panic!("Failed to obtain random data");
|
||||
}
|
||||
}
|
||||
(rdrand64(), rdrand64())
|
||||
}
|
78
src/libstd/sys/sgx/mutex.rs
Normal file
78
src/libstd/sys/sgx/mutex.rs
Normal file
@ -0,0 +1,78 @@
|
||||
// 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 cell::UnsafeCell;
|
||||
|
||||
pub struct Mutex {
|
||||
locked: UnsafeCell<bool>,
|
||||
}
|
||||
|
||||
unsafe impl Send for Mutex {}
|
||||
unsafe impl Sync for Mutex {} // FIXME
|
||||
|
||||
impl Mutex {
|
||||
pub const fn new() -> Mutex {
|
||||
Mutex { locked: UnsafeCell::new(false) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn init(&mut self) {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn lock(&self) {
|
||||
let locked = self.locked.get();
|
||||
assert!(!*locked, "cannot recursively acquire mutex");
|
||||
*locked = true;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn unlock(&self) {
|
||||
*self.locked.get() = false;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn try_lock(&self) -> bool {
|
||||
let locked = self.locked.get();
|
||||
if *locked {
|
||||
false
|
||||
} else {
|
||||
*locked = true;
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn destroy(&self) {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME
|
||||
pub struct ReentrantMutex {
|
||||
}
|
||||
|
||||
impl ReentrantMutex {
|
||||
pub unsafe fn uninitialized() -> ReentrantMutex {
|
||||
ReentrantMutex { }
|
||||
}
|
||||
|
||||
pub unsafe fn init(&mut self) {}
|
||||
|
||||
pub unsafe fn lock(&self) {}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn try_lock(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub unsafe fn unlock(&self) {}
|
||||
|
||||
pub unsafe fn destroy(&self) {}
|
||||
}
|
356
src/libstd/sys/sgx/net.rs
Normal file
356
src/libstd/sys/sgx/net.rs
Normal file
@ -0,0 +1,356 @@
|
||||
// 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};
|
||||
use time::Duration;
|
||||
use sys::{unsupported, Void};
|
||||
use convert::TryFrom;
|
||||
|
||||
pub struct TcpStream(Void);
|
||||
|
||||
impl TcpStream {
|
||||
pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write(&self, _: &[u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn duplicate(&self) -> io::Result<TcpStream> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn nodelay(&self) -> io::Result<bool> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn ttl(&self) -> io::Result<u32> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for TcpStream {
|
||||
fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TcpListener(Void);
|
||||
|
||||
impl TcpListener {
|
||||
pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn duplicate(&self) -> io::Result<TcpListener> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn ttl(&self) -> io::Result<u32> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn only_v6(&self) -> io::Result<bool> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for TcpListener {
|
||||
fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UdpSocket(Void);
|
||||
|
||||
impl UdpSocket {
|
||||
pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn duplicate(&self) -> io::Result<UdpSocket> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn broadcast(&self) -> io::Result<bool> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn multicast_loop_v4(&self) -> io::Result<bool> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn multicast_loop_v6(&self) -> io::Result<bool> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
|
||||
-> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32)
|
||||
-> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
|
||||
-> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32)
|
||||
-> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn ttl(&self) -> io::Result<u32> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn send(&self, _: &[u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for UdpSocket {
|
||||
fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LookupHost(Void);
|
||||
|
||||
impl LookupHost {
|
||||
pub fn port(&self) -> u16 {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for LookupHost {
|
||||
type Item = SocketAddr;
|
||||
fn next(&mut self) -> Option<SocketAddr> {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<&'a str> for LookupHost {
|
||||
type Error = io::Error;
|
||||
|
||||
fn try_from(_v: &'a str) -> io::Result<LookupHost> {
|
||||
unsupported()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
|
||||
type Error = io::Error;
|
||||
|
||||
fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> {
|
||||
unsupported()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(bad_style)]
|
||||
pub mod netc {
|
||||
pub const AF_INET: u8 = 0;
|
||||
pub const AF_INET6: u8 = 1;
|
||||
pub type sa_family_t = u8;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct in_addr {
|
||||
pub s_addr: u32,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct sockaddr_in {
|
||||
pub sin_family: sa_family_t,
|
||||
pub sin_port: u16,
|
||||
pub sin_addr: in_addr,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct in6_addr {
|
||||
pub s6_addr: [u8; 16],
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct sockaddr_in6 {
|
||||
pub sin6_family: sa_family_t,
|
||||
pub sin6_port: u16,
|
||||
pub sin6_addr: in6_addr,
|
||||
pub sin6_flowinfo: u32,
|
||||
pub sin6_scope_id: u32,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct sockaddr {
|
||||
}
|
||||
|
||||
pub type socklen_t = usize;
|
||||
}
|
120
src/libstd/sys/sgx/os.rs
Normal file
120
src/libstd/sys/sgx/os.rs
Normal file
@ -0,0 +1,120 @@
|
||||
// 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;
|
||||
use ffi::{OsString, OsStr};
|
||||
use fmt;
|
||||
use io;
|
||||
use path::{self, PathBuf};
|
||||
use str;
|
||||
use sys::{unsupported, Void, sgx_ineffective, decode_error_kind};
|
||||
|
||||
pub fn errno() -> i32 {
|
||||
RESULT_SUCCESS
|
||||
}
|
||||
|
||||
pub fn error_string(errno: i32) -> String {
|
||||
if errno == RESULT_SUCCESS {
|
||||
"operation succesful".into()
|
||||
} else if ((Error::UserRangeStart as _)..=(Error::UserRangeEnd as _)).contains(&errno) {
|
||||
format!("user-specified error {:08x}", errno)
|
||||
} else {
|
||||
decode_error_kind(errno).as_str().into()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getcwd() -> io::Result<PathBuf> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn chdir(_: &path::Path) -> io::Result<()> {
|
||||
sgx_ineffective(())
|
||||
}
|
||||
|
||||
pub struct SplitPaths<'a>(&'a Void);
|
||||
|
||||
pub fn split_paths(_unparsed: &OsStr) -> SplitPaths {
|
||||
panic!("unsupported")
|
||||
}
|
||||
|
||||
impl<'a> Iterator for SplitPaths<'a> {
|
||||
type Item = PathBuf;
|
||||
fn next(&mut self) -> Option<PathBuf> {
|
||||
match *self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct JoinPathsError;
|
||||
|
||||
pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError>
|
||||
where I: Iterator<Item=T>, T: AsRef<OsStr>
|
||||
{
|
||||
Err(JoinPathsError)
|
||||
}
|
||||
|
||||
impl fmt::Display for JoinPathsError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
"not supported in SGX yet".fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl StdError for JoinPathsError {
|
||||
fn description(&self) -> &str {
|
||||
"not supported in SGX yet"
|
||||
}
|
||||
}
|
||||
|
||||
pub fn current_exe() -> io::Result<PathBuf> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub struct Env;
|
||||
|
||||
impl Iterator for Env {
|
||||
type Item = (OsString, OsString);
|
||||
fn next(&mut self) -> Option<(OsString, OsString)> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn env() -> Env {
|
||||
Env
|
||||
}
|
||||
|
||||
pub fn getenv(_k: &OsStr) -> io::Result<Option<OsString>> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn setenv(_k: &OsStr, _v: &OsStr) -> io::Result<()> {
|
||||
sgx_ineffective(()) // FIXME: this could trigger a panic higher up the stack
|
||||
}
|
||||
|
||||
pub fn unsetenv(_k: &OsStr) -> io::Result<()> {
|
||||
sgx_ineffective(()) // FIXME: this could trigger a panic higher up the stack
|
||||
}
|
||||
|
||||
pub fn temp_dir() -> PathBuf {
|
||||
panic!("no filesystem in SGX")
|
||||
}
|
||||
|
||||
pub fn home_dir() -> Option<PathBuf> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn exit(code: i32) -> ! {
|
||||
super::abi::exit_with_code(code as _)
|
||||
}
|
||||
|
||||
pub fn getpid() -> u32 {
|
||||
panic!("no pids in SGX")
|
||||
}
|
189
src/libstd/sys/sgx/os_str.rs
Normal file
189
src/libstd/sys/sgx/os_str.rs
Normal file
@ -0,0 +1,189 @@
|
||||
// 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]`.
|
||||
|
||||
use borrow::Cow;
|
||||
use fmt;
|
||||
use str;
|
||||
use mem;
|
||||
use rc::Rc;
|
||||
use sync::Arc;
|
||||
use sys_common::{AsInner, IntoInner};
|
||||
use sys_common::bytestring::debug_fmt_bytestring;
|
||||
use core::str::lossy::Utf8Lossy;
|
||||
|
||||
#[derive(Clone, Hash)]
|
||||
pub struct Buf {
|
||||
pub inner: Vec<u8>
|
||||
}
|
||||
|
||||
pub struct Slice {
|
||||
pub inner: [u8]
|
||||
}
|
||||
|
||||
impl fmt::Debug for Slice {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
debug_fmt_bytestring(&self.inner, formatter)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Slice {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Display::fmt(&Utf8Lossy::from_bytes(&self.inner), formatter)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Buf {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Debug::fmt(self.as_slice(), formatter)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Buf {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Display::fmt(self.as_slice(), formatter)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoInner<Vec<u8>> for Buf {
|
||||
fn into_inner(self) -> Vec<u8> {
|
||||
self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl AsInner<[u8]> for Buf {
|
||||
fn as_inner(&self) -> &[u8] {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Buf {
|
||||
pub fn from_string(s: String) -> Buf {
|
||||
Buf { inner: s.into_bytes() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn with_capacity(capacity: usize) -> Buf {
|
||||
Buf {
|
||||
inner: Vec::with_capacity(capacity)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn clear(&mut self) {
|
||||
self.inner.clear()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn capacity(&self) -> usize {
|
||||
self.inner.capacity()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn reserve(&mut self, additional: usize) {
|
||||
self.inner.reserve(additional)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn reserve_exact(&mut self, additional: usize) {
|
||||
self.inner.reserve_exact(additional)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn shrink_to_fit(&mut self) {
|
||||
self.inner.shrink_to_fit()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn shrink_to(&mut self, min_capacity: usize) {
|
||||
self.inner.shrink_to(min_capacity)
|
||||
}
|
||||
|
||||
pub fn as_slice(&self) -> &Slice {
|
||||
unsafe { mem::transmute(&*self.inner) }
|
||||
}
|
||||
|
||||
pub fn into_string(self) -> Result<String, Buf> {
|
||||
String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() } )
|
||||
}
|
||||
|
||||
pub fn push_slice(&mut self, s: &Slice) {
|
||||
self.inner.extend_from_slice(&s.inner)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_box(self) -> Box<Slice> {
|
||||
unsafe { mem::transmute(self.inner.into_boxed_slice()) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_box(boxed: Box<Slice>) -> Buf {
|
||||
let inner: Box<[u8]> = unsafe { mem::transmute(boxed) };
|
||||
Buf { inner: inner.into_vec() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_arc(&self) -> Arc<Slice> {
|
||||
self.as_slice().into_arc()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_rc(&self) -> Rc<Slice> {
|
||||
self.as_slice().into_rc()
|
||||
}
|
||||
}
|
||||
|
||||
impl Slice {
|
||||
fn from_u8_slice(s: &[u8]) -> &Slice {
|
||||
unsafe { mem::transmute(s) }
|
||||
}
|
||||
|
||||
pub fn from_str(s: &str) -> &Slice {
|
||||
Slice::from_u8_slice(s.as_bytes())
|
||||
}
|
||||
|
||||
pub fn to_str(&self) -> Option<&str> {
|
||||
str::from_utf8(&self.inner).ok()
|
||||
}
|
||||
|
||||
pub fn to_string_lossy(&self) -> Cow<str> {
|
||||
String::from_utf8_lossy(&self.inner)
|
||||
}
|
||||
|
||||
pub fn to_owned(&self) -> Buf {
|
||||
Buf { inner: self.inner.to_vec() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_box(&self) -> Box<Slice> {
|
||||
let boxed: Box<[u8]> = self.inner.into();
|
||||
unsafe { mem::transmute(boxed) }
|
||||
}
|
||||
|
||||
pub fn empty_box() -> Box<Slice> {
|
||||
let boxed: Box<[u8]> = Default::default();
|
||||
unsafe { mem::transmute(boxed) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_arc(&self) -> Arc<Slice> {
|
||||
let arc: Arc<[u8]> = Arc::from(&self.inner);
|
||||
unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_rc(&self) -> Rc<Slice> {
|
||||
let rc: Rc<[u8]> = Rc::from(&self.inner);
|
||||
unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
|
||||
}
|
||||
}
|
29
src/libstd/sys/sgx/path.rs
Normal file
29
src/libstd/sys/sgx/path.rs
Normal file
@ -0,0 +1,29 @@
|
||||
// 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;
|
||||
|
||||
#[inline]
|
||||
pub fn is_sep_byte(b: u8) -> bool {
|
||||
b == b'/'
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_verbatim_sep(b: u8) -> bool {
|
||||
b == b'/'
|
||||
}
|
||||
|
||||
pub fn parse_prefix(_: &OsStr) -> Option<Prefix> {
|
||||
None
|
||||
}
|
||||
|
||||
pub const MAIN_SEP_STR: &'static str = "/";
|
||||
pub const MAIN_SEP: char = '/';
|
35
src/libstd/sys/sgx/pipe.rs
Normal file
35
src/libstd/sys/sgx/pipe.rs
Normal file
@ -0,0 +1,35 @@
|
||||
// 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;
|
||||
|
||||
pub struct AnonPipe(Void);
|
||||
|
||||
impl AnonPipe {
|
||||
pub fn read(&self, _buf: &mut [u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn diverge(&self) -> ! {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read2(p1: AnonPipe,
|
||||
_v1: &mut Vec<u8>,
|
||||
_p2: AnonPipe,
|
||||
_v2: &mut Vec<u8>) -> io::Result<()> {
|
||||
match p1.0 {}
|
||||
}
|
162
src/libstd/sys/sgx/process.rs
Normal file
162
src/libstd/sys/sgx/process.rs
Normal file
@ -0,0 +1,162 @@
|
||||
// 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;
|
||||
use sys::fs::File;
|
||||
use sys::pipe::AnonPipe;
|
||||
use sys::{unsupported, Void};
|
||||
use sys_common::process::{CommandEnv, DefaultEnvKey};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Command
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub struct Command {
|
||||
env: CommandEnv<DefaultEnvKey>
|
||||
}
|
||||
|
||||
// passed back to std::process with the pipes connected to the child, if any
|
||||
// were requested
|
||||
pub struct StdioPipes {
|
||||
pub stdin: Option<AnonPipe>,
|
||||
pub stdout: Option<AnonPipe>,
|
||||
pub stderr: Option<AnonPipe>,
|
||||
}
|
||||
|
||||
pub enum Stdio {
|
||||
Inherit,
|
||||
Null,
|
||||
MakePipe,
|
||||
}
|
||||
|
||||
impl Command {
|
||||
pub fn new(_program: &OsStr) -> Command {
|
||||
Command {
|
||||
env: Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn arg(&mut self, _arg: &OsStr) {
|
||||
}
|
||||
|
||||
pub fn env_mut(&mut self) -> &mut CommandEnv<DefaultEnvKey> {
|
||||
&mut self.env
|
||||
}
|
||||
|
||||
pub fn cwd(&mut self, _dir: &OsStr) {
|
||||
}
|
||||
|
||||
pub fn stdin(&mut self, _stdin: Stdio) {
|
||||
}
|
||||
|
||||
pub fn stdout(&mut self, _stdout: Stdio) {
|
||||
}
|
||||
|
||||
pub fn stderr(&mut self, _stderr: Stdio) {
|
||||
}
|
||||
|
||||
pub fn spawn(&mut self, _default: Stdio, _needs_stdin: bool)
|
||||
-> io::Result<(Process, StdioPipes)> {
|
||||
unsupported()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AnonPipe> for Stdio {
|
||||
fn from(pipe: AnonPipe) -> Stdio {
|
||||
pipe.diverge()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<File> for Stdio {
|
||||
fn from(file: File) -> Stdio {
|
||||
file.diverge()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Command {
|
||||
fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ExitStatus(Void);
|
||||
|
||||
impl ExitStatus {
|
||||
pub fn success(&self) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn code(&self) -> Option<i32> {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for ExitStatus {
|
||||
fn clone(&self) -> ExitStatus {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl Copy for ExitStatus {}
|
||||
|
||||
impl PartialEq for ExitStatus {
|
||||
fn eq(&self, _other: &ExitStatus) -> bool {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for ExitStatus {
|
||||
}
|
||||
|
||||
impl fmt::Debug for ExitStatus {
|
||||
fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ExitStatus {
|
||||
fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||
pub struct ExitCode(bool);
|
||||
|
||||
impl ExitCode {
|
||||
pub const SUCCESS: ExitCode = ExitCode(false);
|
||||
pub const FAILURE: ExitCode = ExitCode(true);
|
||||
|
||||
pub fn as_i32(&self) -> i32 {
|
||||
self.0 as i32
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Process(Void);
|
||||
|
||||
impl Process {
|
||||
pub fn id(&self) -> u32 {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn kill(&mut self) -> io::Result<()> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn wait(&mut self) -> io::Result<ExitStatus> {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
82
src/libstd/sys/sgx/rwlock.rs
Normal file
82
src/libstd/sys/sgx/rwlock.rs
Normal file
@ -0,0 +1,82 @@
|
||||
// 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 cell::UnsafeCell;
|
||||
|
||||
pub struct RWLock {
|
||||
mode: UnsafeCell<isize>,
|
||||
}
|
||||
|
||||
unsafe impl Send for RWLock {}
|
||||
unsafe impl Sync for RWLock {} // FIXME
|
||||
|
||||
impl RWLock {
|
||||
pub const fn new() -> RWLock {
|
||||
RWLock {
|
||||
mode: UnsafeCell::new(0),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn read(&self) {
|
||||
let mode = self.mode.get();
|
||||
if *mode >= 0 {
|
||||
*mode += 1;
|
||||
} else {
|
||||
rtabort!("rwlock locked for writing");
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn try_read(&self) -> bool {
|
||||
let mode = self.mode.get();
|
||||
if *mode >= 0 {
|
||||
*mode += 1;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn write(&self) {
|
||||
let mode = self.mode.get();
|
||||
if *mode == 0 {
|
||||
*mode = -1;
|
||||
} else {
|
||||
rtabort!("rwlock locked for reading")
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn try_write(&self) -> bool {
|
||||
let mode = self.mode.get();
|
||||
if *mode == 0 {
|
||||
*mode = -1;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn read_unlock(&self) {
|
||||
*self.mode.get() -= 1;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn write_unlock(&self) {
|
||||
*self.mode.get() += 1;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn destroy(&self) {
|
||||
}
|
||||
}
|
23
src/libstd/sys/sgx/stack_overflow.rs
Normal file
23
src/libstd/sys/sgx/stack_overflow.rs
Normal file
@ -0,0 +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.
|
||||
|
||||
pub struct Handler;
|
||||
|
||||
impl Handler {
|
||||
pub unsafe fn new() -> Handler {
|
||||
Handler
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn init() {
|
||||
}
|
||||
|
||||
pub unsafe fn cleanup() {
|
||||
}
|
73
src/libstd/sys/sgx/stdio.rs
Normal file
73
src/libstd/sys/sgx/stdio.rs
Normal file
@ -0,0 +1,73 @@
|
||||
// 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;
|
||||
|
||||
pub struct Stdin;
|
||||
pub struct Stdout;
|
||||
pub struct Stderr;
|
||||
|
||||
impl Stdin {
|
||||
pub fn new() -> io::Result<Stdin> {
|
||||
Ok(Stdin)
|
||||
}
|
||||
|
||||
pub fn read(&self, _data: &mut [u8]) -> io::Result<usize> {
|
||||
unsupported()
|
||||
}
|
||||
}
|
||||
|
||||
impl Stdout {
|
||||
pub fn new() -> io::Result<Stdout> {
|
||||
Ok(Stdout)
|
||||
}
|
||||
|
||||
pub fn write(&self, _data: &[u8]) -> io::Result<usize> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn flush(&self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Stderr {
|
||||
pub fn new() -> io::Result<Stderr> {
|
||||
Ok(Stderr)
|
||||
}
|
||||
|
||||
pub fn write(&self, _data: &[u8]) -> io::Result<usize> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn flush(&self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Write for Stderr {
|
||||
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
|
||||
(&*self).write(data)
|
||||
}
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
(&*self).flush()
|
||||
}
|
||||
}
|
||||
|
||||
pub const STDIN_BUF_SIZE: usize = 0;
|
||||
|
||||
pub fn is_ebadf(_err: &io::Error) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn panic_output() -> Option<impl io::Write> {
|
||||
super::abi::panic::SgxPanicOutput::new()
|
||||
}
|
51
src/libstd/sys/sgx/thread.rs
Normal file
51
src/libstd/sys/sgx/thread.rs
Normal file
@ -0,0 +1,51 @@
|
||||
// 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;
|
||||
use sys::{unsupported, Void};
|
||||
use time::Duration;
|
||||
|
||||
pub struct Thread(Void);
|
||||
|
||||
pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
|
||||
|
||||
impl Thread {
|
||||
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
|
||||
pub unsafe fn new(_stack: usize, _p: Box<dyn FnBox()>)
|
||||
-> io::Result<Thread>
|
||||
{
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn yield_now() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
pub fn set_name(_name: &CStr) {
|
||||
// nope
|
||||
}
|
||||
|
||||
pub fn sleep(_dur: Duration) {
|
||||
panic!("can't sleep");
|
||||
}
|
||||
|
||||
pub fn join(self) {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod guard {
|
||||
pub type Guard = !;
|
||||
pub unsafe fn current() -> Option<Guard> { None }
|
||||
pub unsafe fn init() -> Option<Guard> { None }
|
||||
pub unsafe fn deinit() {}
|
||||
}
|
50
src/libstd/sys/sgx/thread_local.rs
Normal file
50
src/libstd/sys/sgx/thread_local.rs
Normal file
@ -0,0 +1,50 @@
|
||||
// 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::Box;
|
||||
use ptr;
|
||||
|
||||
pub type Key = usize;
|
||||
|
||||
struct Allocated {
|
||||
value: *mut u8,
|
||||
dtor: Option<unsafe extern fn(*mut u8)>,
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn create(dtor: Option<unsafe extern fn(*mut u8)>) -> Key {
|
||||
Box::into_raw(Box::new(Allocated {
|
||||
value: ptr::null_mut(),
|
||||
dtor,
|
||||
})) as usize
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn set(key: Key, value: *mut u8) {
|
||||
(*(key as *mut Allocated)).value = value;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn get(key: Key) -> *mut u8 {
|
||||
(*(key as *mut Allocated)).value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn destroy(key: Key) {
|
||||
let key = Box::from_raw(key as *mut Allocated);
|
||||
if let Some(f) = key.dtor {
|
||||
f(key.value);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn requires_synchronized_create() -> bool {
|
||||
false
|
||||
}
|
61
src/libstd/sys/sgx/time.rs
Normal file
61
src/libstd/sys/sgx/time.rs
Normal file
@ -0,0 +1,61 @@
|
||||
// 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 sys::unsupported_err;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
|
||||
pub struct Instant(Duration);
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
|
||||
pub struct SystemTime(Duration);
|
||||
|
||||
pub const UNIX_EPOCH: SystemTime = SystemTime(Duration::from_secs(0));
|
||||
|
||||
impl Instant {
|
||||
pub fn now() -> Instant {
|
||||
panic!("{}", unsupported_err());
|
||||
}
|
||||
|
||||
pub fn sub_instant(&self, other: &Instant) -> Duration {
|
||||
self.0 - other.0
|
||||
}
|
||||
|
||||
pub fn add_duration(&self, other: &Duration) -> Instant {
|
||||
Instant(self.0 + *other)
|
||||
}
|
||||
|
||||
pub fn sub_duration(&self, other: &Duration) -> Instant {
|
||||
Instant(self.0 - *other)
|
||||
}
|
||||
}
|
||||
|
||||
impl SystemTime {
|
||||
pub fn now() -> SystemTime {
|
||||
panic!("{}", unsupported_err());
|
||||
}
|
||||
|
||||
pub fn sub_time(&self, other: &SystemTime)
|
||||
-> Result<Duration, Duration> {
|
||||
self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
|
||||
}
|
||||
|
||||
pub fn add_duration(&self, other: &Duration) -> SystemTime {
|
||||
SystemTime(self.0 + *other)
|
||||
}
|
||||
|
||||
pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
|
||||
self.0.checked_add(*other).map(|d| SystemTime(d))
|
||||
}
|
||||
|
||||
pub fn sub_duration(&self, other: &Duration) -> SystemTime {
|
||||
SystemTime(self.0 - *other)
|
||||
}
|
||||
}
|
@ -57,9 +57,11 @@ pub mod bytestring;
|
||||
pub mod process;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(target_os = "cloudabi", target_os = "l4re", target_os = "redox"))] {
|
||||
pub use sys::net;
|
||||
} else if #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] {
|
||||
if #[cfg(any(target_os = "cloudabi",
|
||||
target_os = "l4re",
|
||||
target_os = "redox",
|
||||
all(target_arch = "wasm32", not(target_os = "emscripten")),
|
||||
target_env = "sgx"))] {
|
||||
pub use sys::net;
|
||||
} else {
|
||||
pub mod net;
|
||||
|
@ -1018,10 +1018,12 @@ fn use_color(opts: &TestOpts) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "cloudabi", target_os = "redox",
|
||||
all(target_arch = "wasm32", not(target_os = "emscripten"))))]
|
||||
#[cfg(any(target_os = "cloudabi",
|
||||
target_os = "redox",
|
||||
all(target_arch = "wasm32", not(target_os = "emscripten")),
|
||||
target_env = "sgx"))]
|
||||
fn stdout_isatty() -> bool {
|
||||
// FIXME: Implement isatty on Redox
|
||||
// FIXME: Implement isatty on Redox and SGX
|
||||
false
|
||||
}
|
||||
#[cfg(unix)]
|
||||
@ -1246,7 +1248,7 @@ fn get_concurrency() -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
|
||||
#[cfg(any(all(target_arch = "wasm32", not(target_os = "emscripten")), target_env = "sgx"))]
|
||||
fn num_cpus() -> usize {
|
||||
1
|
||||
}
|
||||
|
@ -26,7 +26,10 @@ mod macros;
|
||||
cfg_if! {
|
||||
if #[cfg(target_env = "msvc")] {
|
||||
// no extra unwinder support needed
|
||||
} else if #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] {
|
||||
} else if #[cfg(any(
|
||||
all(target_arch = "wasm32", not(target_os = "emscripten")),
|
||||
target_env = "sgx"
|
||||
))] {
|
||||
// no unwinder on the system!
|
||||
} else {
|
||||
extern crate libc;
|
||||
|
1
src/rust-sgx
Submodule
1
src/rust-sgx
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 9656260888095f44830641ca7bb3da609a793451
|
14
src/rustc/fortanix-sgx-abi_shim/Cargo.toml
Normal file
14
src/rustc/fortanix-sgx-abi_shim/Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "fortanix-sgx-abi"
|
||||
version = "0.0.0"
|
||||
authors = ["The Rust Project Developers"]
|
||||
|
||||
[lib]
|
||||
path = "../../rust-sgx/fortanix-sgx-abi/src/lib.rs"
|
||||
test = false
|
||||
bench = false
|
||||
doc = false
|
||||
|
||||
[dependencies]
|
||||
core = { path = "../../libcore" }
|
||||
compiler_builtins = { path = "../../rustc/compiler_builtins_shim" }
|
@ -1 +1 @@
|
||||
Subproject commit 0309be1ade6bf61066f2c69f77ac3567b7dc31b5
|
||||
Subproject commit 5e628c5120c619a22799187371f057ec41e06f87
|
@ -76,6 +76,7 @@ fn filter_dirs(path: &Path) -> bool {
|
||||
"src/tools/lldb",
|
||||
"src/target",
|
||||
"src/stdsimd",
|
||||
"src/rust-sgx",
|
||||
"target",
|
||||
"vendor",
|
||||
];
|
||||
|
Loading…
Reference in New Issue
Block a user