# hotpatch-rs
Live code hot reloading for Rust processes with atomic function pointer swapping and a stable C ABI contract.
## What this crate provides
- Function-level patch points via symbol indirection slots.
- Runtime loading of `.so` / `.dll` patch modules via `libloading`.
- Atomic implementation swaps per symbol (`AtomicUsize` pointer exchange).
- State preservation by keeping application state in host process memory.
- Versioned ABI (`HOTPATCH_MODULE_V1` manifest with magic + version checks).
- Linux-first flow with dynamic `.so` modules.
## Core architecture
- Host process owns state and a `HotpatchRuntime`.
- Runtime keeps symbol slots that call through function pointers.
- Patch modules export `HOTPATCH_MODULE_V1` describing symbol -> function mappings.
- On load, runtime validates ABI, then atomically swaps slots to new implementations.
- Loaded libraries stay resident for process lifetime to avoid stale function-pointer unload hazards.
## ABI surface
`PatchFn` signature:
```rust
unsafe extern "C" fn(
host_state: *mut core::ffi::c_void,
input: *const core::ffi::c_void,
output: *mut core::ffi::c_void,
) -> i32
```
This keeps host/plugin coupling explicit and stable across crate versions.
## Quick usage
```rust
use hotpatch_rs::HotpatchRuntime;
let runtime = HotpatchRuntime::new();
// runtime.register_fallback("counter.add", fallback_fn)?;
// runtime.load_module("./libcounter_patch_v2.so")?;
```
## Demo (Linux)
The `demo/` directory contains:
- `shared-abi`: shared `#[repr(C)]` input/output/state structs.
- `counter-host`: long-running host process.
- `counter-patch-v1`: first patch module.
- `counter-patch-v2`: replacement patch module.
Build demo patches and host:
```bash
cd demo/counter-patch-v1 && cargo build --release
cd ../counter-patch-v2 && cargo build --release
cd ../counter-host && cargo run -- \
../counter-patch-v1/target/release/libcounter_patch_v1.so \
../counter-patch-v2/target/release/libcounter_patch_v2.so
```
The host starts with fallback behavior, loads v1, then hot-swaps to v2 without restart.
## Safety notes
- Plugin function pointers are `unsafe extern "C"`; host must pass valid pointers.
- Struct layouts crossing ABI boundary should be `#[repr(C)]` and versioned.
- This crate does not yet provide quiescent-state synchronization for module unload; modules remain loaded by design.
- Optional `wasm-sandbox` feature is reserved for future pluggable execution backends.