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 unsafe {
90 let _lock = GDB_REGISTRATION.lock().unwrap();
91 let desc = &mut *wasmtime_jit_debug_descriptor();
92
93 (*entry).next_entry = desc.first_entry;
95 if !desc.first_entry.is_null() {
96 (*desc.first_entry).prev_entry = entry;
97 }
98 desc.first_entry = entry;
99 desc.relevant_entry = entry;
101 desc.action_flag = JIT_REGISTER_FN;
103 __jit_debug_register_code();
104
105 desc.action_flag = JIT_NOACTION;
106 desc.relevant_entry = ptr::null_mut();
107 }
108}
109
110unsafe fn unregister_gdb_jit_image(entry: *mut JITCodeEntry) {
111 unsafe {
112 let _lock = GDB_REGISTRATION.lock().unwrap();
113 let desc = &mut *wasmtime_jit_debug_descriptor();
114
115 if !(*entry).prev_entry.is_null() {
117 (*(*entry).prev_entry).next_entry = (*entry).next_entry;
118 } else {
119 desc.first_entry = (*entry).next_entry;
120 }
121 if !(*entry).next_entry.is_null() {
122 (*(*entry).next_entry).prev_entry = (*entry).prev_entry;
123 }
124 desc.relevant_entry = entry;
126 desc.action_flag = JIT_UNREGISTER_FN;
128 __jit_debug_register_code();
129
130 desc.action_flag = JIT_NOACTION;
131 desc.relevant_entry = ptr::null_mut();
132 }
133}