wasmer_wasix/syscalls/wasix/
dlopen.rs1use super::*;
2use crate::{state::DlModuleSpec, syscalls::*};
3
4#[instrument(level = "trace", skip_all, fields(path = field::Empty, ld_library_path = field::Empty, flags), ret)]
6pub fn dlopen<M: MemorySize>(
7 mut ctx: FunctionEnvMut<'_, WasiEnv>,
8 path: WasmPtr<u8, M>,
9 path_len: M::Offset,
10 flags: DlFlags,
11 err_buf: WasmPtr<u8, M>,
12 err_buf_len: M::Offset,
13 ld_library_path: WasmPtr<u8, M>,
14 ld_library_path_len: M::Offset,
15 out_handle: WasmPtr<DlHandle, M>,
16) -> Result<Errno, WasiError> {
17 WasiEnv::do_pending_operations(&mut ctx)?;
18
19 let (env, mut store) = ctx.data_and_store_mut();
20 let memory = unsafe { env.memory_view(&store) };
21
22 let env_inner = unsafe { env.inner() };
23 let Some(linker) = env_inner.linker() else {
24 wasi_dl_err!(
25 "The current instance is not a dynamically-linked instance",
26 memory,
27 err_buf,
28 err_buf_len
29 );
30 };
31
32 if path.is_null() {
33 wasi_try_mem_ok!(out_handle.write(&memory, crate::state::MAIN_MODULE_HANDLE.into()));
35 return Ok(Errno::Success);
36 }
37
38 let path = unsafe { get_input_str_ok!(&memory, path, path_len) };
39 Span::current().record("path", path.as_str());
40
41 let ld_library_path =
42 unsafe { get_input_str_ok!(&memory, ld_library_path, ld_library_path_len) };
43 Span::current().record("ld_library_path", ld_library_path.as_str());
44 let ld_library_path = ld_library_path
45 .split(':')
46 .map(Path::new)
47 .collect::<Vec<_>>();
48
49 let linker = linker.clone();
50
51 let location = DlModuleSpec::FileSystem {
52 module_spec: Path::new(&path),
53 ld_library_path: ld_library_path.as_slice(),
54 };
55 let module_handle = linker.load_module(location, &mut ctx);
56
57 let (env, mut store) = ctx.data_and_store_mut();
59 let memory = unsafe { env.memory_view(&store) };
60
61 let module_handle = wasi_try_dl!(
62 module_handle,
63 "failed to load module: {}",
64 memory,
65 err_buf,
66 err_buf_len
67 );
68
69 wasi_try_mem_ok!(out_handle.write(&memory, module_handle.into()));
70
71 Ok(Errno::Success)
72}
73
74pub(crate) fn write_dl_error<M: MemorySize>(
75 mut err: &str,
76 memory: &MemoryView,
77 err_buf: WasmPtr<u8, M>,
78 err_buf_len: u64,
79) -> Result<(), MemoryAccessError> {
80 let mut err_len = err.len();
81
82 if err_len > err_buf_len as usize {
83 err_len = err_buf_len as usize - 1;
84 err = &err[..err_len];
85 }
86
87 let mut buf = vec![0; err_len + 1];
88 buf[0..err_len].copy_from_slice(err.as_bytes());
89
90 let Ok(err_len_offset) = M::Offset::try_from(err_len + 1) else {
91 panic!("Failed to convert size to offset")
92 };
93 let mut err_buf = err_buf.slice(memory, err_len_offset)?.access()?;
94 err_buf.copy_from_slice(&buf[..]);
95
96 Ok(())
97}