about summary refs log tree commit diff
path: root/src/libstd/sys
diff options
context:
space:
mode:
authorBaoshan <pangbw@gmail.com>2019-09-03 16:33:18 -0700
committerGitHub <noreply@github.com>2019-09-03 16:33:18 -0700
commite316ba3b60433bd703575a00d7fd5e344e29912d (patch)
tree4d74702faa98a70d127b17f19f908dc3875e8faa /src/libstd/sys
parent964c37cdecbd1aa0e7870afac9ba38e5168be65f (diff)
parentb9de4ef89e0e53099a084001b26ec3207c5f8391 (diff)
downloadrust-e316ba3b60433bd703575a00d7fd5e344e29912d.tar.gz
rust-e316ba3b60433bd703575a00d7fd5e344e29912d.zip
Merge pull request #12 from rust-lang/master
sync with rust-lang/rust branch master
Diffstat (limited to 'src/libstd/sys')
-rw-r--r--src/libstd/sys/unix/process/process_unix.rs25
-rw-r--r--src/libstd/sys/vxworks/backtrace/mod.rs110
-rw-r--r--src/libstd/sys/vxworks/backtrace/printing/dladdr.rs35
-rw-r--r--src/libstd/sys/vxworks/backtrace/printing/mod.rs33
-rw-r--r--src/libstd/sys/vxworks/backtrace/tracing/backtrace_fn.rs39
-rw-r--r--src/libstd/sys/vxworks/backtrace/tracing/gcc_s.rs99
-rw-r--r--src/libstd/sys/vxworks/backtrace/tracing/mod.rs8
-rw-r--r--src/libstd/sys/vxworks/fast_thread_local.rs27
-rw-r--r--src/libstd/sys/vxworks/thread.rs2
-rw-r--r--src/libstd/sys/wasi/mod.rs20
-rw-r--r--src/libstd/sys/wasm/args.rs4
-rw-r--r--src/libstd/sys/wasm/mod.rs222
-rw-r--r--src/libstd/sys/wasm/os.rs18
-rw-r--r--src/libstd/sys/wasm/stdio.rs15
-rw-r--r--src/libstd/sys/wasm/time.rs5
15 files changed, 51 insertions, 611 deletions
diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs
index a9711c71b7a..e6a742bd45d 100644
--- a/src/libstd/sys/unix/process/process_unix.rs
+++ b/src/libstd/sys/unix/process/process_unix.rs
@@ -178,23 +178,22 @@ impl Command {
             cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO))?;
         }
 
-        if cfg!(not(any(target_os = "l4re"))) {
+        #[cfg(not(target_os = "l4re"))]
+        {
             if let Some(u) = self.get_gid() {
                 cvt(libc::setgid(u as gid_t))?;
             }
             if let Some(u) = self.get_uid() {
+                // When dropping privileges from root, the `setgroups` call
+                // will remove any extraneous groups. If we don't call this,
+                // then even though our uid has dropped, we may still have
+                // groups that enable us to do super-user things. This will
+                // fail if we aren't root, so don't bother checking the
+                // return value, this is just done as an optimistic
+                // privilege dropping function.
                 //FIXME: Redox kernel does not support setgroups yet
-                if cfg!(not(target_os = "redox")) {
-                    // When dropping privileges from root, the `setgroups` call
-                    // will remove any extraneous groups. If we don't call this,
-                    // then even though our uid has dropped, we may still have
-                    // groups that enable us to do super-user things. This will
-                    // fail if we aren't root, so don't bother checking the
-                    // return value, this is just done as an optimistic
-                    // privilege dropping function.
-                    let _ = libc::setgroups(0, ptr::null());
-                }
-
+                #[cfg(not(target_os = "redox"))]
+                let _ = libc::setgroups(0, ptr::null());
                 cvt(libc::setuid(u as uid_t))?;
             }
         }
@@ -203,7 +202,7 @@ impl Command {
         }
 
         // emscripten has no signal support.
-        #[cfg(not(any(target_os = "emscripten")))]
+        #[cfg(not(target_os = "emscripten"))]
         {
             use crate::mem::MaybeUninit;
             // Reset signal handling so the child process starts in a
diff --git a/src/libstd/sys/vxworks/backtrace/mod.rs b/src/libstd/sys/vxworks/backtrace/mod.rs
deleted file mode 100644
index 0887e5a4df9..00000000000
--- a/src/libstd/sys/vxworks/backtrace/mod.rs
+++ /dev/null
@@ -1,110 +0,0 @@
-/// Backtrace support built on libgcc with some extra OS-specific support
-///
-/// Some methods of getting a backtrace:
-///
-/// * The backtrace() functions on unix. It turns out this doesn't work very
-///   well for green threads on macOS, and the address to symbol portion of it
-///   suffers problems that are described below.
-///
-/// * Using libunwind. This is more difficult than it sounds because libunwind
-///   isn't installed everywhere by default. It's also a bit of a hefty library,
-///   so possibly not the best option. When testing, libunwind was excellent at
-///   getting both accurate backtraces and accurate symbols across platforms.
-///   This route was not chosen in favor of the next option, however.
-///
-/// * We're already using libgcc_s for exceptions in rust (triggering thread
-///   unwinding and running destructors on the stack), and it turns out that it
-///   conveniently comes with a function that also gives us a backtrace. All of
-///   these functions look like _Unwind_*, but it's not quite the full
-///   repertoire of the libunwind API. Due to it already being in use, this was
-///   the chosen route of getting a backtrace.
-///
-/// After choosing libgcc_s for backtraces, the sad part is that it will only
-/// give us a stack trace of instruction pointers. Thankfully these instruction
-/// pointers are accurate (they work for green and native threads), but it's
-/// then up to us again to figure out how to translate these addresses to
-/// symbols. As with before, we have a few options. Before, that, a little bit
-/// of an interlude about symbols. This is my very limited knowledge about
-/// symbol tables, and this information is likely slightly wrong, but the
-/// general idea should be correct.
-///
-/// When talking about symbols, it's helpful to know a few things about where
-/// symbols are located. Some symbols are located in the dynamic symbol table
-/// of the executable which in theory means that they're available for dynamic
-/// linking and lookup. Other symbols end up only in the local symbol table of
-/// the file. This loosely corresponds to pub and priv functions in Rust.
-///
-/// Armed with this knowledge, we know that our solution for address to symbol
-/// translation will need to consult both the local and dynamic symbol tables.
-/// With that in mind, here's our options of translating an address to
-/// a symbol.
-///
-/// * Use dladdr(). The original backtrace()-based idea actually uses dladdr()
-///   behind the scenes to translate, and this is why backtrace() was not used.
-///   Conveniently, this method works fantastically on macOS. It appears dladdr()
-///   uses magic to consult the local symbol table, or we're putting everything
-///   in the dynamic symbol table anyway. Regardless, for macOS, this is the
-///   method used for translation. It's provided by the system and easy to do.o
-///
-///   Sadly, all other systems have a dladdr() implementation that does not
-///   consult the local symbol table. This means that most functions are blank
-///   because they don't have symbols. This means that we need another solution.
-///
-/// * Use unw_get_proc_name(). This is part of the libunwind api (not the
-///   libgcc_s version of the libunwind api), but involves taking a dependency
-///   to libunwind. We may pursue this route in the future if we bundle
-///   libunwind, but libunwind was unwieldy enough that it was not chosen at
-///   this time to provide this functionality.
-///
-/// * Shell out to a utility like `readelf`. Crazy though it may sound, it's a
-///   semi-reasonable solution. The stdlib already knows how to spawn processes,
-///   so in theory it could invoke readelf, parse the output, and consult the
-///   local/dynamic symbol tables from there. This ended up not getting chosen
-///   due to the craziness of the idea plus the advent of the next option.
-///
-/// * Use `libbacktrace`. It turns out that this is a small library bundled in
-///   the gcc repository which provides backtrace and symbol translation
-///   functionality. All we really need from it is the backtrace functionality,
-///   and we only really need this on everything that's not macOS, so this is the
-///   chosen route for now.
-///
-/// In summary, the current situation uses libgcc_s to get a trace of stack
-/// pointers, and we use dladdr() or libbacktrace to translate these addresses
-/// to symbols. This is a bit of a hokey implementation as-is, but it works for
-/// all unix platforms we support right now, so it at least gets the job done.
-
-pub use self::tracing::unwind_backtrace;
-pub use self::printing::{foreach_symbol_fileline, resolve_symname};
-
-// tracing impls:
-mod tracing;
-// symbol resolvers:
-mod printing;
-
-#[cfg(not(target_os = "emscripten"))]
-pub mod gnu {
-    use crate::io;
-    use crate::fs;
-
-    use libc::c_char;
-
-    #[cfg(not(any(target_os = "macos", target_os = "ios")))]
-    pub fn get_executable_filename() -> io::Result<(Vec<c_char>, fs::File)> {
-        Err(io::Error::new(io::ErrorKind::Other, "Not implemented"))
-    }
-
-    #[cfg(any(target_os = "macos", target_os = "ios"))]
-    pub fn get_executable_filename() -> io::Result<(Vec<c_char>, fs::File)> {
-        use crate::env;
-        use crate::os::unix::ffi::OsStrExt;
-
-        let filename = env::current_exe()?;
-        let file = fs::File::open(&filename)?;
-        let mut filename_cstr: Vec<_> = filename.as_os_str().as_bytes().iter()
-            .map(|&x| x as c_char).collect();
-        filename_cstr.push(0); // Null terminate
-        Ok((filename_cstr, file))
-    }
-}
-
-pub struct BacktraceContext;
diff --git a/src/libstd/sys/vxworks/backtrace/printing/dladdr.rs b/src/libstd/sys/vxworks/backtrace/printing/dladdr.rs
deleted file mode 100644
index 202164dd3c4..00000000000
--- a/src/libstd/sys/vxworks/backtrace/printing/dladdr.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-use crate::io;
-use crate::intrinsics;
-use crate::ffi::CStr;
-use crate::sys::backtrace::BacktraceContext;
-use crate::sys_common::backtrace::Frame;
-
-pub fn resolve_symname<F>(frame: Frame,
-                          callback: F,
-                          _: &BacktraceContext) -> io::Result<()>
-    where F: FnOnce(Option<&str>) -> io::Result<()>
-{
-    unsafe {
-        let mut info: Dl_info = intrinsics::init();
-        let symname = if dladdr(frame.exact_position as *mut _, &mut info) == 0 ||
-                         info.dli_sname.is_null() {
-            None
-        } else {
-            CStr::from_ptr(info.dli_sname).to_str().ok()
-        };
-        callback(symname)
-    }
-}
-
-#[repr(C)]
-struct Dl_info {
-    dli_fname: *const libc::c_char,
-    dli_fbase: *mut libc::c_void,
-    dli_sname: *const libc::c_char,
-    dli_saddr: *mut libc::c_void,
-}
-
-extern {
-    #[ link_name = "_rtld_dladdr" ]
-    fn dladdr(addr: *const libc::c_void, info: *mut Dl_info) -> libc::c_int;
-}
diff --git a/src/libstd/sys/vxworks/backtrace/printing/mod.rs b/src/libstd/sys/vxworks/backtrace/printing/mod.rs
deleted file mode 100644
index d090caede43..00000000000
--- a/src/libstd/sys/vxworks/backtrace/printing/mod.rs
+++ /dev/null
@@ -1,33 +0,0 @@
-mod dladdr;
-
-use crate::sys::backtrace::BacktraceContext;
-use crate::sys_common::backtrace::Frame;
-use crate::io;
-
-#[cfg(target_os = "emscripten")]
-pub use self::dladdr::resolve_symname;
-
-#[cfg(target_os = "emscripten")]
-pub fn foreach_symbol_fileline<F>(_: Frame, _: F, _: &BacktraceContext) -> io::Result<bool>
-where
-    F: FnMut(&[u8], u32) -> io::Result<()>
-{
-    Ok(false)
-}
-
-#[cfg(not(target_os = "emscripten"))]
-pub use crate::sys_common::gnu::libbacktrace::foreach_symbol_fileline;
-
-#[cfg(not(target_os = "emscripten"))]
-pub fn resolve_symname<F>(frame: Frame, callback: F, bc: &BacktraceContext) -> io::Result<()>
-where
-    F: FnOnce(Option<&str>) -> io::Result<()>
-{
-    crate::sys_common::gnu::libbacktrace::resolve_symname(frame, |symname| {
-        if symname.is_some() {
-            callback(symname)
-        } else {
-            dladdr::resolve_symname(frame, callback, bc)
-        }
-    }, bc)
-}
diff --git a/src/libstd/sys/vxworks/backtrace/tracing/backtrace_fn.rs b/src/libstd/sys/vxworks/backtrace/tracing/backtrace_fn.rs
deleted file mode 100644
index a628d107ad6..00000000000
--- a/src/libstd/sys/vxworks/backtrace/tracing/backtrace_fn.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-/// As always - iOS on arm uses SjLj exceptions and
-/// _Unwind_Backtrace is even not available there. Still,
-/// backtraces could be extracted using a backtrace function,
-/// which thanks god is public
-///
-/// As mentioned in a huge comment block in `super::super`, backtrace
-/// doesn't play well with green threads, so while it is extremely nice and
-/// simple to use it should be used only on iOS devices as the only viable
-/// option.
-
-use crate::io;
-use crate::ptr;
-use crate::sys::backtrace::BacktraceContext;
-use crate::sys_common::backtrace::Frame;
-
-#[inline(never)] // if we know this is a function call, we can skip it when
-                 // tracing
-pub fn unwind_backtrace(frames: &mut [Frame])
-    -> io::Result<(usize, BacktraceContext)>
-{
-    const FRAME_LEN: usize = 100;
-    assert!(FRAME_LEN >= frames.len());
-    let mut raw_frames = [ptr::null_mut(); FRAME_LEN];
-    let nb_frames = unsafe {
-        backtrace(raw_frames.as_mut_ptr(), raw_frames.len() as libc::c_int)
-    } as usize;
-    for (from, to) in raw_frames.iter().zip(frames.iter_mut()).take(nb_frames) {
-        *to = Frame {
-            exact_position: *from as *mut u8,
-            symbol_addr: *from as *mut u8,
-            inline_context: 0,
-        };
-    }
-    Ok((nb_frames as usize, BacktraceContext))
-}
-
-extern {
-    fn backtrace(buf: *mut *mut libc::c_void, sz: libc::c_int) -> libc::c_int;
-}
diff --git a/src/libstd/sys/vxworks/backtrace/tracing/gcc_s.rs b/src/libstd/sys/vxworks/backtrace/tracing/gcc_s.rs
deleted file mode 100644
index e6379132baf..00000000000
--- a/src/libstd/sys/vxworks/backtrace/tracing/gcc_s.rs
+++ /dev/null
@@ -1,99 +0,0 @@
-use crate::error::Error;
-use crate::fmt;
-use crate::io;
-use crate::sys::backtrace::BacktraceContext;
-use crate::sys_common::backtrace::Frame;
-
-use unwind as uw;
-
-struct Context<'a> {
-    idx: usize,
-    frames: &'a mut [Frame],
-}
-
-#[derive(Debug)]
-struct UnwindError(uw::_Unwind_Reason_Code);
-
-impl Error for UnwindError {
-    fn description(&self) -> &'static str {
-        "unexpected return value while unwinding"
-    }
-}
-
-impl fmt::Display for UnwindError {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}: {:?}", self.description(), self.0)
-    }
-}
-
-#[inline(never)] // if we know this is a function call, we can skip it when
-                 // tracing
-pub fn unwind_backtrace(frames: &mut [Frame])
-    -> io::Result<(usize, BacktraceContext)>
-{
-    let mut cx = Context {
-        idx: 0,
-        frames,
-    };
-    let result_unwind = unsafe {
-        uw::_Unwind_Backtrace(trace_fn,
-                              &mut cx as *mut Context<'_>
-                              as *mut libc::c_void)
-    };
-    // See libunwind:src/unwind/Backtrace.c for the return values.
-    // No, there is no doc.
-    match result_unwind {
-        // These return codes seem to be benign and need to be ignored for backtraces
-        // to show up properly on all tested platforms.
-        uw::_URC_END_OF_STACK | uw::_URC_FATAL_PHASE1_ERROR | uw::_URC_FAILURE => {
-            Ok((cx.idx, BacktraceContext))
-        }
-        _ => {
-            Err(io::Error::new(io::ErrorKind::Other,
-                               UnwindError(result_unwind)))
-        }
-    }
-}
-
-extern fn trace_fn(ctx: *mut uw::_Unwind_Context,
-                   arg: *mut libc::c_void) -> uw::_Unwind_Reason_Code {
-    let cx = unsafe { &mut *(arg as *mut Context<'_>) };
-    if cx.idx >= cx.frames.len() {
-        return uw::_URC_NORMAL_STOP;
-    }
-
-    let mut ip_before_insn = 0;
-    let mut ip = unsafe {
-        uw::_Unwind_GetIPInfo(ctx, &mut ip_before_insn) as *mut libc::c_void
-    };
-    if !ip.is_null() && ip_before_insn == 0 {
-        // this is a non-signaling frame, so `ip` refers to the address
-        // after the calling instruction. account for that.
-        ip = (ip as usize - 1) as *mut _;
-    }
-
-    // dladdr() on osx gets whiny when we use FindEnclosingFunction, and
-    // it appears to work fine without it, so we only use
-    // FindEnclosingFunction on non-osx platforms. In doing so, we get a
-    // slightly more accurate stack trace in the process.
-    //
-    // This is often because panic involves the last instruction of a
-    // function being "call std::rt::begin_unwind", with no ret
-    // instructions after it. This means that the return instruction
-    // pointer points *outside* of the calling function, and by
-    // unwinding it we go back to the original function.
-    let symaddr = if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
-        ip
-    } else {
-        unsafe { uw::_Unwind_FindEnclosingFunction(ip) }
-    };
-
-    cx.frames[cx.idx] = Frame {
-        symbol_addr: symaddr as *mut u8,
-        exact_position: ip as *mut u8,
-        inline_context: 0,
-    };
-    cx.idx += 1;
-
-    uw::_URC_NO_REASON
-}
diff --git a/src/libstd/sys/vxworks/backtrace/tracing/mod.rs b/src/libstd/sys/vxworks/backtrace/tracing/mod.rs
deleted file mode 100644
index 11863e64545..00000000000
--- a/src/libstd/sys/vxworks/backtrace/tracing/mod.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-pub use self::imp::*;
-
-#[cfg(not(all(target_os = "ios", target_arch = "arm")))]
-#[path = "gcc_s.rs"]
-mod imp;
-#[cfg(all(target_os = "ios", target_arch = "arm"))]
-#[path = "backtrace_fn.rs"]
-mod imp;
diff --git a/src/libstd/sys/vxworks/fast_thread_local.rs b/src/libstd/sys/vxworks/fast_thread_local.rs
index f5a2e263d25..2e021980778 100644
--- a/src/libstd/sys/vxworks/fast_thread_local.rs
+++ b/src/libstd/sys/vxworks/fast_thread_local.rs
@@ -1,33 +1,10 @@
+// Copyright (c) 2019 Wind River Systems, Inc.
+
 #![cfg(target_thread_local)]
 #![unstable(feature = "thread_local_internals", issue = "0")]
 
-// Since what appears to be glibc 2.18 this symbol has been shipped which
-// GCC and clang both use to invoke destructors in thread_local globals, so
-// let's do the same!
-//
-// Note, however, that we run on lots older linuxes, as well as cross
-// compiling from a newer linux to an older linux, so we also have a
-// fallback implementation to use as well.
-//
-// Due to rust-lang/rust#18804, make sure this is not generic!
 pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
-    use crate::mem;
     use crate::sys_common::thread_local::register_dtor_fallback;
-
-    extern {
-        #[linkage = "extern_weak"]
-        static __dso_handle: *mut u8;
-        #[linkage = "extern_weak"]
-        static __cxa_thread_atexit_impl: *const libc::c_void;
-    }
-    if !__cxa_thread_atexit_impl.is_null() {
-        type F = unsafe extern fn(dtor: unsafe extern fn(*mut u8),
-                                  arg: *mut u8,
-                                  dso_handle: *mut u8) -> libc::c_int;
-        mem::transmute::<*const libc::c_void, F>(__cxa_thread_atexit_impl)
-            (dtor, t, &__dso_handle as *const _ as *mut _);
-        return
-    }
     register_dtor_fallback(t, dtor);
 }
 
diff --git a/src/libstd/sys/vxworks/thread.rs b/src/libstd/sys/vxworks/thread.rs
index 58af8cbe48e..ef896f6a6e8 100644
--- a/src/libstd/sys/vxworks/thread.rs
+++ b/src/libstd/sys/vxworks/thread.rs
@@ -77,7 +77,7 @@ impl Thread {
     }
 
     pub fn set_name(_name: &CStr) {
-        assert!(false, "FIXME: set_name");
+        // VxWorks does not provide a way to set the task name except at creation time
     }
 
     pub fn sleep(dur: Duration) {
diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs
index f842869e08e..57da81b41e7 100644
--- a/src/libstd/sys/wasi/mod.rs
+++ b/src/libstd/sys/wasi/mod.rs
@@ -64,8 +64,24 @@ pub fn unsupported_err() -> Error {
     Error::new(ErrorKind::Other, "operation not supported on wasm yet")
 }
 
-pub fn decode_error_kind(_code: i32) -> ErrorKind {
-    ErrorKind::Other
+pub fn decode_error_kind(errno: i32) -> ErrorKind {
+    match errno as libc::c_int {
+        libc::ECONNREFUSED => ErrorKind::ConnectionRefused,
+        libc::ECONNRESET => ErrorKind::ConnectionReset,
+        libc::EPERM | libc::EACCES => ErrorKind::PermissionDenied,
+        libc::EPIPE => ErrorKind::BrokenPipe,
+        libc::ENOTCONN => ErrorKind::NotConnected,
+        libc::ECONNABORTED => ErrorKind::ConnectionAborted,
+        libc::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
+        libc::EADDRINUSE => ErrorKind::AddrInUse,
+        libc::ENOENT => ErrorKind::NotFound,
+        libc::EINTR => ErrorKind::Interrupted,
+        libc::EINVAL => ErrorKind::InvalidInput,
+        libc::ETIMEDOUT => ErrorKind::TimedOut,
+        libc::EEXIST => ErrorKind::AlreadyExists,
+        libc::EAGAIN => ErrorKind::WouldBlock,
+        _ => ErrorKind::Other,
+    }
 }
 
 // This enum is used as the storage for a bunch of types which can't actually
diff --git a/src/libstd/sys/wasm/args.rs b/src/libstd/sys/wasm/args.rs
index b3c77b86995..8279e5280e9 100644
--- a/src/libstd/sys/wasm/args.rs
+++ b/src/libstd/sys/wasm/args.rs
@@ -1,7 +1,6 @@
 use crate::ffi::OsString;
 use crate::marker::PhantomData;
 use crate::vec;
-use crate::sys::ArgsSysCall;
 
 pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
     // On wasm these should always be null, so there's nothing for us to do here
@@ -11,9 +10,8 @@ pub unsafe fn cleanup() {
 }
 
 pub fn args() -> Args {
-    let v = ArgsSysCall::perform();
     Args {
-        iter: v.into_iter(),
+        iter: Vec::new().into_iter(),
         _dont_send_or_sync_me: PhantomData,
     }
 }
diff --git a/src/libstd/sys/wasm/mod.rs b/src/libstd/sys/wasm/mod.rs
index 56cbafcfdb8..de0bb38dc31 100644
--- a/src/libstd/sys/wasm/mod.rs
+++ b/src/libstd/sys/wasm/mod.rs
@@ -15,11 +15,6 @@
 //! guaranteed to be a runtime error!
 
 use crate::os::raw::c_char;
-use crate::ptr;
-use crate::sys::os_str::Buf;
-use crate::sys_common::{AsInner, FromInner};
-use crate::ffi::{OsString, OsStr};
-use crate::time::Duration;
 
 pub mod alloc;
 pub mod args;
@@ -89,7 +84,7 @@ pub unsafe fn strlen(mut s: *const c_char) -> usize {
 }
 
 pub unsafe fn abort_internal() -> ! {
-    ExitSysCall::perform(1)
+    crate::arch::wasm32::unreachable()
 }
 
 // We don't have randomness yet, but I totally used a random number generator to
@@ -100,218 +95,3 @@ pub unsafe fn abort_internal() -> ! {
 pub fn hashmap_random_keys() -> (u64, u64) {
     (1, 2)
 }
-
-// Implement a minimal set of system calls to enable basic IO
-pub enum SysCallIndex {
-    Read = 0,
-    Write = 1,
-    Exit = 2,
-    Args = 3,
-    GetEnv = 4,
-    SetEnv = 5,
-    Time = 6,
-}
-
-#[repr(C)]
-pub struct ReadSysCall {
-    fd: usize,
-    ptr: *mut u8,
-    len: usize,
-    result: usize,
-}
-
-impl ReadSysCall {
-    pub fn perform(fd: usize, buffer: &mut [u8]) -> usize {
-        let mut call_record = ReadSysCall {
-            fd,
-            len: buffer.len(),
-            ptr: buffer.as_mut_ptr(),
-            result: 0
-        };
-        if unsafe { syscall(SysCallIndex::Read, &mut call_record) } {
-            call_record.result
-        } else {
-            0
-        }
-    }
-}
-
-#[repr(C)]
-pub struct WriteSysCall {
-    fd: usize,
-    ptr: *const u8,
-    len: usize,
-}
-
-impl WriteSysCall {
-    pub fn perform(fd: usize, buffer: &[u8]) {
-        let mut call_record = WriteSysCall {
-            fd,
-            len: buffer.len(),
-            ptr: buffer.as_ptr()
-        };
-        unsafe { syscall(SysCallIndex::Write, &mut call_record); }
-    }
-}
-
-#[repr(C)]
-pub struct ExitSysCall {
-    code: usize,
-}
-
-impl ExitSysCall {
-    pub fn perform(code: usize) -> ! {
-        let mut call_record = ExitSysCall {
-            code
-        };
-        unsafe {
-            syscall(SysCallIndex::Exit, &mut call_record);
-            crate::intrinsics::abort();
-        }
-    }
-}
-
-fn receive_buffer<E, F: FnMut(&mut [u8]) -> Result<usize, E>>(estimate: usize, mut f: F)
-    -> Result<Vec<u8>, E>
-{
-    let mut buffer = vec![0; estimate];
-    loop {
-        let result = f(&mut buffer)?;
-        if result <= buffer.len() {
-            buffer.truncate(result);
-            break;
-        }
-        buffer.resize(result, 0);
-    }
-    Ok(buffer)
-}
-
-#[repr(C)]
-pub struct ArgsSysCall {
-    ptr: *mut u8,
-    len: usize,
-    result: usize
-}
-
-impl ArgsSysCall {
-    pub fn perform() -> Vec<OsString> {
-        receive_buffer(1024, |buffer| -> Result<usize, !> {
-            let mut call_record = ArgsSysCall {
-                len: buffer.len(),
-                ptr: buffer.as_mut_ptr(),
-                result: 0
-            };
-            if unsafe { syscall(SysCallIndex::Args, &mut call_record) } {
-                Ok(call_record.result)
-            } else {
-                Ok(0)
-            }
-        })
-            .unwrap()
-            .split(|b| *b == 0)
-            .map(|s| FromInner::from_inner(Buf { inner: s.to_owned() }))
-            .collect()
-    }
-}
-
-#[repr(C)]
-pub struct GetEnvSysCall {
-    key_ptr: *const u8,
-    key_len: usize,
-    value_ptr: *mut u8,
-    value_len: usize,
-    result: usize
-}
-
-impl GetEnvSysCall {
-    pub fn perform(key: &OsStr) -> Option<OsString> {
-        let key_buf = &AsInner::as_inner(key).inner;
-        receive_buffer(64, |buffer| {
-            let mut call_record = GetEnvSysCall {
-                key_len: key_buf.len(),
-                key_ptr: key_buf.as_ptr(),
-                value_len: buffer.len(),
-                value_ptr: buffer.as_mut_ptr(),
-                result: !0usize
-            };
-            if unsafe { syscall(SysCallIndex::GetEnv, &mut call_record) } {
-                if call_record.result == !0usize {
-                    Err(())
-                } else {
-                    Ok(call_record.result)
-                }
-            } else {
-                Err(())
-            }
-        }).ok().map(|s| {
-            FromInner::from_inner(Buf { inner: s })
-        })
-    }
-}
-
-#[repr(C)]
-pub struct SetEnvSysCall {
-    key_ptr: *const u8,
-    key_len: usize,
-    value_ptr: *const u8,
-    value_len: usize
-}
-
-impl SetEnvSysCall {
-    pub fn perform(key: &OsStr, value: Option<&OsStr>) {
-        let key_buf = &AsInner::as_inner(key).inner;
-        let value_buf = value.map(|v| &AsInner::as_inner(v).inner);
-        let mut call_record = SetEnvSysCall {
-            key_len: key_buf.len(),
-            key_ptr: key_buf.as_ptr(),
-            value_len: value_buf.map(|v| v.len()).unwrap_or(!0usize),
-            value_ptr: value_buf.map(|v| v.as_ptr()).unwrap_or(ptr::null())
-        };
-        unsafe { syscall(SysCallIndex::SetEnv, &mut call_record); }
-    }
-}
-
-pub enum TimeClock {
-    Monotonic = 0,
-    System = 1,
-}
-
-#[repr(C)]
-pub struct TimeSysCall {
-    clock: usize,
-    secs_hi: usize,
-    secs_lo: usize,
-    nanos: usize
-}
-
-impl TimeSysCall {
-    pub fn perform(clock: TimeClock) -> Duration {
-        let mut call_record = TimeSysCall {
-            clock: clock as usize,
-            secs_hi: 0,
-            secs_lo: 0,
-            nanos: 0
-        };
-        if unsafe { syscall(SysCallIndex::Time, &mut call_record) } {
-            Duration::new(
-                ((call_record.secs_hi as u64) << 32) | (call_record.secs_lo as u64),
-                call_record.nanos as u32
-            )
-        } else {
-            panic!("Time system call is not implemented by WebAssembly host");
-        }
-    }
-}
-
-unsafe fn syscall<T>(index: SysCallIndex, data: &mut T) -> bool {
-    #[cfg(feature = "wasm_syscall")]
-    extern {
-        #[no_mangle]
-        fn rust_wasm_syscall(index: usize, data: *mut Void) -> usize;
-    }
-
-    #[cfg(not(feature = "wasm_syscall"))]
-    unsafe fn rust_wasm_syscall(_index: usize, _data: *mut Void) -> usize { 0 }
-
-    rust_wasm_syscall(index as usize, data as *mut T as *mut Void) != 0
-}
diff --git a/src/libstd/sys/wasm/os.rs b/src/libstd/sys/wasm/os.rs
index 5d21999a991..890049e8bfa 100644
--- a/src/libstd/sys/wasm/os.rs
+++ b/src/libstd/sys/wasm/os.rs
@@ -4,7 +4,7 @@ use crate::fmt;
 use crate::io;
 use crate::path::{self, PathBuf};
 use crate::str;
-use crate::sys::{unsupported, Void, ExitSysCall, GetEnvSysCall, SetEnvSysCall};
+use crate::sys::{unsupported, Void};
 
 pub fn errno() -> i32 {
     0
@@ -73,16 +73,16 @@ pub fn env() -> Env {
     panic!("not supported on web assembly")
 }
 
-pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
-    Ok(GetEnvSysCall::perform(k))
+pub fn getenv(_: &OsStr) -> io::Result<Option<OsString>> {
+    Ok(None)
 }
 
-pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
-    Ok(SetEnvSysCall::perform(k, Some(v)))
+pub fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> {
+    Err(io::Error::new(io::ErrorKind::Other, "cannot set env vars on wasm32-unknown-unknown"))
 }
 
-pub fn unsetenv(k: &OsStr) -> io::Result<()> {
-    Ok(SetEnvSysCall::perform(k, None))
+pub fn unsetenv(_: &OsStr) -> io::Result<()> {
+    Err(io::Error::new(io::ErrorKind::Other, "cannot unset env vars on wasm32-unknown-unknown"))
 }
 
 pub fn temp_dir() -> PathBuf {
@@ -94,7 +94,9 @@ pub fn home_dir() -> Option<PathBuf> {
 }
 
 pub fn exit(_code: i32) -> ! {
-    ExitSysCall::perform(_code as isize as usize)
+    unsafe {
+        crate::arch::wasm32::unreachable();
+    }
 }
 
 pub fn getpid() -> u32 {
diff --git a/src/libstd/sys/wasm/stdio.rs b/src/libstd/sys/wasm/stdio.rs
index b8899a9c847..5a4e4505e93 100644
--- a/src/libstd/sys/wasm/stdio.rs
+++ b/src/libstd/sys/wasm/stdio.rs
@@ -1,5 +1,4 @@
 use crate::io;
-use crate::sys::{ReadSysCall, WriteSysCall};
 
 pub struct Stdin;
 pub struct Stdout;
@@ -12,8 +11,8 @@ impl Stdin {
 }
 
 impl io::Read for Stdin {
-    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
-        Ok(ReadSysCall::perform(0, buf))
+    fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
+        Ok(0)
     }
 }
 
@@ -25,7 +24,6 @@ impl Stdout {
 
 impl io::Write for Stdout {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        WriteSysCall::perform(1, buf);
         Ok(buf.len())
     }
 
@@ -42,7 +40,6 @@ impl Stderr {
 
 impl io::Write for Stderr {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        WriteSysCall::perform(2, buf);
         Ok(buf.len())
     }
 
@@ -57,10 +54,6 @@ pub fn is_ebadf(_err: &io::Error) -> bool {
     true
 }
 
-pub fn panic_output() -> Option<impl io::Write> {
-    if cfg!(feature = "wasm_syscall") {
-        Stderr::new().ok()
-    } else {
-        None
-    }
+pub fn panic_output() -> Option<Vec<u8>> {
+    None
 }
diff --git a/src/libstd/sys/wasm/time.rs b/src/libstd/sys/wasm/time.rs
index 3f71461eea4..dd9ad3760b0 100644
--- a/src/libstd/sys/wasm/time.rs
+++ b/src/libstd/sys/wasm/time.rs
@@ -1,5 +1,4 @@
 use crate::time::Duration;
-use crate::sys::{TimeSysCall, TimeClock};
 
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
 pub struct Instant(Duration);
@@ -11,7 +10,7 @@ pub const UNIX_EPOCH: SystemTime = SystemTime(Duration::from_secs(0));
 
 impl Instant {
     pub fn now() -> Instant {
-        Instant(TimeSysCall::perform(TimeClock::Monotonic))
+        panic!("time not implemented on wasm32-unknown-unknown")
     }
 
     pub const fn zero() -> Instant {
@@ -37,7 +36,7 @@ impl Instant {
 
 impl SystemTime {
     pub fn now() -> SystemTime {
-        SystemTime(TimeSysCall::perform(TimeClock::System))
+        panic!("time not implemented on wasm32-unknown-unknown")
     }
 
     pub fn sub_time(&self, other: &SystemTime)