mirror of
https://github.com/fluencelabs/wasmer
synced 2024-12-13 06:15:33 +00:00
Add a bunch of required functions and syscalls
This commit is contained in:
parent
2c2d21044f
commit
7f91a64cf6
14
src/apis/emscripten/exception.rs
Normal file
14
src/apis/emscripten/exception.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
use crate::webassembly::Instance;
|
||||||
|
|
||||||
|
/// emscripten: ___cxa_allocate_exception
|
||||||
|
pub extern "C" fn ___cxa_allocate_exception(size: u32, instance: &mut Instance) -> u32 {
|
||||||
|
debug!("emscripten::___cxa_allocate_exception");
|
||||||
|
(instance.emscripten_data.as_ref().unwrap().malloc)(size as _, instance)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// emscripten: ___cxa_throw
|
||||||
|
/// TODO: We don't have support for exceptions yet
|
||||||
|
pub extern "C" fn ___cxa_throw(ptr: u32, ty: u32, destructor: u32, instance: &mut Instance) {
|
||||||
|
debug!("emscripten::___cxa_throw");
|
||||||
|
debug!("unimplmeneted yet!");
|
||||||
|
}
|
@ -10,3 +10,8 @@ pub extern "C" fn ___lock(_which: c_int, _varargs: c_int, _instance: &mut Instan
|
|||||||
pub extern "C" fn ___unlock(_which: c_int, _varargs: c_int, _instance: &mut Instance) {
|
pub extern "C" fn ___unlock(_which: c_int, _varargs: c_int, _instance: &mut Instance) {
|
||||||
debug!("emscripten::___unlock");
|
debug!("emscripten::___unlock");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: Not implemented by Emscripten
|
||||||
|
pub extern "C" fn ___wait(_which: c_int, _varargs: c_int, _instance: &mut Instance) {
|
||||||
|
debug!("emscripten::___wait");
|
||||||
|
}
|
||||||
|
19
src/apis/emscripten/math.rs
Normal file
19
src/apis/emscripten/math.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
use crate::webassembly::Instance;
|
||||||
|
|
||||||
|
/// emscripten: _llvm_log10_f64
|
||||||
|
pub extern "C" fn _llvm_log10_f64(value: f64) -> f64 {
|
||||||
|
debug!("emscripten::_llvm_log10_f64");
|
||||||
|
value.log10()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// emscripten: _llvm_log2_f64
|
||||||
|
pub extern "C" fn _llvm_log2_f64(value: f64) -> f64 {
|
||||||
|
debug!("emscripten::_llvm_log2_f64");
|
||||||
|
value.log2()
|
||||||
|
}
|
||||||
|
|
||||||
|
// emscripten: f64-rem
|
||||||
|
pub extern "C" fn f64_rem(x: f64, y: f64) -> f64 {
|
||||||
|
debug!("emscripten::f64-rem");
|
||||||
|
x % y
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
use super::process::abort_with_message;
|
use super::process::abort_with_message;
|
||||||
use crate::webassembly::Instance;
|
use crate::webassembly::Instance;
|
||||||
use libc::{c_void, memcpy, size_t};
|
use libc::{c_void, memcpy, size_t, c_int};
|
||||||
|
|
||||||
/// emscripten: _emscripten_memcpy_big
|
/// emscripten: _emscripten_memcpy_big
|
||||||
pub extern "C" fn _emscripten_memcpy_big(
|
pub extern "C" fn _emscripten_memcpy_big(
|
||||||
@ -36,3 +36,11 @@ pub extern "C" fn abort_on_cannot_grow_memory() {
|
|||||||
debug!("emscripten::abort_on_cannot_grow_memory");
|
debug!("emscripten::abort_on_cannot_grow_memory");
|
||||||
abort_with_message("Cannot enlarge memory arrays!");
|
abort_with_message("Cannot enlarge memory arrays!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// emscripten: ___map_file
|
||||||
|
pub extern "C" fn ___map_file() -> c_int {
|
||||||
|
debug!("emscripten::___map_file");
|
||||||
|
// NOTE: TODO: Em returns -1 here as well. May need to implement properly
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,8 @@ mod errno;
|
|||||||
mod io;
|
mod io;
|
||||||
mod lock;
|
mod lock;
|
||||||
mod memory;
|
mod memory;
|
||||||
|
mod math;
|
||||||
|
mod exception;
|
||||||
mod nullfunc;
|
mod nullfunc;
|
||||||
mod process;
|
mod process;
|
||||||
mod signal;
|
mod signal;
|
||||||
@ -99,6 +101,7 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
|||||||
// Lock
|
// Lock
|
||||||
import_object.set("env", "___lock", ImportValue::Func(lock::___lock as _));
|
import_object.set("env", "___lock", ImportValue::Func(lock::___lock as _));
|
||||||
import_object.set("env", "___unlock", ImportValue::Func(lock::___unlock as _));
|
import_object.set("env", "___unlock", ImportValue::Func(lock::___unlock as _));
|
||||||
|
import_object.set("env", "___wait", ImportValue::Func(lock::___wait as _));
|
||||||
// Env
|
// Env
|
||||||
import_object.set("env", "_getenv", ImportValue::Func(env::_getenv as _));
|
import_object.set("env", "_getenv", ImportValue::Func(env::_getenv as _));
|
||||||
import_object.set("env", "_getpwnam", ImportValue::Func(env::_getpwnam as _));
|
import_object.set("env", "_getpwnam", ImportValue::Func(env::_getpwnam as _));
|
||||||
@ -136,16 +139,71 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
|||||||
"___syscall6",
|
"___syscall6",
|
||||||
ImportValue::Func(syscalls::___syscall6 as _),
|
ImportValue::Func(syscalls::___syscall6 as _),
|
||||||
);
|
);
|
||||||
|
import_object.set(
|
||||||
|
"env",
|
||||||
|
"___syscall12",
|
||||||
|
ImportValue::Func(syscalls::___syscall12 as _),
|
||||||
|
);
|
||||||
|
import_object.set(
|
||||||
|
"env",
|
||||||
|
"___syscall20",
|
||||||
|
ImportValue::Func(syscalls::___syscall20 as _),
|
||||||
|
);
|
||||||
|
import_object.set(
|
||||||
|
"env",
|
||||||
|
"___syscall39",
|
||||||
|
ImportValue::Func(syscalls::___syscall39 as _),
|
||||||
|
);
|
||||||
|
import_object.set(
|
||||||
|
"env",
|
||||||
|
"___syscall40",
|
||||||
|
ImportValue::Func(syscalls::___syscall40 as _),
|
||||||
|
);
|
||||||
import_object.set(
|
import_object.set(
|
||||||
"env",
|
"env",
|
||||||
"___syscall54",
|
"___syscall54",
|
||||||
ImportValue::Func(syscalls::___syscall54 as _),
|
ImportValue::Func(syscalls::___syscall54 as _),
|
||||||
);
|
);
|
||||||
|
import_object.set(
|
||||||
|
"env",
|
||||||
|
"___syscall57",
|
||||||
|
ImportValue::Func(syscalls::___syscall57 as _),
|
||||||
|
);
|
||||||
|
import_object.set(
|
||||||
|
"env",
|
||||||
|
"___syscall63",
|
||||||
|
ImportValue::Func(syscalls::___syscall63 as _),
|
||||||
|
);
|
||||||
|
import_object.set(
|
||||||
|
"env",
|
||||||
|
"___syscall64",
|
||||||
|
ImportValue::Func(syscalls::___syscall64 as _),
|
||||||
|
);
|
||||||
|
import_object.set(
|
||||||
|
"env",
|
||||||
|
"___syscall102",
|
||||||
|
ImportValue::Func(syscalls::___syscall102 as _),
|
||||||
|
);
|
||||||
|
import_object.set(
|
||||||
|
"env",
|
||||||
|
"___syscall114",
|
||||||
|
ImportValue::Func(syscalls::___syscall114 as _),
|
||||||
|
);
|
||||||
|
import_object.set(
|
||||||
|
"env",
|
||||||
|
"___syscall122",
|
||||||
|
ImportValue::Func(syscalls::___syscall122 as _),
|
||||||
|
);
|
||||||
import_object.set(
|
import_object.set(
|
||||||
"env",
|
"env",
|
||||||
"___syscall140",
|
"___syscall140",
|
||||||
ImportValue::Func(syscalls::___syscall140 as _),
|
ImportValue::Func(syscalls::___syscall140 as _),
|
||||||
);
|
);
|
||||||
|
import_object.set(
|
||||||
|
"env",
|
||||||
|
"___syscall142",
|
||||||
|
ImportValue::Func(syscalls::___syscall142 as _),
|
||||||
|
);
|
||||||
import_object.set(
|
import_object.set(
|
||||||
"env",
|
"env",
|
||||||
"___syscall145",
|
"___syscall145",
|
||||||
@ -158,23 +216,28 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
|||||||
);
|
);
|
||||||
import_object.set(
|
import_object.set(
|
||||||
"env",
|
"env",
|
||||||
"___syscall221",
|
"___syscall180",
|
||||||
ImportValue::Func(syscalls::___syscall221 as _),
|
ImportValue::Func(syscalls::___syscall180 as _),
|
||||||
);
|
);
|
||||||
import_object.set(
|
import_object.set(
|
||||||
"env",
|
"env",
|
||||||
"___syscall20",
|
"___syscall181",
|
||||||
ImportValue::Func(syscalls::___syscall20 as _),
|
ImportValue::Func(syscalls::___syscall181 as _),
|
||||||
);
|
);
|
||||||
import_object.set(
|
import_object.set(
|
||||||
"env",
|
"env",
|
||||||
"___syscall64",
|
"___syscall192",
|
||||||
ImportValue::Func(syscalls::___syscall64 as _),
|
ImportValue::Func(syscalls::___syscall192 as _),
|
||||||
);
|
);
|
||||||
import_object.set(
|
import_object.set(
|
||||||
"env",
|
"env",
|
||||||
"___syscall122",
|
"___syscall195",
|
||||||
ImportValue::Func(syscalls::___syscall122 as _),
|
ImportValue::Func(syscalls::___syscall195 as _),
|
||||||
|
);
|
||||||
|
import_object.set(
|
||||||
|
"env",
|
||||||
|
"___syscall197",
|
||||||
|
ImportValue::Func(syscalls::___syscall197 as _),
|
||||||
);
|
);
|
||||||
import_object.set(
|
import_object.set(
|
||||||
"env",
|
"env",
|
||||||
@ -186,36 +249,6 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
|||||||
"___syscall202",
|
"___syscall202",
|
||||||
ImportValue::Func(syscalls::___syscall202 as _),
|
ImportValue::Func(syscalls::___syscall202 as _),
|
||||||
);
|
);
|
||||||
import_object.set(
|
|
||||||
"env",
|
|
||||||
"___syscall340",
|
|
||||||
ImportValue::Func(syscalls::___syscall340 as _),
|
|
||||||
);
|
|
||||||
import_object.set(
|
|
||||||
"env",
|
|
||||||
"___syscall197",
|
|
||||||
ImportValue::Func(syscalls::___syscall197 as _),
|
|
||||||
);
|
|
||||||
import_object.set(
|
|
||||||
"env",
|
|
||||||
"___syscall180",
|
|
||||||
ImportValue::Func(syscalls::___syscall180 as _),
|
|
||||||
);
|
|
||||||
import_object.set(
|
|
||||||
"env",
|
|
||||||
"___syscall181",
|
|
||||||
ImportValue::Func(syscalls::___syscall181 as _),
|
|
||||||
);
|
|
||||||
import_object.set(
|
|
||||||
"env",
|
|
||||||
"___syscall39",
|
|
||||||
ImportValue::Func(syscalls::___syscall39 as _),
|
|
||||||
);
|
|
||||||
import_object.set(
|
|
||||||
"env",
|
|
||||||
"___syscall195",
|
|
||||||
ImportValue::Func(syscalls::___syscall195 as _),
|
|
||||||
);
|
|
||||||
import_object.set(
|
import_object.set(
|
||||||
"env",
|
"env",
|
||||||
"___syscall212",
|
"___syscall212",
|
||||||
@ -228,40 +261,14 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
|||||||
);
|
);
|
||||||
import_object.set(
|
import_object.set(
|
||||||
"env",
|
"env",
|
||||||
"___syscall102",
|
"___syscall330",
|
||||||
ImportValue::Func(syscalls::___syscall102 as _),
|
ImportValue::Func(syscalls::___syscall330 as _),
|
||||||
);
|
);
|
||||||
import_object.set(
|
import_object.set(
|
||||||
"env",
|
"env",
|
||||||
"___syscall54",
|
"___syscall340",
|
||||||
ImportValue::Func(syscalls::___syscall54 as _),
|
ImportValue::Func(syscalls::___syscall340 as _),
|
||||||
);
|
);
|
||||||
import_object.set(
|
|
||||||
"env",
|
|
||||||
"___syscall12",
|
|
||||||
ImportValue::Func(syscalls::___syscall12 as _),
|
|
||||||
);
|
|
||||||
import_object.set(
|
|
||||||
"env",
|
|
||||||
"___syscall192",
|
|
||||||
ImportValue::Func(syscalls::___syscall192 as _),
|
|
||||||
);
|
|
||||||
import_object.set(
|
|
||||||
"env",
|
|
||||||
"___syscall63",
|
|
||||||
ImportValue::Func(syscalls::___syscall63 as _),
|
|
||||||
);
|
|
||||||
import_object.set(
|
|
||||||
"env",
|
|
||||||
"___syscall142",
|
|
||||||
ImportValue::Func(syscalls::___syscall142 as _),
|
|
||||||
);
|
|
||||||
import_object.set(
|
|
||||||
"env",
|
|
||||||
"___syscall57",
|
|
||||||
ImportValue::Func(syscalls::___syscall57 as _),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Process
|
// Process
|
||||||
import_object.set("env", "abort", ImportValue::Func(process::em_abort as _));
|
import_object.set("env", "abort", ImportValue::Func(process::em_abort as _));
|
||||||
import_object.set("env", "_abort", ImportValue::Func(process::_abort as _));
|
import_object.set("env", "_abort", ImportValue::Func(process::_abort as _));
|
||||||
@ -270,9 +277,15 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
|||||||
"abortStackOverflow",
|
"abortStackOverflow",
|
||||||
ImportValue::Func(process::abort_stack_overflow as _),
|
ImportValue::Func(process::abort_stack_overflow as _),
|
||||||
);
|
);
|
||||||
|
import_object.set(
|
||||||
|
"env",
|
||||||
|
"_llvm_trap",
|
||||||
|
ImportValue::Func(process::_llvm_trap as _),
|
||||||
|
);
|
||||||
import_object.set("env", "_fork", ImportValue::Func(process::_fork as _));
|
import_object.set("env", "_fork", ImportValue::Func(process::_fork as _));
|
||||||
import_object.set("env", "_exit", ImportValue::Func(process::_exit as _));
|
import_object.set("env", "_exit", ImportValue::Func(process::_exit as _));
|
||||||
|
import_object.set("env", "_system", ImportValue::Func(process::_system as _));
|
||||||
|
import_object.set("env", "_popen", ImportValue::Func(process::_popen as _));
|
||||||
// Signal
|
// Signal
|
||||||
import_object.set(
|
import_object.set(
|
||||||
"env",
|
"env",
|
||||||
@ -320,6 +333,22 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
|||||||
"getTotalMemory",
|
"getTotalMemory",
|
||||||
ImportValue::Func(memory::get_total_memory as _),
|
ImportValue::Func(memory::get_total_memory as _),
|
||||||
);
|
);
|
||||||
|
import_object.set(
|
||||||
|
"env",
|
||||||
|
"___map_file",
|
||||||
|
ImportValue::Func(memory::___map_file as _),
|
||||||
|
);
|
||||||
|
// Exception
|
||||||
|
import_object.set(
|
||||||
|
"env",
|
||||||
|
"___cxa_allocate_exception",
|
||||||
|
ImportValue::Func(exception::___cxa_allocate_exception as _),
|
||||||
|
);
|
||||||
|
import_object.set(
|
||||||
|
"env",
|
||||||
|
"___cxa_allocate_exception",
|
||||||
|
ImportValue::Func(exception::___cxa_throw as _),
|
||||||
|
);
|
||||||
// NullFuncs
|
// NullFuncs
|
||||||
import_object.set(
|
import_object.set(
|
||||||
"env",
|
"env",
|
||||||
@ -366,6 +395,16 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
|||||||
"nullFunc_viiii",
|
"nullFunc_viiii",
|
||||||
ImportValue::Func(nullfunc::nullfunc_viiii as _),
|
ImportValue::Func(nullfunc::nullfunc_viiii as _),
|
||||||
);
|
);
|
||||||
|
import_object.set(
|
||||||
|
"env",
|
||||||
|
"nullFunc_viiiii",
|
||||||
|
ImportValue::Func(nullfunc::nullfunc_viiiii as _),
|
||||||
|
);
|
||||||
|
import_object.set(
|
||||||
|
"env",
|
||||||
|
"nullFunc_viiiiii",
|
||||||
|
ImportValue::Func(nullfunc::nullfunc_viiiiii as _),
|
||||||
|
);
|
||||||
// Time
|
// Time
|
||||||
import_object.set(
|
import_object.set(
|
||||||
"env",
|
"env",
|
||||||
@ -377,6 +416,21 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
|||||||
"_clock_gettime",
|
"_clock_gettime",
|
||||||
ImportValue::Func(time::_clock_gettime as _),
|
ImportValue::Func(time::_clock_gettime as _),
|
||||||
);
|
);
|
||||||
|
import_object.set(
|
||||||
|
"env",
|
||||||
|
"___clock_gettime",
|
||||||
|
ImportValue::Func(time::___clock_gettime as _),
|
||||||
|
);
|
||||||
|
import_object.set(
|
||||||
|
"env",
|
||||||
|
"_clock",
|
||||||
|
ImportValue::Func(time::_clock as _),
|
||||||
|
);
|
||||||
|
import_object.set(
|
||||||
|
"env",
|
||||||
|
"_difftime",
|
||||||
|
ImportValue::Func(time::_difftime as _),
|
||||||
|
);
|
||||||
import_object.set(
|
import_object.set(
|
||||||
"env",
|
"env",
|
||||||
"_asctime",
|
"_asctime",
|
||||||
@ -409,6 +463,11 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
|||||||
"_sysconf",
|
"_sysconf",
|
||||||
ImportValue::Func(env::_sysconf as _),
|
ImportValue::Func(env::_sysconf as _),
|
||||||
);
|
);
|
||||||
|
// Math
|
||||||
|
import_object.set("env", "_llvm_log10_f64", ImportValue::Func(math::_llvm_log10_f64 as _));
|
||||||
|
import_object.set("env", "_llvm_log2_f64", ImportValue::Func(math::_llvm_log2_f64 as _));
|
||||||
|
import_object.set("asm2wasm", "f64-rem", ImportValue::Func(math::f64_rem as _));
|
||||||
|
|
||||||
|
|
||||||
mock_external!(import_object, _waitpid);
|
mock_external!(import_object, _waitpid);
|
||||||
mock_external!(import_object, _utimes);
|
mock_external!(import_object, _utimes);
|
||||||
|
@ -45,3 +45,13 @@ pub extern "C" fn nullfunc_viiii(_x: u32, _instance: &Instance) {
|
|||||||
debug!("emscripten::nullfunc_viiii");
|
debug!("emscripten::nullfunc_viiii");
|
||||||
abort_with_message("Invalid function pointer called with signature 'viiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)");
|
abort_with_message("Invalid function pointer called with signature 'viiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub extern "C" fn nullfunc_viiiii(_x: u32, _instance: &Instance) {
|
||||||
|
debug!("emscripten::nullfunc_viiiii");
|
||||||
|
abort_with_message("Invalid function pointer called with signature 'viiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern "C" fn nullfunc_viiiiii(_x: u32, _instance: &Instance) {
|
||||||
|
debug!("emscripten::nullfunc_viiiiii");
|
||||||
|
abort_with_message("Invalid function pointer called with signature 'viiiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)");
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use libc::{abort, c_char, pid_t, c_int, exit};
|
use libc::{abort, c_char, pid_t, c_int, exit, EAGAIN};
|
||||||
|
|
||||||
use crate::webassembly::Instance;
|
use crate::webassembly::Instance;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
@ -48,3 +48,22 @@ pub extern "C" fn abort_stack_overflow() {
|
|||||||
// TODO: Message incomplete. Need to finish em runtime data first
|
// TODO: Message incomplete. Need to finish em runtime data first
|
||||||
abort_with_message("Stack overflow! Attempted to allocate some bytes on the stack");
|
abort_with_message("Stack overflow! Attempted to allocate some bytes on the stack");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub extern "C" fn _llvm_trap() {
|
||||||
|
debug!("emscripten::_llvm_trap");
|
||||||
|
abort_with_message("abort!");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern "C" fn _system() -> c_int {
|
||||||
|
debug!("emscripten::_system");
|
||||||
|
// TODO: May need to change this Em impl to a working version
|
||||||
|
eprintln!("Can't call external programs");
|
||||||
|
return EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern "C" fn _popen() -> c_int {
|
||||||
|
debug!("emscripten::_popen");
|
||||||
|
// TODO: May need to change this Em impl to a working version
|
||||||
|
eprintln!("Missing function: popen");
|
||||||
|
unsafe { abort(); }
|
||||||
|
}
|
||||||
|
@ -63,9 +63,21 @@ use libc::{
|
|||||||
SOL_SOCKET,
|
SOL_SOCKET,
|
||||||
TIOCGWINSZ,
|
TIOCGWINSZ,
|
||||||
// ENOTTY,
|
// ENOTTY,
|
||||||
c_char
|
c_char,
|
||||||
|
rusage,
|
||||||
|
rmdir,
|
||||||
|
EINVAL,
|
||||||
|
fcntl,
|
||||||
|
F_SETFD,
|
||||||
|
F_GETFD,
|
||||||
};
|
};
|
||||||
// use std::sys::fd::FileDesc;
|
|
||||||
|
// Linking to functions that are provided by rust libc
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
#[link(name = "c")]
|
||||||
|
extern {
|
||||||
|
pub fn wait4(pid: pid_t, status: *mut c_int, options: c_int, rusage: *mut rusage) -> pid_t;
|
||||||
|
}
|
||||||
|
|
||||||
// Another conditional constant for name resolution: Macos et iOS use
|
// Another conditional constant for name resolution: Macos et iOS use
|
||||||
// SO_NOSIGPIPE as a setsockopt flag to disable SIGPIPE emission on socket.
|
// SO_NOSIGPIPE as a setsockopt flag to disable SIGPIPE emission on socket.
|
||||||
@ -181,15 +193,19 @@ pub extern "C" fn ___syscall39(
|
|||||||
let pathname: u32 = varargs.get(instance);
|
let pathname: u32 = varargs.get(instance);
|
||||||
let mode: u32 = varargs.get(instance);
|
let mode: u32 = varargs.get(instance);
|
||||||
let pathname_addr = instance.memory_offset_addr(0, pathname as usize) as *const i8;
|
let pathname_addr = instance.memory_offset_addr(0, pathname as usize) as *const i8;
|
||||||
|
unsafe { mkdir(pathname_addr, mode as _) }
|
||||||
unsafe { mkdir(pathname_addr, mode as _) };
|
|
||||||
0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// getppid
|
// rmdir
|
||||||
pub extern "C" fn ___syscall64() -> pid_t {
|
pub extern "C" fn ___syscall40(
|
||||||
debug!("emscripten::___syscall64 (getppid)");
|
_which: c_int,
|
||||||
unsafe { getpid() }
|
mut varargs: VarArgs,
|
||||||
|
instance: &mut Instance,
|
||||||
|
) -> c_int {
|
||||||
|
debug!("emscripten::___syscall40 (rmdir)");
|
||||||
|
let pathname: u32 = varargs.get(instance);
|
||||||
|
let pathname_addr = instance.memory_offset_addr(0, pathname as usize) as *const i8;
|
||||||
|
unsafe { rmdir(pathname_addr) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ioctl
|
/// ioctl
|
||||||
@ -234,6 +250,40 @@ pub extern "C" fn ___syscall54(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setpgid
|
||||||
|
pub extern "C" fn ___syscall57(
|
||||||
|
_which: c_int,
|
||||||
|
mut varargs: VarArgs,
|
||||||
|
instance: &mut Instance,
|
||||||
|
) -> c_int {
|
||||||
|
debug!("emscripten::___syscall57 (setpgid)");
|
||||||
|
let pid: i32 = varargs.get(instance);
|
||||||
|
let pgid: i32 = varargs.get(instance);
|
||||||
|
unsafe {
|
||||||
|
setpgid(pid, pgid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dup2
|
||||||
|
pub extern "C" fn ___syscall63(
|
||||||
|
_which: c_int,
|
||||||
|
mut varargs: VarArgs,
|
||||||
|
instance: &mut Instance,
|
||||||
|
) -> c_int {
|
||||||
|
debug!("emscripten::___syscall63 (dup2)");
|
||||||
|
|
||||||
|
let src: i32 = varargs.get(instance);
|
||||||
|
let dst: i32 = varargs.get(instance);
|
||||||
|
|
||||||
|
unsafe { dup2(src, dst) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// getppid
|
||||||
|
pub extern "C" fn ___syscall64() -> pid_t {
|
||||||
|
debug!("emscripten::___syscall64 (getppid)");
|
||||||
|
unsafe { getpid() }
|
||||||
|
}
|
||||||
|
|
||||||
// socketcall
|
// socketcall
|
||||||
pub extern "C" fn ___syscall102(
|
pub extern "C" fn ___syscall102(
|
||||||
_which: c_int,
|
_which: c_int,
|
||||||
@ -365,7 +415,7 @@ pub extern "C" fn ___syscall102(
|
|||||||
|
|
||||||
let fd = unsafe { accept(socket, address, address_len_addr) };
|
let fd = unsafe { accept(socket, address, address_len_addr) };
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let address_linux = instance.memory_offset_addr(0, address_addr as usize) as *mut LinuxSockAddr;
|
let address_linux = instance.memory_offset_addr(0, address_addr as usize) as *mut LinuxSockAddr;
|
||||||
(*address_linux).sa_family = (*address).sa_family as u16;
|
(*address_linux).sa_family = (*address).sa_family as u16;
|
||||||
(*address_linux).sa_data = (*address).sa_data;
|
(*address_linux).sa_data = (*address).sa_data;
|
||||||
@ -503,6 +553,27 @@ pub extern "C" fn ___syscall102(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// wait4
|
||||||
|
pub extern "C" fn ___syscall114(
|
||||||
|
_which: c_int,
|
||||||
|
mut varargs: VarArgs,
|
||||||
|
instance: &mut Instance,
|
||||||
|
) -> pid_t {
|
||||||
|
debug!("emscripten::___syscall114 (wait4)");
|
||||||
|
let pid: pid_t = varargs.get(instance);
|
||||||
|
let status: u32 = varargs.get(instance);
|
||||||
|
let options: c_int = varargs.get(instance);
|
||||||
|
let rusage: u32 = varargs.get(instance);
|
||||||
|
let status_addr = instance.memory_offset_addr(0, status as usize) as *mut c_int;
|
||||||
|
let rusage_addr = instance.memory_offset_addr(0, rusage as usize) as *mut rusage;
|
||||||
|
let res = unsafe { wait4(pid, status_addr, options, rusage_addr) };
|
||||||
|
debug!(
|
||||||
|
"=> pid: {}, status: {:?}, options: {}, rusage: {:?} = pid: {}",
|
||||||
|
pid, status_addr, options, rusage_addr, res
|
||||||
|
);
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
/// uname
|
/// uname
|
||||||
// NOTE: Wondering if we should return custom utsname, like Emscripten.
|
// NOTE: Wondering if we should return custom utsname, like Emscripten.
|
||||||
pub extern "C" fn ___syscall122(
|
pub extern "C" fn ___syscall122(
|
||||||
@ -517,6 +588,29 @@ pub extern "C" fn ___syscall122(
|
|||||||
unsafe { uname(buf_addr) }
|
unsafe { uname(buf_addr) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// select
|
||||||
|
pub extern "C" fn ___syscall142(
|
||||||
|
_which: c_int,
|
||||||
|
mut varargs: VarArgs,
|
||||||
|
instance: &mut Instance,
|
||||||
|
) -> c_int {
|
||||||
|
debug!("emscripten::___syscall142 (newselect)");
|
||||||
|
|
||||||
|
let nfds: i32 = varargs.get(instance);
|
||||||
|
let readfds: u32 = varargs.get(instance);
|
||||||
|
let writefds: u32 = varargs.get(instance);
|
||||||
|
let exceptfds: u32 = varargs.get(instance);
|
||||||
|
let _timeout: i32 = varargs.get(instance);
|
||||||
|
|
||||||
|
assert!(nfds <= 64, "`nfds` must be less than or equal to 64");
|
||||||
|
assert!(exceptfds == 0, "`exceptfds` is not supporrted");
|
||||||
|
|
||||||
|
let readfds_ptr = instance.memory_offset_addr(0, readfds as _) as _;
|
||||||
|
let writefds_ptr = instance.memory_offset_addr(0, writefds as _) as _;
|
||||||
|
|
||||||
|
unsafe { select(nfds, readfds_ptr, writefds_ptr, 0 as _, 0 as _) }
|
||||||
|
}
|
||||||
|
|
||||||
// mmap2
|
// mmap2
|
||||||
pub extern "C" fn ___syscall192(
|
pub extern "C" fn ___syscall192(
|
||||||
_which: c_int,
|
_which: c_int,
|
||||||
@ -798,6 +892,42 @@ pub extern "C" fn ___syscall221(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// dup3
|
||||||
|
pub extern "C" fn ___syscall330(
|
||||||
|
_which: c_int,
|
||||||
|
mut varargs: VarArgs,
|
||||||
|
instance: &mut Instance,
|
||||||
|
) -> pid_t {
|
||||||
|
// Implementation based on description at https://linux.die.net/man/2/dup3
|
||||||
|
debug!("emscripten::___syscall330 (dup3)");
|
||||||
|
let oldfd: c_int = varargs.get(instance);
|
||||||
|
let newfd: c_int = varargs.get(instance);
|
||||||
|
let flags: c_int = varargs.get(instance);
|
||||||
|
|
||||||
|
if oldfd == newfd {
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = unsafe { dup2(oldfd, newfd) };
|
||||||
|
|
||||||
|
// Set flags on newfd (https://www.gnu.org/software/libc/manual/html_node/Descriptor-Flags.html)
|
||||||
|
let mut old_flags = unsafe { fcntl (newfd, F_GETFD, 0) };
|
||||||
|
|
||||||
|
if old_flags > 0 {
|
||||||
|
old_flags |= flags;
|
||||||
|
} else if old_flags == 0 {
|
||||||
|
old_flags &= !flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe { fcntl (newfd, F_SETFD, old_flags); }
|
||||||
|
|
||||||
|
debug!(
|
||||||
|
"=> oldfd: {}, newfd: {}, flags: {} = pid: {}",
|
||||||
|
oldfd, newfd, flags, res
|
||||||
|
);
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
// prlimit64
|
// prlimit64
|
||||||
pub extern "C" fn ___syscall340(
|
pub extern "C" fn ___syscall340(
|
||||||
_which: c_int,
|
_which: c_int,
|
||||||
@ -824,54 +954,3 @@ pub extern "C" fn ___syscall340(
|
|||||||
|
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
// dup2
|
|
||||||
pub extern "C" fn ___syscall63(
|
|
||||||
_which: c_int,
|
|
||||||
mut varargs: VarArgs,
|
|
||||||
instance: &mut Instance,
|
|
||||||
) -> c_int {
|
|
||||||
debug!("emscripten::___syscall63 (dup2)");
|
|
||||||
|
|
||||||
let src: i32 = varargs.get(instance);
|
|
||||||
let dst: i32 = varargs.get(instance);
|
|
||||||
|
|
||||||
unsafe { dup2(src, dst) }
|
|
||||||
}
|
|
||||||
|
|
||||||
// select
|
|
||||||
pub extern "C" fn ___syscall142(
|
|
||||||
_which: c_int,
|
|
||||||
mut varargs: VarArgs,
|
|
||||||
instance: &mut Instance,
|
|
||||||
) -> c_int {
|
|
||||||
debug!("emscripten::___syscall142 (newselect)");
|
|
||||||
|
|
||||||
let nfds: i32 = varargs.get(instance);
|
|
||||||
let readfds: u32 = varargs.get(instance);
|
|
||||||
let writefds: u32 = varargs.get(instance);
|
|
||||||
let exceptfds: u32 = varargs.get(instance);
|
|
||||||
let _timeout: i32 = varargs.get(instance);
|
|
||||||
|
|
||||||
assert!(nfds <= 64, "`nfds` must be less than or equal to 64");
|
|
||||||
assert!(exceptfds == 0, "`exceptfds` is not supporrted");
|
|
||||||
|
|
||||||
let readfds_ptr = instance.memory_offset_addr(0, readfds as _) as _;
|
|
||||||
let writefds_ptr = instance.memory_offset_addr(0, writefds as _) as _;
|
|
||||||
|
|
||||||
unsafe { select(nfds, readfds_ptr, writefds_ptr, 0 as _, 0 as _) }
|
|
||||||
}
|
|
||||||
|
|
||||||
// setpgid
|
|
||||||
pub extern "C" fn ___syscall57(
|
|
||||||
_which: c_int,
|
|
||||||
mut varargs: VarArgs,
|
|
||||||
instance: &mut Instance,
|
|
||||||
) -> c_int {
|
|
||||||
debug!("emscripten::___syscall57 (setpgid)");
|
|
||||||
let pid: i32 = varargs.get(instance);
|
|
||||||
let pgid: i32 = varargs.get(instance);
|
|
||||||
unsafe {
|
|
||||||
setpgid(pid, pgid)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -66,6 +66,24 @@ pub extern "C" fn _clock_gettime(clk_id: c_int, tp: c_int, instance: &mut Instan
|
|||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// emscripten: ___clock_gettime
|
||||||
|
pub extern "C" fn ___clock_gettime(clk_id: c_int, tp: c_int, instance: &mut Instance) -> c_int {
|
||||||
|
debug!("emscripten::___clock_gettime {} {}", clk_id, tp);
|
||||||
|
_clock_gettime(clk_id, tp, instance)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// emscripten: _clock
|
||||||
|
pub extern "C" fn _clock() -> c_int {
|
||||||
|
debug!("emscripten::_clock");
|
||||||
|
0 // TODO: unimplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
/// emscripten: _difftime
|
||||||
|
pub extern "C" fn _difftime(t0: u32, t1: u32) -> c_int {
|
||||||
|
debug!("emscripten::_difftime");
|
||||||
|
(t0 - t1) as _
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct guest_tm {
|
struct guest_tm {
|
||||||
pub tm_sec: c_int, // 0
|
pub tm_sec: c_int, // 0
|
||||||
|
@ -17,7 +17,7 @@ pub fn is_emscripten_module(module: &Module) -> bool {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn write_to_buf(string: *const c_char, buf: u32, max: u32, instance: &Instance) -> u32 {
|
pub fn write_to_buf(string: *const c_char, buf: u32, max: u32, instance: &Instance) -> u32 {
|
||||||
let buf_addr = instance.memory_offset_addr(0, buf as _) as *mut c_char;
|
let buf_addr = instance.memory_offset_addr(0, buf as _) as *mut c_char;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
0
src/emtests/syscalls.rs
Normal file
0
src/emtests/syscalls.rs
Normal file
Loading…
Reference in New Issue
Block a user