mirror of
https://github.com/fluencelabs/wasmer
synced 2024-12-13 06:15:33 +00:00
Added a few more syscalls
This commit is contained in:
parent
5a81c501be
commit
76c9107e48
@ -1,8 +1,9 @@
|
||||
use super::super::host;
|
||||
/// NOTE: These syscalls only support wasm_32 for now because they take u32 offset
|
||||
use libc::{c_int};
|
||||
use libc::{c_int, getpwnam as libc_getpwnam, passwd, getgrnam as libc_getgrnam, group};
|
||||
use std::ffi::CStr;
|
||||
use std::os::raw::c_char;
|
||||
use std::{slice, mem};
|
||||
|
||||
use crate::webassembly::Instance;
|
||||
|
||||
@ -20,3 +21,94 @@ pub extern "C" fn _getenv(name_ptr: c_int, instance: &mut Instance) -> c_int {
|
||||
Err(_) => 0,
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn copy_cstr_into_wasm(instance: &mut Instance, cstr: *const c_char) -> u32 {
|
||||
let s = CStr::from_ptr(cstr).to_str().unwrap();
|
||||
let space_offset = (instance.emscripten_data.malloc)(s.len() as _, instance);
|
||||
let raw_memory = instance.memory_offset_addr(0, space_offset as _) as *mut u8;
|
||||
let mut slice = slice::from_raw_parts_mut(raw_memory, s.len());
|
||||
|
||||
for (byte, loc) in s.bytes().zip(slice.iter_mut()) {
|
||||
*loc = byte;
|
||||
}
|
||||
|
||||
space_offset
|
||||
}
|
||||
|
||||
unsafe fn copy_terminated_array_of_cstrs(instance: &mut Instance, cstrs: *mut *mut c_char) -> u32 {
|
||||
let total_num = {
|
||||
let mut ptr = cstrs;
|
||||
let mut counter = 0;
|
||||
while !(*ptr).is_null() {
|
||||
counter += 1;
|
||||
ptr = ptr.add(1);
|
||||
}
|
||||
counter
|
||||
};
|
||||
println!("total_num: {}", total_num);
|
||||
0
|
||||
}
|
||||
|
||||
pub extern "C" fn _getpwnam(name_ptr: c_int, instance: &mut Instance) -> c_int {
|
||||
#[repr(C)]
|
||||
struct GuestPasswd {
|
||||
pw_name: u32,
|
||||
pw_passwd: u32,
|
||||
pw_uid: u32,
|
||||
pw_gid: u32,
|
||||
pw_gecos: u32,
|
||||
pw_dir: u32,
|
||||
pw_shell: u32,
|
||||
}
|
||||
|
||||
debug!("emscripten::_getpwnam {}", name_ptr);
|
||||
let name = unsafe {
|
||||
let memory_name_ptr = instance.memory_offset_addr(0, name_ptr as usize) as *const c_char;
|
||||
CStr::from_ptr(memory_name_ptr)
|
||||
};
|
||||
|
||||
unsafe {
|
||||
let passwd = &*libc_getpwnam(name.as_ptr());
|
||||
let passwd_struct_offset = (instance.emscripten_data.malloc)(mem::size_of::<GuestPasswd>() as _, instance);
|
||||
|
||||
let passwd_struct_ptr = instance.memory_offset_addr(0, passwd_struct_offset as _) as *mut GuestPasswd;
|
||||
(*passwd_struct_ptr).pw_name = copy_cstr_into_wasm(instance, passwd.pw_name);
|
||||
(*passwd_struct_ptr).pw_passwd = copy_cstr_into_wasm(instance, passwd.pw_passwd);
|
||||
(*passwd_struct_ptr).pw_gecos = copy_cstr_into_wasm(instance, passwd.pw_gecos);
|
||||
(*passwd_struct_ptr).pw_dir = copy_cstr_into_wasm(instance, passwd.pw_dir);
|
||||
(*passwd_struct_ptr).pw_shell = copy_cstr_into_wasm(instance, passwd.pw_shell);
|
||||
(*passwd_struct_ptr).pw_uid = passwd.pw_uid;
|
||||
(*passwd_struct_ptr).pw_gid = passwd.pw_gid;
|
||||
|
||||
passwd_struct_offset as c_int
|
||||
}
|
||||
}
|
||||
|
||||
pub extern "C" fn _getgrnam(name_ptr: c_int, instance: &mut Instance) -> c_int {
|
||||
#[repr(C)]
|
||||
struct GuestGroup {
|
||||
gr_name: u32,
|
||||
gr_passwd: u32,
|
||||
gr_gid: u32,
|
||||
gr_mem: u32,
|
||||
}
|
||||
|
||||
debug!("emscripten::_getgrnam {}", name_ptr);
|
||||
let name = unsafe {
|
||||
let memory_name_ptr = instance.memory_offset_addr(0, name_ptr as usize) as *const c_char;
|
||||
CStr::from_ptr(memory_name_ptr)
|
||||
};
|
||||
|
||||
unsafe {
|
||||
let group = &*libc_getgrnam(name.as_ptr());
|
||||
let group_struct_offset = (instance.emscripten_data.malloc)(mem::size_of::<GuestGroup>() as _, instance);
|
||||
|
||||
let group_struct_ptr = instance.memory_offset_addr(0, group_struct_offset as _) as *mut GuestGroup;
|
||||
(*group_struct_ptr).gr_name = copy_cstr_into_wasm(instance, group.gr_name);
|
||||
(*group_struct_ptr).gr_passwd = copy_cstr_into_wasm(instance, group.gr_passwd);
|
||||
(*group_struct_ptr).gr_gid = group.gr_gid;
|
||||
(*group_struct_ptr).gr_mem = copy_terminated_array_of_cstrs(instance, group.gr_mem);
|
||||
|
||||
group_struct_offset as c_int
|
||||
}
|
||||
}
|
@ -258,6 +258,19 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
||||
"nullFunc_viiii",
|
||||
ImportValue::Func(nullfunc::nullfunc_viiii as *const u8),
|
||||
);
|
||||
|
||||
// named syscalls
|
||||
import_object.set(
|
||||
"env",
|
||||
"_getpwnam",
|
||||
ImportValue::Func(env::_getpwnam as _),
|
||||
);
|
||||
// import_object.set(
|
||||
// "env",
|
||||
// "_getgrnam",
|
||||
// ImportValue::Func(env::_getgrnam as _),
|
||||
// );
|
||||
|
||||
import_object
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ use std::iter::FromIterator;
|
||||
use std::iter::Iterator;
|
||||
use std::mem::size_of;
|
||||
use std::ptr::write_unaligned;
|
||||
use std::slice;
|
||||
use std::{fmt, slice, mem};
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::super::common::slice::{BoundedSlice, UncheckedSlice};
|
||||
@ -68,6 +68,20 @@ fn get_function_addr(
|
||||
func_pointer
|
||||
}
|
||||
|
||||
pub struct EmscriptenData {
|
||||
pub malloc: extern fn(i32, &mut Instance) -> u32,
|
||||
pub free: extern fn(i32, &mut Instance),
|
||||
}
|
||||
|
||||
impl fmt::Debug for EmscriptenData {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("EmscriptenData")
|
||||
.field("malloc", &(self.malloc as usize))
|
||||
.field("free", &(self.free as usize))
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// An Instance of a WebAssembly module
|
||||
/// NOTE: There is an assumption that data_pointers is always the
|
||||
/// first field
|
||||
@ -98,6 +112,7 @@ pub struct Instance {
|
||||
pub start_func: Option<FuncIndex>,
|
||||
// Region start memory location
|
||||
// code_base: *const (),
|
||||
pub emscripten_data: EmscriptenData,
|
||||
}
|
||||
|
||||
/// Contains pointers to data (heaps, globals, tables) needed
|
||||
@ -494,6 +509,27 @@ impl Instance {
|
||||
tables: tables_pointer[..].into(),
|
||||
};
|
||||
|
||||
let emscripten_data = unsafe {
|
||||
let malloc_index = if let Some(Export::Function(index)) = module.info.exports.get("_malloc") {
|
||||
index
|
||||
} else {
|
||||
panic!("Unable to find _malloc export")
|
||||
};
|
||||
let malloc_addr = get_function_addr(&malloc_index, &import_functions, &functions);
|
||||
|
||||
let free_index = if let Some(Export::Function(index)) = module.info.exports.get("_free") {
|
||||
index
|
||||
} else {
|
||||
panic!("Unable to find _free export")
|
||||
};
|
||||
let free_addr = get_function_addr(&free_index, &import_functions, &functions);
|
||||
|
||||
EmscriptenData {
|
||||
malloc: mem::transmute(malloc_addr),
|
||||
free: mem::transmute(free_addr),
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Instance {
|
||||
data_pointers,
|
||||
tables: Arc::new(tables.into_iter().collect()), // tables.into_iter().map(|table| RwLock::new(table)).collect()),
|
||||
@ -502,7 +538,7 @@ impl Instance {
|
||||
functions,
|
||||
import_functions,
|
||||
start_func,
|
||||
// emscripten_data,
|
||||
emscripten_data,
|
||||
})
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user