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:
Evan AlmloffandJonathan Kelley authored and GitHub committed 2025-07-23 16:23:33 -07:00
1 parent 86f22983f9
commit 892e154005
2 files changed
+66 -29

No files matched your search

+18 -2
View File
@@ -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);
}