diff --git a/src/apis/emscripten/memory.rs b/src/apis/emscripten/memory.rs index 28d75e5a6..8a9181a59 100644 --- a/src/apis/emscripten/memory.rs +++ b/src/apis/emscripten/memory.rs @@ -18,8 +18,7 @@ pub extern "C" fn _emscripten_memcpy_big(dest: u32, src: u32, len: u32, instance /// emscripten: getTotalMemory pub extern "C" fn get_total_memory(instance: &mut Instance) -> u32 { debug!("emscripten::get_total_memory"); - // instance.memories[0].current_size() - 67108864 + instance.memories[0].current_size() } /// emscripten: enlargeMemory diff --git a/src/apis/emscripten/mod.rs b/src/apis/emscripten/mod.rs index e97717f9f..4ff3b1699 100644 --- a/src/apis/emscripten/mod.rs +++ b/src/apis/emscripten/mod.rs @@ -22,6 +22,8 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> { import_object.set("env", "___syscall3", ImportValue::Func(syscalls::___syscall3 as *const u8)); import_object.set("env", "___syscall4", ImportValue::Func(syscalls::___syscall4 as *const u8)); import_object.set("env", "___syscall5", ImportValue::Func(syscalls::___syscall5 as *const u8)); + import_object.set("env", "___syscall54", ImportValue::Func(syscalls::___syscall54 as *const u8)); + import_object.set("env", "___syscall122", ImportValue::Func(syscalls::___syscall122 as *const u8)); // Emscripten other APIs import_object.set("env", "abort", ImportValue::Func(process::em_abort as *const u8)); import_object.set("env", "_abort", ImportValue::Func(process::_abort as *const u8)); diff --git a/src/apis/emscripten/syscalls.rs b/src/apis/emscripten/syscalls.rs index 26525be03..6b572f76f 100644 --- a/src/apis/emscripten/syscalls.rs +++ b/src/apis/emscripten/syscalls.rs @@ -1,4 +1,5 @@ /// NOTE: These syscalls only support wasm_32 for now because they take u32 offset +/// Syscall list: https://www.cs.utexas.edu/~bismith/test/syscalls/syscalls32.html use libc::{ c_int, @@ -11,62 +12,68 @@ use libc::{ open, close, }; +use std::{mem, ptr}; + use std::os::raw::c_char; use std::ffi::CStr; use crate::webassembly::{Instance}; -/// emscripten: ___syscall3 (sys_read) +// A macro to retrieve variadic arguments given a varargs offset +macro_rules! vararg { + ($name:ident, $type:ident, $instance:ident, $varargs:ident) => ( + let ($name, $varargs) = unsafe { + let ptr = $instance.memory_offset_addr(0, $varargs as usize); + let ret = ptr::read(ptr as *const $type); + (ret, $varargs + 4) + } + ) +} + +/// sys_read pub extern "C" fn ___syscall3(which: c_int, varargs: c_int, instance: &mut Instance) -> ssize_t { - // function ___syscall3(which, varargs) { - // which, varargs - // SYSCALLS.varargs = varargs; - // try { - // var stream = SYSCALLS.getStreamFromFD(), - // buf = SYSCALLS.get(), - // count = SYSCALLS.get(); - // return FS.read(stream, HEAP8, buf, count); - // } catch (e) { - // if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e); - // return -e.errno; - // } - // } - debug!("emscripten::___syscall3({}, {})", which, varargs); + debug!("emscripten::___syscall3"); 0 } -/// emscripten: ___syscall4 (sys_write) -pub extern "C" fn ___syscall4(which_ptr: c_int, varargs_ptr: c_int, instance: &mut Instance) -> c_int { - // function ___syscall4(which, varargs) { - // SYSCALLS.varargs = varargs; - // try { - // var stream = SYSCALLS.getStreamFromFD(), - // buf = SYSCALLS.get(), - // count = SYSCALLS.get(); - // return FS.write(stream, HEAP8, buf, count); - // } catch (e) { - // if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e); - // return -e.errno; - // } - // } - debug!("emscripten::___syscall4({}, {})", which_ptr, varargs_ptr); - 0 +/// sys_write +#[no_mangle] +pub extern "C" fn ___syscall4(which: c_int, varargs: c_int, instance: &mut Instance) -> c_int { + debug!("emscripten::___syscall4"); + vararg!(fd, i32, instance, varargs); + vararg!(buf_ptr, u32, instance, varargs); + vararg!(count, u32, instance, varargs); + debug!("fd: {}, buf_ptr: {}, count: {}", fd, buf_ptr, count); + let buf = instance.memory_offset_addr(0, buf_ptr as usize) as *const c_void; + unsafe { write(fd, buf, count as usize) as i32 } } -/// emscripten: ___syscall5 (sys_open) + +/// sys_open pub extern "C" fn ___syscall5(which: c_int, varargs: c_int, instance: &mut Instance) -> c_int { - // function ___syscall5(which, varargs) { - // SYSCALLS.varargs = varargs; - // try { - // var pathname = SYSCALLS.getStr(), - // flags = SYSCALLS.get(), - // mode = SYSCALLS.get(); - // var stream = FS.open(pathname, flags, mode); - // return stream.fd; - // } catch (e) { - // if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e); - // return -e.errno; - // } - // } - debug!("host::___syscall5({}, {})", which, varargs); + debug!("emscripten::___syscall5"); + vararg!(pathname, u32, instance, varargs); + vararg!(flags, u32, instance, varargs); + vararg!(mode, u32, instance, varargs); + debug!("pathname: {}, flags: {}, mode: {}", pathname, flags, mode); -2 } + + +// sys_ioctl +#[no_mangle] +pub extern "C" fn ___syscall54(which: c_int, varargs: c_int, instance: &mut Instance) -> c_int { + debug!("emscripten::___syscall54"); + vararg!(stream, u32, instance, varargs); + vararg!(op, u32, instance, varargs); + debug!("stream: {}, op: {}", stream, op); + 0 +} + +// sys_newuname +#[no_mangle] +pub extern "C" fn ___syscall122(which: c_int, varargs: c_int, instance: &mut Instance) -> c_int { + debug!("emscripten::___syscall122"); + vararg!(buf, u32, instance, varargs); + debug!("buf: {}", buf); + 0 +} diff --git a/src/apis/host/posix/env.rs b/src/apis/host/posix/env.rs index faaf8e4f4..ea6142f26 100644 --- a/src/apis/host/posix/env.rs +++ b/src/apis/host/posix/env.rs @@ -17,6 +17,6 @@ use crate::webassembly::{Instance}; use std::env; pub extern "C" fn get_env(name: &str, instance: &mut Instance) -> Result { - debug!("host::get_env({})", name); + debug!("host::get_env({:?})", name); env::var(name) } diff --git a/src/webassembly/instance.rs b/src/webassembly/instance.rs index aa48cf6d4..01d229eed 100644 --- a/src/webassembly/instance.rs +++ b/src/webassembly/instance.rs @@ -415,7 +415,6 @@ impl Instance { // let func_index = *elem_index - module.info.imported_funcs.len() as u32; // let func_addr = functions[func_index.index()].as_ptr(); - println!("TABLE LENGTH: {}", table.len()); let func_addr = get_function_addr(&func_index, &import_functions, &functions); table[base + table_element.offset + i] = func_addr as _; }