mirror of
https://github.com/fluencelabs/wasmer
synced 2025-05-05 15:22:13 +00:00
Merge branch 'master' into feature/clif-cgapi
This commit is contained in:
commit
b2e37cecfa
@ -64,6 +64,7 @@ build_script:
|
|||||||
- rename target wapm-cli-target
|
- rename target wapm-cli-target
|
||||||
- cd ..
|
- cd ..
|
||||||
- move wapm-cli\wapm-cli-target wapm-cli-target
|
- move wapm-cli\wapm-cli-target wapm-cli-target
|
||||||
|
- cargo build --release --manifest-path lib/runtime-c-api/Cargo.toml
|
||||||
|
|
||||||
test_script:
|
test_script:
|
||||||
- cargo test --manifest-path lib/spectests/Cargo.toml --features clif
|
- cargo test --manifest-path lib/spectests/Cargo.toml --features clif
|
||||||
|
@ -191,6 +191,11 @@ jobs:
|
|||||||
echo "${CIRCLE_TAG}" >> artifacts/git_version
|
echo "${CIRCLE_TAG}" >> artifacts/git_version
|
||||||
make build-install
|
make build-install
|
||||||
cp ./wasmer.tar.gz ./artifacts/$(./binary-name.sh)
|
cp ./wasmer.tar.gz ./artifacts/$(./binary-name.sh)
|
||||||
|
- run:
|
||||||
|
name: Dynamic library
|
||||||
|
command: |
|
||||||
|
cargo build --release --manifest-path lib/runtime-c-api/Cargo.toml
|
||||||
|
cp target/release/libwasmer_runtime_c_api.so ./artifacts
|
||||||
- persist_to_workspace:
|
- persist_to_workspace:
|
||||||
root: .
|
root: .
|
||||||
paths:
|
paths:
|
||||||
@ -278,6 +283,13 @@ jobs:
|
|||||||
cp ./wasmer.tar.gz ./artifacts/$(./binary-name.sh)
|
cp ./wasmer.tar.gz ./artifacts/$(./binary-name.sh)
|
||||||
# VERSION=$(cargo pkgid | cut -d# -f2 | cut -d: -f2)
|
# VERSION=$(cargo pkgid | cut -d# -f2 | cut -d: -f2)
|
||||||
# echo "${VERSION}" >> artifacts/version
|
# echo "${VERSION}" >> artifacts/version
|
||||||
|
- run:
|
||||||
|
name: Generate dynamic library for the runtime C API
|
||||||
|
command: |
|
||||||
|
export PATH="$HOME/.cargo/bin:$PATH"
|
||||||
|
cargo build --release --manifest-path lib/runtime-c-api/Cargo.toml
|
||||||
|
install_name_tool -id "@rpath/libwasmer_runtime_c_api.dylib" target/release/libwasmer_runtime_c_api.dylib
|
||||||
|
cp target/release/libwasmer_runtime_c_api.dylib ./artifacts
|
||||||
- persist_to_workspace:
|
- persist_to_workspace:
|
||||||
root: .
|
root: .
|
||||||
paths:
|
paths:
|
||||||
@ -351,7 +363,7 @@ jobs:
|
|||||||
# VERSION_TAG=$(git describe --exact-match --tags)
|
# VERSION_TAG=$(git describe --exact-match --tags)
|
||||||
#if [ "$VERSION" == "$VERSION_TAG" ]; then
|
#if [ "$VERSION" == "$VERSION_TAG" ]; then
|
||||||
# echo "Versions match, publishing to Github"
|
# echo "Versions match, publishing to Github"
|
||||||
ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -soft ${VERSION} ./artifacts/
|
ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} ${VERSION} ./artifacts/ || true
|
||||||
#else
|
#else
|
||||||
# echo "Versions don't match. Wasmer output version (wasmer --version) is ${VERSION} while Git tag is ${VERSION_TAG}"
|
# echo "Versions don't match. Wasmer output version (wasmer --version) is ${VERSION} while Git tag is ${VERSION_TAG}"
|
||||||
# exit 1
|
# exit 1
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Wasmer uses the following components:
|
Wasmer uses the following components:
|
||||||
|
|
||||||
- [Cranelift](https://github.com/cranestation/cranelift): for compiling Wasm binaries to machine code
|
- Compiler backends: for compiling Wasm binaries to machine code ([more info here](https://github.com/wasmerio/wasmer/tree/master/lib#backends))
|
||||||
- [wabt](https://github.com/pepyakin/wabt-rs): for transforming `.wast` files to `.wasm` and running WebAssembly spec tests
|
- [wabt](https://github.com/pepyakin/wabt-rs): for transforming `.wast` files to `.wasm` and running WebAssembly spec tests
|
||||||
- [wasmparser](https://github.com/yurydelendik/wasmparser.rs): for parsing the `.wasm` files and translating them into WebAssembly modules
|
- [wasmparser](https://github.com/yurydelendik/wasmparser.rs): for parsing the `.wasm` files and translating them into WebAssembly modules
|
||||||
|
|
||||||
@ -67,3 +67,8 @@ Once that's finished, we will have a `Instance` function that will be ready to e
|
|||||||
|
|
||||||
Wasmer's Emscripten integration tries to wrap (and emulate) all the different syscalls that Emscripten needs.
|
Wasmer's Emscripten integration tries to wrap (and emulate) all the different syscalls that Emscripten needs.
|
||||||
We provide this integration by filling the `import_object` with the Emscripten functions, while instantiating the WebAssembly Instance.
|
We provide this integration by filling the `import_object` with the Emscripten functions, while instantiating the WebAssembly Instance.
|
||||||
|
|
||||||
|
## WASI
|
||||||
|
|
||||||
|
Wasmer's WASI integration implements all the different syscalls that WASI needs.
|
||||||
|
We provide this integration by filling the `import_object` with the WASI functions, while instantiating the WebAssembly Instance.
|
||||||
|
@ -6,6 +6,7 @@ Blocks of changes will separated by version increments.
|
|||||||
|
|
||||||
## **[Unreleased]**
|
## **[Unreleased]**
|
||||||
|
|
||||||
|
- [#470](https://github.com/wasmerio/wasmer/pull/470) Add mapdir support to Emscripten, implement getdents for Unix
|
||||||
- [#467](https://github.com/wasmerio/wasmer/pull/467) `wasmer_instantiate` returns better error messages in the runtime C API
|
- [#467](https://github.com/wasmerio/wasmer/pull/467) `wasmer_instantiate` returns better error messages in the runtime C API
|
||||||
- [#463](https://github.com/wasmerio/wasmer/pull/463) Fix bug in WASI path_open allowing one level above preopened dir to be accessed
|
- [#463](https://github.com/wasmerio/wasmer/pull/463) Fix bug in WASI path_open allowing one level above preopened dir to be accessed
|
||||||
- [#461](https://github.com/wasmerio/wasmer/pull/461) Prevent passing negative lengths in various places in the runtime C API
|
- [#461](https://github.com/wasmerio/wasmer/pull/461) Prevent passing negative lengths in various places in the runtime C API
|
||||||
|
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1412,6 +1412,7 @@ version = "0.4.2"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -28,11 +28,12 @@ curl https://get.wasmer.io -sSfL | sh
|
|||||||
|
|
||||||
Wasmer runtime can also be embedded in different languages, so you can use WebAssembly anywhere ✨:
|
Wasmer runtime can also be embedded in different languages, so you can use WebAssembly anywhere ✨:
|
||||||
|
|
||||||
* [**Rust**](https://github.com/wasmerio/wasmer-rust-example)
|
* [🦀 **Rust**](https://github.com/wasmerio/wasmer-rust-example)
|
||||||
* [**C/C++**](https://github.com/wasmerio/wasmer-c-api)
|
* [**C/C++**](https://github.com/wasmerio/wasmer-c-api)
|
||||||
* [**🐘 PHP**](https://github.com/wasmerio/php-ext-wasm)
|
* [**🐘 PHP**](https://github.com/wasmerio/php-ext-wasm)
|
||||||
* [**🐍 Python**](https://github.com/wasmerio/python-ext-wasm)
|
* [**🐍 Python**](https://github.com/wasmerio/python-ext-wasm)
|
||||||
* [**💎 Ruby**](https://github.com/wasmerio/ruby-ext-wasm)
|
* [**💎 Ruby**](https://github.com/wasmerio/ruby-ext-wasm)
|
||||||
|
* [**🐹 Go**](https://github.com/wasmerio/go-ext-wasm)
|
||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
|
19
SECURITY.md
Normal file
19
SECURITY.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# Security Policy
|
||||||
|
|
||||||
|
## Supported Versions
|
||||||
|
|
||||||
|
While in beta, the latest published version of `wasmer` (`0.x`) will be supported with security updates.
|
||||||
|
|
||||||
|
| Version | Supported |
|
||||||
|
| ------- | ------------------ |
|
||||||
|
| 0.x | :white_check_mark: |
|
||||||
|
|
||||||
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
The Wasmer team and community take security bugs in Wasmer seriously.
|
||||||
|
We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
|
||||||
|
|
||||||
|
To report a security issue, email security@wasmer.io and include the word "SECURITY" in the subject line.
|
||||||
|
|
||||||
|
The Wasmer team will send a response indicating the next steps in handling your report.
|
||||||
|
After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
|
@ -9,14 +9,15 @@ edition = "2018"
|
|||||||
build = "build/mod.rs"
|
build = "build/mod.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.4.2" }
|
byteorder = "1"
|
||||||
|
hashbrown = "0.1"
|
||||||
lazy_static = "1.2.0"
|
lazy_static = "1.2.0"
|
||||||
libc = "0.2.49"
|
libc = "0.2.49"
|
||||||
byteorder = "1"
|
|
||||||
time = "0.1.41"
|
time = "0.1.41"
|
||||||
wasmer-clif-backend = { path = "../clif-backend", version = "0.4.2" }
|
wasmer-clif-backend = { path = "../clif-backend", version = "0.4.2" }
|
||||||
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.4.2", optional = true }
|
|
||||||
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.4.2", optional = true }
|
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.4.2", optional = true }
|
||||||
|
wasmer-runtime-core = { path = "../runtime-core", version = "0.4.2" }
|
||||||
|
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.4.2", optional = true }
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
rand = "0.6"
|
rand = "0.6"
|
||||||
|
40
lib/emscripten/src/env/mod.rs
vendored
40
lib/emscripten/src/env/mod.rs
vendored
@ -10,6 +10,8 @@ pub use self::unix::*;
|
|||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
pub use self::windows::*;
|
pub use self::windows::*;
|
||||||
|
|
||||||
|
use libc::c_char;
|
||||||
|
|
||||||
use crate::{allocate_on_stack, EmscriptenData};
|
use crate::{allocate_on_stack, EmscriptenData};
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
use wasmer_runtime_core::vm::Ctx;
|
use wasmer_runtime_core::vm::Ctx;
|
||||||
@ -112,3 +114,41 @@ pub fn ___assert_fail(_ctx: &mut Ctx, _a: c_int, _b: c_int, _c: c_int, _d: c_int
|
|||||||
// TODO: Implement like emscripten expects regarding memory/page size
|
// TODO: Implement like emscripten expects regarding memory/page size
|
||||||
// TODO raise an error
|
// TODO raise an error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn _pathconf(ctx: &mut Ctx, path_addr: c_int, name: c_int) -> c_int {
|
||||||
|
debug!(
|
||||||
|
"emscripten::_pathconf {} {} - UNIMPLEMENTED",
|
||||||
|
path_addr, name
|
||||||
|
);
|
||||||
|
let _path = emscripten_memory_pointer!(ctx.memory(0), path_addr) as *const c_char;
|
||||||
|
match name {
|
||||||
|
0 => 32000,
|
||||||
|
1 | 2 | 3 => 255,
|
||||||
|
4 | 5 | 16 | 17 | 18 => 4096,
|
||||||
|
6 | 7 | 20 => 1,
|
||||||
|
8 => 0,
|
||||||
|
9 | 10 | 11 | 12 | 14 | 15 | 19 => -1,
|
||||||
|
13 => 64,
|
||||||
|
_ => {
|
||||||
|
// ___setErrNo(22);
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _fpathconf(_ctx: &mut Ctx, _fildes: c_int, name: c_int) -> c_int {
|
||||||
|
debug!("emscripten::_fpathconf {} {}", _fildes, name);
|
||||||
|
match name {
|
||||||
|
0 => 32000,
|
||||||
|
1 | 2 | 3 => 255,
|
||||||
|
4 | 5 | 16 | 17 | 18 => 4096,
|
||||||
|
6 | 7 | 20 => 1,
|
||||||
|
8 => 0,
|
||||||
|
9 | 10 | 11 | 12 | 14 | 15 | 19 => -1,
|
||||||
|
13 => 64,
|
||||||
|
_ => {
|
||||||
|
// ___setErrNo(22);
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,8 +3,10 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate wasmer_runtime_core;
|
extern crate wasmer_runtime_core;
|
||||||
|
|
||||||
|
use hashbrown::HashMap;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use std::cell::UnsafeCell;
|
use std::cell::UnsafeCell;
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::{f64, ffi::c_void};
|
use std::{f64, ffi::c_void};
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
error::CallResult,
|
error::CallResult,
|
||||||
@ -141,10 +143,14 @@ pub struct EmscriptenData<'a> {
|
|||||||
pub stack_save: Option<Func<'a, (), i32>>,
|
pub stack_save: Option<Func<'a, (), i32>>,
|
||||||
pub stack_restore: Option<Func<'a, (i32)>>,
|
pub stack_restore: Option<Func<'a, (i32)>>,
|
||||||
pub set_threw: Option<Func<'a, (i32, i32)>>,
|
pub set_threw: Option<Func<'a, (i32, i32)>>,
|
||||||
|
pub mapped_dirs: HashMap<String, PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> EmscriptenData<'a> {
|
impl<'a> EmscriptenData<'a> {
|
||||||
pub fn new(instance: &'a mut Instance) -> EmscriptenData<'a> {
|
pub fn new(
|
||||||
|
instance: &'a mut Instance,
|
||||||
|
mapped_dirs: HashMap<String, PathBuf>,
|
||||||
|
) -> EmscriptenData<'a> {
|
||||||
let malloc = instance.func("_malloc").unwrap();
|
let malloc = instance.func("_malloc").unwrap();
|
||||||
let free = instance.func("_free").unwrap();
|
let free = instance.func("_free").unwrap();
|
||||||
let memalign = instance.func("_memalign").ok();
|
let memalign = instance.func("_memalign").ok();
|
||||||
@ -272,6 +278,7 @@ impl<'a> EmscriptenData<'a> {
|
|||||||
stack_save,
|
stack_save,
|
||||||
stack_restore,
|
stack_restore,
|
||||||
set_threw,
|
set_threw,
|
||||||
|
mapped_dirs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -282,8 +289,9 @@ pub fn run_emscripten_instance(
|
|||||||
path: &str,
|
path: &str,
|
||||||
args: Vec<&str>,
|
args: Vec<&str>,
|
||||||
entrypoint: Option<String>,
|
entrypoint: Option<String>,
|
||||||
|
mapped_dirs: Vec<(String, PathBuf)>,
|
||||||
) -> CallResult<()> {
|
) -> CallResult<()> {
|
||||||
let mut data = EmscriptenData::new(instance);
|
let mut data = EmscriptenData::new(instance, mapped_dirs.into_iter().collect());
|
||||||
let data_ptr = &mut data as *mut _ as *mut c_void;
|
let data_ptr = &mut data as *mut _ as *mut c_void;
|
||||||
instance.context_mut().data = data_ptr;
|
instance.context_mut().data = data_ptr;
|
||||||
|
|
||||||
@ -545,6 +553,8 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
|||||||
"_sysconf" => func!(crate::env::_sysconf),
|
"_sysconf" => func!(crate::env::_sysconf),
|
||||||
"_getaddrinfo" => func!(crate::env::_getaddrinfo),
|
"_getaddrinfo" => func!(crate::env::_getaddrinfo),
|
||||||
"_times" => func!(crate::env::_times),
|
"_times" => func!(crate::env::_times),
|
||||||
|
"_pathconf" => func!(crate::env::_pathconf),
|
||||||
|
"_fpathconf" => func!(crate::env::_fpathconf),
|
||||||
|
|
||||||
// Syscalls
|
// Syscalls
|
||||||
"___syscall1" => func!(crate::syscalls::___syscall1),
|
"___syscall1" => func!(crate::syscalls::___syscall1),
|
||||||
@ -687,6 +697,7 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
|||||||
"_asctime_r" => func!(crate::time::_asctime_r),
|
"_asctime_r" => func!(crate::time::_asctime_r),
|
||||||
"_localtime" => func!(crate::time::_localtime),
|
"_localtime" => func!(crate::time::_localtime),
|
||||||
"_time" => func!(crate::time::_time),
|
"_time" => func!(crate::time::_time),
|
||||||
|
"_timegm" => func!(crate::time::_timegm),
|
||||||
"_strftime" => func!(crate::time::_strftime),
|
"_strftime" => func!(crate::time::_strftime),
|
||||||
"_strftime_l" => func!(crate::time::_strftime_l),
|
"_strftime_l" => func!(crate::time::_strftime_l),
|
||||||
"_localtime_r" => func!(crate::time::_localtime_r),
|
"_localtime_r" => func!(crate::time::_localtime_r),
|
||||||
@ -705,6 +716,7 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
|||||||
"_llvm_exp2_f32" => func!(crate::math::_llvm_exp2_f32),
|
"_llvm_exp2_f32" => func!(crate::math::_llvm_exp2_f32),
|
||||||
"_llvm_exp2_f64" => func!(crate::math::_llvm_exp2_f64),
|
"_llvm_exp2_f64" => func!(crate::math::_llvm_exp2_f64),
|
||||||
"_llvm_trunc_f64" => func!(crate::math::_llvm_trunc_f64),
|
"_llvm_trunc_f64" => func!(crate::math::_llvm_trunc_f64),
|
||||||
|
"_llvm_fma_f64" => func!(crate::math::_llvm_fma_f64),
|
||||||
"_emscripten_random" => func!(crate::math::_emscripten_random),
|
"_emscripten_random" => func!(crate::math::_emscripten_random),
|
||||||
|
|
||||||
// Jump
|
// Jump
|
||||||
|
@ -49,6 +49,11 @@ pub fn _llvm_trunc_f64(_ctx: &mut Ctx, value: f64) -> f64 {
|
|||||||
value.trunc()
|
value.trunc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn _llvm_fma_f64(_ctx: &mut Ctx, value: f64, a: f64, b: f64) -> f64 {
|
||||||
|
debug!("emscripten::_llvm_fma_f64");
|
||||||
|
value.mul_add(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn _emscripten_random(_ctx: &mut Ctx) -> f64 {
|
pub fn _emscripten_random(_ctx: &mut Ctx) -> f64 {
|
||||||
debug!("emscripten::_emscripten_random");
|
debug!("emscripten::_emscripten_random");
|
||||||
-1.0
|
-1.0
|
||||||
|
@ -10,7 +10,8 @@ pub use self::unix::*;
|
|||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
pub use self::windows::*;
|
pub use self::windows::*;
|
||||||
|
|
||||||
use super::utils::copy_stat_into_wasm;
|
use crate::utils::{copy_stat_into_wasm, get_cstr_path, get_current_directory};
|
||||||
|
|
||||||
use super::varargs::VarArgs;
|
use super::varargs::VarArgs;
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
/// NOTE: TODO: These syscalls only support wasm_32 for now because they assume offsets are u32
|
/// NOTE: TODO: These syscalls only support wasm_32 for now because they assume offsets are u32
|
||||||
@ -38,6 +39,7 @@ use libc::{
|
|||||||
// writev,
|
// writev,
|
||||||
stat,
|
stat,
|
||||||
write,
|
write,
|
||||||
|
// readlink,
|
||||||
};
|
};
|
||||||
use wasmer_runtime_core::vm::Ctx;
|
use wasmer_runtime_core::vm::Ctx;
|
||||||
|
|
||||||
@ -93,14 +95,20 @@ pub fn ___syscall6(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int
|
|||||||
// chdir
|
// chdir
|
||||||
pub fn ___syscall12(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
pub fn ___syscall12(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
||||||
debug!("emscripten::___syscall12 (chdir) {}", _which);
|
debug!("emscripten::___syscall12 (chdir) {}", _which);
|
||||||
let path_addr: i32 = varargs.get(ctx);
|
let path_ptr = varargs.get_str(ctx);
|
||||||
unsafe {
|
let real_path_owned = get_cstr_path(ctx, path_ptr);
|
||||||
let path_ptr = emscripten_memory_pointer!(ctx.memory(0), path_addr) as *const i8;
|
let real_path = if let Some(ref rp) = real_path_owned {
|
||||||
let _path = std::ffi::CStr::from_ptr(path_ptr);
|
rp.as_c_str().as_ptr()
|
||||||
let ret = chdir(path_ptr);
|
} else {
|
||||||
debug!("=> path: {:?}, ret: {}", _path, ret);
|
path_ptr
|
||||||
|
};
|
||||||
|
let ret = unsafe { chdir(real_path) };
|
||||||
|
debug!(
|
||||||
|
"=> path: {:?}, ret: {}",
|
||||||
|
unsafe { std::ffi::CStr::from_ptr(real_path) },
|
||||||
ret
|
ret
|
||||||
}
|
);
|
||||||
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ___syscall10(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
|
pub fn ___syscall10(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
|
||||||
@ -122,15 +130,25 @@ pub fn ___syscall20(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
|
|||||||
// rename
|
// rename
|
||||||
pub fn ___syscall38(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> i32 {
|
pub fn ___syscall38(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> i32 {
|
||||||
debug!("emscripten::___syscall38 (rename)");
|
debug!("emscripten::___syscall38 (rename)");
|
||||||
let old_path_addr: u32 = varargs.get(ctx);
|
let old_path = varargs.get_str(ctx);
|
||||||
let new_path_addr: u32 = varargs.get(ctx);
|
let new_path = varargs.get_str(ctx);
|
||||||
let old_path = emscripten_memory_pointer!(ctx.memory(0), old_path_addr) as *const i8;
|
let real_old_path_owned = get_cstr_path(ctx, old_path);
|
||||||
let new_path = emscripten_memory_pointer!(ctx.memory(0), new_path_addr) as *const i8;
|
let real_old_path = if let Some(ref rp) = real_old_path_owned {
|
||||||
let result = unsafe { rename(old_path, new_path) };
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
old_path
|
||||||
|
};
|
||||||
|
let real_new_path_owned = get_cstr_path(ctx, new_path);
|
||||||
|
let real_new_path = if let Some(ref rp) = real_new_path_owned {
|
||||||
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
new_path
|
||||||
|
};
|
||||||
|
let result = unsafe { rename(real_old_path, real_new_path) };
|
||||||
debug!(
|
debug!(
|
||||||
"=> old_path: {}, new_path: {}, result: {}",
|
"=> old_path: {}, new_path: {}, result: {}",
|
||||||
unsafe { std::ffi::CStr::from_ptr(old_path).to_str().unwrap() },
|
unsafe { std::ffi::CStr::from_ptr(real_old_path).to_str().unwrap() },
|
||||||
unsafe { std::ffi::CStr::from_ptr(new_path).to_str().unwrap() },
|
unsafe { std::ffi::CStr::from_ptr(real_new_path).to_str().unwrap() },
|
||||||
result
|
result
|
||||||
);
|
);
|
||||||
result
|
result
|
||||||
@ -139,9 +157,14 @@ pub fn ___syscall38(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> i32 {
|
|||||||
// rmdir
|
// rmdir
|
||||||
pub fn ___syscall40(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
pub fn ___syscall40(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
||||||
debug!("emscripten::___syscall40 (rmdir)");
|
debug!("emscripten::___syscall40 (rmdir)");
|
||||||
let pathname: u32 = varargs.get(ctx);
|
let pathname_addr = varargs.get_str(ctx);
|
||||||
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
|
let real_path_owned = get_cstr_path(ctx, pathname_addr);
|
||||||
unsafe { rmdir(pathname_addr) }
|
let real_path = if let Some(ref rp) = real_path_owned {
|
||||||
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
pathname_addr
|
||||||
|
};
|
||||||
|
unsafe { rmdir(real_path) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// pipe
|
// pipe
|
||||||
@ -201,9 +224,32 @@ pub fn ___syscall75(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
|
|||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ___syscall85(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
|
// readlink
|
||||||
debug!("emscripten::___syscall85");
|
pub fn ___syscall85(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> i32 {
|
||||||
-1
|
debug!("emscripten::___syscall85 (readlink)");
|
||||||
|
let _path = varargs.get_str(ctx);
|
||||||
|
let buf = varargs.get_str(ctx);
|
||||||
|
// let buf_addr: i32 = varargs.get(ctx);
|
||||||
|
let buf_size: i32 = varargs.get(ctx);
|
||||||
|
let fd = 3;
|
||||||
|
let ret = unsafe { read(fd, buf as _, buf_size as _) as i32 };
|
||||||
|
debug!(
|
||||||
|
"=> buf: {}, buf_size: {}, return: {} ",
|
||||||
|
unsafe { std::ffi::CStr::from_ptr(buf as _).to_str().unwrap() },
|
||||||
|
buf_size,
|
||||||
|
ret
|
||||||
|
);
|
||||||
|
// let ret = unsafe {
|
||||||
|
// readlink(path, buf as _, buf_size as _) as i32
|
||||||
|
// };
|
||||||
|
// debug!("=> path: {}, buf: {}, buf_size: {}, return: {} ",
|
||||||
|
// unsafe { std::ffi::CStr::from_ptr(path).to_str().unwrap() },
|
||||||
|
// unsafe { std::ffi::CStr::from_ptr(buf as _).to_str().unwrap() },
|
||||||
|
// // std::ffi::CStr::from_ptr(buf).to_str().unwrap(),
|
||||||
|
// // buf,
|
||||||
|
// buf_size,
|
||||||
|
// ret);
|
||||||
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ___syscall91(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
|
pub fn ___syscall91(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
|
||||||
@ -224,10 +270,9 @@ pub fn ___syscall110(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
|
|||||||
// getcwd
|
// getcwd
|
||||||
pub fn ___syscall183(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> i32 {
|
pub fn ___syscall183(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> i32 {
|
||||||
debug!("emscripten::___syscall183");
|
debug!("emscripten::___syscall183");
|
||||||
use std::env;
|
|
||||||
let buf_offset: c_int = varargs.get(ctx);
|
let buf_offset: c_int = varargs.get(ctx);
|
||||||
let _size: c_int = varargs.get(ctx);
|
let _size: c_int = varargs.get(ctx);
|
||||||
let path = env::current_dir();
|
let path = get_current_directory(ctx);
|
||||||
let path_string = path.unwrap().display().to_string();
|
let path_string = path.unwrap().display().to_string();
|
||||||
let len = path_string.len();
|
let len = path_string.len();
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -397,19 +442,23 @@ pub fn ___syscall199(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
|
|||||||
// stat64
|
// stat64
|
||||||
pub fn ___syscall195(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
pub fn ___syscall195(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
||||||
debug!("emscripten::___syscall195 (stat64) {}", _which);
|
debug!("emscripten::___syscall195 (stat64) {}", _which);
|
||||||
let pathname: u32 = varargs.get(ctx);
|
let pathname_addr = varargs.get_str(ctx);
|
||||||
let buf: u32 = varargs.get(ctx);
|
let buf: u32 = varargs.get(ctx);
|
||||||
|
|
||||||
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
|
let real_path_owned = get_cstr_path(ctx, pathname_addr);
|
||||||
|
let real_path = if let Some(ref rp) = real_path_owned {
|
||||||
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
pathname_addr
|
||||||
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut _stat: stat = std::mem::zeroed();
|
let mut _stat: stat = std::mem::zeroed();
|
||||||
let ret = stat(pathname_addr, &mut _stat);
|
let ret = stat(real_path, &mut _stat);
|
||||||
debug!(
|
debug!(
|
||||||
"=> pathname: {}, buf: {}, path: {} = {}\nlast os error: {}",
|
"=> pathname: {}, buf: {} = {}, last os error: {}",
|
||||||
pathname,
|
std::ffi::CStr::from_ptr(real_path).to_str().unwrap(),
|
||||||
buf,
|
buf,
|
||||||
std::ffi::CStr::from_ptr(pathname_addr).to_str().unwrap(),
|
|
||||||
ret,
|
ret,
|
||||||
Error::last_os_error()
|
Error::last_os_error()
|
||||||
);
|
);
|
||||||
@ -440,11 +489,6 @@ pub fn ___syscall197(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
|
|||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ___syscall220(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
|
|
||||||
debug!("emscripten::___syscall220");
|
|
||||||
-1
|
|
||||||
}
|
|
||||||
|
|
||||||
// fcntl64
|
// fcntl64
|
||||||
pub fn ___syscall221(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
pub fn ___syscall221(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
||||||
debug!("emscripten::___syscall221 (fcntl64) {}", _which);
|
debug!("emscripten::___syscall221 (fcntl64) {}", _which);
|
||||||
@ -457,7 +501,7 @@ pub fn ___syscall221(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
|
|||||||
// |FNONBLOCK - 0x04
|
// |FNONBLOCK - 0x04
|
||||||
debug!("=> fd: {}, cmd: {}", _fd, cmd);
|
debug!("=> fd: {}, cmd: {}", _fd, cmd);
|
||||||
match cmd {
|
match cmd {
|
||||||
2 => 0,
|
1 | 2 => 0,
|
||||||
13 | 14 => 0, // pretend file locking worked
|
13 | 14 => 0, // pretend file locking worked
|
||||||
_ => -1,
|
_ => -1,
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@ use libc::{
|
|||||||
pid_t,
|
pid_t,
|
||||||
pread,
|
pread,
|
||||||
pwrite,
|
pwrite,
|
||||||
|
readdir,
|
||||||
// readv,
|
// readv,
|
||||||
recvfrom,
|
recvfrom,
|
||||||
recvmsg,
|
recvmsg,
|
||||||
@ -104,19 +105,23 @@ const SO_NOSIGPIPE: c_int = 0;
|
|||||||
/// open
|
/// open
|
||||||
pub fn ___syscall5(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
pub fn ___syscall5(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
||||||
debug!("emscripten::___syscall5 (open) {}", _which);
|
debug!("emscripten::___syscall5 (open) {}", _which);
|
||||||
let pathname: u32 = varargs.get(ctx);
|
let pathname_addr = varargs.get_str(ctx);
|
||||||
let flags: i32 = varargs.get(ctx);
|
let flags: i32 = varargs.get(ctx);
|
||||||
let mode: u32 = varargs.get(ctx);
|
let mode: u32 = varargs.get(ctx);
|
||||||
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
|
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr);
|
||||||
let _path_str = unsafe { std::ffi::CStr::from_ptr(pathname_addr).to_str().unwrap() };
|
let real_path = if let Some(ref rp) = real_path_owned {
|
||||||
let fd = unsafe { open(pathname_addr, flags, mode) };
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
pathname_addr
|
||||||
|
};
|
||||||
|
let _path_str = unsafe { std::ffi::CStr::from_ptr(real_path).to_str().unwrap() };
|
||||||
|
let fd = unsafe { open(real_path, flags, mode) };
|
||||||
debug!(
|
debug!(
|
||||||
"=> pathname: {}, flags: {}, mode: {} = fd: {}\npath: {}\nlast os error: {}",
|
"=> path: {}, flags: {}, mode: {} = fd: {}, last os error: {}",
|
||||||
pathname,
|
_path_str,
|
||||||
flags,
|
flags,
|
||||||
mode,
|
mode,
|
||||||
fd,
|
fd,
|
||||||
_path_str,
|
|
||||||
Error::last_os_error(),
|
Error::last_os_error(),
|
||||||
);
|
);
|
||||||
fd
|
fd
|
||||||
@ -126,10 +131,8 @@ pub fn ___syscall5(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int
|
|||||||
pub fn ___syscall9(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
pub fn ___syscall9(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
||||||
debug!("emscripten::___syscall9 (link) {}", _which);
|
debug!("emscripten::___syscall9 (link) {}", _which);
|
||||||
|
|
||||||
let oldname: c_int = varargs.get(ctx);
|
let oldname_ptr = varargs.get_str(ctx);
|
||||||
let newname: c_int = varargs.get(ctx);
|
let newname_ptr = varargs.get_str(ctx);
|
||||||
let oldname_ptr = emscripten_memory_pointer!(ctx.memory(0), oldname) as *const i8;
|
|
||||||
let newname_ptr = emscripten_memory_pointer!(ctx.memory(0), newname) as *const i8;
|
|
||||||
let result = unsafe { link(oldname_ptr, newname_ptr) };
|
let result = unsafe { link(oldname_ptr, newname_ptr) };
|
||||||
debug!(
|
debug!(
|
||||||
"=> oldname: {}, newname: {}, result: {}",
|
"=> oldname: {}, newname: {}, result: {}",
|
||||||
@ -156,15 +159,25 @@ pub fn ___syscall77(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int
|
|||||||
pub fn ___syscall83(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
pub fn ___syscall83(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
||||||
debug!("emscripten::___syscall83 (symlink) {}", _which);
|
debug!("emscripten::___syscall83 (symlink) {}", _which);
|
||||||
|
|
||||||
let path1_ptr: c_int = varargs.get(ctx);
|
let path1 = varargs.get_str(ctx);
|
||||||
let path2_ptr: c_int = varargs.get(ctx);
|
let path2 = varargs.get_str(ctx);
|
||||||
let path1 = emscripten_memory_pointer!(ctx.memory(0), path1_ptr) as *mut i8;
|
let real_path1_owned = utils::get_cstr_path(ctx, path1);
|
||||||
let path2 = emscripten_memory_pointer!(ctx.memory(0), path2_ptr) as *mut i8;
|
let real_path1 = if let Some(ref rp) = real_path1_owned {
|
||||||
let result = unsafe { symlink(path1, path2) };
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
path1
|
||||||
|
};
|
||||||
|
let real_path2_owned = utils::get_cstr_path(ctx, path2);
|
||||||
|
let real_path2 = if let Some(ref rp) = real_path2_owned {
|
||||||
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
path2
|
||||||
|
};
|
||||||
|
let result = unsafe { symlink(real_path1, real_path2) };
|
||||||
debug!(
|
debug!(
|
||||||
"=> path1: {}, path2: {}, result: {}",
|
"=> path1: {}, path2: {}, result: {}",
|
||||||
unsafe { std::ffi::CStr::from_ptr(path1).to_str().unwrap() },
|
unsafe { std::ffi::CStr::from_ptr(real_path1).to_str().unwrap() },
|
||||||
unsafe { std::ffi::CStr::from_ptr(path2).to_str().unwrap() },
|
unsafe { std::ffi::CStr::from_ptr(real_path2).to_str().unwrap() },
|
||||||
result,
|
result,
|
||||||
);
|
);
|
||||||
result
|
result
|
||||||
@ -186,14 +199,19 @@ pub fn ___syscall194(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
|
|||||||
/// lchown
|
/// lchown
|
||||||
pub fn ___syscall198(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
pub fn ___syscall198(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
||||||
debug!("emscripten::___syscall198 (lchown) {}", _which);
|
debug!("emscripten::___syscall198 (lchown) {}", _which);
|
||||||
let path: c_int = varargs.get(ctx);
|
let path_ptr = varargs.get_str(ctx);
|
||||||
|
let real_path_owned = utils::get_cstr_path(ctx, path_ptr);
|
||||||
|
let real_path = if let Some(ref rp) = real_path_owned {
|
||||||
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
path_ptr
|
||||||
|
};
|
||||||
let uid: uid_t = varargs.get(ctx);
|
let uid: uid_t = varargs.get(ctx);
|
||||||
let gid: gid_t = varargs.get(ctx);
|
let gid: gid_t = varargs.get(ctx);
|
||||||
let path_ptr = emscripten_memory_pointer!(ctx.memory(0), path) as *const i8;
|
let result = unsafe { lchown(real_path, uid, gid) };
|
||||||
let result = unsafe { lchown(path_ptr, uid, gid) };
|
|
||||||
debug!(
|
debug!(
|
||||||
"=> path: {}, uid: {}, gid: {}, result: {}",
|
"=> path: {}, uid: {}, gid: {}, result: {}",
|
||||||
unsafe { std::ffi::CStr::from_ptr(path_ptr).to_str().unwrap() },
|
unsafe { std::ffi::CStr::from_ptr(real_path).to_str().unwrap() },
|
||||||
uid,
|
uid,
|
||||||
gid,
|
gid,
|
||||||
result,
|
result,
|
||||||
@ -222,13 +240,17 @@ pub fn ___syscall205(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
|
|||||||
pub fn ___syscall212(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
pub fn ___syscall212(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
||||||
debug!("emscripten::___syscall212 (chown) {}", _which);
|
debug!("emscripten::___syscall212 (chown) {}", _which);
|
||||||
|
|
||||||
let pathname: u32 = varargs.get(ctx);
|
let pathname_addr = varargs.get_str(ctx);
|
||||||
|
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr);
|
||||||
|
let real_path = if let Some(ref rp) = real_path_owned {
|
||||||
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
pathname_addr
|
||||||
|
};
|
||||||
let owner: u32 = varargs.get(ctx);
|
let owner: u32 = varargs.get(ctx);
|
||||||
let group: u32 = varargs.get(ctx);
|
let group: u32 = varargs.get(ctx);
|
||||||
|
|
||||||
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
|
unsafe { chown(real_path, owner, group) }
|
||||||
|
|
||||||
unsafe { chown(pathname_addr, owner, group) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// madvise
|
/// madvise
|
||||||
@ -247,13 +269,18 @@ pub fn ___syscall219(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
|
|||||||
/// access
|
/// access
|
||||||
pub fn ___syscall33(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
pub fn ___syscall33(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
||||||
debug!("emscripten::___syscall33 (access) {}", _which);
|
debug!("emscripten::___syscall33 (access) {}", _which);
|
||||||
let path_ptr: c_int = varargs.get(ctx);
|
let path = varargs.get_str(ctx);
|
||||||
|
let real_path_owned = utils::get_cstr_path(ctx, path);
|
||||||
|
let real_path = if let Some(ref rp) = real_path_owned {
|
||||||
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
path
|
||||||
|
};
|
||||||
let amode: c_int = varargs.get(ctx);
|
let amode: c_int = varargs.get(ctx);
|
||||||
let path = emscripten_memory_pointer!(ctx.memory(0), path_ptr) as *const i8;
|
let result = unsafe { access(real_path, amode) };
|
||||||
let result = unsafe { access(path, amode) };
|
|
||||||
debug!(
|
debug!(
|
||||||
"=> path: {}, amode: {}, result: {}",
|
"=> path: {}, amode: {}, result: {}",
|
||||||
unsafe { std::ffi::CStr::from_ptr(path).to_str().unwrap() },
|
unsafe { std::ffi::CStr::from_ptr(real_path).to_str().unwrap() },
|
||||||
amode,
|
amode,
|
||||||
result
|
result
|
||||||
);
|
);
|
||||||
@ -270,10 +297,15 @@ pub fn ___syscall34(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int
|
|||||||
// mkdir
|
// mkdir
|
||||||
pub fn ___syscall39(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
pub fn ___syscall39(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
||||||
debug!("emscripten::___syscall39 (mkdir) {}", _which);
|
debug!("emscripten::___syscall39 (mkdir) {}", _which);
|
||||||
let pathname: u32 = varargs.get(ctx);
|
let pathname_addr = varargs.get_str(ctx);
|
||||||
|
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr);
|
||||||
|
let real_path = if let Some(ref rp) = real_path_owned {
|
||||||
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
pathname_addr
|
||||||
|
};
|
||||||
let mode: u32 = varargs.get(ctx);
|
let mode: u32 = varargs.get(ctx);
|
||||||
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
|
unsafe { mkdir(real_path, mode as _) }
|
||||||
unsafe { mkdir(pathname_addr, mode as _) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// dup
|
/// dup
|
||||||
@ -771,9 +803,14 @@ pub fn ___syscall122(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
|
|||||||
/// lstat64
|
/// lstat64
|
||||||
pub fn ___syscall196(ctx: &mut Ctx, _which: i32, mut varargs: VarArgs) -> i32 {
|
pub fn ___syscall196(ctx: &mut Ctx, _which: i32, mut varargs: VarArgs) -> i32 {
|
||||||
debug!("emscripten::___syscall196 (lstat64) {}", _which);
|
debug!("emscripten::___syscall196 (lstat64) {}", _which);
|
||||||
let path_ptr: c_int = varargs.get(ctx);
|
let path = varargs.get_str(ctx);
|
||||||
|
let real_path_owned = utils::get_cstr_path(ctx, path);
|
||||||
|
let real_path = if let Some(ref rp) = real_path_owned {
|
||||||
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
path
|
||||||
|
};
|
||||||
let buf_ptr: u32 = varargs.get(ctx);
|
let buf_ptr: u32 = varargs.get(ctx);
|
||||||
let path = emscripten_memory_pointer!(ctx.memory(0), path_ptr) as *const i8;
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut stat: stat = std::mem::zeroed();
|
let mut stat: stat = std::mem::zeroed();
|
||||||
|
|
||||||
@ -783,9 +820,9 @@ pub fn ___syscall196(ctx: &mut Ctx, _which: i32, mut varargs: VarArgs) -> i32 {
|
|||||||
let stat_ptr = &mut stat as *mut stat;
|
let stat_ptr = &mut stat as *mut stat;
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
let ret = lstat64(path, stat_ptr);
|
let ret = lstat64(real_path, stat_ptr);
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
let ret = lstat(path, stat_ptr);
|
let ret = lstat(real_path, stat_ptr);
|
||||||
|
|
||||||
debug!("ret: {}", ret);
|
debug!("ret: {}", ret);
|
||||||
if ret != 0 {
|
if ret != 0 {
|
||||||
@ -796,6 +833,45 @@ pub fn ___syscall196(ctx: &mut Ctx, _which: i32, mut varargs: VarArgs) -> i32 {
|
|||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getdents
|
||||||
|
// dirent structure is
|
||||||
|
// i64, i64, u16 (280), i8, [i8; 256]
|
||||||
|
pub fn ___syscall220(ctx: &mut Ctx, _which: i32, mut varargs: VarArgs) -> i32 {
|
||||||
|
debug!("emscripten::___syscall220");
|
||||||
|
let fd: i32 = varargs.get(ctx);
|
||||||
|
let dirp_addr: i32 = varargs.get(ctx);
|
||||||
|
let count: u32 = varargs.get(ctx);
|
||||||
|
|
||||||
|
let dirp = emscripten_memory_pointer!(ctx.memory(0), dirp_addr) as *mut u8;
|
||||||
|
// need to persist stream across calls?
|
||||||
|
let dir: *mut libc::DIR = unsafe { libc::fdopendir(fd) };
|
||||||
|
|
||||||
|
let mut pos = 0;
|
||||||
|
let offset = 280;
|
||||||
|
while pos + offset <= count as usize {
|
||||||
|
let dirent = unsafe { readdir(dir) };
|
||||||
|
if dirent.is_null() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
|
unsafe {
|
||||||
|
*(dirp.add(pos) as *mut u64) = (*dirent).d_ino;
|
||||||
|
*(dirp.add(pos + 8) as *mut u64) = pos as u64 + offset as u64;
|
||||||
|
*(dirp.add(pos + 16) as *mut u16) = offset as u16;
|
||||||
|
*(dirp.add(pos + 18) as *mut u8) = (*dirent).d_type;
|
||||||
|
let upper_bound = std::cmp::min((*dirent).d_reclen, 254) as usize;
|
||||||
|
let mut i = 0;
|
||||||
|
while i < upper_bound {
|
||||||
|
*(dirp.add(pos + 19 + i) as *mut i8) = (*dirent).d_name[i];
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
*(dirp.add(pos + 19 + i) as *mut i8) = 0 as i8;
|
||||||
|
}
|
||||||
|
pos += offset;
|
||||||
|
}
|
||||||
|
pos as i32
|
||||||
|
}
|
||||||
|
|
||||||
/// fallocate
|
/// fallocate
|
||||||
pub fn ___syscall324(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
pub fn ___syscall324(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
||||||
debug!("emscripten::___syscall324 (fallocate) {}", _which);
|
debug!("emscripten::___syscall324 (fallocate) {}", _which);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::utils::copy_cstr_into_wasm;
|
use crate::utils::{copy_cstr_into_wasm, get_cstr_path};
|
||||||
use crate::varargs::VarArgs;
|
use crate::varargs::VarArgs;
|
||||||
use libc::mkdir;
|
use libc::mkdir;
|
||||||
use libc::open;
|
use libc::open;
|
||||||
@ -18,11 +18,16 @@ pub fn ___syscall5(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int {
|
|||||||
debug!("emscripten::___syscall5 (open) {}", which);
|
debug!("emscripten::___syscall5 (open) {}", which);
|
||||||
#[cfg(not(feature = "debug"))]
|
#[cfg(not(feature = "debug"))]
|
||||||
let _ = which;
|
let _ = which;
|
||||||
let pathname: u32 = varargs.get(ctx);
|
let pathname_addr = varargs.get_str(ctx);
|
||||||
|
let real_path_owned = get_cstr_path(ctx, pathname_addr);
|
||||||
|
let real_path = if let Some(ref rp) = real_path_owned {
|
||||||
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
pathname_addr
|
||||||
|
};
|
||||||
let flags: i32 = varargs.get(ctx);
|
let flags: i32 = varargs.get(ctx);
|
||||||
let mode: u32 = varargs.get(ctx);
|
let mode: u32 = varargs.get(ctx);
|
||||||
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
|
let path_str = unsafe { std::ffi::CStr::from_ptr(real_path).to_str().unwrap() };
|
||||||
let path_str = unsafe { std::ffi::CStr::from_ptr(pathname_addr).to_str().unwrap() };
|
|
||||||
match path_str {
|
match path_str {
|
||||||
"/dev/urandom" => {
|
"/dev/urandom" => {
|
||||||
// create a fake urandom file for windows, super hacky
|
// create a fake urandom file for windows, super hacky
|
||||||
@ -43,15 +48,15 @@ pub fn ___syscall5(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int {
|
|||||||
let fd = unsafe { open(raw_pointer_to_urandom_file, flags, mode) };
|
let fd = unsafe { open(raw_pointer_to_urandom_file, flags, mode) };
|
||||||
debug!(
|
debug!(
|
||||||
"=> pathname: {}, flags: {}, mode: {} = fd: {}",
|
"=> pathname: {}, flags: {}, mode: {} = fd: {}",
|
||||||
pathname, flags, mode, fd
|
path_str, flags, mode, fd
|
||||||
);
|
);
|
||||||
fd
|
fd
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let fd = unsafe { open(pathname_addr, flags, mode) };
|
let fd = unsafe { open(real_path, flags, mode) };
|
||||||
debug!(
|
debug!(
|
||||||
"=> pathname: {}, flags: {}, mode: {} = fd: {}\npath: {}",
|
"=> pathname: {}, flags: {}, mode: {} = fd: {}\npath: {}",
|
||||||
pathname, flags, mode, fd, path_str
|
path_str, flags, mode, fd, path_str
|
||||||
);
|
);
|
||||||
fd
|
fd
|
||||||
}
|
}
|
||||||
@ -95,9 +100,14 @@ pub fn ___syscall39(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int
|
|||||||
debug!("emscripten::___syscall39 (mkdir) {}", which);
|
debug!("emscripten::___syscall39 (mkdir) {}", which);
|
||||||
#[cfg(not(feature = "debug"))]
|
#[cfg(not(feature = "debug"))]
|
||||||
let _ = which;
|
let _ = which;
|
||||||
let pathname: u32 = varargs.get(ctx);
|
let pathname_addr = varargs.get_str(ctx);
|
||||||
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
|
let real_path_owned = get_cstr_path(ctx, pathname_addr);
|
||||||
unsafe { mkdir(pathname_addr) }
|
let real_path = if let Some(ref rp) = real_path_owned {
|
||||||
|
rp.as_c_str().as_ptr()
|
||||||
|
} else {
|
||||||
|
pathname_addr
|
||||||
|
};
|
||||||
|
unsafe { mkdir(real_path) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// dup
|
/// dup
|
||||||
@ -251,6 +261,12 @@ pub fn ___syscall196(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
|
|||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getdents
|
||||||
|
pub fn ___syscall220(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
|
||||||
|
debug!("emscripten::___syscall220");
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
|
||||||
/// fchown
|
/// fchown
|
||||||
pub fn ___syscall207(_ctx: &mut Ctx, _which: c_int, _varargs: VarArgs) -> c_int {
|
pub fn ___syscall207(_ctx: &mut Ctx, _which: c_int, _varargs: VarArgs) -> c_int {
|
||||||
debug!("emscripten::___syscall207 (fchown) {}", _which);
|
debug!("emscripten::___syscall207 (fchown) {}", _which);
|
||||||
|
@ -4,7 +4,9 @@ use std::mem;
|
|||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
use libc::{clockid_t, time as libc_time};
|
use libc::{clockid_t, time as libc_time, timegm as libc_timegm, tm as libc_tm};
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
use std::ffi::CString;
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
use libc::time_t;
|
use libc::time_t;
|
||||||
@ -298,6 +300,57 @@ pub fn _time(ctx: &mut Ctx, time_p: u32) -> i32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// emscripten: _timegm
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
|
pub fn _timegm(ctx: &mut Ctx, time_ptr: u32) -> i32 {
|
||||||
|
debug!("emscripten::_timegm {}", time_ptr);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let time_p_addr = emscripten_memory_pointer!(ctx.memory(0), time_ptr) as *mut guest_tm;
|
||||||
|
|
||||||
|
let x: *mut c_char = CString::new("").expect("CString::new failed").into_raw();
|
||||||
|
let mut rust_tm = libc_tm {
|
||||||
|
tm_sec: 0,
|
||||||
|
tm_min: 0,
|
||||||
|
tm_hour: 0,
|
||||||
|
tm_mday: 0,
|
||||||
|
tm_mon: 0,
|
||||||
|
tm_year: 0,
|
||||||
|
tm_wday: 0,
|
||||||
|
tm_yday: 0,
|
||||||
|
tm_isdst: 0,
|
||||||
|
tm_gmtoff: 0,
|
||||||
|
tm_zone: x,
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = libc_timegm(&mut rust_tm) as i32;
|
||||||
|
if result != 0 {
|
||||||
|
(*time_p_addr).tm_sec = rust_tm.tm_sec;
|
||||||
|
(*time_p_addr).tm_min = rust_tm.tm_min;
|
||||||
|
(*time_p_addr).tm_hour = rust_tm.tm_hour;
|
||||||
|
(*time_p_addr).tm_mday = rust_tm.tm_mday;
|
||||||
|
(*time_p_addr).tm_mon = rust_tm.tm_mon;
|
||||||
|
(*time_p_addr).tm_year = rust_tm.tm_year;
|
||||||
|
(*time_p_addr).tm_wday = rust_tm.tm_wday;
|
||||||
|
(*time_p_addr).tm_yday = rust_tm.tm_yday;
|
||||||
|
(*time_p_addr).tm_isdst = rust_tm.tm_isdst;
|
||||||
|
(*time_p_addr).tm_gmtoff = rust_tm.tm_gmtoff as _;
|
||||||
|
(*time_p_addr).tm_zone = 0;
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
pub fn _timegm(_ctx: &mut Ctx, _time_ptr: c_int) -> i32 {
|
||||||
|
debug!(
|
||||||
|
"emscripten::_timegm - UNIMPLEMENTED IN WINDOWS {}",
|
||||||
|
_time_ptr
|
||||||
|
);
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
|
||||||
/// emscripten: _strftime
|
/// emscripten: _strftime
|
||||||
pub fn _strftime(
|
pub fn _strftime(
|
||||||
ctx: &mut Ctx,
|
ctx: &mut Ctx,
|
||||||
|
@ -5,6 +5,7 @@ use libc::stat;
|
|||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
use std::os::raw::c_char;
|
use std::os::raw::c_char;
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use wasmer_runtime_core::memory::Memory;
|
use wasmer_runtime_core::memory::Memory;
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
@ -204,6 +205,61 @@ pub fn read_string_from_wasm(memory: &Memory, offset: u32) -> String {
|
|||||||
String::from_utf8_lossy(&v).to_owned().to_string()
|
String::from_utf8_lossy(&v).to_owned().to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This function trys to find an entry in mapdir
|
||||||
|
/// translating paths into their correct value
|
||||||
|
pub fn get_cstr_path(ctx: &mut Ctx, path: *const i8) -> Option<std::ffi::CString> {
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
|
let path_str = unsafe { std::ffi::CStr::from_ptr(path).to_str().unwrap() }.to_string();
|
||||||
|
let data = get_emscripten_data(ctx);
|
||||||
|
let path = PathBuf::from(path_str);
|
||||||
|
let mut prefix_added = false;
|
||||||
|
let mut components = path.components().collect::<VecDeque<_>>();
|
||||||
|
// TODO(mark): handle absolute/non-canonical/non-relative paths too (this
|
||||||
|
// functionality should be shared among the abis)
|
||||||
|
if components.len() == 1 {
|
||||||
|
components.push_front(std::path::Component::CurDir);
|
||||||
|
prefix_added = true;
|
||||||
|
}
|
||||||
|
let mut cumulative_path = PathBuf::new();
|
||||||
|
for c in components.into_iter() {
|
||||||
|
cumulative_path.push(c);
|
||||||
|
if let Some(val) = data
|
||||||
|
.mapped_dirs
|
||||||
|
.get(&cumulative_path.to_string_lossy().to_string())
|
||||||
|
{
|
||||||
|
let rest_of_path = if !prefix_added {
|
||||||
|
path.strip_prefix(cumulative_path).ok()?
|
||||||
|
} else {
|
||||||
|
&path
|
||||||
|
};
|
||||||
|
let rebased_path = val.join(rest_of_path);
|
||||||
|
return std::ffi::CString::new(rebased_path.to_string_lossy().as_bytes()).ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
/// gets the current directory
|
||||||
|
/// handles mapdir logic
|
||||||
|
pub fn get_current_directory(ctx: &mut Ctx) -> Option<PathBuf> {
|
||||||
|
if let Some(val) = get_emscripten_data(ctx).mapped_dirs.get(".") {
|
||||||
|
return Some(val.clone());
|
||||||
|
}
|
||||||
|
std::env::current_dir()
|
||||||
|
.map(|cwd| {
|
||||||
|
if let Some(val) = get_emscripten_data(ctx)
|
||||||
|
.mapped_dirs
|
||||||
|
.get(&cwd.to_string_lossy().to_string())
|
||||||
|
{
|
||||||
|
val.clone()
|
||||||
|
} else {
|
||||||
|
cwd
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.ok()
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::is_emscripten_module;
|
use super::is_emscripten_module;
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use wasmer_runtime_core::{types::WasmExternType, vm::Ctx};
|
use wasmer_runtime_core::{types::WasmExternType, vm::Ctx};
|
||||||
|
// use std::ffi::CStr;
|
||||||
|
use std::os::raw::c_char;
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
@ -13,6 +15,14 @@ impl VarArgs {
|
|||||||
self.pointer += mem::size_of::<T>() as u32;
|
self.pointer += mem::size_of::<T>() as u32;
|
||||||
unsafe { (ptr as *const T).read() }
|
unsafe { (ptr as *const T).read() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pub fn getStr<'a>(&mut self, ctx: &mut Ctx) -> &'a CStr {
|
||||||
|
pub fn get_str(&mut self, ctx: &mut Ctx) -> *const c_char {
|
||||||
|
let ptr_addr: u32 = self.get(ctx);
|
||||||
|
let ptr = emscripten_memory_pointer!(ctx.memory(0), ptr_addr) as *const c_char;
|
||||||
|
ptr
|
||||||
|
// unsafe { CStr::from_ptr(ptr) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl WasmExternType for VarArgs {
|
unsafe impl WasmExternType for VarArgs {
|
||||||
|
@ -56,6 +56,7 @@ macro_rules! assert_emscripten_output {
|
|||||||
$name,
|
$name,
|
||||||
$args,
|
$args,
|
||||||
None,
|
None,
|
||||||
|
vec![],
|
||||||
).expect("run_emscripten_instance finishes");
|
).expect("run_emscripten_instance finishes");
|
||||||
|
|
||||||
let output = capturer.end().unwrap().0;
|
let output = capturer.end().unwrap().0;
|
||||||
|
@ -445,9 +445,6 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
|||||||
.instantiate(&import_object)
|
.instantiate(&import_object)
|
||||||
.map_err(|e| format!("Can't instantiate module: {:?}", e))?;
|
.map_err(|e| format!("Can't instantiate module: {:?}", e))?;
|
||||||
|
|
||||||
if !mapped_dirs.is_empty() {
|
|
||||||
eprintln!("WARN: mapdir is not implemented for emscripten targets");
|
|
||||||
}
|
|
||||||
wasmer_emscripten::run_emscripten_instance(
|
wasmer_emscripten::run_emscripten_instance(
|
||||||
&module,
|
&module,
|
||||||
&mut instance,
|
&mut instance,
|
||||||
@ -458,6 +455,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
|||||||
},
|
},
|
||||||
options.args.iter().map(|arg| arg.as_str()).collect(),
|
options.args.iter().map(|arg| arg.as_str()).collect(),
|
||||||
options.em_entrypoint.clone(),
|
options.em_entrypoint.clone(),
|
||||||
|
mapped_dirs,
|
||||||
)
|
)
|
||||||
.map_err(|e| format!("{:?}", e))?;
|
.map_err(|e| format!("{:?}", e))?;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user