From 66fa42a94627dc04de6d44227c5d06fec6b26d76 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Perennou Date: Thu, 8 Oct 2020 15:05:31 +0200 Subject: [PATCH] allow using the system-wide llvm-libunwind as the unwinder Signed-off-by: Marc-Antoine Perennou --- config.toml.example | 3 ++- library/std/Cargo.toml | 1 + library/test/Cargo.toml | 1 + library/unwind/Cargo.toml | 1 + library/unwind/src/lib.rs | 16 +++++++++++++++- src/bootstrap/config.rs | 35 ++++++++++++++++++++++++++++++++--- src/bootstrap/configure.py | 2 +- src/bootstrap/lib.rs | 8 +++++--- 8 files changed, 58 insertions(+), 9 deletions(-) diff --git a/config.toml.example b/config.toml.example index e7e37c679e5..05bc989dc98 100644 --- a/config.toml.example +++ b/config.toml.example @@ -527,7 +527,8 @@ changelog-seen = 2 #test-compare-mode = false # Use LLVM libunwind as the implementation for Rust's unwinder. -#llvm-libunwind = false +# Accepted values are 'in-tree' (formerly true), 'system' or 'no' (formerly false). +#llvm-libunwind = 'no' # Enable Windows Control Flow Guard checks in the standard library. # This only applies from stage 1 onwards, and only for Windows targets. diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index c08828bc0cd..5dfa3395ddd 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -61,6 +61,7 @@ profiler = ["profiler_builtins"] compiler-builtins-c = ["alloc/compiler-builtins-c"] compiler-builtins-mem = ["alloc/compiler-builtins-mem"] llvm-libunwind = ["unwind/llvm-libunwind"] +system-llvm-libunwind = ["unwind/system-llvm-libunwind"] # Make panics and failed asserts immediately abort without formatting any message panic_immediate_abort = ["core/panic_immediate_abort"] diff --git a/library/test/Cargo.toml b/library/test/Cargo.toml index e44c7811135..3d6910b107d 100644 --- a/library/test/Cargo.toml +++ b/library/test/Cargo.toml @@ -27,6 +27,7 @@ backtrace = ["std/backtrace"] compiler-builtins-c = ["std/compiler-builtins-c"] compiler-builtins-mem = ["std/compiler-builtins-mem"] llvm-libunwind = ["std/llvm-libunwind"] +system-llvm-libunwind = ["std/system-llvm-libunwind"] panic-unwind = ["std/panic_unwind"] panic_immediate_abort = ["std/panic_immediate_abort"] profiler = ["std/profiler"] diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml index 7138d0c8fea..4f7a304a59f 100644 --- a/library/unwind/Cargo.toml +++ b/library/unwind/Cargo.toml @@ -23,3 +23,4 @@ cc = { version = "1.0.1" } [features] llvm-libunwind = [] +system-llvm-libunwind = [] diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs index e7fa37bc9db..dbdefa471a9 100644 --- a/library/unwind/src/lib.rs +++ b/library/unwind/src/lib.rs @@ -45,10 +45,24 @@ extern "C" {} // When building with crt-static, we get `gcc_eh` from the `libc` crate, since // glibc needs it, and needs it listed later on the linker command line. We // don't want to duplicate it here. -#[cfg(all(target_os = "linux", target_env = "gnu", not(feature = "llvm-libunwind")))] +#[cfg(all( + target_os = "linux", + target_env = "gnu", + not(feature = "llvm-libunwind"), + not(feature = "system-llvm-libunwind") +))] #[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))] extern "C" {} +#[cfg(all( + target_os = "linux", + target_env = "gnu", + not(feature = "llvm-libunwind"), + feature = "system-llvm-libunwind" +))] +#[link(name = "unwind", cfg(not(target_feature = "crt-static")))] +extern "C" {} + #[cfg(target_os = "redox")] #[link(name = "gcc_eh", kind = "static-nobundle", cfg(target_feature = "crt-static"))] #[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))] diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 3c1249f8de4..7698ff62880 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -10,6 +10,7 @@ use std::ffi::OsString; use std::fmt; use std::fs; use std::path::{Path, PathBuf}; +use std::str::FromStr; use crate::cache::{Interned, INTERNER}; use crate::flags::Flags; @@ -65,7 +66,7 @@ pub struct Config { pub rustc_error_format: Option, pub json_output: bool, pub test_compare_mode: bool, - pub llvm_libunwind: bool, + pub llvm_libunwind: Option, pub on_fail: Option, pub stage: u32, @@ -177,6 +178,32 @@ pub struct Config { pub out: PathBuf, } +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum LlvmLibunwind { + No, + InTree, + System, +} + +impl Default for LlvmLibunwind { + fn default() -> Self { + Self::No + } +} + +impl FromStr for LlvmLibunwind { + type Err = String; + + fn from_str(value: &str) -> Result { + match value { + "no" => Ok(Self::No), + "in-tree" => Ok(Self::InTree), + "system" => Ok(Self::System), + invalid => Err(format!("Invalid value '{}' for rust.llvm-libunwind config.", invalid)), + } + } +} + #[derive(Debug, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct TargetSelection { pub triple: Interned, @@ -457,7 +484,7 @@ struct Rust { remap_debuginfo: Option, jemalloc: Option, test_compare_mode: Option, - llvm_libunwind: Option, + llvm_libunwind: Option, control_flow_guard: Option, new_symbol_mangling: Option, } @@ -799,7 +826,9 @@ 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); + config.llvm_libunwind = rust + .llvm_libunwind + .map(|v| v.parse().expect("failed to parse rust.llvm-libunwind")); set(&mut config.backtrace, rust.backtrace); set(&mut config.channel, rust.channel); set(&mut config.rust_dist_src, rust.dist_src); diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 47673ce1e87..e156952d56f 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -65,7 +65,7 @@ v("llvm-cflags", "llvm.cflags", "build LLVM with these extra compiler flags") v("llvm-cxxflags", "llvm.cxxflags", "build LLVM with these extra compiler flags") v("llvm-ldflags", "llvm.ldflags", "build LLVM with these extra linker flags") -o("llvm-libunwind", "rust.llvm-libunwind", "use LLVM libunwind") +v("llvm-libunwind", "rust.llvm-libunwind", "use LLVM libunwind") # Optimization and debugging options. These may be overridden by the release # channel, etc. diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 22a8e828862..b24c6a2c4b8 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -121,7 +121,7 @@ use std::os::windows::fs::symlink_file; use build_helper::{mtime, output, run, run_suppressed, t, try_run, try_run_suppressed}; use filetime::FileTime; -use crate::config::TargetSelection; +use crate::config::{LlvmLibunwind, TargetSelection}; use crate::util::{exe, libdir, CiEnv}; mod builder; @@ -537,8 +537,10 @@ impl Build { fn std_features(&self) -> String { let mut features = "panic-unwind".to_string(); - if self.config.llvm_libunwind { - features.push_str(" llvm-libunwind"); + match self.config.llvm_libunwind.unwrap_or_default() { + LlvmLibunwind::InTree => features.push_str(" llvm-libunwind"), + LlvmLibunwind::System => features.push_str(" system-llvm-libunwind"), + LlvmLibunwind::No => {} } if self.config.backtrace { features.push_str(" backtrace");