diff --git a/src/apis/emscripten/env.rs b/src/apis/emscripten/env.rs index 97f91c2b6..d8b433533 100644 --- a/src/apis/emscripten/env.rs +++ b/src/apis/emscripten/env.rs @@ -1,12 +1,21 @@ use super::super::host; /// NOTE: These syscalls only support wasm_32 for now because they take u32 offset -use libc::{c_int, getpwnam as libc_getpwnam, passwd, getgrnam as libc_getgrnam, group}; +use libc::{ + c_int, getpwnam as libc_getpwnam, passwd, + getgrnam as libc_getgrnam, group, clock_gettime as libc_clock_gettime, timespec, + // uname as libc_uname, utsname, +}; use std::ffi::CStr; use std::os::raw::c_char; use std::{slice, mem}; +use std::time::SystemTime; use crate::webassembly::Instance; +<<<<<<< HEAD use super::utils::{copy_cstr_into_wasm, copy_terminated_array_of_cstrs}; +======= +use crate::webassembly::LinearMemory; +>>>>>>> Add a few more syscalls /// emscripten: _getenv pub extern "C" fn _getenv(name_ptr: c_int, instance: &mut Instance) -> c_int { @@ -86,3 +95,22 @@ pub extern "C" fn _getgrnam(name_ptr: c_int, instance: &mut Instance) -> c_int { group_struct_offset as c_int } } + +pub extern fn _getpid(_instance: &mut Instance) -> c_int { + 0 +} +pub extern fn _getppid(_instance: &mut Instance) -> c_int { + 0 +} + +pub extern fn _uname(_buf: c_int, _instance: &mut Instance) -> c_int { + 0 +} + +pub extern fn _localtime_r() -> u32 { + 0 +} + +pub extern fn _getpagesize() -> u32 { + LinearMemory::PAGE_SIZE +} diff --git a/src/apis/emscripten/mod.rs b/src/apis/emscripten/mod.rs index b0495743a..7a24dd663 100644 --- a/src/apis/emscripten/mod.rs +++ b/src/apis/emscripten/mod.rs @@ -57,9 +57,9 @@ pub fn emscripten_set_up_memory(memory: &mut LinearMemory) { macro_rules! mock_external { ($import:ident, $name:ident) => {{ - fn _mocked_fn() { + fn _mocked_fn() -> i32 { println!("emscripten::{} ", stringify!($name)); - // return 0 + 0 } $import.set( "env", @@ -293,8 +293,34 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> { import_object.set( "env", "_clock_gettime", - ImportValue::Func(time::_clock_gettime as _), + ImportValue::Func(env::_clock_gettime as _), ); + import_object.set( + "env", + "___syscall20", + ImportValue::Func(env::_getpid as _), + ); + import_object.set( + "env", + "___syscall64", + ImportValue::Func(env::_getppid as _), + ); + import_object.set( + "env", + "___syscall122", + ImportValue::Func(env::_uname as _), + ); + import_object.set( + "env", + "_localtime_r", + ImportValue::Func(env::_localtime_r as _), + ); + import_object.set( + "env", + "_getpagesize", + ImportValue::Func(env::_getpagesize as _), + ); + mock_external!(import_object, _waitpid); mock_external!(import_object, _utimes); mock_external!(import_object, _usleep); @@ -315,14 +341,14 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> { mock_external!(import_object, _sched_yield); mock_external!(import_object, _raise); mock_external!(import_object, _mktime); - mock_external!(import_object, _localtime_r); + // mock_external!(import_object, _localtime_r); mock_external!(import_object, _localtime); mock_external!(import_object, _llvm_stacksave); mock_external!(import_object, _llvm_stackrestore); mock_external!(import_object, _kill); mock_external!(import_object, _gmtime_r); // mock_external!(import_object, _gettimeofday); - mock_external!(import_object, _getpagesize); + // mock_external!(import_object, _getpagesize); mock_external!(import_object, _getgrent); mock_external!(import_object, _getaddrinfo); mock_external!(import_object, _fork); @@ -335,7 +361,7 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> { mock_external!(import_object, ___syscall85); mock_external!(import_object, ___syscall75); mock_external!(import_object, ___syscall66); - mock_external!(import_object, ___syscall64); + // mock_external!(import_object, ___syscall64); mock_external!(import_object, ___syscall63); mock_external!(import_object, ___syscall60); mock_external!(import_object, ___syscall54); @@ -364,9 +390,9 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> { // mock_external!(import_object, ___syscall145); mock_external!(import_object, ___syscall142); mock_external!(import_object, ___syscall140); - mock_external!(import_object, ___syscall122); + // mock_external!(import_object, ___syscall122); mock_external!(import_object, ___syscall102); - mock_external!(import_object, ___syscall20); + // mock_external!(import_object, ___syscall20); mock_external!(import_object, ___syscall15); mock_external!(import_object, ___syscall10); diff --git a/src/apis/emscripten/time.rs b/src/apis/emscripten/time.rs index 85c9d7519..35fd37253 100644 --- a/src/apis/emscripten/time.rs +++ b/src/apis/emscripten/time.rs @@ -4,29 +4,72 @@ use std::ptr; use crate::webassembly::Instance; /// emscripten: _gettimeofday -pub extern "C" fn _gettimeofday(timeval_ptr_offset: c_int, tz_offset: c_int, instance: &mut Instance) -> c_int { - debug!("emscripten::_gettimeofday {}", timeval_ptr_offset); +// pub extern "C" fn _gettimeofday(timeval_ptr_offset: c_int, tz_offset: c_int, instance: &mut Instance) -> c_int { +// debug!("emscripten::_gettimeofday {}", timeval_ptr_offset); - unsafe { - let mut timeval_value = *(instance.memory_offset_addr(0, timeval_ptr_offset as _) as *mut timeval); - // We skip the timezone for now - let mut tz = ptr::null_mut(); - debug!("emscripten::_gettimeofday(initial) {} {}", (timeval_value).tv_sec, (timeval_value).tv_usec); +// unsafe { +// let mut timeval_value = *(instance.memory_offset_addr(0, timeval_ptr_offset as _) as *mut timeval); +// // We skip the timezone for now +// let mut tz = ptr::null_mut(); +// debug!("emscripten::_gettimeofday(initial) {} {}", (timeval_value).tv_sec, (timeval_value).tv_usec); - let returned = gettimeofday(&mut timeval_value, tz); - debug!("emscripten::_gettimeofday(filled) {} {}", (timeval_value).tv_sec, (timeval_value).tv_usec); - returned +// let returned = gettimeofday(&mut timeval_value, tz); +// debug!("emscripten::_gettimeofday(filled) {} {}", (timeval_value).tv_sec, (timeval_value).tv_usec); +// returned +// } +// } +pub extern fn _gettimeofday(tp: c_int, tz: c_int, instance: &mut Instance) -> c_int { + #[repr(C)] + struct GuestTimeVal { + tv_sec: i32, + tv_usec: i32, } + + assert!(tz == 0, "the timezone argument of `_gettimeofday` must be null"); + unsafe { + let now = SystemTime::now(); + let since_epoch = now.duration_since(SystemTime::UNIX_EPOCH).unwrap(); + let timeval_struct_ptr = instance.memory_offset_addr(0, tp as _) as *mut GuestTimeVal; + + (*timeval_struct_ptr).tv_sec = since_epoch.as_secs() as _; + (*timeval_struct_ptr).tv_usec = since_epoch.subsec_nanos() as _; + } + 0 } + /// emscripten: _clock_gettime -pub extern "C" fn _clock_gettime(clk_id: clockid_t, tp_offset: c_int, instance: &mut Instance) -> c_int { - debug!("emscripten::_clock_gettime {} {}", clk_id, tp_offset); +// pub extern "C" fn _clock_gettime(clk_id: clockid_t, tp_offset: c_int, instance: &mut Instance) -> c_int { +// debug!("emscripten::_clock_gettime {} {}", clk_id, tp_offset); + +// unsafe { +// let mut tp = instance.memory_offset_addr(0, tp_offset as _) as *mut timespec; +// let returned = clock_gettime(clk_id, tp); +// debug!("emscripten::clock_gettime(filled) {} {}", (*tp).tv_sec, (*tp).tv_nsec); +// returned +// } +// } + +pub extern fn _clock_gettime(clk_id: c_int, tp: c_int, instance: &mut Instance) -> c_int { + #[repr(C)] + struct GuestTimeSpec { + tv_sec: i32, + tv_nsec: i32, + } unsafe { - let mut tp = instance.memory_offset_addr(0, tp_offset as _) as *mut timespec; - let returned = clock_gettime(clk_id, tp); - debug!("emscripten::clock_gettime(filled) {} {}", (*tp).tv_sec, (*tp).tv_nsec); - returned + let mut timespec = timespec { + tv_sec: 0, + tv_nsec: 0, + }; + let ret = libc_clock_gettime(clk_id as _, &mut timespec); + if ret != 0 { + return ret; + } + + let timespec_struct_ptr = instance.memory_offset_addr(0, tp as _) as *mut GuestTimeSpec; + (*timespec_struct_ptr).tv_sec = timespec.tv_sec as _; + (*timespec_struct_ptr).tv_nsec = timespec.tv_nsec as _; } -} + 0 +} \ No newline at end of file