Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -3849,6 +3849,7 @@ dependencies = [
name = "unwind"
version = "0.0.0"
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)",
"core 0.0.0",
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
3 changes: 3 additions & 0 deletions config.toml.example
Original file line number Diff line number Diff line change
@@ -421,6 +421,9 @@
# development of NLL
#test-compare-mode = false

# Use LLVM libunwind as the implementation for Rust's unwinder.
#llvm-libunwind = false

# =============================================================================
# Options for specific targets
#
3 changes: 3 additions & 0 deletions src/bootstrap/config.rs
Original file line number Diff line number Diff line change
@@ -48,6 +48,7 @@ pub struct Config {
pub exclude: Vec<PathBuf>,
pub rustc_error_format: Option<String>,
pub test_compare_mode: bool,
pub llvm_libunwind: bool,

pub run_host_only: bool,

@@ -329,6 +330,7 @@ struct Rust {
remap_debuginfo: Option<bool>,
jemalloc: Option<bool>,
test_compare_mode: Option<bool>,
llvm_libunwind: Option<bool>,
}

/// 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.jemalloc, rust.jemalloc);
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.channel, rust.channel.clone());
set(&mut config.rust_dist_src, rust.dist_src);
2 changes: 2 additions & 0 deletions src/bootstrap/configure.py
Original file line number Diff line number Diff line change
@@ -68,6 +68,8 @@ def v(*args):
o("cxxflags", "llvm.cxxflags", "build LLVM with these extra compiler 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
# channel, etc.
o("optimize", "rust.optimize", "build optimized rust code")
3 changes: 3 additions & 0 deletions src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
@@ -506,6 +506,9 @@ impl Build {
fn std_features(&self) -> String {
let mut features = "panic-unwind".to_string();

if self.config.llvm_libunwind {
features.push_str(" llvm-libunwind");
}
if self.config.backtrace {
features.push_str(" backtrace");
}
1 change: 1 addition & 0 deletions src/libstd/Cargo.toml
Original file line number Diff line number Diff line change
@@ -54,6 +54,7 @@ backtrace = ["backtrace-sys"]
panic-unwind = ["panic_unwind"]
profiler = ["profiler_builtins"]
compiler_builtins_c = ["compiler_builtins/c"]
llvm-libunwind = ["unwind/llvm-libunwind"]

# Make panics and failed asserts immediately abort without formatting any message
panic_immediate_abort = ["core/panic_immediate_abort"]
9 changes: 9 additions & 0 deletions src/libunwind/Cargo.toml
Original file line number Diff line number Diff line change
@@ -4,6 +4,9 @@ name = "unwind"
version = "0.0.0"
build = "build.rs"
edition = "2018"
include = [
'/libunwind/*',
]

[lib]
name = "unwind"
@@ -16,3 +19,9 @@ doc = false
core = { path = "../libcore" }
libc = { version = "0.2.43", features = ['rustc-dep-of-std'], default-features = false }
compiler_builtins = "0.1.0"

[build-dependencies]
cc = { optional = true, version = "1.0.1" }

[features]
llvm-libunwind = ["cc"]
67 changes: 66 additions & 1 deletion src/libunwind/build.rs
Original file line number Diff line number Diff line change
@@ -4,7 +4,13 @@ fn main() {
println!("cargo:rerun-if-changed=build.rs");
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") {
// musl is handled in lib.rs
} else if !target.contains("android") {
@@ -37,3 +43,62 @@ fn main() {
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");
}
}