diff --git a/src/apis/emscripten/signal.rs b/src/apis/emscripten/signal.rs index cd387615f..ff7c9c115 100644 --- a/src/apis/emscripten/signal.rs +++ b/src/apis/emscripten/signal.rs @@ -1,16 +1,16 @@ // use super::varargs::VarArgs; use crate::webassembly::Instance; -pub extern "C" fn _sigemptyset(_set: u32, _instance: &mut Instance) -> i32 { +pub extern "C" fn _sigemptyset(set: u32, instance: &mut Instance) -> i32 { debug!("emscripten::_sigemptyset"); - // let set_addr = instance.memory_offset_addr(0, set as _) as *mut u32; - // unsafe { - // *set_addr = 0; - // } + let set_addr = instance.memory_offset_addr(0, set as _) as *mut u32; + unsafe { + *set_addr = 0; + } 0 } -pub extern "C" fn _sigaction(_signum: u32, _act: u32, _oldact: u32) -> i32 { +pub extern "C" fn _sigaction(_signum: u32, _act: u32, _oldact: u32, _instance: &mut Instance) -> i32 { debug!("emscripten::_sigaction"); 0 } diff --git a/src/apis/emscripten/syscalls.rs b/src/apis/emscripten/syscalls.rs index 86b0e19ff..7be897c6a 100644 --- a/src/apis/emscripten/syscalls.rs +++ b/src/apis/emscripten/syscalls.rs @@ -1,6 +1,8 @@ use super::utils::copy_stat_into_wasm; use super::varargs::VarArgs; use crate::webassembly::Instance; +use byteorder::{ByteOrder, LittleEndian}; +use std::slice; /// NOTE: TODO: These syscalls only support wasm_32 for now because they assume offsets are u32 /// Syscall list: https://www.cs.utexas.edu/~bismith/test/syscalls/syscalls32.html use libc::{ @@ -9,7 +11,8 @@ use libc::{ c_int, c_void, chown, - // fcntl, ioctl, setsockopt, getppid + ioctl, + // fcntl, setsockopt, getppid close, connect, dup2, @@ -47,6 +50,7 @@ use libc::{ utsname, write, writev, + FIONBIO, }; /// exit @@ -171,11 +175,18 @@ pub extern "C" fn ___syscall54( instance: &mut Instance, ) -> c_int { debug!("emscripten::___syscall54 (ioctl)"); - let _fd: i32 = varargs.get(instance); - let _request: u32 = varargs.get(instance); - // debug!("fd: {}, op: {}", fd, request); - // unsafe { ioctl(fd, request as _) } - 0 + let fd: i32 = varargs.get(instance); + let request: u32 = varargs.get(instance); + debug!("fd: {}, op: {}", fd, request); + + match request as _ { + 21537 => { // FIONBIO + let argp: u32 = varargs.get(instance); + let argp_ptr = instance.memory_offset_addr(0, argp as _); + unsafe { ioctl(fd, FIONBIO, argp_ptr) } + }, + _ => unimplemented!(), + } } // socketcall @@ -401,7 +412,7 @@ pub extern "C" fn ___syscall192( ) -> c_int { debug!("emscripten::___syscall192 (mmap2)"); let addr: i32 = varargs.get(instance); - let len: i32 = varargs.get(instance); + let len: u32 = varargs.get(instance); let prot: i32 = varargs.get(instance); let flags: i32 = varargs.get(instance); let fd: i32 = varargs.get(instance); @@ -410,7 +421,22 @@ pub extern "C" fn ___syscall192( "=> addr: {}, len: {}, prot: {}, flags: {}, fd: {}, off: {}", addr, len, prot, flags, fd, off ); - 0 + + let (memalign, memset) = { + let emscripten_data = &instance.emscripten_data.as_ref().unwrap(); + (emscripten_data.memalign, emscripten_data.memset) + }; + + if fd == -1 { + let ptr = memalign(16384, len, instance); + if ptr == 0 { + return -1; + } + memset(ptr, 0, len, instance); + ptr as _ + } else { + -1 + } } /// lseek @@ -612,11 +638,27 @@ pub extern "C" fn ___syscall221( // prlimit64 pub extern "C" fn ___syscall340( _which: c_int, - mut _varargs: VarArgs, - _instance: &mut Instance, + mut varargs: VarArgs, + instance: &mut Instance, ) -> c_int { debug!("emscripten::___syscall340 (prlimit64)"); // NOTE: Doesn't really matter. Wasm modules cannot exceed WASM_PAGE_SIZE anyway. + let _pid: i32 = varargs.get(instance); + let _resource: i32 = varargs.get(instance); + let _new_limit: u32 = varargs.get(instance); + let old_limit: u32 = varargs.get(instance); + + if old_limit != 0 { + // just report no limits + let buf_ptr = instance.memory_offset_addr(0, old_limit as _) as *mut u8; + let buf = unsafe { slice::from_raw_parts_mut(buf_ptr, 16) }; + + LittleEndian::write_i32(&mut buf[..], -1); // RLIM_INFINITY + LittleEndian::write_i32(&mut buf[4..], -1); // RLIM_INFINITY + LittleEndian::write_i32(&mut buf[8..], -1); // RLIM_INFINITY + LittleEndian::write_i32(&mut buf[12..], -1); // RLIM_INFINITY + } + 0 } diff --git a/src/webassembly/instance.rs b/src/webassembly/instance.rs index de81d00e0..c0bb07ba1 100644 --- a/src/webassembly/instance.rs +++ b/src/webassembly/instance.rs @@ -70,6 +70,8 @@ fn get_function_addr( pub struct EmscriptenData { pub malloc: extern "C" fn(i32, &mut Instance) -> u32, pub free: extern "C" fn(i32, &mut Instance), + pub memalign: extern "C" fn (u32, u32, &mut Instance) -> u32, + pub memset: extern "C" fn(u32, i32, u32, &mut Instance) -> u32, } impl fmt::Debug for EmscriptenData { @@ -514,28 +516,23 @@ impl Instance { debug!("emscripten::initiating data"); let malloc_export = module.info.exports.get("_malloc"); let free_export = module.info.exports.get("_free"); - if malloc_export.is_none() || free_export.is_none() { - None - } else { - let malloc_index = if let Some(Export::Function(malloc_index)) = malloc_export { - malloc_index - } else { - panic!("Expected malloc function") - }; - let malloc_addr = - get_function_addr(&malloc_index, &import_functions, &functions); + let memalign_export = module.info.exports.get("_memalign"); + let memset_export = module.info.exports.get("_memset"); - let free_index = if let Some(Export::Function(free_index)) = free_export { - free_index - } else { - panic!("Expected free export function") - }; + if let (Some(Export::Function(malloc_index)), Some(Export::Function(free_index)), Some(Export::Function(memalign_index)), Some(Export::Function(memset_index))) = (malloc_export, free_export, memalign_export, memset_export) { + let malloc_addr = get_function_addr(&malloc_index, &import_functions, &functions); let free_addr = get_function_addr(&free_index, &import_functions, &functions); - + let memalign_addr = get_function_addr(&memalign_index, &import_functions, &functions); + let memset_addr = get_function_addr(&memset_index, &import_functions, &functions); + Some(EmscriptenData { malloc: mem::transmute(malloc_addr), free: mem::transmute(free_addr), + memalign: mem::transmute(memalign_addr), + memset: mem::transmute(memset_addr), }) + } else { + None } } } else { diff --git a/src/webassembly/memory.rs b/src/webassembly/memory.rs index dd094b92e..c06000819 100644 --- a/src/webassembly/memory.rs +++ b/src/webassembly/memory.rs @@ -49,7 +49,7 @@ impl LinearMemory { 0 as _, LinearMemory::DEFAULT_SIZE, ProtFlags::PROT_NONE, - MapFlags::MAP_ANON | MapFlags::MAP_SHARED, + MapFlags::MAP_ANON | MapFlags::MAP_PRIVATE, -1, 0, ).unwrap()