implmented mmap2

This commit is contained in:
Lachlan Sneff 2018-11-29 00:11:36 -05:00
parent 65b36eb6ba
commit 1db0306b8b
4 changed files with 72 additions and 33 deletions

View File

@ -1,16 +1,16 @@
// use super::varargs::VarArgs; // use super::varargs::VarArgs;
use crate::webassembly::Instance; 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"); debug!("emscripten::_sigemptyset");
// let set_addr = instance.memory_offset_addr(0, set as _) as *mut u32; let set_addr = instance.memory_offset_addr(0, set as _) as *mut u32;
// unsafe { unsafe {
// *set_addr = 0; *set_addr = 0;
// } }
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"); debug!("emscripten::_sigaction");
0 0
} }

View File

@ -1,6 +1,8 @@
use super::utils::copy_stat_into_wasm; use super::utils::copy_stat_into_wasm;
use super::varargs::VarArgs; use super::varargs::VarArgs;
use crate::webassembly::Instance; 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 /// 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 /// Syscall list: https://www.cs.utexas.edu/~bismith/test/syscalls/syscalls32.html
use libc::{ use libc::{
@ -9,7 +11,8 @@ use libc::{
c_int, c_int,
c_void, c_void,
chown, chown,
// fcntl, ioctl, setsockopt, getppid ioctl,
// fcntl, setsockopt, getppid
close, close,
connect, connect,
dup2, dup2,
@ -47,6 +50,7 @@ use libc::{
utsname, utsname,
write, write,
writev, writev,
FIONBIO,
}; };
/// exit /// exit
@ -171,11 +175,18 @@ pub extern "C" fn ___syscall54(
instance: &mut Instance, instance: &mut Instance,
) -> c_int { ) -> c_int {
debug!("emscripten::___syscall54 (ioctl)"); debug!("emscripten::___syscall54 (ioctl)");
let _fd: i32 = varargs.get(instance); let fd: i32 = varargs.get(instance);
let _request: u32 = varargs.get(instance); let request: u32 = varargs.get(instance);
// debug!("fd: {}, op: {}", fd, request); debug!("fd: {}, op: {}", fd, request);
// unsafe { ioctl(fd, request as _) }
0 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 // socketcall
@ -401,7 +412,7 @@ pub extern "C" fn ___syscall192(
) -> c_int { ) -> c_int {
debug!("emscripten::___syscall192 (mmap2)"); debug!("emscripten::___syscall192 (mmap2)");
let addr: i32 = varargs.get(instance); 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 prot: i32 = varargs.get(instance);
let flags: i32 = varargs.get(instance); let flags: i32 = varargs.get(instance);
let fd: 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: {}",
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 /// lseek
@ -612,11 +638,27 @@ pub extern "C" fn ___syscall221(
// prlimit64 // prlimit64
pub extern "C" fn ___syscall340( pub extern "C" fn ___syscall340(
_which: c_int, _which: c_int,
mut _varargs: VarArgs, mut varargs: VarArgs,
_instance: &mut Instance, instance: &mut Instance,
) -> c_int { ) -> c_int {
debug!("emscripten::___syscall340 (prlimit64)"); debug!("emscripten::___syscall340 (prlimit64)");
// NOTE: Doesn't really matter. Wasm modules cannot exceed WASM_PAGE_SIZE anyway. // 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 0
} }

View File

@ -70,6 +70,8 @@ fn get_function_addr(
pub struct EmscriptenData { pub struct EmscriptenData {
pub malloc: extern "C" fn(i32, &mut Instance) -> u32, pub malloc: extern "C" fn(i32, &mut Instance) -> u32,
pub free: extern "C" fn(i32, &mut Instance), 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 { impl fmt::Debug for EmscriptenData {
@ -514,28 +516,23 @@ impl Instance {
debug!("emscripten::initiating data"); debug!("emscripten::initiating data");
let malloc_export = module.info.exports.get("_malloc"); let malloc_export = module.info.exports.get("_malloc");
let free_export = module.info.exports.get("_free"); let free_export = module.info.exports.get("_free");
if malloc_export.is_none() || free_export.is_none() { let memalign_export = module.info.exports.get("_memalign");
None let memset_export = module.info.exports.get("_memset");
} 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 free_index = if let Some(Export::Function(free_index)) = free_export { 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) {
free_index let malloc_addr = get_function_addr(&malloc_index, &import_functions, &functions);
} else {
panic!("Expected free export function")
};
let free_addr = get_function_addr(&free_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 { Some(EmscriptenData {
malloc: mem::transmute(malloc_addr), malloc: mem::transmute(malloc_addr),
free: mem::transmute(free_addr), free: mem::transmute(free_addr),
memalign: mem::transmute(memalign_addr),
memset: mem::transmute(memset_addr),
}) })
} else {
None
} }
} }
} else { } else {

View File

@ -49,7 +49,7 @@ impl LinearMemory {
0 as _, 0 as _,
LinearMemory::DEFAULT_SIZE, LinearMemory::DEFAULT_SIZE,
ProtFlags::PROT_NONE, ProtFlags::PROT_NONE,
MapFlags::MAP_ANON | MapFlags::MAP_SHARED, MapFlags::MAP_ANON | MapFlags::MAP_PRIVATE,
-1, -1,
0, 0,
).unwrap() ).unwrap()