mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-06 20:58:28 +00:00
Fix segfault when using --object-format serialized and compile errors
This commit is contained in:
6
Makefile
6
Makefile
@@ -450,15 +450,15 @@ build-capi-llvm-universal: capi-setup
|
|||||||
build-capi-headless: capi-setup
|
build-capi-headless: capi-setup
|
||||||
ifeq ($(CARGO_TARGET),)
|
ifeq ($(CARGO_TARGET),)
|
||||||
RUSTFLAGS="${RUSTFLAGS} -C panic=abort -C link-dead-code -C lto -O -C embed-bitcode=yes" $(CARGO_BINARY) build --target $(HOST_TARGET) --manifest-path lib/c-api/Cargo.toml --release \
|
RUSTFLAGS="${RUSTFLAGS} -C panic=abort -C link-dead-code -C lto -O -C embed-bitcode=yes" $(CARGO_BINARY) build --target $(HOST_TARGET) --manifest-path lib/c-api/Cargo.toml --release \
|
||||||
--no-default-features --features compiler-headless,wasi --target-dir target/$(CARGO_TARGET)/headless
|
--no-default-features --features compiler-headless,wasi,webc_runner --target-dir target/$(CARGO_TARGET)/headless
|
||||||
else
|
else
|
||||||
RUSTFLAGS="${RUSTFLAGS} -C panic=abort -C link-dead-code -C lto -O -C embed-bitcode=yes" $(CARGO_BINARY) build $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml --release \
|
RUSTFLAGS="${RUSTFLAGS} -C panic=abort -C link-dead-code -C lto -O -C embed-bitcode=yes" $(CARGO_BINARY) build $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml --release \
|
||||||
--no-default-features --features compiler-headless,wasi --target-dir target/$(CARGO_TARGET)/headless
|
--no-default-features --features compiler-headless,wasi,webc_runner --target-dir target/$(CARGO_TARGET)/headless
|
||||||
endif
|
endif
|
||||||
|
|
||||||
build-capi-headless-ios: capi-setup
|
build-capi-headless-ios: capi-setup
|
||||||
RUSTFLAGS="${RUSTFLAGS} -C panic=abort" cargo lipo --manifest-path lib/c-api/Cargo.toml --release \
|
RUSTFLAGS="${RUSTFLAGS} -C panic=abort" cargo lipo --manifest-path lib/c-api/Cargo.toml --release \
|
||||||
--no-default-features --features compiler-headless,wasi --target-dir target/$(CARGO_TARGET)/headless
|
--no-default-features --features compiler-headless,wasi,webc_runner --target-dir target/$(CARGO_TARGET)/headless
|
||||||
|
|
||||||
#####
|
#####
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -161,8 +161,9 @@ impl CreateExe {
|
|||||||
let starting_cd = env::current_dir()?;
|
let starting_cd = env::current_dir()?;
|
||||||
let input_path = starting_cd.join(&self.path);
|
let input_path = starting_cd.join(&self.path);
|
||||||
let output_path = starting_cd.join(&self.output);
|
let output_path = starting_cd.join(&self.output);
|
||||||
|
let object_format = self.object_format.unwrap_or_default();
|
||||||
let cross_compilation =
|
let cross_compilation =
|
||||||
utils::get_cross_compile_setup(&mut cc, &target_triple, &starting_cd)?;
|
utils::get_cross_compile_setup(&mut cc, &target_triple, &starting_cd, &object_format)?;
|
||||||
|
|
||||||
if input_path.is_dir() {
|
if input_path.is_dir() {
|
||||||
return Err(anyhow::anyhow!("input path cannot be a directory"));
|
return Err(anyhow::anyhow!("input path cannot be a directory"));
|
||||||
@@ -180,7 +181,7 @@ impl CreateExe {
|
|||||||
&self.compiler,
|
&self.compiler,
|
||||||
&self.cpu_features,
|
&self.cpu_features,
|
||||||
&cross_compilation.target,
|
&cross_compilation.target,
|
||||||
self.object_format.unwrap_or_default(),
|
object_format,
|
||||||
&self.precompiled_atom,
|
&self.precompiled_atom,
|
||||||
AllowMultiWasm::Allow,
|
AllowMultiWasm::Allow,
|
||||||
)?;
|
)?;
|
||||||
@@ -210,7 +211,7 @@ impl CreateExe {
|
|||||||
&self.compiler,
|
&self.compiler,
|
||||||
&cross_compilation.target,
|
&cross_compilation.target,
|
||||||
&self.cpu_features,
|
&self.cpu_features,
|
||||||
self.object_format.unwrap_or_default(),
|
object_format,
|
||||||
&self.precompiled_atom,
|
&self.precompiled_atom,
|
||||||
)?;
|
)?;
|
||||||
get_module_infos(&tempdir, &atoms)?;
|
get_module_infos(&tempdir, &atoms)?;
|
||||||
@@ -641,7 +642,12 @@ fn conpile_atoms(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Compile the C code.
|
/// Compile the C code.
|
||||||
fn run_c_compile(path_to_c_src: &Path, output_name: &Path, target: &Triple) -> anyhow::Result<()> {
|
fn run_c_compile(
|
||||||
|
path_to_c_src: &Path,
|
||||||
|
output_name: &Path,
|
||||||
|
target: &Triple,
|
||||||
|
debug: bool,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
let c_compiler = "cc";
|
let c_compiler = "cc";
|
||||||
// We must use a C++ compiler on Windows because wasm.h uses `static_assert`
|
// We must use a C++ compiler on Windows because wasm.h uses `static_assert`
|
||||||
@@ -658,9 +664,16 @@ fn run_c_compile(path_to_c_src: &Path, output_name: &Path, target: &Triple) -> a
|
|||||||
.arg("-I")
|
.arg("-I")
|
||||||
.arg(utils::get_wasmer_include_directory()?)
|
.arg(utils::get_wasmer_include_directory()?)
|
||||||
.arg("-target")
|
.arg("-target")
|
||||||
.arg(format!("{}", target));
|
.arg(format!("{}", target))
|
||||||
|
.arg("-o")
|
||||||
|
.arg(output_name);
|
||||||
|
|
||||||
let output = command.arg("-o").arg(output_name).output()?;
|
if debug {
|
||||||
|
println!("{command:#?}");
|
||||||
|
}
|
||||||
|
|
||||||
|
let output = command.output()?;
|
||||||
|
if debug {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"run_c_compile: stdout: {}\n\nstderr: {}",
|
"run_c_compile: stdout: {}\n\nstderr: {}",
|
||||||
std::str::from_utf8(&output.stdout)
|
std::str::from_utf8(&output.stdout)
|
||||||
@@ -668,6 +681,7 @@ fn run_c_compile(path_to_c_src: &Path, output_name: &Path, target: &Triple) -> a
|
|||||||
std::str::from_utf8(&output.stderr)
|
std::str::from_utf8(&output.stderr)
|
||||||
.expect("stderr is not utf8! need to handle arbitrary bytes")
|
.expect("stderr is not utf8! need to handle arbitrary bytes")
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if !output.status.success() {
|
if !output.status.success() {
|
||||||
bail!(
|
bail!(
|
||||||
@@ -963,6 +977,7 @@ fn link_exe_from_dir(
|
|||||||
&directory.join("wasmer_main.c"),
|
&directory.join("wasmer_main.c"),
|
||||||
&directory.join("wasmer_main.o"),
|
&directory.join("wasmer_main.o"),
|
||||||
&cross_compilation.target,
|
&cross_compilation.target,
|
||||||
|
debug,
|
||||||
)
|
)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
anyhow::anyhow!(
|
anyhow::anyhow!(
|
||||||
@@ -1210,8 +1225,6 @@ fn generate_wasmer_main_c(
|
|||||||
}}
|
}}
|
||||||
")?;
|
")?;
|
||||||
} else {
|
} else {
|
||||||
extra_headers.push(format!("const extern unsigned char {module_name}[];\r\n"));
|
|
||||||
|
|
||||||
write!(
|
write!(
|
||||||
c_code_to_add,
|
c_code_to_add,
|
||||||
"
|
"
|
||||||
@@ -1319,7 +1332,7 @@ fn generate_wasmer_main_c(
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(super) mod utils {
|
pub(super) mod utils {
|
||||||
|
|
||||||
use super::{CrossCompile, CrossCompileSetup};
|
use super::{CrossCompile, CrossCompileSetup, ObjectFormat};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use target_lexicon::{Architecture, OperatingSystem, Triple};
|
use target_lexicon::{Architecture, OperatingSystem, Triple};
|
||||||
@@ -1342,9 +1355,14 @@ pub(super) mod utils {
|
|||||||
cross_subc: &mut CrossCompile,
|
cross_subc: &mut CrossCompile,
|
||||||
target_triple: &Triple,
|
target_triple: &Triple,
|
||||||
starting_cd: &Path,
|
starting_cd: &Path,
|
||||||
|
object_format: &ObjectFormat,
|
||||||
) -> Result<CrossCompileSetup, anyhow::Error> {
|
) -> Result<CrossCompileSetup, anyhow::Error> {
|
||||||
let target = target_triple;
|
let target = target_triple;
|
||||||
|
|
||||||
|
if *object_format == ObjectFormat::Serialized && *target_triple != Triple::host() {
|
||||||
|
return Err(anyhow::anyhow!("cannot cross-compile: --object-format serialized + cross-compilation is not supported"));
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(tarball_path) = cross_subc.tarball.as_mut() {
|
if let Some(tarball_path) = cross_subc.tarball.as_mut() {
|
||||||
if tarball_path.is_relative() {
|
if tarball_path.is_relative() {
|
||||||
*tarball_path = starting_cd.join(&tarball_path);
|
*tarball_path = starting_cd.join(&tarball_path);
|
||||||
@@ -1381,8 +1399,31 @@ pub(super) mod utils {
|
|||||||
if let Some(local_tarball) = cross_subc.tarball.as_ref() {
|
if let Some(local_tarball) = cross_subc.tarball.as_ref() {
|
||||||
find_filename(local_tarball, target)
|
find_filename(local_tarball, target)
|
||||||
} else {
|
} else {
|
||||||
|
// check WASMER_DIR if Target = native
|
||||||
|
let mut local = None;
|
||||||
|
if *target_triple == Triple::host() && std::env::var("WASMER_DIR").is_ok() {
|
||||||
|
let wasmer_dir = wasmer_registry::WasmerConfig::get_wasmer_dir().ok();
|
||||||
|
if let Some(library) = wasmer_dir.as_ref().and_then(|wasmer_dir| {
|
||||||
|
find_libwasmer_in_files(&target, &super::http_fetch::list_dir(wasmer_dir))
|
||||||
|
.ok()
|
||||||
|
}) {
|
||||||
|
if Path::new(&library).exists() {
|
||||||
|
local = Some((
|
||||||
|
format!(
|
||||||
|
"{}",
|
||||||
|
Path::new(&library).canonicalize().unwrap().display()
|
||||||
|
),
|
||||||
|
wasmer_dir.unwrap(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check if the tarball for the target already exists locally
|
// check if the tarball for the target already exists locally
|
||||||
let local_tarball = std::fs::read_dir(get_libwasmer_cache_path()?)?
|
let local_tarball = if local.is_some() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
std::fs::read_dir(get_libwasmer_cache_path()?)?
|
||||||
.filter_map(|e| e.ok())
|
.filter_map(|e| e.ok())
|
||||||
.filter_map(|e| {
|
.filter_map(|e| {
|
||||||
let path = format!("{}", e.path().display());
|
let path = format!("{}", e.path().display());
|
||||||
@@ -1393,9 +1434,12 @@ pub(super) mod utils {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter_map(|p| filter_tarballs(&p, target))
|
.filter_map(|p| filter_tarballs(&p, target))
|
||||||
.next();
|
.next()
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(local_tarball) = local_tarball.as_ref() {
|
if let Some(local) = local {
|
||||||
|
Ok(local)
|
||||||
|
} else if let Some(local_tarball) = local_tarball.as_ref() {
|
||||||
find_filename(local_tarball, target)
|
find_filename(local_tarball, target)
|
||||||
} else {
|
} else {
|
||||||
let release = super::http_fetch::get_latest_release()?;
|
let release = super::http_fetch::get_latest_release()?;
|
||||||
@@ -1431,11 +1475,14 @@ pub(super) mod utils {
|
|||||||
std::fs::create_dir_all(&target_file_path)
|
std::fs::create_dir_all(&target_file_path)
|
||||||
.map_err(|e| anyhow::anyhow!("{e}"))
|
.map_err(|e| anyhow::anyhow!("{e}"))
|
||||||
.with_context(|| anyhow::anyhow!("{}", target_file_path.display()))?;
|
.with_context(|| anyhow::anyhow!("{}", target_file_path.display()))?;
|
||||||
let files =
|
let files = super::http_fetch::untar(local_tarball, &target_file_path)?;
|
||||||
super::http_fetch::untar(local_tarball.to_path_buf(), target_file_path.clone())?;
|
|
||||||
let tarball_dir = target_file_path.canonicalize().unwrap_or(target_file_path);
|
let tarball_dir = target_file_path.canonicalize().unwrap_or(target_file_path);
|
||||||
|
let file = find_libwasmer_in_files(&target, &files)?;
|
||||||
|
Ok((file, tarball_dir))
|
||||||
|
}
|
||||||
|
|
||||||
let file = files
|
fn find_libwasmer_in_files(target: &Triple, files: &[String]) -> Result<String, anyhow::Error> {
|
||||||
|
files
|
||||||
.iter()
|
.iter()
|
||||||
.find(|f| f.ends_with("libwasmer-headless.a") || f.ends_with("wasmer-headless.lib"))
|
.find(|f| f.ends_with("libwasmer-headless.a") || f.ends_with("wasmer-headless.lib"))
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
@@ -1446,9 +1493,7 @@ pub(super) mod utils {
|
|||||||
.cloned()
|
.cloned()
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
anyhow!("Could not find libwasmer.a for {} target in the provided tarball path (files = {files:#?})", target)
|
anyhow!("Could not find libwasmer.a for {} target in the provided tarball path (files = {files:#?})", target)
|
||||||
})?;
|
})
|
||||||
|
|
||||||
Ok((file, tarball_dir))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn filter_tarballs(p: &Path, target: &Triple) -> Option<PathBuf> {
|
pub(super) fn filter_tarballs(p: &Path, target: &Triple) -> Option<PathBuf> {
|
||||||
@@ -1661,6 +1706,7 @@ mod http_fetch {
|
|||||||
use anyhow::{anyhow, Context, Result};
|
use anyhow::{anyhow, Context, Result};
|
||||||
use http_req::{request::Request, response::StatusCode, uri::Uri};
|
use http_req::{request::Request, response::StatusCode, uri::Uri};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
use std::path::Path;
|
||||||
use target_lexicon::OperatingSystem;
|
use target_lexicon::OperatingSystem;
|
||||||
|
|
||||||
pub(super) fn get_latest_release() -> Result<serde_json::Value> {
|
pub(super) fn get_latest_release() -> Result<serde_json::Value> {
|
||||||
@@ -1917,18 +1963,17 @@ mod http_fetch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn untar(
|
pub(crate) fn list_dir(target: &Path) -> Vec<String> {
|
||||||
tarball: std::path::PathBuf,
|
|
||||||
target: std::path::PathBuf,
|
|
||||||
) -> Result<Vec<String>> {
|
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
WalkDir::new(&target)
|
||||||
wasmer_registry::try_unpack_targz(&tarball, &target, false)?;
|
|
||||||
|
|
||||||
Ok(WalkDir::new(&target)
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|e| e.ok())
|
.filter_map(|e| e.ok())
|
||||||
.map(|entry| format!("{}", entry.path().display()))
|
.map(|entry| format!("{}", entry.path().display()))
|
||||||
.collect())
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn untar(tarball: &Path, target: &Path) -> Result<Vec<String>> {
|
||||||
|
wasmer_registry::try_unpack_targz(tarball, target, false)?;
|
||||||
|
Ok(list_dir(target))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user