about summary refs log tree commit diff
path: root/src/bootstrap
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2017-04-18 04:22:16 +0800
committerkennytm <kennytm@gmail.com>2017-04-25 10:31:01 +0800
commit00dff0aa59ce2d71957ca16a4444c303910686a3 (patch)
tree852ffe5c231746516dfd968e7e5272840d09a92d /src/bootstrap
parent93d57d64b86d574efa35e2fb354d8dc92153b8a7 (diff)
downloadrust-00dff0aa59ce2d71957ca16a4444c303910686a3.tar.gz
rust-00dff0aa59ce2d71957ca16a4444c303910686a3.zip
Support AddressSanitizer and ThreadSanitizer on x86_64-apple-darwin.
ASan and TSan are supported on macOS, and this commit enables their
support.

The sanitizers are always built as *.dylib on Apple platforms, so they
cannot be statically linked into the corresponding `rustc_?san.rlib`. The
dylibs are directly copied to `lib/rustlib/x86_64-apple-darwin/lib/`
instead.

Note, although Xcode also ships with their own copies of ASan/TSan dylibs,
we cannot use them due to version mismatch.

There is a caveat: the sanitizer libraries are linked as @rpath, so the
user needs to additionally pass `-C rpath`:

    rustc -Z sanitizer=address -C rpath file.rs
                               ^~~~~~~~

Otherwise there will be a runtime error:

    dyld: Library not loaded: @rpath/libclang_rt.asan_osx_dynamic.dylib
      Referenced from: /path/to/executable
      Reason: image not found
    Abort trap: 6

The next commit includes a temporary change in compiler to force the linker
to emit a usable @rpath.
Diffstat (limited to 'src/bootstrap')
-rw-r--r--src/bootstrap/compile.rs19
1 files changed, 19 insertions, 0 deletions
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index cd87b27d4f1..6f1de62d07e 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -115,6 +115,13 @@ pub fn std_link(build: &Build,
     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
@@ -126,6 +133,18 @@ fn copy_musl_third_party_objects(build: &Build, target: &str, into: &Path) {
     }
 }
 
+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.