pub struct Patcher { /* private fields */ }Implementations§
Source§impl Patcher
impl Patcher
Sourcepub fn new(
package: String,
rustc_path: PathBuf,
linker_path: PathBuf,
cwd: PathBuf,
patch_out_dir: PathBuf,
target_os: LinkerOs,
original_cache: HotpatchModuleCache,
captured_rustc_args: HashMap<String, CapturedRustcInvocation>,
captured_linker_args: HashMap<String, CapturedLinkerInvocation>,
) -> Self
pub fn new( package: String, rustc_path: PathBuf, linker_path: PathBuf, cwd: PathBuf, patch_out_dir: PathBuf, target_os: LinkerOs, original_cache: HotpatchModuleCache, captured_rustc_args: HashMap<String, CapturedRustcInvocation>, captured_linker_args: HashMap<String, CapturedLinkerInvocation>, ) -> Self
Direct constructor. Tests use this to inject hand-built
state (so they don’t have to run a real cargo build or
touch the workspace).
Sourcepub fn initialize(
workspace_root: &Path,
package: String,
rustc_cache_dir: &Path,
linker_cache_dir: &Path,
real_linker: &Path,
original_binary: &Path,
target_os: LinkerOs,
target_triple: Option<&str>,
) -> Result<Self>
pub fn initialize( workspace_root: &Path, package: String, rustc_cache_dir: &Path, linker_cache_dir: &Path, real_linker: &Path, original_binary: &Path, target_os: LinkerOs, target_triple: Option<&str>, ) -> Result<Self>
Production setup. Fat build already done — the dev loop runs it through Builder::with_capture, so this constructor only needs to read the resulting caches and parse the original binary. Splitting the build out lets the dev loop reuse its existing initial-build phase rather than spawning cargo a second time.
original_binary is the file the device actually loaded —
for Android that’s lib<crate>.so extracted from the APK or
found under the Gradle-built jniLibs tree.
Sourcepub async fn build_patch(
&self,
aslr_reference: u64,
crate_key: Option<&str>,
) -> Result<PatchPlan>
pub async fn build_patch( &self, aslr_reference: u64, crate_key: Option<&str>, ) -> Result<PatchPlan>
Build a single hot-patch from a change. Returns the diff alongside the JumpTable so the dev loop can log warnings (added / removed / weak symbols).
aslr_reference is the runtime address of main reported by
the connected device through the hello WebSocket handshake.
We compute the ASLR slide as
aslr_reference - cache.aslr_reference and bake the result
into a small stub object that resolves every host symbol the
patch references — see stub_object for the rationale. Pass
0 for cases where no device has connected yet (the patch
will still build but won’t dispatch correctly at runtime; the
caller should refrain from sending it in that state).
crate_key is the rustc-form name of the crate that owns
the change. None defaults to the user crate. Sub-crate
patches (#103) pass the changed crate’s name so the thin
build picks up that crate’s captured rustc args (a fresh .o
of the changed sub-crate), then links it into a patch dylib
using the user crate’s linker invocation as template. The
original user dylib already exports the sub-crate’s symbols
(rustc linked its rlib in fat-build time); subsecond’s
JumpTable redirects them onto the patch dylib’s new bodies.
Sourcepub fn expected_patch_path(&self) -> PathBuf
pub fn expected_patch_path(&self) -> PathBuf
Where this Patcher would put the next patch dylib —
<patch_out_dir>/lib<crate>.{so,dylib,dll}. The filename is
chosen for the target OS (e.g. Android’s .so even when the
dev session runs on macOS) so the on-device runtime can
recognise it.