wasmtime_jit_debug/
gdb_jit_int.rs1use once_cell::sync::Lazy;
6use std::pin::Pin;
7use std::ptr;
8use std::sync::Mutex;
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
30extern "C" {
31 fn wasmtime_jit_debug_descriptor() -> *mut JITDescriptor;
32 fn __jit_debug_register_code();
33}
34
35static GDB_REGISTRATION: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(Default::default()));
42
43pub struct GdbJitImageRegistration {
45 entry: Pin<Box<JITCodeEntry>>,
46 file: Pin<Box<[u8]>>,
47}
48
49impl GdbJitImageRegistration {
50 pub fn register(file: Vec<u8>) -> Self {
52 let file = Pin::new(file.into_boxed_slice());
53
54 let mut entry = Pin::new(Box::new(JITCodeEntry {
57 next_entry: ptr::null_mut(),
58 prev_entry: ptr::null_mut(),
59 symfile_addr: file.as_ptr(),
60 symfile_size: file.len() as u64,
61 }));
62
63 unsafe {
64 register_gdb_jit_image(&mut *entry);
65 }
66
67 Self { entry, file }
68 }
69
70 pub fn file(&self) -> &[u8] {
72 &self.file
73 }
74}
75
76impl Drop for GdbJitImageRegistration {
77 fn drop(&mut self) {
78 unsafe {
79 unregister_gdb_jit_image(&mut *self.entry);
80 }
81 }
82}
83
84unsafe impl Send for GdbJitImageRegistration {}
85unsafe impl Sync for GdbJitImageRegistration {}
86
87unsafe fn register_gdb_jit_image(entry: *mut JITCodeEntry) {
88 let _lock = GDB_REGISTRATION.lock().unwrap();
89 let desc = &mut *wasmtime_jit_debug_descriptor();
90
91 (*entry).next_entry = desc.first_entry;
93 if !desc.first_entry.is_null() {
94 (*desc.first_entry).prev_entry = entry;
95 }
96 desc.first_entry = entry;
97 desc.relevant_entry = entry;
99 desc.action_flag = JIT_REGISTER_FN;
101 __jit_debug_register_code();
102
103 desc.action_flag = JIT_NOACTION;
104 desc.relevant_entry = ptr::null_mut();
105}
106
107unsafe fn unregister_gdb_jit_image(entry: *mut JITCodeEntry) {
108 let _lock = GDB_REGISTRATION.lock().unwrap();
109 let desc = &mut *wasmtime_jit_debug_descriptor();
110
111 if !(*entry).prev_entry.is_null() {
113 (*(*entry).prev_entry).next_entry = (*entry).next_entry;
114 } else {
115 desc.first_entry = (*entry).next_entry;
116 }
117 if !(*entry).next_entry.is_null() {
118 (*(*entry).next_entry).prev_entry = (*entry).prev_entry;
119 }
120 desc.relevant_entry = entry;
122 desc.action_flag = JIT_UNREGISTER_FN;
124 __jit_debug_register_code();
125
126 desc.action_flag = JIT_NOACTION;
127 desc.relevant_entry = ptr::null_mut();
128}