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:
1
.github/workflows/main.yml
vendored
1
.github/workflows/main.yml
vendored
@@ -163,6 +163,7 @@ jobs:
|
|||||||
- run: |
|
- run: |
|
||||||
rustup target add wasm32-unknown-emscripten
|
rustup target add wasm32-unknown-emscripten
|
||||||
rustup target add armv7-unknown-linux-gnueabihf
|
rustup target add armv7-unknown-linux-gnueabihf
|
||||||
|
sudo apt-get install -y gcc-arm-linux-gnueabihf
|
||||||
- run: cargo check --target wasm32-unknown-emscripten -p wasi-common
|
- run: cargo check --target wasm32-unknown-emscripten -p wasi-common
|
||||||
- run: cargo check --target armv7-unknown-linux-gnueabihf -p wasi-common
|
- run: cargo check --target armv7-unknown-linux-gnueabihf -p wasi-common
|
||||||
|
|
||||||
|
|||||||
55
Cargo.lock
generated
55
Cargo.lock
generated
@@ -287,9 +287,9 @@ checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cap-fs-ext"
|
name = "cap-fs-ext"
|
||||||
version = "0.19.0"
|
version = "0.19.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a3e78f3c966b077a24e7bab715b983989b775f6e4fc925555b4cc64ede44022e"
|
checksum = "1bf5c3b436b94a1adac74032ff35d8aa5bae6ec2a7900e76432c9ae8dac4d673"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cap-primitives",
|
"cap-primitives",
|
||||||
"cap-std",
|
"cap-std",
|
||||||
@@ -300,9 +300,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cap-primitives"
|
name = "cap-primitives"
|
||||||
version = "0.19.0"
|
version = "0.19.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "53cdbdb79473b78acebdef84f853914cbda08f29d4fc80d8f647f68372e3b6bb"
|
checksum = "b51bd736eec54ae6552d18b0c958885b01d88c84c5fe6985e28c2b57ff385e94"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ambient-authority",
|
"ambient-authority",
|
||||||
"errno",
|
"errno",
|
||||||
@@ -321,9 +321,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cap-rand"
|
name = "cap-rand"
|
||||||
version = "0.19.0"
|
version = "0.19.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ce38e251919457b5e2808d53d8982a6a267898907a57c4fd909305c93300efd2"
|
checksum = "6e6e89d00b0cebeb6da7a459b81e6a49cf2092cc4afe03f28eb99b8f0e889344"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ambient-authority",
|
"ambient-authority",
|
||||||
"rand 0.8.3",
|
"rand 0.8.3",
|
||||||
@@ -331,9 +331,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cap-std"
|
name = "cap-std"
|
||||||
version = "0.19.0"
|
version = "0.19.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2f659706c014c6cfdbf1e13903699bc1c2d8bb84c1a0e1ae9b4cb333e8c6f3de"
|
checksum = "037334fe2f30ec71bcc51af1e8cbb8a9f9ac6a6b8cbd657d58dfef2ad5b9f19a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cap-primitives",
|
"cap-primitives",
|
||||||
"io-lifetimes",
|
"io-lifetimes",
|
||||||
@@ -345,9 +345,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cap-tempfile"
|
name = "cap-tempfile"
|
||||||
version = "0.19.0"
|
version = "0.19.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b3ec13e2e4ebce1d22ccb4553264fdb5c170d2070839d17540ddf17c05642d96"
|
checksum = "5160158dd17a01cfaf359e27a17fb6cc37c083347ed8c6e10583e08055d12c94"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cap-std",
|
"cap-std",
|
||||||
"rand 0.8.3",
|
"rand 0.8.3",
|
||||||
@@ -356,9 +356,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cap-time-ext"
|
name = "cap-time-ext"
|
||||||
version = "0.19.0"
|
version = "0.19.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "79d636df2f22174ea46acd0ca12b6f884139f82afbf10d9e91bdab694f988213"
|
checksum = "aea5319ada3a9517fc70eafe9cf3275f04da795c53770ebc5d91f4a33f4dd2b5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cap-primitives",
|
"cap-primitives",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
@@ -708,7 +708,7 @@ name = "cranelift-native"
|
|||||||
version = "0.77.0"
|
version = "0.77.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
"libc",
|
"rsix",
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1265,9 +1265,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fs-set-times"
|
name = "fs-set-times"
|
||||||
version = "0.11.0"
|
version = "0.12.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b05f9ac4aceff7d9f3cd1701217aa72f87a0bf7c6592886efe819727292a4c7f"
|
checksum = "807e3ef0de04fbe498bebd560ae041e006d97bf9f726dc0b485a86316be0ebc8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"io-lifetimes",
|
"io-lifetimes",
|
||||||
"rsix",
|
"rsix",
|
||||||
@@ -1480,9 +1480,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "io-lifetimes"
|
name = "io-lifetimes"
|
||||||
version = "0.3.0"
|
version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e94e87a80ab2e1aad23d4b8c4feb954125ac4da906891e041d93f5861a5fdd78"
|
checksum = "47f5ce4afb9bf504b9f496a3307676bc232122f91a93c4da6d540aa99a0a0e0b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustc_version",
|
"rustc_version",
|
||||||
"winapi",
|
"winapi",
|
||||||
@@ -1648,9 +1648,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.0.23"
|
version = "0.0.24"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5802c30e8a573a9af97d504e9e66a076e0b881112222a67a8e037a79658447d6"
|
checksum = "13d803e4a041d0deed25db109ac7ba704d1edd62588b623feb8beed5da78e579"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
@@ -2603,9 +2603,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rsix"
|
name = "rsix"
|
||||||
version = "0.22.4"
|
version = "0.23.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "19dc84e006a7522c44207fcd9c1f504f7c9a503093070840105930a685e299a0"
|
checksum = "bcb64fd899aa29c8f920e52732489630b55dba438039eee73ee068e995f64ef2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cc",
|
"cc",
|
||||||
@@ -2934,9 +2934,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "system-interface"
|
name = "system-interface"
|
||||||
version = "0.14.0"
|
version = "0.15.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8687be991be7468d6042aeecaedea242221afadbec8d0cb86f5a0df1a4206dc7"
|
checksum = "6cb3a23bf923c3fdaf0c36a8c016047e415f0559a5b891de7ec3d19d58b9b503"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
@@ -3628,14 +3628,13 @@ dependencies = [
|
|||||||
"base64",
|
"base64",
|
||||||
"bincode",
|
"bincode",
|
||||||
"directories-next",
|
"directories-next",
|
||||||
"errno",
|
|
||||||
"file-per-thread-logger",
|
"file-per-thread-logger",
|
||||||
"filetime",
|
"filetime",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
|
||||||
"log",
|
"log",
|
||||||
"more-asserts",
|
"more-asserts",
|
||||||
"pretty_env_logger",
|
"pretty_env_logger",
|
||||||
|
"rsix",
|
||||||
"serde",
|
"serde",
|
||||||
"sha2",
|
"sha2",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
@@ -3663,6 +3662,7 @@ dependencies = [
|
|||||||
"object",
|
"object",
|
||||||
"pretty_env_logger",
|
"pretty_env_logger",
|
||||||
"rayon",
|
"rayon",
|
||||||
|
"rsix",
|
||||||
"structopt",
|
"structopt",
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
@@ -3730,7 +3730,7 @@ version = "0.30.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"rsix",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -3783,11 +3783,11 @@ dependencies = [
|
|||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"gimli",
|
"gimli",
|
||||||
"ittapi-rs",
|
"ittapi-rs",
|
||||||
"libc",
|
|
||||||
"log",
|
"log",
|
||||||
"more-asserts",
|
"more-asserts",
|
||||||
"object",
|
"object",
|
||||||
"region",
|
"region",
|
||||||
|
"rsix",
|
||||||
"serde",
|
"serde",
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
@@ -3828,6 +3828,7 @@ dependencies = [
|
|||||||
"more-asserts",
|
"more-asserts",
|
||||||
"rand 0.8.3",
|
"rand 0.8.3",
|
||||||
"region",
|
"region",
|
||||||
|
"rsix",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"userfaultfd",
|
"userfaultfd",
|
||||||
"wasmtime-environ",
|
"wasmtime-environ",
|
||||||
|
|||||||
@@ -44,6 +44,9 @@ humantime = "2.0.0"
|
|||||||
wasmparser = "0.80.0"
|
wasmparser = "0.80.0"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
|
|
||||||
|
[target.'cfg(unix)'.dependencies]
|
||||||
|
rsix = "0.23.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
env_logger = "0.8.1"
|
env_logger = "0.8.1"
|
||||||
filecheck = "0.5.0"
|
filecheck = "0.5.0"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ cranelift-codegen = { path = "../codegen", version = "0.77.0", default-features
|
|||||||
target-lexicon = "0.12"
|
target-lexicon = "0.12"
|
||||||
|
|
||||||
[target.'cfg(target_arch = "s390x")'.dependencies]
|
[target.'cfg(target_arch = "s390x")'.dependencies]
|
||||||
libc = "0.2.95"
|
rsix = "0.23.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ pub fn builder_with_options(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// There is no is_s390x_feature_detected macro yet, so for now
|
// There is no is_s390x_feature_detected macro yet, so for now
|
||||||
// we use getauxval from the libc crate directly.
|
// we use linux_hwcap from the rsix crate directly.
|
||||||
#[cfg(all(target_arch = "s390x", target_os = "linux"))]
|
#[cfg(all(target_arch = "s390x", target_os = "linux"))]
|
||||||
{
|
{
|
||||||
use cranelift_codegen::settings::Configurable;
|
use cranelift_codegen::settings::Configurable;
|
||||||
@@ -135,8 +135,8 @@ pub fn builder_with_options(
|
|||||||
return Ok(isa_builder);
|
return Ok(isa_builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
let v = unsafe { libc::getauxval(libc::AT_HWCAP) };
|
let v = rsix::process::linux_hwcap().0;
|
||||||
const HWCAP_S390X_VXRS_EXT2: libc::c_ulong = 32768;
|
const HWCAP_S390X_VXRS_EXT2: usize = 32768;
|
||||||
if (v & HWCAP_S390X_VXRS_EXT2) != 0 {
|
if (v & HWCAP_S390X_VXRS_EXT2) != 0 {
|
||||||
isa_builder.enable("has_vxrs_ext2").unwrap();
|
isa_builder.enable("has_vxrs_ext2").unwrap();
|
||||||
// There is no separate HWCAP bit for mie2, so assume
|
// There is no separate HWCAP bit for mie2, so assume
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ wasmtime-wasi = { path = "../wasi" }
|
|||||||
wasmtime-wasi-crypto = { path = "../wasi-crypto", optional = true }
|
wasmtime-wasi-crypto = { path = "../wasi-crypto", optional = true }
|
||||||
wasmtime-wasi-nn = { path = "../wasi-nn", optional = true }
|
wasmtime-wasi-nn = { path = "../wasi-nn", optional = true }
|
||||||
wasi-cap-std-sync = { path = "../wasi-common/cap-std-sync" }
|
wasi-cap-std-sync = { path = "../wasi-common/cap-std-sync" }
|
||||||
cap-std = "0.19.0"
|
cap-std = "0.19.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
wat = "1.0"
|
wat = "1.0"
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ wat = { version = "1.0.36", optional = true }
|
|||||||
wasi-common = { path = "../wasi-common", optional = true }
|
wasi-common = { path = "../wasi-common", optional = true }
|
||||||
wasi-cap-std-sync = { path = "../wasi-common/cap-std-sync", optional = true }
|
wasi-cap-std-sync = { path = "../wasi-common/cap-std-sync", optional = true }
|
||||||
wasmtime-wasi = { path = "../wasi", optional = true }
|
wasmtime-wasi = { path = "../wasi", optional = true }
|
||||||
cap-std = { version = "0.19.0", optional = true }
|
cap-std = { version = "0.19.1", optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ['jitdump', 'wat', 'wasi', 'cache']
|
default = ['jitdump', 'wat', 'wasi', 'cache']
|
||||||
|
|||||||
3
crates/cache/Cargo.toml
vendored
3
crates/cache/Cargo.toml
vendored
@@ -24,8 +24,7 @@ zstd = { version = "0.9", default-features = false }
|
|||||||
winapi = "0.3.7"
|
winapi = "0.3.7"
|
||||||
|
|
||||||
[target.'cfg(not(target_os = "windows"))'.dependencies]
|
[target.'cfg(not(target_os = "windows"))'.dependencies]
|
||||||
errno = "0.2.4"
|
rsix = "0.23.0"
|
||||||
libc = "0.2.60"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
filetime = "0.2.7"
|
filetime = "0.2.7"
|
||||||
|
|||||||
22
crates/cache/src/worker.rs
vendored
22
crates/cache/src/worker.rs
vendored
@@ -256,19 +256,15 @@ impl WorkerThread {
|
|||||||
|
|
||||||
const NICE_DELTA_FOR_BACKGROUND_TASKS: i32 = 3;
|
const NICE_DELTA_FOR_BACKGROUND_TASKS: i32 = 3;
|
||||||
|
|
||||||
errno::set_errno(errno::Errno(0));
|
match rsix::process::nice(NICE_DELTA_FOR_BACKGROUND_TASKS) {
|
||||||
let current_nice = unsafe { libc::nice(NICE_DELTA_FOR_BACKGROUND_TASKS) };
|
Ok(current_nice) => {
|
||||||
let errno_val = errno::errno().0;
|
debug!("New nice value of worker thread: {}", current_nice);
|
||||||
|
}
|
||||||
if errno_val != 0 {
|
Err(err) => {
|
||||||
warn!(
|
warn!(
|
||||||
"Failed to lower worker thread priority. It might affect application performance. \
|
"Failed to lower worker thread priority ({:?}). It might affect application performance.", err);
|
||||||
errno: {}",
|
}
|
||||||
errno_val
|
};
|
||||||
);
|
|
||||||
} else {
|
|
||||||
debug!("New nice value of worker thread: {}", current_nice);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Increases the usage counter and recompresses the file
|
/// Increases the usage counter and recompresses the file
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ edition = "2018"
|
|||||||
links = "wasmtime-fiber-shims"
|
links = "wasmtime-fiber-shims"
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
libc = "0.2.80"
|
rsix = "0.23.0"
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies.winapi]
|
[target.'cfg(windows)'.dependencies.winapi]
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
|
|||||||
@@ -45,38 +45,30 @@ pub struct FiberStack {
|
|||||||
|
|
||||||
impl FiberStack {
|
impl FiberStack {
|
||||||
pub fn new(size: usize) -> io::Result<Self> {
|
pub fn new(size: usize) -> io::Result<Self> {
|
||||||
unsafe {
|
// Round up our stack size request to the nearest multiple of the
|
||||||
// Round up our stack size request to the nearest multiple of the
|
// page size.
|
||||||
// page size.
|
let page_size = rsix::process::page_size();
|
||||||
let page_size = libc::sysconf(libc::_SC_PAGESIZE) as usize;
|
let size = if size == 0 {
|
||||||
let size = if size == 0 {
|
page_size
|
||||||
page_size
|
} else {
|
||||||
} else {
|
(size + (page_size - 1)) & (!(page_size - 1))
|
||||||
(size + (page_size - 1)) & (!(page_size - 1))
|
};
|
||||||
};
|
|
||||||
|
|
||||||
|
unsafe {
|
||||||
// Add in one page for a guard page and then ask for some memory.
|
// Add in one page for a guard page and then ask for some memory.
|
||||||
let mmap_len = size + page_size;
|
let mmap_len = size + page_size;
|
||||||
let mmap = libc::mmap(
|
let mmap = rsix::io::mmap_anonymous(
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
mmap_len,
|
mmap_len,
|
||||||
libc::PROT_NONE,
|
rsix::io::ProtFlags::NONE,
|
||||||
libc::MAP_ANON | libc::MAP_PRIVATE,
|
rsix::io::MapFlags::PRIVATE,
|
||||||
-1,
|
)?;
|
||||||
0,
|
|
||||||
);
|
|
||||||
if mmap == libc::MAP_FAILED {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
if libc::mprotect(
|
rsix::io::mprotect(
|
||||||
mmap.cast::<u8>().add(page_size).cast(),
|
mmap.cast::<u8>().add(page_size).cast(),
|
||||||
size,
|
size,
|
||||||
libc::PROT_READ | libc::PROT_WRITE,
|
rsix::io::MprotectFlags::READ | rsix::io::MprotectFlags::WRITE,
|
||||||
) != 0
|
)?;
|
||||||
{
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
top: mmap.cast::<u8>().add(mmap_len),
|
top: mmap.cast::<u8>().add(mmap_len),
|
||||||
@@ -98,8 +90,8 @@ impl Drop for FiberStack {
|
|||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
if let Some(len) = self.len {
|
if let Some(len) = self.len {
|
||||||
let ret = libc::munmap(self.top.sub(len) as _, len);
|
let ret = rsix::io::munmap(self.top.sub(len) as _, len);
|
||||||
debug_assert!(ret == 0);
|
debug_assert!(ret.is_ok());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,15 +25,17 @@ gimli = { version = "0.25.0", default-features = false, features = ["std", "read
|
|||||||
object = { version = "0.26.0", default-features = false, features = ["std", "read_core", "elf"] }
|
object = { version = "0.26.0", default-features = false, features = ["std", "read_core", "elf"] }
|
||||||
serde = { version = "1.0.94", features = ["derive"] }
|
serde = { version = "1.0.94", features = ["derive"] }
|
||||||
addr2line = { version = "0.16.0", default-features = false }
|
addr2line = { version = "0.16.0", default-features = false }
|
||||||
libc = { version = "0.2.60", default-features = false, optional = true }
|
|
||||||
ittapi-rs = { version = "0.1.5", optional = true }
|
ittapi-rs = { version = "0.1.5", optional = true }
|
||||||
bincode = "1.2.1"
|
bincode = "1.2.1"
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
winapi = { version = "0.3.8", features = ["winnt", "impl-default"] }
|
winapi = { version = "0.3.8", features = ["winnt", "impl-default"] }
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "linux")'.dependencies]
|
||||||
|
rsix = { version = "0.23.0", optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
jitdump = ['libc']
|
jitdump = ['rsix']
|
||||||
vtune = ['ittapi-rs']
|
vtune = ['ittapi-rs']
|
||||||
|
|
||||||
[badges]
|
[badges]
|
||||||
|
|||||||
@@ -16,9 +16,7 @@ use anyhow::Result;
|
|||||||
use object::{Object, ObjectSection};
|
use object::{Object, ObjectSection};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::fs::{File, OpenOptions};
|
use std::fs::{File, OpenOptions};
|
||||||
use std::io;
|
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::os::unix::prelude::*;
|
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use std::{borrow, mem, process};
|
use std::{borrow, mem, process};
|
||||||
@@ -177,17 +175,14 @@ impl JitDumpAgent {
|
|||||||
// To match what some perf examples are doing we keep this `mmap` alive
|
// To match what some perf examples are doing we keep this `mmap` alive
|
||||||
// until this agent goes away.
|
// until this agent goes away.
|
||||||
let map_addr = unsafe {
|
let map_addr = unsafe {
|
||||||
let ptr = libc::mmap(
|
let ptr = rsix::io::mmap(
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
libc::sysconf(libc::_SC_PAGESIZE) as usize,
|
rsix::process::page_size(),
|
||||||
libc::PROT_EXEC | libc::PROT_READ,
|
rsix::io::ProtFlags::EXEC | rsix::io::ProtFlags::READ,
|
||||||
libc::MAP_PRIVATE,
|
rsix::io::MapFlags::PRIVATE,
|
||||||
jitdump_file.as_raw_fd(),
|
&jitdump_file,
|
||||||
0,
|
0,
|
||||||
);
|
)?;
|
||||||
if ptr == libc::MAP_FAILED {
|
|
||||||
return Err(io::Error::last_os_error().into());
|
|
||||||
}
|
|
||||||
ptr as usize
|
ptr as usize
|
||||||
};
|
};
|
||||||
let mut state = State {
|
let mut state = State {
|
||||||
@@ -216,16 +211,9 @@ impl State {
|
|||||||
// conveniently also uses, but `Instant` doesn't allow us to get access
|
// conveniently also uses, but `Instant` doesn't allow us to get access
|
||||||
// to nanoseconds as an internal detail, so we calculate the nanoseconds
|
// to nanoseconds as an internal detail, so we calculate the nanoseconds
|
||||||
// ourselves here.
|
// ourselves here.
|
||||||
unsafe {
|
let ts = rsix::time::clock_gettime(rsix::time::ClockId::Monotonic);
|
||||||
let mut ts = mem::MaybeUninit::zeroed();
|
// TODO: What does it mean for either sec or nsec to be negative?
|
||||||
assert_eq!(
|
(ts.tv_sec * 1_000_000_000 + ts.tv_nsec) as u64
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the ELF machine architecture.
|
/// Returns the ELF machine architecture.
|
||||||
@@ -649,10 +637,7 @@ impl State {
|
|||||||
impl Drop for State {
|
impl Drop for State {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
libc::munmap(
|
rsix::io::munmap(self.map_addr as *mut _, rsix::process::page_size()).unwrap();
|
||||||
self.map_addr as *mut _,
|
|
||||||
libc::sysconf(libc::_SC_PAGESIZE) as usize,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ anyhow = "1.0.38"
|
|||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
mach = "0.3.2"
|
mach = "0.3.2"
|
||||||
|
|
||||||
|
[target.'cfg(unix)'.dependencies]
|
||||||
|
rsix = "0.23.2"
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
winapi = { version = "0.3.7", features = ["winbase", "memoryapi", "errhandlingapi", "handleapi"] }
|
winapi = { version = "0.3.7", features = ["winbase", "memoryapi", "errhandlingapi", "handleapi"] }
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use anyhow::{bail, Context, Result};
|
use anyhow::{Context, Result};
|
||||||
|
|
||||||
fn decommit(addr: *mut u8, len: usize, protect: bool) -> Result<()> {
|
fn decommit(addr: *mut u8, len: usize, protect: bool) -> Result<()> {
|
||||||
if len == 0 {
|
if len == 0 {
|
||||||
@@ -12,12 +12,8 @@ fn decommit(addr: *mut u8, len: usize, protect: bool) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// On Linux, this is enough to cause the kernel to initialize the pages to 0 on next access
|
// On Linux, this is enough to cause the kernel to initialize the pages to 0 on next access
|
||||||
if libc::madvise(addr as _, len, libc::MADV_DONTNEED) != 0 {
|
rsix::io::madvise(addr as _, len, rsix::io::Advice::LinuxDontNeed)
|
||||||
bail!(
|
.context("madvise failed to decommit: {}")?;
|
||||||
"madvise failed to decommit: {}",
|
|
||||||
std::io::Error::last_os_error()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
use super::{InstancePool, MemoryPool};
|
use super::{InstancePool, MemoryPool};
|
||||||
use crate::instance::Instance;
|
use crate::instance::Instance;
|
||||||
use anyhow::{bail, Context, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
|
use rsix::io::{madvise, Advice};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use userfaultfd::{Event, FeatureFlags, IoctlFlags, Uffd, UffdBuilder};
|
use userfaultfd::{Event, FeatureFlags, IoctlFlags, Uffd, UffdBuilder};
|
||||||
use wasmtime_environ::{DefinedMemoryIndex, EntityRef, MemoryInitialization};
|
use wasmtime_environ::{DefinedMemoryIndex, EntityRef, MemoryInitialization};
|
||||||
@@ -50,12 +51,7 @@ fn decommit(addr: *mut u8, len: usize) -> Result<()> {
|
|||||||
// and the user fault handler will receive the event.
|
// and the user fault handler will receive the event.
|
||||||
// If the pages are not monitored by uffd, the kernel will zero the page on next access,
|
// If the pages are not monitored by uffd, the kernel will zero the page on next access,
|
||||||
// as if it were mmap'd for the first time.
|
// as if it were mmap'd for the first time.
|
||||||
if libc::madvise(addr as _, len, libc::MADV_DONTNEED) != 0 {
|
madvise(addr as _, len, Advice::LinuxDontNeed).context("madvise failed to decommit")?;
|
||||||
bail!(
|
|
||||||
"madvise failed to decommit: {}",
|
|
||||||
std::io::Error::last_os_error()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use anyhow::{bail, Context, Result};
|
use anyhow::{Context, Result};
|
||||||
|
|
||||||
fn decommit(addr: *mut u8, len: usize, protect: bool) -> Result<()> {
|
fn decommit(addr: *mut u8, len: usize, protect: bool) -> Result<()> {
|
||||||
if len == 0 {
|
if len == 0 {
|
||||||
@@ -9,25 +9,18 @@ fn decommit(addr: *mut u8, len: usize, protect: bool) -> Result<()> {
|
|||||||
// mapping for the pages in the given range.
|
// mapping for the pages in the given range.
|
||||||
// The new mapping will be to the CoW zero page, so this effectively
|
// The new mapping will be to the CoW zero page, so this effectively
|
||||||
// zeroes the pages.
|
// zeroes the pages.
|
||||||
if unsafe {
|
unsafe {
|
||||||
libc::mmap(
|
rsix::io::mmap_anonymous(
|
||||||
addr as _,
|
addr as _,
|
||||||
len,
|
len,
|
||||||
if protect {
|
if protect {
|
||||||
libc::PROT_NONE
|
rsix::io::ProtFlags::NONE
|
||||||
} else {
|
} else {
|
||||||
libc::PROT_READ | libc::PROT_WRITE
|
rsix::io::ProtFlags::READ | rsix::io::ProtFlags::WRITE
|
||||||
},
|
},
|
||||||
libc::MAP_PRIVATE | libc::MAP_ANON | libc::MAP_FIXED,
|
rsix::io::MapFlags::PRIVATE | rsix::io::MapFlags::FIXED,
|
||||||
-1,
|
)
|
||||||
0,
|
.context("mmap failed to remap pages: {}")?;
|
||||||
) as *mut u8
|
|
||||||
} != addr
|
|
||||||
{
|
|
||||||
bail!(
|
|
||||||
"mmap failed to remap pages: {}",
|
|
||||||
std::io::Error::last_os_error()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -2,11 +2,10 @@
|
|||||||
//! of memory.
|
//! of memory.
|
||||||
|
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use anyhow::{bail, Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use more_asserts::assert_le;
|
use more_asserts::assert_le;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io;
|
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
@@ -57,8 +56,6 @@ impl Mmap {
|
|||||||
pub fn from_file(path: &Path) -> Result<Self> {
|
pub fn from_file(path: &Path) -> Result<Self> {
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
{
|
{
|
||||||
use std::os::unix::prelude::*;
|
|
||||||
|
|
||||||
let file = File::open(path).context("failed to open file")?;
|
let file = File::open(path).context("failed to open file")?;
|
||||||
let len = file
|
let len = file
|
||||||
.metadata()
|
.metadata()
|
||||||
@@ -66,19 +63,16 @@ impl Mmap {
|
|||||||
.len();
|
.len();
|
||||||
let len = usize::try_from(len).map_err(|_| anyhow!("file too large to map"))?;
|
let len = usize::try_from(len).map_err(|_| anyhow!("file too large to map"))?;
|
||||||
let ptr = unsafe {
|
let ptr = unsafe {
|
||||||
libc::mmap(
|
rsix::io::mmap(
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
len,
|
len,
|
||||||
libc::PROT_READ,
|
rsix::io::ProtFlags::READ,
|
||||||
libc::MAP_PRIVATE,
|
rsix::io::MapFlags::PRIVATE,
|
||||||
file.as_raw_fd(),
|
&file,
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
|
.context(format!("mmap failed to allocate {:#x} bytes", len))?
|
||||||
};
|
};
|
||||||
if ptr as isize == -1_isize {
|
|
||||||
return Err(io::Error::last_os_error())
|
|
||||||
.context(format!("mmap failed to allocate {:#x} bytes", len));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
ptr: ptr as usize,
|
ptr: ptr as usize,
|
||||||
@@ -90,6 +84,7 @@ impl Mmap {
|
|||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
|
use std::io;
|
||||||
use std::os::windows::prelude::*;
|
use std::os::windows::prelude::*;
|
||||||
use winapi::um::handleapi::*;
|
use winapi::um::handleapi::*;
|
||||||
use winapi::um::memoryapi::*;
|
use winapi::um::memoryapi::*;
|
||||||
@@ -175,22 +170,14 @@ impl Mmap {
|
|||||||
Ok(if accessible_size == mapping_size {
|
Ok(if accessible_size == mapping_size {
|
||||||
// Allocate a single read-write region at once.
|
// Allocate a single read-write region at once.
|
||||||
let ptr = unsafe {
|
let ptr = unsafe {
|
||||||
libc::mmap(
|
rsix::io::mmap_anonymous(
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
mapping_size,
|
mapping_size,
|
||||||
libc::PROT_READ | libc::PROT_WRITE,
|
rsix::io::ProtFlags::READ | rsix::io::ProtFlags::WRITE,
|
||||||
libc::MAP_PRIVATE | libc::MAP_ANON,
|
rsix::io::MapFlags::PRIVATE,
|
||||||
-1,
|
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
|
.context(format!("mmap failed to allocate {:#x} bytes", mapping_size))?
|
||||||
};
|
};
|
||||||
if ptr as isize == -1_isize {
|
|
||||||
bail!(
|
|
||||||
"mmap failed to allocate {:#x} bytes: {}",
|
|
||||||
mapping_size,
|
|
||||||
io::Error::last_os_error()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
ptr: ptr as usize,
|
ptr: ptr as usize,
|
||||||
@@ -200,22 +187,14 @@ impl Mmap {
|
|||||||
} else {
|
} else {
|
||||||
// Reserve the mapping size.
|
// Reserve the mapping size.
|
||||||
let ptr = unsafe {
|
let ptr = unsafe {
|
||||||
libc::mmap(
|
rsix::io::mmap_anonymous(
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
mapping_size,
|
mapping_size,
|
||||||
libc::PROT_NONE,
|
rsix::io::ProtFlags::NONE,
|
||||||
libc::MAP_PRIVATE | libc::MAP_ANON,
|
rsix::io::MapFlags::PRIVATE,
|
||||||
-1,
|
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
|
.context(format!("mmap failed to allocate {:#x} bytes", mapping_size))?
|
||||||
};
|
};
|
||||||
if ptr as isize == -1_isize {
|
|
||||||
bail!(
|
|
||||||
"mmap failed to allocate {:#x} bytes: {}",
|
|
||||||
mapping_size,
|
|
||||||
io::Error::last_os_error()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut result = Self {
|
let mut result = Self {
|
||||||
ptr: ptr as usize,
|
ptr: ptr as usize,
|
||||||
@@ -237,6 +216,8 @@ impl Mmap {
|
|||||||
/// must be native page-size multiples.
|
/// must be native page-size multiples.
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
pub fn accessible_reserved(accessible_size: usize, mapping_size: usize) -> Result<Self> {
|
pub fn accessible_reserved(accessible_size: usize, mapping_size: usize) -> Result<Self> {
|
||||||
|
use anyhow::bail;
|
||||||
|
use std::io;
|
||||||
use winapi::um::memoryapi::VirtualAlloc;
|
use winapi::um::memoryapi::VirtualAlloc;
|
||||||
use winapi::um::winnt::{MEM_COMMIT, MEM_RESERVE, PAGE_NOACCESS, PAGE_READWRITE};
|
use winapi::um::winnt::{MEM_COMMIT, MEM_RESERVE, PAGE_NOACCESS, PAGE_READWRITE};
|
||||||
|
|
||||||
@@ -316,6 +297,8 @@ impl Mmap {
|
|||||||
/// `self`'s reserved memory.
|
/// `self`'s reserved memory.
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
pub fn make_accessible(&mut self, start: usize, len: usize) -> Result<()> {
|
pub fn make_accessible(&mut self, start: usize, len: usize) -> Result<()> {
|
||||||
|
use anyhow::bail;
|
||||||
|
use std::io;
|
||||||
use winapi::ctypes::c_void;
|
use winapi::ctypes::c_void;
|
||||||
use winapi::um::memoryapi::VirtualAlloc;
|
use winapi::um::memoryapi::VirtualAlloc;
|
||||||
use winapi::um::winnt::{MEM_COMMIT, PAGE_READWRITE};
|
use winapi::um::winnt::{MEM_COMMIT, PAGE_READWRITE};
|
||||||
@@ -398,6 +381,7 @@ impl Mmap {
|
|||||||
// we don't want our modifications to go back to the original file.
|
// we don't want our modifications to go back to the original file.
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
|
use std::io;
|
||||||
use winapi::um::memoryapi::*;
|
use winapi::um::memoryapi::*;
|
||||||
use winapi::um::winnt::*;
|
use winapi::um::winnt::*;
|
||||||
|
|
||||||
@@ -440,8 +424,8 @@ impl Drop for Mmap {
|
|||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if self.len != 0 {
|
if self.len != 0 {
|
||||||
let r = unsafe { libc::munmap(self.ptr as *mut libc::c_void, self.len) };
|
unsafe { rsix::io::munmap(self.ptr as *mut std::ffi::c_void, self.len) }
|
||||||
assert_eq!(r, 0, "munmap failed: {}", io::Error::last_os_error());
|
.expect("munmap failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use crate::traphandlers::{tls, wasmtime_longjmp, Trap};
|
use crate::traphandlers::{tls, wasmtime_longjmp, Trap};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::convert::TryInto;
|
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::mem::{self, MaybeUninit};
|
use std::mem::{self, MaybeUninit};
|
||||||
use std::ptr::{self, null_mut};
|
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
|
// ... but failing that we need to allocate our own, so do all that
|
||||||
// here.
|
// 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 guard_size = page_size;
|
||||||
let alloc_size = guard_size + MIN_STACK_SIZE;
|
let alloc_size = guard_size + MIN_STACK_SIZE;
|
||||||
|
|
||||||
let ptr = libc::mmap(
|
let ptr = rsix::io::mmap_anonymous(
|
||||||
null_mut(),
|
null_mut(),
|
||||||
alloc_size,
|
alloc_size,
|
||||||
libc::PROT_NONE,
|
rsix::io::ProtFlags::NONE,
|
||||||
libc::MAP_PRIVATE | libc::MAP_ANON,
|
rsix::io::MapFlags::PRIVATE,
|
||||||
-1,
|
)
|
||||||
0,
|
.map_err(|_| Box::new(Trap::oom()))?;
|
||||||
);
|
|
||||||
if ptr == libc::MAP_FAILED {
|
|
||||||
return Err(Box::new(Trap::oom()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare the stack with readable/writable memory and then register it
|
// Prepare the stack with readable/writable memory and then register it
|
||||||
// with `sigaltstack`.
|
// with `sigaltstack`.
|
||||||
let stack_ptr = (ptr as usize + guard_size) as *mut libc::c_void;
|
let stack_ptr = (ptr as usize + guard_size) as *mut std::ffi::c_void;
|
||||||
let r = libc::mprotect(
|
rsix::io::mprotect(
|
||||||
stack_ptr,
|
stack_ptr,
|
||||||
MIN_STACK_SIZE,
|
MIN_STACK_SIZE,
|
||||||
libc::PROT_READ | libc::PROT_WRITE,
|
rsix::io::MprotectFlags::READ | rsix::io::MprotectFlags::WRITE,
|
||||||
);
|
)
|
||||||
assert_eq!(
|
.expect("mprotect to configure memory for sigaltstack failed");
|
||||||
r,
|
|
||||||
0,
|
|
||||||
"mprotect to configure memory for sigaltstack failed: {}",
|
|
||||||
io::Error::last_os_error()
|
|
||||||
);
|
|
||||||
let new_stack = libc::stack_t {
|
let new_stack = libc::stack_t {
|
||||||
ss_sp: stack_ptr,
|
ss_sp: stack_ptr,
|
||||||
ss_flags: 0,
|
ss_flags: 0,
|
||||||
@@ -344,8 +334,8 @@ pub fn lazy_per_thread_init() -> Result<(), Box<Trap>> {
|
|||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
// Deallocate the stack memory.
|
// Deallocate the stack memory.
|
||||||
let r = libc::munmap(self.mmap_ptr, self.mmap_size);
|
let r = rsix::io::munmap(self.mmap_ptr, self.mmap_size);
|
||||||
debug_assert_eq!(r, 0, "munmap failed during thread shutdown");
|
debug_assert!(r.is_ok(), "munmap failed during thread shutdown");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ tempfile = "3.1.0"
|
|||||||
os_pipe = "0.9"
|
os_pipe = "0.9"
|
||||||
anyhow = "1.0.19"
|
anyhow = "1.0.19"
|
||||||
wat = "1.0.37"
|
wat = "1.0.37"
|
||||||
cap-std = "0.19.0"
|
cap-std = "0.19.1"
|
||||||
tokio = { version = "1.8.0", features = ["rt-multi-thread"] }
|
tokio = { version = "1.8.0", features = ["rt-multi-thread"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|||||||
@@ -22,13 +22,13 @@ anyhow = "1.0"
|
|||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
wiggle = { path = "../wiggle", default-features = false, version = "0.30.0" }
|
wiggle = { path = "../wiggle", default-features = false, version = "0.30.0" }
|
||||||
tracing = "0.1.19"
|
tracing = "0.1.19"
|
||||||
cap-std = "0.19.0"
|
cap-std = "0.19.1"
|
||||||
cap-rand = "0.19.0"
|
cap-rand = "0.19.1"
|
||||||
bitflags = "1.2"
|
bitflags = "1.2"
|
||||||
io-lifetimes = { version = "0.3.0", default-features = false }
|
io-lifetimes = { version = "0.3.1", default-features = false }
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
rsix = "0.22.4"
|
rsix = "0.23.0"
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = "0.3"
|
winapi = "0.3"
|
||||||
|
|||||||
@@ -15,18 +15,18 @@ include = ["src/**/*", "README.md", "LICENSE" ]
|
|||||||
wasi-common = { path = "../", version = "0.30.0" }
|
wasi-common = { path = "../", version = "0.30.0" }
|
||||||
async-trait = "0.1"
|
async-trait = "0.1"
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
cap-std = "0.19.0"
|
cap-std = "0.19.1"
|
||||||
cap-fs-ext = "0.19.0"
|
cap-fs-ext = "0.19.1"
|
||||||
cap-time-ext = "0.19.0"
|
cap-time-ext = "0.19.1"
|
||||||
cap-rand = "0.19.0"
|
cap-rand = "0.19.1"
|
||||||
fs-set-times = "0.11.0"
|
fs-set-times = "0.12.0"
|
||||||
system-interface = { version = "0.14.0", features = ["cap_std_impls"] }
|
system-interface = { version = "0.15.0", features = ["cap_std_impls"] }
|
||||||
tracing = "0.1.19"
|
tracing = "0.1.19"
|
||||||
bitflags = "1.2"
|
bitflags = "1.2"
|
||||||
io-lifetimes = { version = "0.3.0", default-features = false }
|
io-lifetimes = { version = "0.3.0", default-features = false }
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
rsix = "0.22.4"
|
rsix = "0.23.0"
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = "0.3"
|
winapi = "0.3"
|
||||||
|
|||||||
@@ -15,18 +15,18 @@ wasi-common = { path = "../", version = "0.30.0" }
|
|||||||
wasi-cap-std-sync = { path = "../cap-std-sync", version = "0.30.0" }
|
wasi-cap-std-sync = { path = "../cap-std-sync", version = "0.30.0" }
|
||||||
wiggle = { path = "../../wiggle", version = "0.30.0" }
|
wiggle = { path = "../../wiggle", version = "0.30.0" }
|
||||||
tokio = { version = "1.8.0", features = [ "rt", "fs", "time", "io-util", "net", "io-std", "rt-multi-thread"] }
|
tokio = { version = "1.8.0", features = [ "rt", "fs", "time", "io-util", "net", "io-std", "rt-multi-thread"] }
|
||||||
cap-std = "0.19.0"
|
cap-std = "0.19.1"
|
||||||
cap-fs-ext = "0.19.0"
|
cap-fs-ext = "0.19.1"
|
||||||
cap-time-ext = "0.19.0"
|
cap-time-ext = "0.19.1"
|
||||||
fs-set-times = "0.11.0"
|
fs-set-times = "0.12.0"
|
||||||
system-interface = { version = "0.14.0", features = ["cap_std_impls"] }
|
system-interface = { version = "0.15.0", features = ["cap_std_impls"] }
|
||||||
tracing = "0.1.19"
|
tracing = "0.1.19"
|
||||||
bitflags = "1.2"
|
bitflags = "1.2"
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
io-lifetimes = { version = "0.3.0", default-features = false }
|
io-lifetimes = { version = "0.3.0", default-features = false }
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
rsix = "0.22.4"
|
rsix = "0.23.0"
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = "0.3"
|
winapi = "0.3"
|
||||||
@@ -36,4 +36,4 @@ lazy_static = "1.4"
|
|||||||
tempfile = "3.1.0"
|
tempfile = "3.1.0"
|
||||||
tokio = { version = "1.8.0", features = [ "macros" ] }
|
tokio = { version = "1.8.0", features = [ "macros" ] }
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
cap-tempfile = "0.19.0"
|
cap-tempfile = "0.19.1"
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
))]
|
))]
|
||||||
mod tests {
|
mod tests {
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use rsix::io::{mprotect, MprotectFlags};
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use wasmtime::unix::StoreExt;
|
use wasmtime::unix::StoreExt;
|
||||||
@@ -59,7 +60,7 @@ mod tests {
|
|||||||
|
|
||||||
// So we can later trigger SIGSEGV by performing a read
|
// So we can later trigger SIGSEGV by performing a read
|
||||||
unsafe {
|
unsafe {
|
||||||
libc::mprotect(base as *mut libc::c_void, length, libc::PROT_NONE);
|
mprotect(base as *mut std::ffi::c_void, length, MprotectFlags::NONE).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("memory: base={:?}, length={}", base, length);
|
println!("memory: base={:?}, length={}", base, length);
|
||||||
@@ -81,11 +82,12 @@ mod tests {
|
|||||||
let result = (si_addr as u64) < (base as u64) + (length as u64);
|
let result = (si_addr as u64) < (base as u64) + (length as u64);
|
||||||
// Remove protections so the execution may resume
|
// Remove protections so the execution may resume
|
||||||
unsafe {
|
unsafe {
|
||||||
libc::mprotect(
|
mprotect(
|
||||||
base as *mut libc::c_void,
|
base as *mut libc::c_void,
|
||||||
length,
|
length,
|
||||||
libc::PROT_READ | libc::PROT_WRITE,
|
MprotectFlags::READ | MprotectFlags::WRITE,
|
||||||
);
|
)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
println!("signal handled: {}", result);
|
println!("signal handled: {}", result);
|
||||||
result
|
result
|
||||||
@@ -213,11 +215,12 @@ mod tests {
|
|||||||
let instance1_handler_triggered = instance1_handler_triggered.clone();
|
let instance1_handler_triggered = instance1_handler_triggered.clone();
|
||||||
move |_signum, _siginfo, _context| {
|
move |_signum, _siginfo, _context| {
|
||||||
// Remove protections so the execution may resume
|
// Remove protections so the execution may resume
|
||||||
libc::mprotect(
|
mprotect(
|
||||||
base1 as *mut libc::c_void,
|
base1 as *mut libc::c_void,
|
||||||
length1,
|
length1,
|
||||||
libc::PROT_READ | libc::PROT_WRITE,
|
MprotectFlags::READ | MprotectFlags::WRITE,
|
||||||
);
|
)
|
||||||
|
.unwrap();
|
||||||
instance1_handler_triggered.store(true, Ordering::SeqCst);
|
instance1_handler_triggered.store(true, Ordering::SeqCst);
|
||||||
println!(
|
println!(
|
||||||
"Hello from instance1 signal handler! {}",
|
"Hello from instance1 signal handler! {}",
|
||||||
@@ -258,11 +261,12 @@ mod tests {
|
|||||||
let instance2_handler_triggered = instance2_handler_triggered.clone();
|
let instance2_handler_triggered = instance2_handler_triggered.clone();
|
||||||
move |_signum, _siginfo, _context| {
|
move |_signum, _siginfo, _context| {
|
||||||
// Remove protections so the execution may resume
|
// Remove protections so the execution may resume
|
||||||
libc::mprotect(
|
mprotect(
|
||||||
base2 as *mut libc::c_void,
|
base2 as *mut libc::c_void,
|
||||||
length2,
|
length2,
|
||||||
libc::PROT_READ | libc::PROT_WRITE,
|
MprotectFlags::READ | MprotectFlags::WRITE,
|
||||||
);
|
)
|
||||||
|
.unwrap();
|
||||||
instance2_handler_triggered.store(true, Ordering::SeqCst);
|
instance2_handler_triggered.store(true, Ordering::SeqCst);
|
||||||
println!(
|
println!(
|
||||||
"Hello from instance2 signal handler! {}",
|
"Hello from instance2 signal handler! {}",
|
||||||
|
|||||||
@@ -3,13 +3,9 @@ mod not_for_windows {
|
|||||||
use wasmtime::*;
|
use wasmtime::*;
|
||||||
use wasmtime_environ::{WASM32_MAX_PAGES, WASM_PAGE_SIZE};
|
use wasmtime_environ::{WASM32_MAX_PAGES, WASM_PAGE_SIZE};
|
||||||
|
|
||||||
use libc::MAP_FAILED;
|
use rsix::io::{mmap_anonymous, mprotect, munmap, MapFlags, MprotectFlags, ProtFlags};
|
||||||
use libc::{mmap, mprotect, munmap};
|
|
||||||
use libc::{sysconf, _SC_PAGESIZE};
|
|
||||||
use libc::{MAP_ANON, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE};
|
|
||||||
|
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::io::Error;
|
|
||||||
use std::ptr::null_mut;
|
use std::ptr::null_mut;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
@@ -23,16 +19,16 @@ mod not_for_windows {
|
|||||||
|
|
||||||
impl CustomMemory {
|
impl CustomMemory {
|
||||||
unsafe fn new(minimum: usize, maximum: usize, glob_counter: Arc<Mutex<usize>>) -> Self {
|
unsafe fn new(minimum: usize, maximum: usize, glob_counter: Arc<Mutex<usize>>) -> Self {
|
||||||
let page_size = sysconf(_SC_PAGESIZE) as usize;
|
let page_size = rsix::process::page_size();
|
||||||
let guard_size = page_size;
|
let guard_size = page_size;
|
||||||
let size = maximum + guard_size;
|
let size = maximum + guard_size;
|
||||||
assert_eq!(size % page_size, 0); // we rely on WASM_PAGE_SIZE being multiple of host page size
|
assert_eq!(size % page_size, 0); // we rely on WASM_PAGE_SIZE being multiple of host page size
|
||||||
|
|
||||||
let mem = mmap(null_mut(), size, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
let mem = mmap_anonymous(null_mut(), size, ProtFlags::NONE, MapFlags::PRIVATE)
|
||||||
assert_ne!(mem, MAP_FAILED, "mmap failed: {}", Error::last_os_error());
|
.expect("mmap failed");
|
||||||
|
|
||||||
let r = mprotect(mem, minimum, PROT_READ | PROT_WRITE);
|
mprotect(mem, minimum, MprotectFlags::READ | MprotectFlags::WRITE)
|
||||||
assert_eq!(r, 0, "mprotect failed: {}", Error::last_os_error());
|
.expect("mprotect failed");
|
||||||
*glob_counter.lock().unwrap() += minimum;
|
*glob_counter.lock().unwrap() += minimum;
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@@ -48,8 +44,7 @@ mod not_for_windows {
|
|||||||
impl Drop for CustomMemory {
|
impl Drop for CustomMemory {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
*self.glob_bytes_counter.lock().unwrap() -= self.used_wasm_bytes;
|
*self.glob_bytes_counter.lock().unwrap() -= self.used_wasm_bytes;
|
||||||
let r = unsafe { munmap(self.mem as *mut _, self.size) };
|
unsafe { munmap(self.mem as *mut _, self.size).expect("munmap failed") };
|
||||||
assert_eq!(r, 0, "munmap failed: {}", Error::last_os_error());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,8 +62,8 @@ mod not_for_windows {
|
|||||||
let delta = new_size - self.used_wasm_bytes;
|
let delta = new_size - self.used_wasm_bytes;
|
||||||
unsafe {
|
unsafe {
|
||||||
let start = (self.mem as *mut u8).add(self.used_wasm_bytes) as _;
|
let start = (self.mem as *mut u8).add(self.used_wasm_bytes) as _;
|
||||||
let r = mprotect(start, delta, PROT_READ | PROT_WRITE);
|
mprotect(start, delta, MprotectFlags::READ | MprotectFlags::WRITE)
|
||||||
assert_eq!(r, 0, "mprotect failed: {}", Error::last_os_error());
|
.expect("mprotect failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
*self.glob_bytes_counter.lock().unwrap() += delta;
|
*self.glob_bytes_counter.lock().unwrap() += delta;
|
||||||
|
|||||||
Reference in New Issue
Block a user