diff --git a/configure b/configure index 4ce80a5e849..0904143a7b5 100755 --- a/configure +++ b/configure @@ -649,6 +649,7 @@ opt codegen-tests 1 "run the src/test/codegen tests" opt option-checking 1 "complain about unrecognized options in this configure script" opt ninja 0 "build LLVM using the Ninja generator (for MSVC, requires building in the correct environment)" opt vendor 0 "enable usage of vendored Rust crates" +opt sanitizers 0 "build the sanitizer runtimes (asan, lsan, msan, tsan)" # Optimization and debugging options. These may be overridden by the release channel, etc. opt_nosave optimize 1 "build optimized rust code" diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 573d0df0cee..32cce45e067 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -236,6 +236,10 @@ pub fn compiletest(build: &Build, cmd.env("RUSTC_BOOTSTRAP", "1"); build.add_rust_test_threads(&mut cmd); + if build.config.sanitizers { + cmd.env("SANITIZER_SUPPORT", "1"); + } + cmd.arg("--adb-path").arg("adb"); cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR); if target.contains("android") { @@ -332,10 +336,7 @@ pub fn krate(build: &Build, krate: Option<&str>) { let (name, path, features, root) = match mode { Mode::Libstd => { - ("libstd", - "src/rustc/std_shim", - build.std_features(), - "std_shim") + ("libstd", "src/rustc/std_shim", build.std_features(), "std_shim") } Mode::Libtest => { ("libtest", "src/rustc/test_shim", String::new(), "test_shim") diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 3e29339a75b..d329f9c0690 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -52,15 +52,14 @@ pub fn std(build: &Build, target: &str, compiler: &Compiler) { features.push_str(" force_alloc_system"); } - if compiler.stage != 0 && !build.system_llvm(target) { + if compiler.stage != 0 && build.config.sanitizers { // This variable is used by the sanitizer runtime crates, e.g. // rustc_lsan, to build the sanitizer runtime from C code // When this variable is missing, those crates won't compile the C code, // so we don't set this variable during stage0 where llvm-config is // missing - // We also don't build the runtimes when compiling against system llvm - // because some distributions ship llvm packages that have a directory - // layout different from the one that the runtime's build system expects + // We also only build the runtimes when --enable-sanitizers (or its + // config.toml equivalent) is used cargo.env("LLVM_CONFIG", build.llvm_config(target)); } cargo.arg("--features").arg(features) diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index b171c89c20a..a31b202a0ae 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -48,6 +48,7 @@ pub struct Config { pub target_config: HashMap, pub full_bootstrap: bool, pub extended: bool, + pub sanitizers: bool, // llvm codegen options pub llvm_assertions: bool, @@ -108,8 +109,6 @@ pub struct Config { /// Per-target configuration stored in the global configuration structure. #[derive(Default)] pub struct Target { - // `true` if compiling against system LLVM or a pre-built LLVM - pub system_llvm: bool, pub llvm_config: Option, pub jemalloc: Option, pub cc: Option, @@ -150,6 +149,7 @@ struct Build { python: Option, full_bootstrap: Option, extended: Option, + sanitizers: Option, } /// TOML representation of various global install decisions. @@ -294,6 +294,7 @@ pub fn parse(build: &str, file: Option) -> Config { set(&mut config.vendor, build.vendor); set(&mut config.full_bootstrap, build.full_bootstrap); set(&mut config.extended, build.extended); + set(&mut config.sanitizers, build.sanitizers); if let Some(ref install) = toml.install { config.prefix = install.prefix.clone().map(PathBuf::from); @@ -437,6 +438,7 @@ macro_rules! check { ("VENDOR", self.vendor), ("FULL_BOOTSTRAP", self.full_bootstrap), ("EXTENDED", self.extended), + ("SANITIZERS", self.sanitizers), } match key { @@ -514,7 +516,6 @@ macro_rules! check { .or_insert(Target::default()); let root = parse_configure_path(value); target.llvm_config = Some(push_exe_path(root, &["bin", "llvm-config"])); - target.system_llvm = true; } "CFG_JEMALLOC_ROOT" if value.len() > 0 => { let target = self.target_config.entry(self.build.clone()) diff --git a/src/bootstrap/config.toml.example b/src/bootstrap/config.toml.example index a53419ad7fd..025fe990f91 100644 --- a/src/bootstrap/config.toml.example +++ b/src/bootstrap/config.toml.example @@ -124,6 +124,9 @@ # disabled by default. #extended = false +# Build the sanitizer runtimes +#sanitizers = false + # ============================================================================= # General install configuration options # ============================================================================= diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 21dd4b1520a..1d01b8773ce 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -717,10 +717,6 @@ fn llvm_config(&self, target: &str) -> PathBuf { } } - fn system_llvm(&self, target: &str) -> bool { - self.config.target_config.get(target).map(|t| t.system_llvm).unwrap_or(false) - } - /// Returns the path to `FileCheck` binary for the specified target fn llvm_filecheck(&self, target: &str) -> PathBuf { let target_config = self.config.target_config.get(target); diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index 6c9976ca3f8..bd24f7657e7 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -127,7 +127,7 @@ pub enum Attribute { ZExt = 18, InReg = 19, SanitizeThread = 20, - SanitizeAddress = 21, + SanitizeAddress = 21, SanitizeMemory = 22, } diff --git a/src/test/run-make/sanitizer-address/Makefile b/src/test/run-make/sanitizer-address/Makefile index c490f490cdf..5931145f3a4 100644 --- a/src/test/run-make/sanitizer-address/Makefile +++ b/src/test/run-make/sanitizer-address/Makefile @@ -1,9 +1,7 @@ -include ../tools.mk # NOTE the address sanitizer only supports x86_64 linux -ifndef IS_WINDOWS -ifeq ($(shell uname),Linux) -ifeq ($(shell uname -m),x86_64) +ifdef SANITIZER_SUPPORT all: $(RUSTC) -g -Z sanitizer=address -Z print-link-args overflow.rs | grep -q librustc_asan $(TMPDIR)/overflow 2>&1 | grep -q stack-buffer-overflow @@ -11,11 +9,3 @@ else all: endif -else -all: - -endif -else -all: - -endif diff --git a/src/test/run-make/sanitizer-leak/Makefile b/src/test/run-make/sanitizer-leak/Makefile index 492e328fab2..f02d948fdc8 100644 --- a/src/test/run-make/sanitizer-leak/Makefile +++ b/src/test/run-make/sanitizer-leak/Makefile @@ -1,11 +1,6 @@ -include ../tools.mk -# NOTE the leak sanitizer only supports x86_64 linux -# Also, this particular sanitizer sometimes doesn't work so we are not going to -# run the binary -ifndef IS_WINDOWS -ifeq ($(shell uname),Linux) -ifeq ($(shell uname -m),x86_64) +ifdef SANITIZER_SUPPORT all: $(RUSTC) -C opt-level=1 -g -Z sanitizer=leak -Z print-link-args leak.rs | grep -q librustc_lsan $(TMPDIR)/leak 2>&1 | grep -q 'detected memory leaks' @@ -13,11 +8,3 @@ else all: endif -else -all: - -endif -else -all: - -endif diff --git a/src/test/run-make/sanitizer-memory/Makefile b/src/test/run-make/sanitizer-memory/Makefile index f8960992a0d..08682e5975e 100644 --- a/src/test/run-make/sanitizer-memory/Makefile +++ b/src/test/run-make/sanitizer-memory/Makefile @@ -1,9 +1,6 @@ -include ../tools.mk -# NOTE the memory sanitizer only supports x86_64 linux -ifndef IS_WINDOWS -ifeq ($(shell uname),Linux) -ifeq ($(shell uname -m),x86_64) +ifdef SANITIZER_SUPPORT all: $(RUSTC) -g -Z sanitizer=memory -Z print-link-args uninit.rs | grep -q librustc_msan $(TMPDIR)/uninit 2>&1 | grep -q use-of-uninitialized-value @@ -11,11 +8,3 @@ else all: endif -else -all: - -endif -else -all: - -endif diff --git a/src/test/run-make/sanitizer-thread/Makefile b/src/test/run-make/sanitizer-thread/Makefile index e32247c4a9b..8bb89a241cb 100644 --- a/src/test/run-make/sanitizer-thread/Makefile +++ b/src/test/run-make/sanitizer-thread/Makefile @@ -1,9 +1,6 @@ -include ../tools.mk -# NOTE the leak sanitizer only supports x86_64 linux -ifndef IS_WINDOWS -ifeq ($(shell uname),Linux) -ifeq ($(shell uname -m),x86_64) +ifdef SANITIZER_SUPPORT all: $(RUSTC) -g -Z sanitizer=thread -Z print-link-args racy.rs | grep -q librustc_tsan $(TMPDIR)/racy 2>&1 | grep -q 'data race' @@ -11,11 +8,3 @@ else all: endif -else -all: - -endif -else -all: - -endif