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 #[versioned_export]
11 pub unsafe extern "C" fn resolve_vmctx_memory(ptr: usize) -> *const u8 {
12     Instance::from_vmctx(VMCTX_AND_MEMORY.0, |handle| {
13         assert!(
14             VMCTX_AND_MEMORY.1 < handle.env_module().memory_plans.len(),
15             "memory index for debugger is out of bounds"
16         );
17         let index = MemoryIndex::new(VMCTX_AND_MEMORY.1);
18         let mem = handle.get_memory(index);
19         mem.base.add(ptr)
20     })
21 }
22 
23 #[versioned_export]
24 pub unsafe extern "C" fn resolve_vmctx_memory_ptr(p: *const u32) -> *const u8 {
25     let ptr = std::ptr::read(p);
26     assert!(
27         !VMCTX_AND_MEMORY.0.is_null(),
28         "must call `__vmctx->set()` before resolving Wasm pointers"
29     );
30     Instance::from_vmctx(VMCTX_AND_MEMORY.0, |handle| {
31         assert!(
32             VMCTX_AND_MEMORY.1 < handle.env_module().memory_plans.len(),
33             "memory index for debugger is out of bounds"
34         );
35         let index = MemoryIndex::new(VMCTX_AND_MEMORY.1);
36         let mem = handle.get_memory(index);
37         mem.base.add(ptr as usize)
38     })
39 }
40 
41 #[versioned_export]
42 pub unsafe extern "C" fn set_vmctx_memory(vmctx_ptr: *mut VMContext) {
43     // TODO multi-memory
44     VMCTX_AND_MEMORY = (vmctx_ptr, 0);
45 }
46 
47 // Ensures that set_vmctx_memory and resolve_vmctx_memory_ptr are linked and
48 // exported as symbols. It is a workaround: the executable normally ignores
49 // `pub extern "C"`, see rust-lang/rust#25057.
50 pub fn ensure_exported() {
51     if cfg!(miri) {
52         return;
53     }
54     unsafe {
55         std::ptr::read_volatile(resolve_vmctx_memory_ptr as *const u8);
56         std::ptr::read_volatile(set_vmctx_memory as *const u8);
57         std::ptr::read_volatile(resolve_vmctx_memory as *const u8);
58     }
59 }
60