Auto merge of #59136 - jethrogb:jb/sgx-std-test, r=sanxiyn

SGX target: fix std unit tests

This fixes some tests and some code in the SGX sys implementation to make the `std` unit test suite pass.

#59009 must be merged first.
This commit is contained in:
bors 2019-03-26 01:48:34 +00:00
commit 54479c624c
27 changed files with 236 additions and 94 deletions

View file

@ -72,3 +72,7 @@ wasm-bindgen-threads = []
# https://github.com/rust-lang-nursery/stdsimd/blob/master/crates/std_detect/Cargo.toml
std_detect_file_io = []
std_detect_dlsym_getauxval = []
[package.metadata.fortanix-sgx]
# Maximum possible number of threads when testing
threads = 125

View file

@ -975,7 +975,7 @@ mod tests {
use crate::path::Path;
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
#[cfg_attr(any(target_os = "emscripten", target_env = "sgx"), ignore)]
fn test_self_exe_path() {
let path = current_exe();
assert!(path.is_ok());
@ -989,6 +989,7 @@ mod tests {
fn test() {
assert!((!Path::new("test-path").is_absolute()));
#[cfg(not(target_env = "sgx"))]
current_dir().unwrap();
}

View file

@ -2095,7 +2095,7 @@ impl AsInnerMut<fs_imp::DirBuilder> for DirBuilder {
}
}
#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))]
#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))]
mod tests {
use crate::io::prelude::*;

View file

@ -941,7 +941,10 @@ mod tests {
assert_eq!(Ok(vec![a]), tsa(("2a02:6b8:0:1::1", 53)));
let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924);
#[cfg(not(target_env = "sgx"))]
assert!(tsa(("localhost", 23924)).unwrap().contains(&a));
#[cfg(target_env = "sgx")]
let _ = a;
}
#[test]
@ -953,7 +956,10 @@ mod tests {
assert_eq!(Ok(vec![a]), tsa("[2a02:6b8:0:1::1]:53"));
let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924);
#[cfg(not(target_env = "sgx"))]
assert!(tsa("localhost:23924").unwrap().contains(&a));
#[cfg(target_env = "sgx")]
let _ = a;
}
#[test]

View file

@ -929,12 +929,12 @@ impl fmt::Debug for TcpListener {
#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))]
mod tests {
use crate::fmt;
use crate::io::{ErrorKind, IoVec, IoVecMut};
use crate::io::prelude::*;
use crate::net::*;
use crate::net::test::{next_test_ip4, next_test_ip6};
use crate::sync::mpsc::channel;
use crate::sys_common::AsInner;
use crate::time::{Instant, Duration};
use crate::thread;
@ -1129,7 +1129,7 @@ mod tests {
connect(i + 1, addr);
t!(stream.write(&[i as u8]));
});
t.join().ok().unwrap();
t.join().ok().expect("thread panicked");
}
}
@ -1162,7 +1162,7 @@ mod tests {
connect(i + 1, addr);
t!(stream.write(&[99]));
});
t.join().ok().unwrap();
t.join().ok().expect("thread panicked");
}
}
@ -1377,6 +1377,8 @@ mod tests {
}
#[test]
// FIXME: https://github.com/fortanix/rust-sgx/issues/110
#[cfg_attr(target_env = "sgx", ignore)]
fn shutdown_smoke() {
each_ip(&mut |addr| {
let a = t!(TcpListener::bind(&addr));
@ -1397,6 +1399,8 @@ mod tests {
}
#[test]
// FIXME: https://github.com/fortanix/rust-sgx/issues/110
#[cfg_attr(target_env = "sgx", ignore)]
fn close_readwrite_smoke() {
each_ip(&mut |addr| {
let a = t!(TcpListener::bind(&addr));
@ -1550,30 +1554,51 @@ mod tests {
#[test]
fn debug() {
let name = if cfg!(windows) {"socket"} else {"fd"};
#[cfg(not(target_env = "sgx"))]
fn render_socket_addr<'a>(addr: &'a SocketAddr) -> impl fmt::Debug + 'a {
addr
}
#[cfg(target_env = "sgx")]
fn render_socket_addr<'a>(addr: &'a SocketAddr) -> impl fmt::Debug + 'a {
addr.to_string()
}
#[cfg(unix)]
use crate::os::unix::io::AsRawFd;
#[cfg(target_env = "sgx")]
use crate::os::fortanix_sgx::io::AsRawFd;
#[cfg(not(windows))]
fn render_inner(addr: &dyn AsRawFd) -> impl fmt::Debug {
addr.as_raw_fd()
}
#[cfg(windows)]
fn render_inner(addr: &dyn crate::os::windows::io::AsRawSocket) -> impl fmt::Debug {
addr.as_raw_socket()
}
let inner_name = if cfg!(windows) {"socket"} else {"fd"};
let socket_addr = next_test_ip4();
let listener = t!(TcpListener::bind(&socket_addr));
let listener_inner = listener.0.socket().as_inner();
let compare = format!("TcpListener {{ addr: {:?}, {}: {:?} }}",
socket_addr, name, listener_inner);
render_socket_addr(&socket_addr),
inner_name,
render_inner(&listener));
assert_eq!(format!("{:?}", listener), compare);
let stream = t!(TcpStream::connect(&("localhost",
socket_addr.port())));
let stream_inner = stream.0.socket().as_inner();
let compare = format!("TcpStream {{ addr: {:?}, \
peer: {:?}, {}: {:?} }}",
stream.local_addr().unwrap(),
stream.peer_addr().unwrap(),
name,
stream_inner);
let stream = t!(TcpStream::connect(&("localhost", socket_addr.port())));
let compare = format!("TcpStream {{ addr: {:?}, peer: {:?}, {}: {:?} }}",
render_socket_addr(&stream.local_addr().unwrap()),
render_socket_addr(&stream.peer_addr().unwrap()),
inner_name,
render_inner(&stream));
assert_eq!(format!("{:?}", stream), compare);
}
// FIXME: re-enabled bitrig/openbsd tests once their socket timeout code
// no longer has rounding errors.
#[cfg_attr(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"), ignore)]
#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
#[test]
fn timeouts() {
let addr = next_test_ip4();
@ -1601,6 +1626,7 @@ mod tests {
}
#[test]
#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn test_read_timeout() {
let addr = next_test_ip4();
let listener = t!(TcpListener::bind(&addr));
@ -1618,6 +1644,7 @@ mod tests {
}
#[test]
#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn test_read_with_timeout() {
let addr = next_test_ip4();
let listener = t!(TcpListener::bind(&addr));
@ -1661,6 +1688,7 @@ mod tests {
}
#[test]
#[cfg_attr(target_env = "sgx", ignore)]
fn nodelay() {
let addr = next_test_ip4();
let _listener = t!(TcpListener::bind(&addr));
@ -1675,6 +1703,7 @@ mod tests {
}
#[test]
#[cfg_attr(target_env = "sgx", ignore)]
fn ttl() {
let ttl = 100;
@ -1691,6 +1720,7 @@ mod tests {
}
#[test]
#[cfg_attr(target_env = "sgx", ignore)]
fn set_nonblocking() {
let addr = next_test_ip4();
let listener = t!(TcpListener::bind(&addr));
@ -1712,6 +1742,7 @@ mod tests {
}
#[test]
#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn peek() {
each_ip(&mut |addr| {
let (txdone, rxdone) = channel();
@ -1743,6 +1774,7 @@ mod tests {
}
#[test]
#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn connect_timeout_valid() {
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let addr = listener.local_addr().unwrap();

View file

@ -36,12 +36,16 @@ pub fn tsa<A: ToSocketAddrs>(a: A) -> Result<Vec<SocketAddr>, String> {
// all want to use ports. This function figures out which workspace
// it is running in and assigns a port range based on it.
fn base_port() -> u16 {
let cwd = env::current_dir().unwrap();
let cwd = if cfg!(target_env = "sgx") {
String::from("sgx")
} else {
env::current_dir().unwrap().into_os_string().into_string().unwrap()
};
let dirs = ["32-opt", "32-nopt",
"musl-64-opt", "cross-opt",
"64-opt", "64-nopt", "64-opt-vg", "64-debug-opt",
"all-opt", "snap3", "dist"];
"all-opt", "snap3", "dist", "sgx"];
dirs.iter().enumerate().find(|&(_, dir)| {
cwd.to_str().unwrap().contains(dir)
cwd.contains(dir)
}).map(|p| p.0).unwrap_or(0) as u16 * 1000 + 19600
}

View file

@ -837,7 +837,7 @@ impl fmt::Debug for UdpSocket {
}
}
#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))]
#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))]
mod tests {
use crate::io::ErrorKind;
use crate::net::*;

View file

@ -3801,7 +3801,7 @@ mod tests {
});
);
if cfg!(unix) {
if cfg!(unix) || cfg!(all(target_env = "sgx", target_vendor = "fortanix")) {
tp!("", "foo", "foo");
tp!("foo", "bar", "foo/bar");
tp!("foo/", "bar", "foo/bar");
@ -3960,7 +3960,7 @@ mod tests {
tfn!("foo", "bar", "bar");
tfn!("foo", "", "");
tfn!("", "foo", "foo");
if cfg!(unix) {
if cfg!(unix) || cfg!(all(target_env = "sgx", target_vendor = "fortanix")) {
tfn!(".", "foo", "./foo");
tfn!("foo/", "bar", "bar");
tfn!("foo/.", "bar", "bar");

View file

@ -1621,7 +1621,7 @@ impl Termination for ExitCode {
}
}
#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))]
#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))]
mod tests {
use crate::io::prelude::*;

View file

@ -705,6 +705,7 @@ mod tests {
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn wait_timeout_wait() {
let m = Arc::new(Mutex::new(()));
let c = Arc::new(Condvar::new());
@ -724,6 +725,7 @@ mod tests {
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn wait_timeout_until_wait() {
let m = Arc::new(Mutex::new(()));
let c = Arc::new(Condvar::new());
@ -748,6 +750,7 @@ mod tests {
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn wait_timeout_until_wake() {
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair_copy = pair.clone();
@ -771,6 +774,7 @@ mod tests {
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn wait_timeout_wake() {
let m = Arc::new(Mutex::new(()));
let c = Arc::new(Condvar::new());

View file

@ -1951,7 +1951,7 @@ mod tests {
for _ in 0..10000 {
assert_eq!(rx.recv().unwrap(), 1);
}
t.join().ok().unwrap();
t.join().ok().expect("thread panicked");
}
#[test]
@ -1977,7 +1977,7 @@ mod tests {
});
}
drop(tx);
t.join().ok().unwrap();
t.join().ok().expect("thread panicked");
}
#[test]
@ -1996,8 +1996,8 @@ mod tests {
tx2.send(1).unwrap();
}
});
t1.join().ok().unwrap();
t2.join().ok().unwrap();
t1.join().ok().expect("thread panicked");
t2.join().ok().expect("thread panicked");
}
#[test]
@ -2011,7 +2011,7 @@ mod tests {
for _ in 0..40 {
tx.send(1).unwrap();
}
t.join().ok().unwrap();
t.join().ok().expect("thread panicked");
}
#[test]
@ -2026,8 +2026,8 @@ mod tests {
tx1.send(1).unwrap();
assert_eq!(rx2.recv().unwrap(), 2);
});
t1.join().ok().unwrap();
t2.join().ok().unwrap();
t1.join().ok().expect("thread panicked");
t2.join().ok().expect("thread panicked");
}
#[test]
@ -2225,6 +2225,7 @@ mod tests {
}
#[test]
#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn oneshot_single_thread_recv_timeout() {
let (tx, rx) = channel();
tx.send(()).unwrap();
@ -2235,6 +2236,7 @@ mod tests {
}
#[test]
#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn stress_recv_timeout_two_threads() {
let (tx, rx) = channel();
let stress = stress_factor() + 100;
@ -2265,6 +2267,7 @@ mod tests {
}
#[test]
#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn recv_timeout_upgrade() {
let (tx, rx) = channel::<()>();
let timeout = Duration::from_millis(1);
@ -2276,6 +2279,7 @@ mod tests {
}
#[test]
#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn stress_recv_timeout_shared() {
let (tx, rx) = channel();
let stress = stress_factor() + 100;
@ -2306,6 +2310,7 @@ mod tests {
}
#[test]
#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn very_long_recv_timeout_wont_panic() {
let (tx, rx) = channel::<()>();
let join_handle = thread::spawn(move || {
@ -2325,6 +2330,7 @@ mod tests {
}
#[test]
#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn shared_recv_timeout() {
let (tx, rx) = channel();
let total = 5;
@ -2550,6 +2556,7 @@ mod sync_tests {
}
#[test]
#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn recv_timeout() {
let (tx, rx) = sync_channel::<i32>(1);
assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Err(RecvTimeoutError::Timeout));
@ -2639,6 +2646,7 @@ mod sync_tests {
}
#[test]
#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn stress_recv_timeout_two_threads() {
let (tx, rx) = sync_channel::<i32>(0);
@ -2662,6 +2670,7 @@ mod sync_tests {
}
#[test]
#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn stress_recv_timeout_shared() {
const AMT: u32 = 1000;
const NTHREADS: u32 = 8;

View file

@ -1,3 +1,5 @@
#![cfg_attr(test, allow(unused))] // RT initialization logic is not compiled for test
use core::sync::atomic::{AtomicUsize, Ordering};
use crate::io::Write;
@ -12,8 +14,10 @@ pub mod tls;
#[macro_use]
pub mod usercalls;
#[cfg(not(test))]
global_asm!(include_str!("entry.S"));
#[cfg(not(test))]
#[no_mangle]
unsafe extern "C" fn tcs_init(secondary: bool) {
// Be very careful when changing this code: it runs before the binary has been
@ -48,6 +52,7 @@ unsafe extern "C" fn tcs_init(secondary: bool) {
// 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
#[cfg(not(test))]
#[no_mangle]
extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64) -> (u64, u64) {
// FIXME: how to support TLS in library mode?

View file

@ -49,7 +49,7 @@ impl Write for SgxPanicOutput {
}
}
#[no_mangle]
#[cfg_attr(not(test), no_mangle)]
pub extern "C" fn panic_msg(msg: &str) -> ! {
let _ = SgxPanicOutput::new().map(|mut out| out.write(msg.as_bytes()));
usercalls::exit(true)

View file

@ -10,45 +10,16 @@ const USIZE_BITS: usize = 64;
const TLS_KEYS: usize = 128; // Same as POSIX minimum
const TLS_KEYS_BITSET_SIZE: usize = (TLS_KEYS + (USIZE_BITS - 1)) / USIZE_BITS;
#[cfg_attr(test, linkage = "available_externally")]
#[export_name = "_ZN16__rust_internals3std3sys3sgx3abi3tls14TLS_KEY_IN_USEE"]
static TLS_KEY_IN_USE: SyncBitset = SYNC_BITSET_INIT;
macro_rules! dup {
((* $($exp:tt)*) $($val:tt)*) => (dup!( ($($exp)*) $($val)* $($val)* ));
(() $($val:tt)*) => ([$($val),*])
}
static TLS_DESTRUCTOR: [AtomicUsize; TLS_KEYS] = [
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
];
#[cfg_attr(test, linkage = "available_externally")]
#[export_name = "_ZN16__rust_internals3std3sys3sgx3abi3tls14TLS_DESTRUCTORE"]
static TLS_DESTRUCTOR: [AtomicUsize; TLS_KEYS] = dup!((* * * * * * *) (AtomicUsize::new(0)));
extern "C" {
fn get_tls_ptr() -> *const u8;

View file

@ -188,8 +188,13 @@ impl<T: ?Sized> User<T> where T: UserSafe {
// from outside as obtained by `super::alloc`.
fn new_uninit_bytes(size: usize) -> Self {
unsafe {
let ptr = super::alloc(size, T::align_of()).expect("User memory allocation failed");
User(NonNull::new_userref(T::from_raw_sized(ptr as _, size)))
// Mustn't call alloc with size 0.
let ptr = if size > 0 {
super::alloc(size, T::align_of()).expect("User memory allocation failed") as _
} else {
T::align_of() as _ // dangling pointer ok for size 0
};
User(NonNull::new_userref(T::from_raw_sized(ptr, size)))
}
}

View file

@ -4,6 +4,8 @@ use super::waitqueue::SpinMutex;
// Using a SpinMutex because we never want to exit the enclave waiting for the
// allocator.
#[cfg_attr(test, linkage = "available_externally")]
#[export_name = "_ZN16__rust_internals3std3sys3sgx5alloc8DLMALLOCE"]
static DLMALLOC: SpinMutex<dlmalloc::Dlmalloc> = SpinMutex::new(dlmalloc::DLMALLOC_INIT);
#[stable(feature = "alloc_system_type", since = "1.28.0")]

View file

@ -5,9 +5,12 @@ use crate::sys::os_str::Buf;
use crate::sys_common::FromInner;
use crate::slice;
#[cfg_attr(test, linkage = "available_externally")]
#[export_name = "_ZN16__rust_internals3std3sys3sgx4args4ARGSE"]
static ARGS: AtomicUsize = AtomicUsize::new(0);
type ArgsStore = Vec<OsString>;
#[cfg_attr(test, allow(dead_code))]
pub unsafe fn init(argc: isize, argv: *const *const u8) {
if argc != 0 {
let args = alloc::User::<[ByteBuffer]>::from_raw_parts(argv as _, argc as _);

View file

@ -32,7 +32,8 @@ impl Condvar {
mutex.lock()
}
pub unsafe fn wait_timeout(&self, _mutex: &Mutex, _dur: Duration) -> bool {
pub unsafe fn wait_timeout(&self, mutex: &Mutex, _dur: Duration) -> bool {
mutex.unlock(); // don't hold the lock while panicking
panic!("timeout not supported in SGX");
}

View file

@ -41,12 +41,29 @@ impl FromInner<FileDesc> for Socket {
}
}
#[derive(Debug, Clone)]
#[derive(Clone)]
pub struct TcpStream {
inner: Socket,
peer_addr: Option<String>,
}
impl fmt::Debug for TcpStream {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut res = f.debug_struct("TcpStream");
if let Some(ref addr) = self.inner.local_addr {
res.field("addr", addr);
}
if let Some(ref peer) = self.peer_addr {
res.field("peer", peer);
}
res.field("fd", &self.inner.inner.as_inner())
.finish()
}
}
fn io_err_to_addr(result: io::Result<&SocketAddr>) -> io::Result<String> {
match result {
Ok(saddr) => Ok(saddr.to_string()),
@ -75,16 +92,32 @@ impl TcpStream {
Ok(TcpStream { inner: Socket::new(fd, local_addr), peer_addr: Some(peer_addr) })
}
pub fn connect_timeout(addr: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
pub fn connect_timeout(addr: &SocketAddr, dur: Duration) -> io::Result<TcpStream> {
if dur == Duration::default() {
return Err(io::Error::new(io::ErrorKind::InvalidInput,
"cannot set a 0 duration timeout"));
}
Self::connect(Ok(addr)) // FIXME: ignoring timeout
}
pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
sgx_ineffective(())
pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
match dur {
Some(dur) if dur == Duration::default() => {
return Err(io::Error::new(io::ErrorKind::InvalidInput,
"cannot set a 0 duration timeout"));
}
_ => sgx_ineffective(())
}
}
pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
sgx_ineffective(())
pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
match dur {
Some(dur) if dur == Duration::default() => {
return Err(io::Error::new(io::ErrorKind::InvalidInput,
"cannot set a 0 duration timeout"));
}
_ => sgx_ineffective(())
}
}
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
@ -174,11 +207,24 @@ impl FromInner<(Socket, Option<String>)> for TcpStream {
}
}
#[derive(Debug, Clone)]
#[derive(Clone)]
pub struct TcpListener {
inner: Socket,
}
impl fmt::Debug for TcpListener {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut res = f.debug_struct("TcpListener");
if let Some(ref addr) = self.inner.local_addr {
res.field("addr", addr);
}
res.field("fd", &self.inner.inner.as_inner())
.finish()
}
}
impl TcpListener {
pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
let addr = io_err_to_addr(addr)?;

View file

@ -73,7 +73,11 @@ pub fn current_exe() -> io::Result<PathBuf> {
unsupported()
}
#[cfg_attr(test, linkage = "available_externally")]
#[export_name = "_ZN16__rust_internals3std3sys3sgx2os3ENVE"]
static ENV: AtomicUsize = AtomicUsize::new(0);
#[cfg_attr(test, linkage = "available_externally")]
#[export_name = "_ZN16__rust_internals3std3sys3sgx2os8ENV_INITE"]
static ENV_INIT: Once = Once::new();
type EnvStore = Mutex<HashMap<OsString, OsString>>;

View file

@ -1,6 +1,9 @@
#[cfg(not(test))]
use crate::alloc::{self, Layout};
use crate::num::NonZeroUsize;
#[cfg(not(test))]
use crate::slice;
#[cfg(not(test))]
use crate::str;
use super::waitqueue::{
@ -147,6 +150,7 @@ impl RWLock {
// only used by __rust_rwlock_unlock below
#[inline]
#[cfg_attr(test, allow(dead_code))]
unsafe fn unlock(&self) {
let rguard = self.readers.lock();
let wguard = self.writer.lock();
@ -161,9 +165,11 @@ impl RWLock {
pub unsafe fn destroy(&self) {}
}
#[cfg(not(test))]
const EINVAL: i32 = 22;
// used by libunwind port
#[cfg(not(test))]
#[no_mangle]
pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RWLock) -> i32 {
if p.is_null() {
@ -173,6 +179,7 @@ pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RWLock) -> i32 {
return 0;
}
#[cfg(not(test))]
#[no_mangle]
pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RWLock) -> i32 {
if p.is_null() {
@ -181,6 +188,7 @@ pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RWLock) -> i32 {
(*p).write();
return 0;
}
#[cfg(not(test))]
#[no_mangle]
pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RWLock) -> i32 {
if p.is_null() {
@ -192,6 +200,7 @@ pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RWLock) -> i32 {
// the following functions are also used by the libunwind port. They're
// included here to make sure parallel codegen and LTO don't mess things up.
#[cfg(not(test))]
#[no_mangle]
pub unsafe extern "C" fn __rust_print_err(m: *mut u8, s: i32) {
if s < 0 {
@ -203,17 +212,20 @@ pub unsafe extern "C" fn __rust_print_err(m: *mut u8, s: i32) {
}
}
#[cfg(not(test))]
#[no_mangle]
// NB. used by both libunwind and libpanic_abort
pub unsafe extern "C" fn __rust_abort() {
crate::sys::abort_internal();
}
#[cfg(not(test))]
#[no_mangle]
pub unsafe extern "C" fn __rust_c_alloc(size: usize, align: usize) -> *mut u8 {
alloc::alloc(Layout::from_size_align_unchecked(size, align))
}
#[cfg(not(test))]
#[no_mangle]
pub unsafe extern "C" fn __rust_c_dealloc(ptr: *mut u8, size: usize, align: usize) {
alloc::dealloc(ptr, Layout::from_size_align_unchecked(size, align))
@ -221,15 +233,13 @@ pub unsafe extern "C" fn __rust_c_dealloc(ptr: *mut u8, size: usize, align: usiz
#[cfg(test)]
mod tests {
use super::*;
use core::array::FixedSizeArray;
use crate::mem::MaybeUninit;
use crate::{mem, ptr};
use crate::mem::{self, MaybeUninit};
// The below test verifies that the bytes of initialized RWLock are the ones
// we use in libunwind.
// If they change we need to update src/UnwindRustSgx.h in libunwind.
// Verify that the bytes of initialized RWLock are the same as in
// libunwind. If they change, `src/UnwindRustSgx.h` in libunwind needs to
// be changed too.
#[test]
fn test_c_rwlock_initializer() {
const RWLOCK_INIT: &[u8] = &[
@ -251,11 +261,28 @@ mod tests {
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
];
let mut init = MaybeUninit::<RWLock>::zeroed();
init.set(RWLock::new());
assert_eq!(
mem::transmute::<_, [u8; 128]>(init.into_inner()).as_slice(),
RWLOCK_INIT
);
#[inline(never)]
fn zero_stack() {
test::black_box(MaybeUninit::<[RWLock; 16]>::zeroed());
}
#[inline(never)]
unsafe fn rwlock_new(init: &mut MaybeUninit<RWLock>) {
init.set(RWLock::new());
}
unsafe {
// try hard to make sure that the padding/unused bytes in RWLock
// get initialized as 0. If the assertion below fails, that might
// just be an issue with the test code and not with the value of
// RWLOCK_INIT.
zero_stack();
let mut init = MaybeUninit::<RWLock>::zeroed();
rwlock_new(&mut init);
assert_eq!(
mem::transmute::<_, [u8; 128]>(init.into_initialized()).as_slice(),
RWLOCK_INIT
)
};
}
}

View file

@ -6,6 +6,7 @@ impl Handler {
}
}
#[cfg_attr(test, allow(dead_code))]
pub unsafe fn init() {
}

View file

@ -1,3 +1,4 @@
#![cfg_attr(test, allow(dead_code))] // why is this necessary?
use crate::boxed::FnBox;
use crate::ffi::CStr;
use crate::io;
@ -33,7 +34,11 @@ mod task_queue {
}
}
#[cfg_attr(test, linkage = "available_externally")]
#[export_name = "_ZN16__rust_internals3std3sys3sgx6thread15TASK_QUEUE_INITE"]
static TASK_QUEUE_INIT: Once = Once::new();
#[cfg_attr(test, linkage = "available_externally")]
#[export_name = "_ZN16__rust_internals3std3sys3sgx6thread10TASK_QUEUEE"]
static mut TASK_QUEUE: Option<Mutex<Vec<Task>>> = None;
pub(super) fn lock() -> MutexGuard<'static, Vec<Task>> {

View file

@ -498,6 +498,7 @@ mod spin_mutex {
use super::*;
use crate::sync::Arc;
use crate::thread;
use crate::time::{SystemTime, Duration};
#[test]
fn sleep() {
@ -507,7 +508,13 @@ mod spin_mutex {
let t1 = thread::spawn(move || {
*mutex2.lock() = 1;
});
thread::sleep_ms(50);
// "sleep" for 50ms
// FIXME: https://github.com/fortanix/rust-sgx/issues/31
let start = SystemTime::now();
let max = Duration::from_millis(50);
while start.elapsed().unwrap() < max {}
assert_eq!(*guard, 0);
drop(guard);
t1.join().unwrap();
@ -530,7 +537,8 @@ mod tests {
let locked = wq.lock();
let t1 = thread::spawn(move || {
assert!(WaitQueue::notify_one(wq2.lock()).is_none())
// if we obtain the lock, the main thread should be waiting
assert!(WaitQueue::notify_one(wq2.lock()).is_ok());
});
WaitQueue::wait(locked);

View file

@ -530,7 +530,7 @@ mod tests {
thread::spawn(|| {
assert!(FOO.try_with(|_| ()).is_ok());
}).join().ok().unwrap();
}).join().ok().expect("thread panicked");
}
#[test]
@ -584,7 +584,7 @@ mod tests {
thread::spawn(move|| {
drop(S1);
}).join().ok().unwrap();
}).join().ok().expect("thread panicked");
}
#[test]
@ -600,7 +600,7 @@ mod tests {
thread::spawn(move|| unsafe {
K1.with(|s| *s.get() = Some(S1));
}).join().ok().unwrap();
}).join().ok().expect("thread panicked");
}
// Note that this test will deadlock if TLS destructors aren't run (this

View file

@ -1499,7 +1499,7 @@ mod tests {
fn test_unnamed_thread() {
thread::spawn(move|| {
assert!(thread::current().name().is_none());
}).join().ok().unwrap();
}).join().ok().expect("thread panicked");
}
#[test]
@ -1693,6 +1693,7 @@ mod tests {
}
#[test]
#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn test_park_timeout_unpark_not_called() {
for _ in 0..10 {
thread::park_timeout(Duration::from_millis(10));
@ -1700,6 +1701,7 @@ mod tests {
}
#[test]
#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn test_park_timeout_unpark_called_other_thread() {
for _ in 0..10 {
let th = thread::current();
@ -1714,6 +1716,7 @@ mod tests {
}
#[test]
#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn sleep_ms_smoke() {
thread::sleep(Duration::from_millis(2));
}

View file

@ -54,6 +54,7 @@ const EXCEPTION_PATHS: &[&str] = &[
"src/libstd/f64.rs",
// Integration test for platform-specific run-time feature detection:
"src/libstd/tests/run-time-detect.rs" ,
"src/libstd/net/test.rs",
"src/libstd/sys_common/mod.rs",
"src/libstd/sys_common/net.rs",
"src/libterm", // Not sure how to make this crate portable, but test crate needs it.