Fix hot patching hook types (#4381)
* fix hot patching hook types * fix clippy * fix doc check * just expose the subsecond jumptable * prefer panicking, forcing more cold branches * make get_jump_table unsafe --------- Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
This commit is contained in:
1 parent
86f22983f9
commit
892e154005
2 files changed
+66
-29
No files matched your search
@@ -278,10 +278,26 @@ pub fn call<O>(mut f: impl FnMut() -> O) -> O {
|
||||
// multithreading, it might become an issue.
|
||||
static APP_JUMP_TABLE: AtomicPtr<JumpTable> = AtomicPtr::new(std::ptr::null_mut());
|
||||
static HOTRELOAD_HANDLERS: Mutex<Vec<Arc<dyn Fn() + Send + Sync>>> = Mutex::new(Vec::new());
|
||||
|
||||
/// Register a function that will be called whenever a patch is applied.
|
||||
///
|
||||
/// This handler will be run immediately after the patch library is loaded into the process and the
|
||||
/// JumpTable has been set.
|
||||
pub fn register_handler(handler: Arc<dyn Fn() + Send + Sync + 'static>) {
|
||||
HOTRELOAD_HANDLERS.lock().unwrap().push(handler);
|
||||
}
|
||||
fn get_jump_table() -> Option<&'static JumpTable> {
|
||||
|
||||
/// Get the current jump table, if it exists.
|
||||
///
|
||||
/// This will return `None` if no jump table has been set yet.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The `JumpTable` returned here is a pointer into a leaked box. While technically this reference is
|
||||
/// valid, we might change the implementation to invalidate the pointer between hotpatches.
|
||||
///
|
||||
/// You should only use this lifetime in temporary contexts - not *across* hotpatches!
|
||||
pub unsafe fn get_jump_table() -> Option<&'static JumpTable> {
|
||||
let ptr = APP_JUMP_TABLE.load(std::sync::atomic::Ordering::Relaxed);
|
||||
if ptr.is_null() {
|
||||
return None;
|
||||
@@ -378,7 +394,7 @@ impl<A, M, F: HotFunction<A, M>> HotFn<A, M, F> {
|
||||
}
|
||||
|
||||
let known_fn_ptr = <F as HotFunction<A, M>>::call_it as *const () as usize;
|
||||
if let Some(jump_table) = get_jump_table() {
|
||||
if let Some(jump_table) = unsafe { get_jump_table() } {
|
||||
if let Some(ptr) = jump_table.map.get(&(known_fn_ptr as u64)).cloned() {
|
||||
return HotFnPtr(ptr);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user