substrate_wasmtime_runtime/
jit_int.rs1use std::ptr;
6use std::sync::{
7 atomic::{AtomicPtr, Ordering},
8 Mutex,
9};
10
11#[repr(C)]
12struct JITCodeEntry {
13 next_entry: *mut JITCodeEntry,
14 prev_entry: *mut JITCodeEntry,
15 symfile_addr: *const u8,
16 symfile_size: u64,
17}
18
19const JIT_NOACTION: u32 = 0;
20const JIT_REGISTER_FN: u32 = 1;
21const JIT_UNREGISTER_FN: u32 = 2;
22
23lazy_static::lazy_static! {
24 pub static ref JIT_DESCRIPTOR_LOCK: Mutex<()> = Mutex::new(());
25}
26
27#[repr(C)]
28struct JITDescriptor {
29 version: u32,
30 action_flag: u32,
31 relevant_entry: *mut JITCodeEntry,
32 first_entry: *mut JITCodeEntry,
33}
34
35#[no_mangle]
36#[used]
37static mut __jit_debug_descriptor: JITDescriptor = JITDescriptor {
38 version: 1,
39 action_flag: JIT_NOACTION,
40 relevant_entry: ptr::null_mut(),
41 first_entry: ptr::null_mut(),
42};
43
44#[no_mangle]
45#[inline(never)]
46extern "C" fn __jit_debug_register_code() {
47 let x = 3;
49 unsafe {
50 std::ptr::read_volatile(&x);
51 }
52}
53
54pub struct GdbJitImageRegistration {
56 entry: AtomicPtr<JITCodeEntry>,
57 file: Vec<u8>,
58}
59
60impl GdbJitImageRegistration {
61 pub fn register(file: Vec<u8>) -> Self {
63 Self {
64 entry: unsafe { register_gdb_jit_image(&file) },
65 file,
66 }
67 }
68
69 pub fn file(&self) -> &[u8] {
71 &self.file
72 }
73}
74
75impl Drop for GdbJitImageRegistration {
76 fn drop(&mut self) {
77 unsafe {
78 unregister_gdb_jit_image(self.entry.load(Ordering::SeqCst));
79 }
80 }
81}
82
83unsafe fn register_gdb_jit_image(file: &[u8]) -> AtomicPtr<JITCodeEntry> {
84 let _lock = JIT_DESCRIPTOR_LOCK.lock();
86 let entry = AtomicPtr::new(Box::into_raw(Box::new(JITCodeEntry {
87 next_entry: __jit_debug_descriptor.first_entry,
88 prev_entry: ptr::null_mut(),
89 symfile_addr: file.as_ptr(),
90 symfile_size: file.len() as u64,
91 })));
92 if !__jit_debug_descriptor.first_entry.is_null() {
94 (*__jit_debug_descriptor.first_entry).prev_entry = entry.load(Ordering::SeqCst);
95 }
96 __jit_debug_descriptor.first_entry = entry.load(Ordering::SeqCst);
97 __jit_debug_descriptor.relevant_entry = entry.load(Ordering::SeqCst);
99 __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
101 __jit_debug_register_code();
102
103 __jit_debug_descriptor.action_flag = JIT_NOACTION;
104 __jit_debug_descriptor.relevant_entry = ptr::null_mut();
105 entry
106}
107
108unsafe fn unregister_gdb_jit_image(entry: *mut JITCodeEntry) {
109 let _lock = JIT_DESCRIPTOR_LOCK.lock();
111 if !(*entry).prev_entry.is_null() {
112 (*(*entry).prev_entry).next_entry = (*entry).next_entry;
113 } else {
114 __jit_debug_descriptor.first_entry = (*entry).next_entry;
115 }
116 if !(*entry).next_entry.is_null() {
117 (*(*entry).next_entry).prev_entry = (*entry).prev_entry;
118 }
119 __jit_debug_descriptor.relevant_entry = entry;
121 __jit_debug_descriptor.action_flag = JIT_UNREGISTER_FN;
123 __jit_debug_register_code();
124
125 __jit_debug_descriptor.action_flag = JIT_NOACTION;
126 __jit_debug_descriptor.relevant_entry = ptr::null_mut();
127 let _box = Box::from_raw(entry);
128}