Support using LLVM's libunwind as the unwinder implementation
This avoids the dependency on host libraries such as libgcc_s which may be undesirable in some deployment environments where these aren't available.
This commit is contained in:
parent
f8673e0ad8
commit
86d1678403
9 changed files with 89 additions and 2 deletions
|
@ -3849,6 +3849,7 @@ dependencies = [
|
||||||
name = "unwind"
|
name = "unwind"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"compiler_builtins 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"compiler_builtins 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"core 0.0.0",
|
"core 0.0.0",
|
||||||
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -421,6 +421,9 @@
|
||||||
# development of NLL
|
# development of NLL
|
||||||
#test-compare-mode = false
|
#test-compare-mode = false
|
||||||
|
|
||||||
|
# Use LLVM libunwind as the implementation for Rust's unwinder.
|
||||||
|
#llvm-libunwind = false
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Options for specific targets
|
# Options for specific targets
|
||||||
#
|
#
|
||||||
|
|
|
@ -48,6 +48,7 @@ pub struct Config {
|
||||||
pub exclude: Vec<PathBuf>,
|
pub exclude: Vec<PathBuf>,
|
||||||
pub rustc_error_format: Option<String>,
|
pub rustc_error_format: Option<String>,
|
||||||
pub test_compare_mode: bool,
|
pub test_compare_mode: bool,
|
||||||
|
pub llvm_libunwind: bool,
|
||||||
|
|
||||||
pub run_host_only: bool,
|
pub run_host_only: bool,
|
||||||
|
|
||||||
|
@ -329,6 +330,7 @@ struct Rust {
|
||||||
remap_debuginfo: Option<bool>,
|
remap_debuginfo: Option<bool>,
|
||||||
jemalloc: Option<bool>,
|
jemalloc: Option<bool>,
|
||||||
test_compare_mode: Option<bool>,
|
test_compare_mode: Option<bool>,
|
||||||
|
llvm_libunwind: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TOML representation of how each build target is configured.
|
/// TOML representation of how each build target is configured.
|
||||||
|
@ -548,6 +550,7 @@ impl Config {
|
||||||
set(&mut config.rust_rpath, rust.rpath);
|
set(&mut config.rust_rpath, rust.rpath);
|
||||||
set(&mut config.jemalloc, rust.jemalloc);
|
set(&mut config.jemalloc, rust.jemalloc);
|
||||||
set(&mut config.test_compare_mode, rust.test_compare_mode);
|
set(&mut config.test_compare_mode, rust.test_compare_mode);
|
||||||
|
set(&mut config.llvm_libunwind, rust.llvm_libunwind);
|
||||||
set(&mut config.backtrace, rust.backtrace);
|
set(&mut config.backtrace, rust.backtrace);
|
||||||
set(&mut config.channel, rust.channel.clone());
|
set(&mut config.channel, rust.channel.clone());
|
||||||
set(&mut config.rust_dist_src, rust.dist_src);
|
set(&mut config.rust_dist_src, rust.dist_src);
|
||||||
|
|
|
@ -68,6 +68,8 @@ o("cflags", "llvm.cflags", "build LLVM with these extra compiler flags")
|
||||||
o("cxxflags", "llvm.cxxflags", "build LLVM with these extra compiler flags")
|
o("cxxflags", "llvm.cxxflags", "build LLVM with these extra compiler flags")
|
||||||
o("ldflags", "llvm.ldflags", "build LLVM with these extra linker flags")
|
o("ldflags", "llvm.ldflags", "build LLVM with these extra linker flags")
|
||||||
|
|
||||||
|
o("llvm-libunwind", "rust.llvm_libunwind", "use LLVM libunwind")
|
||||||
|
|
||||||
# Optimization and debugging options. These may be overridden by the release
|
# Optimization and debugging options. These may be overridden by the release
|
||||||
# channel, etc.
|
# channel, etc.
|
||||||
o("optimize", "rust.optimize", "build optimized rust code")
|
o("optimize", "rust.optimize", "build optimized rust code")
|
||||||
|
|
|
@ -506,6 +506,9 @@ impl Build {
|
||||||
fn std_features(&self) -> String {
|
fn std_features(&self) -> String {
|
||||||
let mut features = "panic-unwind".to_string();
|
let mut features = "panic-unwind".to_string();
|
||||||
|
|
||||||
|
if self.config.llvm_libunwind {
|
||||||
|
features.push_str(" llvm-libunwind");
|
||||||
|
}
|
||||||
if self.config.backtrace {
|
if self.config.backtrace {
|
||||||
features.push_str(" backtrace");
|
features.push_str(" backtrace");
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ backtrace = ["backtrace-sys"]
|
||||||
panic-unwind = ["panic_unwind"]
|
panic-unwind = ["panic_unwind"]
|
||||||
profiler = ["profiler_builtins"]
|
profiler = ["profiler_builtins"]
|
||||||
compiler_builtins_c = ["compiler_builtins/c"]
|
compiler_builtins_c = ["compiler_builtins/c"]
|
||||||
|
llvm-libunwind = ["unwind/llvm-libunwind"]
|
||||||
|
|
||||||
# Make panics and failed asserts immediately abort without formatting any message
|
# Make panics and failed asserts immediately abort without formatting any message
|
||||||
panic_immediate_abort = ["core/panic_immediate_abort"]
|
panic_immediate_abort = ["core/panic_immediate_abort"]
|
||||||
|
|
|
@ -4,6 +4,9 @@ name = "unwind"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
include = [
|
||||||
|
'/libunwind/*',
|
||||||
|
]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "unwind"
|
name = "unwind"
|
||||||
|
@ -16,3 +19,9 @@ doc = false
|
||||||
core = { path = "../libcore" }
|
core = { path = "../libcore" }
|
||||||
libc = { version = "0.2.43", features = ['rustc-dep-of-std'], default-features = false }
|
libc = { version = "0.2.43", features = ['rustc-dep-of-std'], default-features = false }
|
||||||
compiler_builtins = "0.1.0"
|
compiler_builtins = "0.1.0"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
cc = { optional = true, version = "1.0.1" }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
llvm-libunwind = ["cc"]
|
||||||
|
|
|
@ -4,7 +4,13 @@ fn main() {
|
||||||
println!("cargo:rerun-if-changed=build.rs");
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
let target = env::var("TARGET").expect("TARGET was not set");
|
let target = env::var("TARGET").expect("TARGET was not set");
|
||||||
|
|
||||||
if target.contains("linux") {
|
if cfg!(feature = "llvm-libunwind") &&
|
||||||
|
(target.contains("linux") ||
|
||||||
|
target.contains("fuchsia")) {
|
||||||
|
// Build the unwinding from libunwind C/C++ source code.
|
||||||
|
#[cfg(feature = "llvm-libunwind")]
|
||||||
|
llvm_libunwind::compile();
|
||||||
|
} else if target.contains("linux") {
|
||||||
if target.contains("musl") {
|
if target.contains("musl") {
|
||||||
// musl is handled in lib.rs
|
// musl is handled in lib.rs
|
||||||
} else if !target.contains("android") {
|
} else if !target.contains("android") {
|
||||||
|
@ -37,3 +43,62 @@ fn main() {
|
||||||
println!("cargo:rustc-link-lib=unwind");
|
println!("cargo:rustc-link-lib=unwind");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "llvm-libunwind")]
|
||||||
|
mod llvm_libunwind {
|
||||||
|
use std::env;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
/// Compile the libunwind C/C++ source code.
|
||||||
|
pub fn compile() {
|
||||||
|
let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap();
|
||||||
|
let target_vendor = env::var("CARGO_CFG_TARGET_VENDOR").unwrap();
|
||||||
|
let cfg = &mut cc::Build::new();
|
||||||
|
|
||||||
|
cfg.cpp(true);
|
||||||
|
cfg.cpp_set_stdlib(None);
|
||||||
|
cfg.warnings(false);
|
||||||
|
|
||||||
|
if target_env == "msvc" {
|
||||||
|
// Don't pull in extra libraries on MSVC
|
||||||
|
cfg.flag("/Zl");
|
||||||
|
cfg.flag("/EHsc");
|
||||||
|
cfg.define("_CRT_SECURE_NO_WARNINGS", None);
|
||||||
|
cfg.define("_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS", None);
|
||||||
|
} else {
|
||||||
|
cfg.flag("-std=c99");
|
||||||
|
cfg.flag("-std=c++11");
|
||||||
|
cfg.flag("-nostdinc++");
|
||||||
|
if cfg.is_flag_supported("-funwind-tables").unwrap_or_default() &&
|
||||||
|
cfg.is_flag_supported("-fno-exceptions").unwrap_or_default() {
|
||||||
|
cfg.flag("-funwind-tables");
|
||||||
|
cfg.flag("-fno-exceptions");
|
||||||
|
}
|
||||||
|
cfg.flag("-fno-rtti");
|
||||||
|
cfg.flag("-fstrict-aliasing");
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut unwind_sources = vec![
|
||||||
|
"Unwind-EHABI.cpp",
|
||||||
|
"Unwind-seh.cpp",
|
||||||
|
"Unwind-sjlj.c",
|
||||||
|
"UnwindLevel1-gcc-ext.c",
|
||||||
|
"UnwindLevel1.c",
|
||||||
|
"UnwindRegistersRestore.S",
|
||||||
|
"UnwindRegistersSave.S",
|
||||||
|
"libunwind.cpp",
|
||||||
|
];
|
||||||
|
|
||||||
|
if target_vendor == "apple" {
|
||||||
|
unwind_sources.push("Unwind_AppleExtras.cpp");
|
||||||
|
}
|
||||||
|
|
||||||
|
let root = Path::new("../llvm-project/libunwind");
|
||||||
|
cfg.include(root.join("include"));
|
||||||
|
for src in unwind_sources {
|
||||||
|
cfg.file(root.join("src").join(src));
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.compile("unwind");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 1f484cbe0e863e9e215f1b3d7198063444d60873
|
Subproject commit 84abffda0e03b03c62bdfc3cfeda1c2cf1f88c85
|
Loading…
Add table
Reference in a new issue