Use rsix to make system calls in Wasmtime. (#3355)

* Use rsix to make system calls in Wasmtime.

`rsix` is a system call wrapper crate that we use in `wasi-common`,
which can provide the following advantages in the rest of Wasmtime:

 - It eliminates some `unsafe` blocks in Wasmtime's code. There's
   still an `unsafe` block in the library, but this way, the `unsafe`
   is factored out and clearly scoped.

 - And, it makes error handling more consistent, factoring out code for
   checking return values and `io::Error::last_os_error()`, and code that
   does `errno::set_errno(0)`.

This doesn't cover *all* system calls; `rsix` doesn't implement
signal-handling APIs, and this doesn't cover calls made through `std` or
crates like `userfaultfd`, `rand`, and `region`.
This commit is contained in:
Dan Gohman
2021-09-17 15:28:56 -07:00
committed by GitHub
parent 6a98fe2104
commit 47490b4383
25 changed files with 174 additions and 234 deletions

View File

@@ -1,6 +1,5 @@
use crate::traphandlers::{tls, wasmtime_longjmp, Trap};
use std::cell::RefCell;
use std::convert::TryInto;
use std::io;
use std::mem::{self, MaybeUninit};
use std::ptr::{self, null_mut};
@@ -291,36 +290,27 @@ pub fn lazy_per_thread_init() -> Result<(), Box<Trap>> {
// ... but failing that we need to allocate our own, so do all that
// here.
let page_size: usize = libc::sysconf(libc::_SC_PAGESIZE).try_into().unwrap();
let page_size: usize = region::page::size();
let guard_size = page_size;
let alloc_size = guard_size + MIN_STACK_SIZE;
let ptr = libc::mmap(
let ptr = rsix::io::mmap_anonymous(
null_mut(),
alloc_size,
libc::PROT_NONE,
libc::MAP_PRIVATE | libc::MAP_ANON,
-1,
0,
);
if ptr == libc::MAP_FAILED {
return Err(Box::new(Trap::oom()));
}
rsix::io::ProtFlags::NONE,
rsix::io::MapFlags::PRIVATE,
)
.map_err(|_| Box::new(Trap::oom()))?;
// Prepare the stack with readable/writable memory and then register it
// with `sigaltstack`.
let stack_ptr = (ptr as usize + guard_size) as *mut libc::c_void;
let r = libc::mprotect(
let stack_ptr = (ptr as usize + guard_size) as *mut std::ffi::c_void;
rsix::io::mprotect(
stack_ptr,
MIN_STACK_SIZE,
libc::PROT_READ | libc::PROT_WRITE,
);
assert_eq!(
r,
0,
"mprotect to configure memory for sigaltstack failed: {}",
io::Error::last_os_error()
);
rsix::io::MprotectFlags::READ | rsix::io::MprotectFlags::WRITE,
)
.expect("mprotect to configure memory for sigaltstack failed");
let new_stack = libc::stack_t {
ss_sp: stack_ptr,
ss_flags: 0,
@@ -344,8 +334,8 @@ pub fn lazy_per_thread_init() -> Result<(), Box<Trap>> {
fn drop(&mut self) {
unsafe {
// Deallocate the stack memory.
let r = libc::munmap(self.mmap_ptr, self.mmap_size);
debug_assert_eq!(r, 0, "munmap failed during thread shutdown");
let r = rsix::io::munmap(self.mmap_ptr, self.mmap_size);
debug_assert!(r.is_ok(), "munmap failed during thread shutdown");
}
}
}