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