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

@@ -16,9 +16,7 @@ use anyhow::Result;
use object::{Object, ObjectSection};
use std::fmt::Debug;
use std::fs::{File, OpenOptions};
use std::io;
use std::io::Write;
use std::os::unix::prelude::*;
use std::ptr;
use std::sync::Mutex;
use std::{borrow, mem, process};
@@ -177,17 +175,14 @@ impl JitDumpAgent {
// To match what some perf examples are doing we keep this `mmap` alive
// until this agent goes away.
let map_addr = unsafe {
let ptr = libc::mmap(
let ptr = rsix::io::mmap(
ptr::null_mut(),
libc::sysconf(libc::_SC_PAGESIZE) as usize,
libc::PROT_EXEC | libc::PROT_READ,
libc::MAP_PRIVATE,
jitdump_file.as_raw_fd(),
rsix::process::page_size(),
rsix::io::ProtFlags::EXEC | rsix::io::ProtFlags::READ,
rsix::io::MapFlags::PRIVATE,
&jitdump_file,
0,
);
if ptr == libc::MAP_FAILED {
return Err(io::Error::last_os_error().into());
}
)?;
ptr as usize
};
let mut state = State {
@@ -216,16 +211,9 @@ impl State {
// conveniently also uses, but `Instant` doesn't allow us to get access
// to nanoseconds as an internal detail, so we calculate the nanoseconds
// ourselves here.
unsafe {
let mut ts = mem::MaybeUninit::zeroed();
assert_eq!(
libc::clock_gettime(libc::CLOCK_MONOTONIC, ts.as_mut_ptr()),
0
);
let ts = ts.assume_init();
// TODO: What does it mean for either sec or nsec to be negative?
(ts.tv_sec * 1_000_000_000 + ts.tv_nsec) as u64
}
let ts = rsix::time::clock_gettime(rsix::time::ClockId::Monotonic);
// TODO: What does it mean for either sec or nsec to be negative?
(ts.tv_sec * 1_000_000_000 + ts.tv_nsec) as u64
}
/// Returns the ELF machine architecture.
@@ -649,10 +637,7 @@ impl State {
impl Drop for State {
fn drop(&mut self) {
unsafe {
libc::munmap(
self.map_addr as *mut _,
libc::sysconf(libc::_SC_PAGESIZE) as usize,
);
rsix::io::munmap(self.map_addr as *mut _, rsix::process::page_size()).unwrap();
}
}
}