wasmer_wasix/syscalls/wasix/
dlsym.rs

1use state::MAIN_MODULE_HANDLE;
2
3use super::*;
4use crate::{
5    state::{ModuleHandle, ResolvedExport},
6    syscalls::*,
7};
8
9#[instrument(level = "trace", skip_all, fields(symbol = field::Empty), ret)]
10pub fn dlsym<M: MemorySize>(
11    mut ctx: FunctionEnvMut<'_, WasiEnv>,
12    handle: DlHandle,
13    symbol: WasmPtr<u8, M>,
14    symbol_len: M::Offset,
15    err_buf: WasmPtr<u8, M>,
16    err_buf_len: M::Offset,
17    out_symbol: WasmPtr<M::Offset, M>,
18) -> Result<Errno, WasiError> {
19    WasiEnv::do_pending_operations(&mut ctx)?;
20
21    let (env, mut store) = ctx.data_and_store_mut();
22    let memory = unsafe { env.memory_view(&store) };
23    let symbol = unsafe { get_input_str_ok!(&memory, symbol, symbol_len) };
24    Span::current().record("symbol", symbol.as_str());
25
26    let env_inner = unsafe { env.inner() };
27    let Some(linker) = env_inner.linker() else {
28        wasi_dl_err!(
29            "The current instance is not a dynamically-linked instance",
30            memory,
31            err_buf,
32            err_buf_len
33        );
34    };
35    let linker = linker.clone();
36
37    // handle = 0 is RTLD_DEFAULT, so search everywhere
38    let handle = if handle == 0 {
39        None
40    } else {
41        Some(ModuleHandle::from(handle))
42    };
43    let symbol = linker.resolve_export(&mut ctx, handle, &symbol);
44
45    let (env, mut store) = ctx.data_and_store_mut();
46    let memory = unsafe { env.memory_view(&store) };
47
48    let symbol = wasi_try_dl!(
49        symbol,
50        "failed to resolve symbol: {}",
51        memory,
52        err_buf,
53        err_buf_len
54    );
55
56    match symbol {
57        ResolvedExport::Function { func_ptr: addr } | ResolvedExport::Global { data_ptr: addr } => {
58            let Ok(addr) = addr.try_into() else {
59                panic!("Failed to convert u64 address to M::Offset");
60            };
61            wasi_try_mem_ok!(out_symbol.write(&memory, addr));
62        }
63    }
64
65    Ok(Errno::Success)
66}