wasmtime_runtime/
debug_builtins.rs

1#![doc(hidden)]
2
3use crate::instance::InstanceHandle;
4use crate::vmcontext::VMContext;
5use wasmtime_environ::{EntityRef, MemoryIndex};
6
7static mut VMCTX_AND_MEMORY: (*mut VMContext, usize) = (std::ptr::null_mut(), 0);
8
9#[no_mangle]
10pub unsafe extern "C" fn resolve_vmctx_memory(ptr: usize) -> *const u8 {
11    let handle = InstanceHandle::from_vmctx(VMCTX_AND_MEMORY.0);
12    assert!(
13        VMCTX_AND_MEMORY.1 < handle.module().memory_plans.len(),
14        "memory index for debugger is out of bounds"
15    );
16    let index = MemoryIndex::new(VMCTX_AND_MEMORY.1);
17    let mem = handle.instance().get_memory(index);
18    mem.base.add(ptr)
19}
20
21#[no_mangle]
22pub unsafe extern "C" fn resolve_vmctx_memory_ptr(p: *const u32) -> *const u8 {
23    let ptr = std::ptr::read(p);
24    assert!(
25        !VMCTX_AND_MEMORY.0.is_null(),
26        "must call `__vmctx->set()` before resolving Wasm pointers"
27    );
28    let handle = InstanceHandle::from_vmctx(VMCTX_AND_MEMORY.0);
29    assert!(
30        VMCTX_AND_MEMORY.1 < handle.module().memory_plans.len(),
31        "memory index for debugger is out of bounds"
32    );
33    let index = MemoryIndex::new(VMCTX_AND_MEMORY.1);
34    let mem = handle.instance().get_memory(index);
35    mem.base.add(ptr as usize)
36}
37
38#[no_mangle]
39pub unsafe extern "C" fn set_vmctx_memory(vmctx_ptr: *mut VMContext) {
40    // TODO multi-memory
41    VMCTX_AND_MEMORY = (vmctx_ptr, 0);
42}
43
44// Ensures that set_vmctx_memory and resolve_vmctx_memory_ptr are linked and
45// exported as symbols. It is a workaround: the executable normally ignores
46// `pub extern "C"`, see rust-lang/rust#25057.
47pub fn ensure_exported() {
48    unsafe {
49        std::ptr::read_volatile(resolve_vmctx_memory_ptr as *const u8);
50        std::ptr::read_volatile(set_vmctx_memory as *const u8);
51        std::ptr::read_volatile(resolve_vmctx_memory as *const u8);
52    }
53}