# version that we're using, 8.2, cannot compile LLVM for OSX 10.7.
- env: >
RUST_CHECK_TARGET=check
- RUST_CONFIGURE_ARGS=--build=x86_64-apple-darwin
+ RUST_CONFIGURE_ARGS="--build=x86_64-apple-darwin --enable-sanitizers"
SRC=.
RUSTC_RETRY_LINKER_ON_SEGFAULT=1
SCCACHE_ERROR_LOG=/tmp/sccache.log
install: *osx_install_sccache
- env: >
RUST_CHECK_TARGET=dist
- RUST_CONFIGURE_ARGS="--target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-extended"
+ RUST_CONFIGURE_ARGS="--target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-extended --enable-sanitizers"
SRC=.
DEPLOY=1
RUSTC_RETRY_LINKER_ON_SEGFAULT=1
if target.contains("musl") && !target.contains("mips") {
copy_musl_third_party_objects(build, target, &libdir);
}
+
+ if build.config.sanitizers && compiler.stage != 0 && target == "x86_64-apple-darwin" {
+ // The sanitizers are only built in stage1 or above, so the dylibs will
+ // be missing in stage0 and causes panic. See the `std()` function above
+ // for reason why the sanitizers are not built in stage0.
+ copy_apple_sanitizer_dylibs(&build.native_dir(target), "osx", &libdir);
+ }
}
/// Copies the crt(1,i,n).o startup objects
}
}
+fn copy_apple_sanitizer_dylibs(native_dir: &Path, platform: &str, into: &Path) {
+ for &sanitizer in &["asan", "tsan"] {
+ let filename = format!("libclang_rt.{}_{}_dynamic.dylib", sanitizer, platform);
+ let mut src_path = native_dir.join(sanitizer);
+ src_path.push("build");
+ src_path.push("lib");
+ src_path.push("darwin");
+ src_path.push(&filename);
+ copy(&src_path, &into.join(filename));
+ }
+}
+
/// Build and prepare startup objects like rsbegin.o and rsend.o
///
/// These are primarily used on Windows right now for linking executables/dlls.
let out_dir = env::var_os("RUSTBUILD_NATIVE_DIR").unwrap_or(env::var_os("OUT_DIR").unwrap());
let out_dir = PathBuf::from(out_dir).join(out_name);
t!(create_dir_racy(&out_dir));
- println!("cargo:rustc-link-lib=static={}", link_name);
+ if link_name.contains('=') {
+ println!("cargo:rustc-link-lib={}", link_name);
+ } else {
+ println!("cargo:rustc-link-lib=static={}", link_name);
+ }
println!("cargo:rustc-link-search=native={}", out_dir.join(search_subdir).display());
let timestamp = out_dir.join("rustbuild.timestamp");
}
}
+pub fn sanitizer_lib_boilerplate(sanitizer_name: &str) -> Result<NativeLibBoilerplate, ()> {
+ let (link_name, search_path) = match &*env::var("TARGET").unwrap() {
+ "x86_64-unknown-linux-gnu" => (
+ format!("clang_rt.{}-x86_64", sanitizer_name),
+ "build/lib/linux",
+ ),
+ "x86_64-apple-darwin" => (
+ format!("dylib=clang_rt.{}_osx_dynamic", sanitizer_name),
+ "build/lib/darwin",
+ ),
+ _ => return Err(()),
+ };
+ native_lib_boilerplate("compiler-rt", sanitizer_name, &link_name, search_path)
+}
+
fn dir_up_to_date(src: &Path, threshold: &FileTime) -> bool {
t!(fs::read_dir(src)).map(|e| t!(e)).all(|e| {
let meta = t!(e.metadata());
pub uint_type: UintTy,
}
-#[derive(Clone, Hash)]
+#[derive(Clone, Hash, Debug)]
pub enum Sanitizer {
Address,
Leak,
extern crate cmake;
use std::env;
-use build_helper::native_lib_boilerplate;
+use build_helper::sanitizer_lib_boilerplate;
use cmake::Config;
fn main() {
if let Some(llvm_config) = env::var_os("LLVM_CONFIG") {
- let native = match native_lib_boilerplate("compiler-rt", "asan", "clang_rt.asan-x86_64",
- "build/lib/linux") {
+ let native = match sanitizer_lib_boilerplate("asan") {
Ok(native) => native,
_ => return,
};
extern crate cmake;
use std::env;
-use build_helper::native_lib_boilerplate;
+use build_helper::sanitizer_lib_boilerplate;
use cmake::Config;
fn main() {
if let Some(llvm_config) = env::var_os("LLVM_CONFIG") {
- let native = match native_lib_boilerplate("compiler-rt", "lsan", "clang_rt.lsan-x86_64",
- "build/lib/linux") {
+ let native = match sanitizer_lib_boilerplate("lsan") {
Ok(native) => native,
_ => return,
};
fn inject_sanitizer_runtime(&mut self) {
if let Some(ref sanitizer) = self.sess.opts.debugging_opts.sanitizer {
- // Sanitizers can only be used with x86_64 Linux executables linked
- // to `std`
- if self.sess.target.target.llvm_target != "x86_64-unknown-linux-gnu" {
- self.sess.err(&format!("Sanitizers only work with the \
- `x86_64-unknown-linux-gnu` target."));
+ // Sanitizers can only be used on some tested platforms with
+ // executables linked to `std`
+ const ASAN_SUPPORTED_TARGETS: &[&str] = &["x86_64-unknown-linux-gnu",
+ "x86_64-apple-darwin"];
+ const TSAN_SUPPORTED_TARGETS: &[&str] = &["x86_64-unknown-linux-gnu",
+ "x86_64-apple-darwin"];
+ const LSAN_SUPPORTED_TARGETS: &[&str] = &["x86_64-unknown-linux-gnu"];
+ const MSAN_SUPPORTED_TARGETS: &[&str] = &["x86_64-unknown-linux-gnu"];
+
+ let supported_targets = match *sanitizer {
+ Sanitizer::Address => ASAN_SUPPORTED_TARGETS,
+ Sanitizer::Thread => TSAN_SUPPORTED_TARGETS,
+ Sanitizer::Leak => LSAN_SUPPORTED_TARGETS,
+ Sanitizer::Memory => MSAN_SUPPORTED_TARGETS,
+ };
+ if !supported_targets.contains(&&*self.sess.target.target.llvm_target) {
+ self.sess.err(&format!("{:?}Sanitizer only works with the `{}` target",
+ sanitizer,
+ supported_targets.join("` or `")
+ ));
return
}
extern crate cmake;
use std::env;
-use build_helper::native_lib_boilerplate;
+use build_helper::sanitizer_lib_boilerplate;
use cmake::Config;
fn main() {
if let Some(llvm_config) = env::var_os("LLVM_CONFIG") {
- let native = match native_lib_boilerplate("compiler-rt", "msan", "clang_rt.msan-x86_64",
- "build/lib/linux") {
+ let native = match sanitizer_lib_boilerplate("msan") {
Ok(native) => native,
_ => return,
};
extern crate cmake;
use std::env;
-use build_helper::native_lib_boilerplate;
+use build_helper::sanitizer_lib_boilerplate;
use cmake::Config;
fn main() {
if let Some(llvm_config) = env::var_os("LLVM_CONFIG") {
- let native = match native_lib_boilerplate("compiler-rt", "tsan", "clang_rt.tsan-x86_64",
- "build/lib/linux") {
+ let native = match sanitizer_lib_boilerplate("tsan") {
Ok(native) => native,
_ => return,
};
std_unicode = { path = "../libstd_unicode" }
unwind = { path = "../libunwind" }
+[target.x86_64-apple-darwin.dependencies]
+rustc_asan = { path = "../librustc_asan" }
+rustc_tsan = { path = "../librustc_tsan" }
+
[target.x86_64-unknown-linux-gnu.dependencies]
rustc_asan = { path = "../librustc_asan" }
rustc_lsan = { path = "../librustc_lsan" }
-include ../tools.mk
-# NOTE the address sanitizer only supports x86_64 linux
-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
+# NOTE the address sanitizer only supports x86_64 linux and macOS
+
+ifeq ($(TARGET),x86_64-apple-darwin)
+ASAN_SUPPORT=$(SANITIZER_SUPPORT)
+EXTRA_RUSTFLAG=-C rpath
else
-all:
+ifeq ($(TARGET),x86_64-unknown-linux-gnu)
+ASAN_SUPPORT=$(SANITIZER_SUPPORT)
+EXTRA_RUSTFLAG=
+endif
+endif
+all:
+ifeq ($(ASAN_SUPPORT),1)
+ $(RUSTC) -g -Z sanitizer=address -Z print-link-args $(EXTRA_RUSTFLAG) overflow.rs | grep -q librustc_asan
+ $(TMPDIR)/overflow 2>&1 | grep -q stack-buffer-overflow
endif
-include ../tools.mk
all:
- $(RUSTC) -Z sanitizer=leak --target i686-unknown-linux-gnu hello.rs 2>&1 | grep -q 'Sanitizers only work with the `x86_64-unknown-linux-gnu` target'
+ $(RUSTC) -Z sanitizer=leak --target i686-unknown-linux-gnu hello.rs 2>&1 | grep -q 'LeakSanitizer only works with the `x86_64-unknown-linux-gnu` target'
-include ../tools.mk
-ifdef SANITIZER_SUPPORT
all:
+ifeq ($(TARGET),x86_64-unknown-linux-gnu)
+ifdef SANITIZER_SUPPORT
$(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'
-else
-all:
-
endif
+endif
+
-include ../tools.mk
-ifdef SANITIZER_SUPPORT
all:
+ifeq ($(TARGET),x86_64-unknown-linux-gnu)
+ifdef SANITIZER_SUPPORT
$(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
-else
-all:
-
endif
+endif
+