wasmtime_jit_debug/
gdb_jit_int.rs1use std::pin::Pin;
6use std::ptr;
7use std::sync::Mutex;
8use wasmtime_versioned_export_macros::versioned_link;
9
10#[repr(C)]
11struct JITCodeEntry {
12 next_entry: *mut JITCodeEntry,
13 prev_entry: *mut JITCodeEntry,
14 symfile_addr: *const u8,
15 symfile_size: u64,
16}
17
18const JIT_NOACTION: u32 = 0;
19const JIT_REGISTER_FN: u32 = 1;
20const JIT_UNREGISTER_FN: u32 = 2;
21
22#[repr(C)]
23struct JITDescriptor {
24 version: u32,
25 action_flag: u32,
26 relevant_entry: *mut JITCodeEntry,
27 first_entry: *mut JITCodeEntry,
28}
29
30unsafe extern "C" {
31 #[versioned_link]
32 fn wasmtime_jit_debug_descriptor() -> *mut JITDescriptor;
33 fn __jit_debug_register_code();
34}
35
36static GDB_REGISTRATION: Mutex<()> = Mutex::new(());
43
44pub struct GdbJitImageRegistration {
46 entry: Pin<Box<JITCodeEntry>>,
47 file: Pin<Box<[u8]>>,
48}
49
50impl GdbJitImageRegistration {
51 pub fn register(file: Vec<u8>) -> Self {
53 let file = Pin::new(file.into_boxed_slice());
54
55 let mut entry = Pin::new(Box::new(JITCodeEntry {
58 next_entry: ptr::null_mut(),
59 prev_entry: ptr::null_mut(),
60 symfile_addr: file.as_ptr(),
61 symfile_size: file.len() as u64,
62 }));
63
64 unsafe {
65 register_gdb_jit_image(&mut *entry);
66 }
67
68 Self { entry, file }
69 }
70
71 pub fn file(&self) -> &[u8] {
73 &self.file
74 }
75}
76
77impl Drop for GdbJitImageRegistration {
78 fn drop(&mut self) {
79 unsafe {
80 unregister_gdb_jit_image(&mut *self.entry);
81 }
82 }
83}
84
85unsafe impl Send for GdbJitImageRegistration {}
86unsafe impl Sync for GdbJitImageRegistration {}
87
88unsafe fn register_gdb_jit_image(entry: *mut JITCodeEntry) {
89 let _lock = GDB_REGISTRATION.lock().unwrap();
90 let desc = &mut *wasmtime_jit_debug_descriptor();
91
92 (*entry).next_entry = desc.first_entry;
94 if !desc.first_entry.is_null() {
95 (*desc.first_entry).prev_entry = entry;
96 }
97 desc.first_entry = entry;
98 desc.relevant_entry = entry;
100 desc.action_flag = JIT_REGISTER_FN;
102 __jit_debug_register_code();
103
104 desc.action_flag = JIT_NOACTION;
105 desc.relevant_entry = ptr::null_mut();
106}
107
108unsafe fn unregister_gdb_jit_image(entry: *mut JITCodeEntry) {
109 let _lock = GDB_REGISTRATION.lock().unwrap();
110 let desc = &mut *wasmtime_jit_debug_descriptor();
111
112 if !(*entry).prev_entry.is_null() {
114 (*(*entry).prev_entry).next_entry = (*entry).next_entry;
115 } else {
116 desc.first_entry = (*entry).next_entry;
117 }
118 if !(*entry).next_entry.is_null() {
119 (*(*entry).next_entry).prev_entry = (*entry).prev_entry;
120 }
121 desc.relevant_entry = entry;
123 desc.action_flag = JIT_UNREGISTER_FN;
125 __jit_debug_register_code();
126
127 desc.action_flag = JIT_NOACTION;
128 desc.relevant_entry = ptr::null_mut();
129}