CLI fixes for hotpatching the playground (#4715)
* add component subcommand * add dx component add, remove and list commands * handle rust dependencies * handle component dependencies * fetch remote registries * sort components before listing them * remove local dependency * move te component manifest into the dioxus workspace * add additional instalation instructions the first time the component module is created * fix mod name * fix clippy * improve docs and move to the main branch of components * fix typos * more typos * undo const-serialize changes * remove a few unwraps * Allow adding multiple components at once and add a `--all` flag * add options to the config for the base path, global asset path and default registry * component_path -> component_dir * component_dir is always relative to the crate root * fix clippy * fix hot patching with a base path * read the hot patch file from stdin instead of a CLI arg to allow for longer inputs * fix request imports * wip: code style changes * rename to "components" instead of "component" * bump lock * move to method on request * read until eof in the case of pretty json * strip is now copy --------- Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
This commit is contained in:
1 parent
79613f9db9
commit
987e41de16
6 files changed
+1715
-1739
No files matched your search
@@ -640,7 +640,6 @@ impl AppBuilder {
|
||||
) -> Result<JumpTable> {
|
||||
let original = self.build.main_exe();
|
||||
let new = self.build.patch_exe(res.time_start);
|
||||
let triple = self.build.triple.clone();
|
||||
let asset_dir = self.build.asset_dir();
|
||||
|
||||
// Hotpatch asset!() calls
|
||||
@@ -688,7 +687,7 @@ impl AppBuilder {
|
||||
|
||||
tracing::debug!("Patching {} -> {}", original.display(), new.display());
|
||||
|
||||
let mut jump_table = crate::build::create_jump_table(&new, &triple, cache)?;
|
||||
let mut jump_table = self.build.create_jump_table(&new, cache)?;
|
||||
|
||||
// If it's android, we need to copy the assets to the device and then change the location of the patch
|
||||
if self.build.bundle == BundleFormat::Android {
|
||||
@@ -697,16 +696,6 @@ impl AppBuilder {
|
||||
.await?;
|
||||
}
|
||||
|
||||
// Rebase the wasm binary to be relocatable once the jump table is generated
|
||||
if triple.architecture == target_lexicon::Architecture::Wasm32 {
|
||||
// Make sure we use the dir relative to the public dir, so the web can load it as a proper URL
|
||||
//
|
||||
// ie we would've shipped `/Users/foo/Projects/dioxus/target/dx/project/debug/web/public/wasm/lib.wasm`
|
||||
// but we want to ship `/wasm/lib.wasm`
|
||||
jump_table.lib =
|
||||
PathBuf::from("/").join(jump_table.lib.strip_prefix(self.build.root_dir()).unwrap())
|
||||
}
|
||||
|
||||
let changed_files = match &res.mode {
|
||||
BuildMode::Thin { changed_files, .. } => changed_files.clone(),
|
||||
_ => vec![],
|
||||
|
||||
@@ -290,24 +290,7 @@ impl HotpatchModuleCache {
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a jump table for the given original and patch files.
|
||||
pub fn create_jump_table(
|
||||
patch: &Path,
|
||||
triple: &Triple,
|
||||
cache: &HotpatchModuleCache,
|
||||
) -> Result<JumpTable> {
|
||||
// Symbols are stored differently based on the platform, so we need to handle them differently.
|
||||
// - Wasm requires the walrus crate and actually modifies the patch file
|
||||
// - windows requires the pdb crate and pdb files
|
||||
// - nix requires the object crate
|
||||
match triple.operating_system {
|
||||
OperatingSystem::Windows => create_windows_jump_table(patch, cache),
|
||||
_ if triple.architecture == Architecture::Wasm32 => create_wasm_jump_table(patch, cache),
|
||||
_ => create_native_jump_table(patch, triple, cache),
|
||||
}
|
||||
}
|
||||
|
||||
fn create_windows_jump_table(patch: &Path, cache: &HotpatchModuleCache) -> Result<JumpTable> {
|
||||
pub fn create_windows_jump_table(patch: &Path, cache: &HotpatchModuleCache) -> Result<JumpTable> {
|
||||
use pdb::FallibleIterator;
|
||||
let old_name_to_addr = &cache.symbol_table;
|
||||
|
||||
@@ -361,7 +344,7 @@ fn create_windows_jump_table(patch: &Path, cache: &HotpatchModuleCache) -> Resul
|
||||
///
|
||||
/// This does not work for WASM since the `object` crate does not support emitting the WASM format,
|
||||
/// and because WASM requires more logic to handle the wasm-bindgen transformations.
|
||||
fn create_native_jump_table(
|
||||
pub fn create_native_jump_table(
|
||||
patch: &Path,
|
||||
triple: &Triple,
|
||||
cache: &HotpatchModuleCache,
|
||||
@@ -416,7 +399,7 @@ fn create_native_jump_table(
|
||||
/// to manually satisfy them here, removing their need to be imported.
|
||||
///
|
||||
/// <https://github.com/WebAssembly/tool-conventions/blob/main/DynamicLinking.md>
|
||||
fn create_wasm_jump_table(patch: &Path, cache: &HotpatchModuleCache) -> Result<JumpTable> {
|
||||
pub fn create_wasm_jump_table(patch: &Path, cache: &HotpatchModuleCache) -> Result<JumpTable> {
|
||||
let name_to_ifunc_old = &cache.symbol_ifunc_map;
|
||||
let old = &cache.old_wasm;
|
||||
let old_symbols =
|
||||
|
||||
@@ -349,6 +349,7 @@ use std::{
|
||||
},
|
||||
time::{SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
use subsecond_types::JumpTable;
|
||||
use target_lexicon::{Architecture, OperatingSystem, Triple};
|
||||
use tempfile::TempDir;
|
||||
use tokio::{io::AsyncBufReadExt, process::Command};
|
||||
@@ -2334,6 +2335,48 @@ impl BuildRequest {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn create_jump_table(
|
||||
&self,
|
||||
patch: &Path,
|
||||
cache: &HotpatchModuleCache,
|
||||
) -> Result<JumpTable> {
|
||||
use crate::build::patch::{
|
||||
create_native_jump_table, create_wasm_jump_table, create_windows_jump_table,
|
||||
};
|
||||
|
||||
let root_dir = self.root_dir();
|
||||
let base_path = self.base_path();
|
||||
let triple = &self.triple;
|
||||
|
||||
// Symbols are stored differently based on the platform, so we need to handle them differently.
|
||||
// - Wasm requires the walrus crate and actually modifies the patch file
|
||||
// - windows requires the pdb crate and pdb files
|
||||
// - nix requires the object crate
|
||||
let mut jump_table = match triple.operating_system {
|
||||
OperatingSystem::Windows => create_windows_jump_table(patch, cache)?,
|
||||
_ if triple.architecture == Architecture::Wasm32 => {
|
||||
create_wasm_jump_table(patch, cache)?
|
||||
}
|
||||
_ => create_native_jump_table(patch, triple, cache)?,
|
||||
};
|
||||
|
||||
// root_dir: &Path,
|
||||
// base_path: Option<&str>,
|
||||
// Rebase the wasm binary to be relocatable once the jump table is generated
|
||||
if triple.architecture == target_lexicon::Architecture::Wasm32 {
|
||||
// Make sure we use the dir relative to the public dir, so the web can load it as a proper URL
|
||||
//
|
||||
// ie we would've shipped `/Users/foo/Projects/dioxus/target/dx/project/debug/web/public/wasm/lib.wasm`
|
||||
// but we want to ship `/wasm/lib.wasm`
|
||||
jump_table.lib = PathBuf::from(
|
||||
"/".to_string() + base_path.unwrap_or_default().trim_start_matches('/'),
|
||||
)
|
||||
.join(jump_table.lib.strip_prefix(root_dir).unwrap())
|
||||
}
|
||||
|
||||
Ok(jump_table)
|
||||
}
|
||||
|
||||
/// Automatically detect the linker flavor based on the target triple and any custom linkers.
|
||||
///
|
||||
/// This tries to replicate what rustc does when selecting the linker flavor based on the linker
|
||||
@@ -3567,7 +3610,7 @@ impl BuildRequest {
|
||||
|
||||
// Get the strip setting from the profile or the profile it inherits from
|
||||
fn get_strip(profile: &Profile, profiles: &Profiles) -> Option<StripSetting> {
|
||||
profile.strip.clone().or_else(|| {
|
||||
profile.strip.or_else(|| {
|
||||
// If we can't find the strip setting, check if we inherit from another profile
|
||||
profile.inherits.as_ref().and_then(|inherits| {
|
||||
let profile = match inherits.as_str() {
|
||||
|
||||
@@ -5,11 +5,15 @@ use crate::{
|
||||
use anyhow::Context;
|
||||
use clap::Parser;
|
||||
use dioxus_dx_wire_format::StructuredBuildArtifacts;
|
||||
use std::io::Read;
|
||||
use std::sync::Arc;
|
||||
|
||||
const HELP_HEADING: &str = "Hotpatching a binary";
|
||||
|
||||
/// Patches a single binary, but takes the same arguments as a `cargo build`.
|
||||
/// Patches a single binary, but takes the same arguments as a `cargo build` and the serialized output from `dx build --fat-binary` as input.
|
||||
///
|
||||
/// This is intended to be used with something like `dx build --fat-binary >> output.json` and then
|
||||
/// `cat output.json | dx hotpatch --aslr-reference 0x12345678` to produce a hotpatched binary.
|
||||
///
|
||||
/// By default, patches the client, but you can set patch_server to true to patch the server instead.
|
||||
#[derive(Clone, Debug, Parser)]
|
||||
@@ -18,10 +22,6 @@ pub struct HotpatchTip {
|
||||
#[clap(long, num_args = 0..=1, default_missing_value="true", help_heading = HELP_HEADING)]
|
||||
pub patch_server: Option<bool>,
|
||||
|
||||
/// The serialized output from the `dx build --fat-binary` command
|
||||
#[clap(long, help_heading = HELP_HEADING)]
|
||||
pub serialized_artifacts: String,
|
||||
|
||||
/// The ASLR reference of the running app being patched. Used to generate sensible offsets for patched code.
|
||||
#[clap(long, help_heading = HELP_HEADING)]
|
||||
pub aslr_reference: u64,
|
||||
@@ -49,8 +49,13 @@ impl HotpatchTip {
|
||||
&targets.client
|
||||
};
|
||||
|
||||
let mut serialized_artifacts = String::new();
|
||||
std::io::stdin()
|
||||
.lock()
|
||||
.read_to_string(&mut serialized_artifacts)
|
||||
.context("Failed to read serialized build artifacts from stdin")?;
|
||||
let structured_build_artifacts =
|
||||
serde_json::from_str::<StructuredBuildArtifacts>(&self.serialized_artifacts)
|
||||
serde_json::from_str::<StructuredBuildArtifacts>(&serialized_artifacts)
|
||||
.context("Failed to parse structured build artifacts")?;
|
||||
|
||||
let StructuredBuildArtifacts {
|
||||
@@ -82,7 +87,7 @@ impl HotpatchTip {
|
||||
let patch_exe = request.patch_exe(artifacts.time_start);
|
||||
|
||||
Ok(StructuredOutput::Hotpatch {
|
||||
jump_table: crate::build::create_jump_table(&patch_exe, &request.triple, &cache)?,
|
||||
jump_table: request.create_jump_table(&patch_exe, &cache)?,
|
||||
artifacts: artifacts.into_structured_output(),
|
||||
})
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user