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) {
|
||||
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 crate::webassembly::Instance;
|
||||
use libc::{c_void, memcpy, size_t};
|
||||
use libc::{c_void, memcpy, size_t, c_int};
|
||||
|
||||
/// emscripten: _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");
|
||||
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 lock;
|
||||
mod memory;
|
||||
mod math;
|
||||
mod exception;
|
||||
mod nullfunc;
|
||||
mod process;
|
||||
mod signal;
|
||||
@ -99,6 +101,7 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
||||
// Lock
|
||||
import_object.set("env", "___lock", ImportValue::Func(lock::___lock as _));
|
||||
import_object.set("env", "___unlock", ImportValue::Func(lock::___unlock as _));
|
||||
import_object.set("env", "___wait", ImportValue::Func(lock::___wait as _));
|
||||
// Env
|
||||
import_object.set("env", "_getenv", ImportValue::Func(env::_getenv 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",
|
||||
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(
|
||||
"env",
|
||||
"___syscall54",
|
||||
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(
|
||||
"env",
|
||||
"___syscall140",
|
||||
ImportValue::Func(syscalls::___syscall140 as _),
|
||||
);
|
||||
import_object.set(
|
||||
"env",
|
||||
"___syscall142",
|
||||
ImportValue::Func(syscalls::___syscall142 as _),
|
||||
);
|
||||
import_object.set(
|
||||
"env",
|
||||
"___syscall145",
|
||||
@ -158,23 +216,28 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
||||
);
|
||||
import_object.set(
|
||||
"env",
|
||||
"___syscall221",
|
||||
ImportValue::Func(syscalls::___syscall221 as _),
|
||||
"___syscall180",
|
||||
ImportValue::Func(syscalls::___syscall180 as _),
|
||||
);
|
||||
import_object.set(
|
||||
"env",
|
||||
"___syscall20",
|
||||
ImportValue::Func(syscalls::___syscall20 as _),
|
||||
"___syscall181",
|
||||
ImportValue::Func(syscalls::___syscall181 as _),
|
||||
);
|
||||
import_object.set(
|
||||
"env",
|
||||
"___syscall64",
|
||||
ImportValue::Func(syscalls::___syscall64 as _),
|
||||
"___syscall192",
|
||||
ImportValue::Func(syscalls::___syscall192 as _),
|
||||
);
|
||||
import_object.set(
|
||||
"env",
|
||||
"___syscall122",
|
||||
ImportValue::Func(syscalls::___syscall122 as _),
|
||||
"___syscall195",
|
||||
ImportValue::Func(syscalls::___syscall195 as _),
|
||||
);
|
||||
import_object.set(
|
||||
"env",
|
||||
"___syscall197",
|
||||
ImportValue::Func(syscalls::___syscall197 as _),
|
||||
);
|
||||
import_object.set(
|
||||
"env",
|
||||
@ -186,36 +249,6 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
||||
"___syscall202",
|
||||
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(
|
||||
"env",
|
||||
"___syscall212",
|
||||
@ -228,40 +261,14 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
||||
);
|
||||
import_object.set(
|
||||
"env",
|
||||
"___syscall102",
|
||||
ImportValue::Func(syscalls::___syscall102 as _),
|
||||
"___syscall330",
|
||||
ImportValue::Func(syscalls::___syscall330 as _),
|
||||
);
|
||||
import_object.set(
|
||||
"env",
|
||||
"___syscall54",
|
||||
ImportValue::Func(syscalls::___syscall54 as _),
|
||||
"___syscall340",
|
||||
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
|
||||
import_object.set("env", "abort", ImportValue::Func(process::em_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",
|
||||
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", "_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
|
||||
import_object.set(
|
||||
"env",
|
||||
@ -320,6 +333,22 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
||||
"getTotalMemory",
|
||||
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
|
||||
import_object.set(
|
||||
"env",
|
||||
@ -366,6 +395,16 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
||||
"nullFunc_viiii",
|
||||
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
|
||||
import_object.set(
|
||||
"env",
|
||||
@ -377,6 +416,21 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
||||
"_clock_gettime",
|
||||
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(
|
||||
"env",
|
||||
"_asctime",
|
||||
@ -409,6 +463,11 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
||||
"_sysconf",
|
||||
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, _utimes);
|
||||
|
@ -45,3 +45,13 @@ pub extern "C" fn nullfunc_viiii(_x: u32, _instance: &Instance) {
|
||||
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)");
|
||||
}
|
||||
|
||||
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 std::ffi::CStr;
|
||||
@ -48,3 +48,22 @@ pub extern "C" fn abort_stack_overflow() {
|
||||
// TODO: Message incomplete. Need to finish em runtime data first
|
||||
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,
|
||||
TIOCGWINSZ,
|
||||
// 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
|
||||
// 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 mode: u32 = varargs.get(instance);
|
||||
let pathname_addr = instance.memory_offset_addr(0, pathname as usize) as *const i8;
|
||||
|
||||
unsafe { mkdir(pathname_addr, mode as _) };
|
||||
0
|
||||
unsafe { mkdir(pathname_addr, mode as _) }
|
||||
}
|
||||
|
||||
// getppid
|
||||
pub extern "C" fn ___syscall64() -> pid_t {
|
||||
debug!("emscripten::___syscall64 (getppid)");
|
||||
unsafe { getpid() }
|
||||
// rmdir
|
||||
pub extern "C" fn ___syscall40(
|
||||
_which: c_int,
|
||||
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
|
||||
@ -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
|
||||
pub extern "C" fn ___syscall102(
|
||||
_which: c_int,
|
||||
@ -365,7 +415,7 @@ pub extern "C" fn ___syscall102(
|
||||
|
||||
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;
|
||||
(*address_linux).sa_family = (*address).sa_family as u16;
|
||||
(*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
|
||||
// NOTE: Wondering if we should return custom utsname, like Emscripten.
|
||||
pub extern "C" fn ___syscall122(
|
||||
@ -517,6 +588,29 @@ pub extern "C" fn ___syscall122(
|
||||
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
|
||||
pub extern "C" fn ___syscall192(
|
||||
_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
|
||||
pub extern "C" fn ___syscall340(
|
||||
_which: c_int,
|
||||
@ -824,54 +954,3 @@ pub extern "C" fn ___syscall340(
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
/// 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)]
|
||||
struct guest_tm {
|
||||
pub tm_sec: c_int, // 0
|
||||
|
@ -17,7 +17,7 @@ pub fn is_emscripten_module(module: &Module) -> bool {
|
||||
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;
|
||||
|
||||
unsafe {
|
||||
|
0
src/emtests/syscalls.rs
Normal file
0
src/emtests/syscalls.rs
Normal file
Loading…
Reference in New Issue
Block a user