wasmtime/runtime/vm/
debug_builtins.rs

1#![doc(hidden)]
2
3use crate::runtime::vm::instance::Instance;
4use crate::runtime::vm::vmcontext::VMContext;
5use core::ptr::NonNull;
6use wasmtime_environ::{EntityRef, MemoryIndex};
7use wasmtime_versioned_export_macros::versioned_export;
8
9static mut VMCTX_AND_MEMORY: (NonNull<VMContext>, usize) = (NonNull::dangling(), 0);
10
11// These implementatations are referenced from C code in "helpers.c". The symbols defined
12// there (prefixed by "wasmtime_") are the real 'public' interface used in the debug info.
13
14#[versioned_export]
15pub unsafe extern "C" fn resolve_vmctx_memory_ptr(p: *const u32) -> *const u8 {
16    let ptr = std::ptr::read(p);
17    assert!(
18        VMCTX_AND_MEMORY.0 != NonNull::dangling(),
19        "must call `__vmctx->set()` before resolving Wasm pointers"
20    );
21    Instance::from_vmctx(VMCTX_AND_MEMORY.0, |handle| {
22        assert!(
23            VMCTX_AND_MEMORY.1 < handle.env_module().memories.len(),
24            "memory index for debugger is out of bounds"
25        );
26        let index = MemoryIndex::new(VMCTX_AND_MEMORY.1);
27        let mem = handle.get_memory(index);
28        mem.base.as_ptr().add(ptr as usize)
29    })
30}
31
32#[versioned_export]
33pub unsafe extern "C" fn set_vmctx_memory(vmctx_ptr: *mut VMContext) {
34    // TODO multi-memory
35    VMCTX_AND_MEMORY = (NonNull::new(vmctx_ptr).unwrap(), 0);
36}
37
38/// A bit of a hack around various linkage things. The goal here is to force the
39/// `wasmtime_*` symbols defined in `helpers.c` to actually get exported. That
40/// means they need to be referenced for the linker to include them which is
41/// what this function does with trickery in C.
42pub fn init() {
43    unsafe extern "C" {
44        #[wasmtime_versioned_export_macros::versioned_link]
45        fn wasmtime_debug_builtins_init();
46    }
47
48    unsafe {
49        wasmtime_debug_builtins_init();
50    }
51}