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