1pub mod abi;
4mod error;
5mod runtime;
6mod slot;
7
8pub use abi::{PatchEntryV1, PatchFn, PatchModuleV1, ABI_MAGIC_V1, ABI_VERSION_V1, MODULE_EXPORT_SYMBOL_V1};
9pub use error::{HotpatchError, Result};
10pub use runtime::{HotpatchRuntime, ModuleLoadReport};
11
12#[macro_export]
28macro_rules! hotpatch_module {
29 ($module_name:literal, $module_version:expr, [$(($symbol:literal, $func:path)),+ $(,)?]) => {
30 #[doc(hidden)]
31 #[used]
32 static HOTPATCH_ENTRIES: [$crate::PatchEntryV1; hotpatch_module!(@count $(($symbol, $func)),+)] = [
33 $(
34 $crate::PatchEntryV1 {
35 name: concat!($symbol, "\0").as_ptr() as *const core::ffi::c_char,
36 func: $func,
37 flags: 0,
38 reserved: 0,
39 }
40 ),+
41 ];
42
43 #[no_mangle]
44 pub static HOTPATCH_MODULE_V1: $crate::PatchModuleV1 = $crate::PatchModuleV1 {
45 abi_magic: $crate::ABI_MAGIC_V1,
46 abi_version: $crate::ABI_VERSION_V1,
47 struct_size: core::mem::size_of::<$crate::PatchModuleV1>() as u16,
48 module_version: $module_version,
49 name: concat!($module_name, "\0").as_ptr() as *const core::ffi::c_char,
50 entry_count: HOTPATCH_ENTRIES.len() as u32,
51 reserved: 0,
52 entries: HOTPATCH_ENTRIES.as_ptr(),
53 on_load: None,
54 on_unload: None,
55 };
56 };
57 (@count $(($symbol:literal, $func:path)),+) => {
58 <[()]>::len(&[$(hotpatch_module!(@replace $symbol $func)),+])
59 };
60 (@replace $symbol:literal $func:path) => { () };
61}