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