Add various small improvements, update attributions file

This commit is contained in:
Mark McCaskey
2020-02-18 17:31:12 -08:00
parent 3653a448f5
commit 1ac59a31f6
3 changed files with 77 additions and 25 deletions

View File

@ -1,40 +1,52 @@
#![allow(missing_docs)]
//! Code for interacting with the
//! [GDB JIT inteface](https://sourceware.org/gdb/current/onlinedocs/gdb.html#JIT-Interface).
use std::ptr;
use std::sync::Arc;
// =============================================================================
// LLDB hook magic:
// see lldb/packages/Python/lldbsuite/test/functionalities/jitloader_gdb in
// llvm repo for example
//
// see also https://sourceware.org/gdb/current/onlinedocs/gdb.html#JIT-Interface
/// Entrypoint that the debugger will use to trigger a read from the
/// [`__jit_debug_descriptor`] global variable.
///
/// The debugger will wait for this function to be called and then take
/// control to read the data we prepared.
// implementation of this function is from wasmtime and is licensed under
// the Apache 2.0 license. See ATTRIBUTIONS.md for full license and more
// information.
#[no_mangle]
#[inline(never)]
extern "C" fn __jit_debug_register_code() {
// implementation of this function copied from wasmtime (TODO: link and attribution)
// prevent optimization of this function
// This code exists to prevent optimization of this function so that the
// GDB JIT interface behaves as expected
let x = 3;
unsafe {
std::ptr::read_volatile(&x);
}
}
/// The operation that the debugger should perform with the entry that we gave it.
#[allow(non_camel_case_types)]
#[derive(Debug)]
#[repr(u32)]
pub(crate) enum JITAction {
/// Do nothing.
JIT_NOACTION = 0,
/// Register the given code.
JIT_REGISTER_FN = 1,
/// Unregister the given code.
JIT_UNREGISTER_FN = 2,
}
/// Node of the doubly linked list that the GDB JIT interface reads from.
#[no_mangle]
#[repr(C)]
pub(crate) struct JITCodeEntry {
/// Next entry in the linked list.
next: *mut JITCodeEntry,
/// Previous entry in the linked list.
prev: *mut JITCodeEntry,
/// Pointer to the data we want the debugger to read.
symfile_addr: *mut u8,
/// The amount of data at the `symfile_addr` pointer.
symfile_size: u64,
}
@ -49,15 +61,24 @@ impl Default for JITCodeEntry {
}
}
/// Head node of the doubly linked list that the GDB JIT interface expects.
#[no_mangle]
#[repr(C)]
pub(crate) struct JitDebugDescriptor {
/// The version of the JIT interface to use (presumably, TODO: double check this)
version: u32,
/// Which action to perform, see [`JITAction`].
action_flag: u32,
/// The entry in the list that the `action_flag` applies to.
relevant_entry: *mut JITCodeEntry,
/// The first entry in the doubly linked list.
first_entry: *mut JITCodeEntry,
}
/// Global variable that the GDB JIT interface will read the data from.
/// The data is in the form of a doubly linked list. This global variable acts
/// as a head node with extra information about the operation that we want the
/// debugger to perform.
#[no_mangle]
#[allow(non_upper_case_globals)]
pub(crate) static mut __jit_debug_descriptor: JitDebugDescriptor = JitDebugDescriptor {
@ -138,6 +159,7 @@ pub struct JITCodeDebugInfoManager {
}
impl JITCodeDebugInfoManager {
/// Register debug info relating to JIT code with the debugger.
pub(crate) fn register_new_jit_code_entry(
&mut self,
bytes: &[u8],