diff --git a/src/apis/emscripten/env.rs b/src/apis/emscripten/env.rs index 02a9a5853..00931b49d 100644 --- a/src/apis/emscripten/env.rs +++ b/src/apis/emscripten/env.rs @@ -8,16 +8,24 @@ use std::os::raw::c_char; use super::utils::{copy_cstr_into_wasm, copy_terminated_array_of_cstrs}; use crate::webassembly::Instance; -/// emscripten: _getenv -pub extern "C" fn _getenv(name_ptr: c_int, instance: &mut Instance) -> c_int { +/// emscripten: _getenv // (name: *const char) -> *const c_char; +pub extern "C" fn _getenv(name_ptr: c_int, instance: &mut Instance) -> u32 { debug!("emscripten::_getenv {}", 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).to_str().unwrap() }; match host::get_env(name, instance) { - Ok(_) => { - unimplemented!(); + Ok(env_value) => { + // Append null byte + let env_value = env_value + "\0"; + let env_value_ptr = env_value.as_ptr() as *mut c_char; + let res = unsafe { copy_cstr_into_wasm(instance, env_value_ptr) }; + // Test + let c_str = instance.memory_offset_addr(0, res as _) as *mut i8; + use std::ffi::CStr; + debug!("#### cstr = {:?}", unsafe { CStr::from_ptr(c_str) }); + res } Err(_) => 0, } diff --git a/src/apis/emscripten/linking.rs b/src/apis/emscripten/linking.rs new file mode 100644 index 000000000..32f85ee7a --- /dev/null +++ b/src/apis/emscripten/linking.rs @@ -0,0 +1,27 @@ +use crate::webassembly::Instance; + +// TODO: Need to implement. + +/// emscripten: dlopen(filename: *const c_char, flag: c_int) -> *mut c_void +pub extern "C" fn _dlopen(filename: u32, flag: c_int) -> u32 { + debug!("emscripten::_dlopen"); + -1 +} + +/// emscripten: dlclose(handle: *mut c_void) -> c_int +pub extern "C" fn _dlclose(filename: u32) -> u32 { + debug!("emscripten::_dlclose"); + -1 +} + +/// emscripten: dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void +pub extern "C" fn _dlsym(filepath: u32, symbol: u32) -> u32 { + debug!("emscripten::_dlerror"); + -1 +} + +/// emscripten: dlerror() -> *mut c_char +pub extern "C" fn _dlerror() -> u32 { + debug!("emscripten::_dlerror"); + -1 +} diff --git a/src/apis/emscripten/mod.rs b/src/apis/emscripten/mod.rs index 0c23ae302..1375438ad 100644 --- a/src/apis/emscripten/mod.rs +++ b/src/apis/emscripten/mod.rs @@ -349,6 +349,11 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> { "___cxa_allocate_exception", ImportValue::Func(exception::___cxa_throw as _), ); + import_object.set( + "env", + "___cxa_throw", + ImportValue::Func(exception::___cxa_throw as _), + ); // NullFuncs import_object.set( "env", @@ -511,7 +516,7 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> { mock_external!(import_object, ___syscall66); // mock_external!(import_object, ___syscall64); // mock_external!(import_object, ___syscall63); - mock_external!(import_object, ___syscall60); + // mock_external!(import_object, ___syscall60); // mock_external!(import_object, ___syscall54); // mock_external!(import_object, ___syscall39); mock_external!(import_object, ___syscall38); @@ -543,6 +548,10 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> { // mock_external!(import_object, ___syscall20); mock_external!(import_object, ___syscall15); mock_external!(import_object, ___syscall10); + mock_external!(import_object, _dlopen); + mock_external!(import_object, _dlclose); + mock_external!(import_object, _dlsym); + mock_external!(import_object, _dlerror); import_object } diff --git a/src/apis/emscripten/syscalls.rs b/src/apis/emscripten/syscalls.rs index 0661a48c8..220815e0d 100644 --- a/src/apis/emscripten/syscalls.rs +++ b/src/apis/emscripten/syscalls.rs @@ -72,7 +72,7 @@ use libc::{ F_GETFD, }; -// Linking to functions that are provided by rust libc +// Linking to functions that are not provided by rust libc #[cfg(target_os = "macos")] #[link(name = "c")] extern { diff --git a/src/apis/emscripten/time.rs b/src/apis/emscripten/time.rs index 2b4ca5a46..7a51a923d 100644 --- a/src/apis/emscripten/time.rs +++ b/src/apis/emscripten/time.rs @@ -135,7 +135,7 @@ pub extern "C" fn _asctime(time: u32, instance: &mut Instance) -> u32 { let time_str_ptr = fmt_time(time, instance); copy_cstr_into_wasm(instance, time_str_ptr) - // let c_str = instance.memory_offset_addr(0, time_str_offset as _) as *mut i8; + // let c_str = instance.memory_offset_addr(0, res as _) as *mut i8; // use std::ffi::CStr; // debug!("#### cstr = {:?}", CStr::from_ptr(c_str)); } @@ -153,7 +153,7 @@ pub extern "C" fn _asctime_r(time: u32, buf: u32, instance: &mut Instance) -> u3 let time_str_ptr = fmt_time(time, instance); write_to_buf(time_str_ptr, buf, 26, instance) - // let c_str = instance.memory_offset_addr(0, time_str_offset as _) as *mut i8; + // let c_str = instance.memory_offset_addr(0, res as _) as *mut i8; // use std::ffi::CStr; // debug!("#### cstr = {:?}", CStr::from_ptr(c_str)); } diff --git a/src/apis/emscripten/utils.rs b/src/apis/emscripten/utils.rs index fd03b05f2..93e1a717e 100644 --- a/src/apis/emscripten/utils.rs +++ b/src/apis/emscripten/utils.rs @@ -29,20 +29,25 @@ pub fn write_to_buf(string: *const c_char, buf: u32, max: u32, instance: &Instan buf } +/// This function expects nullbyte to be appended. pub unsafe fn copy_cstr_into_wasm(instance: &mut Instance, cstr: *const c_char) -> u32 { let s = CStr::from_ptr(cstr).to_str().unwrap(); let cstr_len = s.len(); + debug!("### 1!"); let space_offset = (instance.emscripten_data.as_ref().unwrap().malloc)((cstr_len as i32) + 1, instance); + debug!("### 2!"); let raw_memory = instance.memory_offset_addr(0, space_offset as _) as *mut u8; let slice = slice::from_raw_parts_mut(raw_memory, cstr_len); for (byte, loc) in s.bytes().zip(slice.iter_mut()) { *loc = byte; } + debug!("### KABOOM 10!"); // TODO: Appending null byte won't work, because there is CStr::from_ptr(cstr) // at the top that crashes when there is no null byte *raw_memory.add(cstr_len) = 0; + debug!("### KABOOM 15!"); space_offset }