Rollup merge of #54681 - alexcrichton:san-names, r=kennytm

Rename sanitizer runtime libraries on OSX

Currently we ship sanitizer libraries as they're built, but these names
unfortunately conflict with the names of the sanitizer libraries
installed on the system. If a crate, for example, links in C code that
wants to use the system sanitizer and the Rust code doesn't use
sanitizers at all, then using `cargo` may accidentally pull in the
Rust-installed sanitizer library due to a conflict in names.

This change is intended to be entirely transparent for Rust users of
sanitizers, it should only hopefully improve our story with other users!

Closes #54134
This commit is contained in:
kennytm 2018-10-01 16:13:04 +08:00 committed by GitHub
commit 7014afcfa1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 4 deletions

View File

@ -249,7 +249,7 @@ fn run(self, builder: &Builder) {
fn copy_apple_sanitizer_dylibs(builder: &Builder, native_dir: &Path, platform: &str, into: &Path) {
for &sanitizer in &["asan", "tsan"] {
let filename = format!("libclang_rt.{}_{}_dynamic.dylib", sanitizer, platform);
let filename = format!("lib__rustc__clang_rt.{}_{}_dynamic.dylib", sanitizer, platform);
let mut src_path = native_dir.join(sanitizer);
src_path.push("build");
src_path.push("lib");

View File

@ -178,6 +178,37 @@ pub struct NativeLibBoilerplate {
pub out_dir: PathBuf,
}
impl NativeLibBoilerplate {
/// On OSX we don't want to ship the exact filename that compiler-rt builds.
/// This conflicts with the system and ours is likely a wildly different
/// version, so they can't be substituted.
///
/// As a result, we rename it here but we need to also use
/// `install_name_tool` on OSX to rename the commands listed inside of it to
/// ensure it's linked against correctly.
pub fn fixup_sanitizer_lib_name(&self, sanitizer_name: &str) {
if env::var("TARGET").unwrap() != "x86_64-apple-darwin" {
return
}
let dir = self.out_dir.join("build/lib/darwin");
let name = format!("clang_rt.{}_osx_dynamic", sanitizer_name);
let src = dir.join(&format!("lib{}.dylib", name));
let new_name = format!("lib__rustc__{}.dylib", name);
let dst = dir.join(&new_name);
println!("{} => {}", src.display(), dst.display());
fs::rename(&src, &dst).unwrap();
let status = Command::new("install_name_tool")
.arg("-id")
.arg(format!("@rpath/{}", new_name))
.arg(&dst)
.status()
.expect("failed to execute `install_name_tool`");
assert!(status.success());
}
}
impl Drop for NativeLibBoilerplate {
fn drop(&mut self) {
if !thread::panicking() {
@ -229,7 +260,7 @@ pub fn native_lib_boilerplate(
pub fn sanitizer_lib_boilerplate(sanitizer_name: &str)
-> Result<(NativeLibBoilerplate, String), ()>
{
let (link_name, search_path, dynamic) = match &*env::var("TARGET").unwrap() {
let (link_name, search_path, apple) = match &*env::var("TARGET").unwrap() {
"x86_64-unknown-linux-gnu" => (
format!("clang_rt.{}-x86_64", sanitizer_name),
"build/lib/linux",
@ -242,8 +273,8 @@ pub fn sanitizer_lib_boilerplate(sanitizer_name: &str)
),
_ => return Err(()),
};
let to_link = if dynamic {
format!("dylib={}", link_name)
let to_link = if apple {
format!("dylib=__rustc__{}", link_name)
} else {
format!("static={}", link_name)
};

View File

@ -31,6 +31,7 @@ fn main() {
.out_dir(&native.out_dir)
.build_target(&target)
.build();
native.fixup_sanitizer_lib_name("asan");
}
println!("cargo:rerun-if-env-changed=LLVM_CONFIG");
}

View File

@ -31,6 +31,7 @@ fn main() {
.out_dir(&native.out_dir)
.build_target(&target)
.build();
native.fixup_sanitizer_lib_name("tsan");
}
println!("cargo:rerun-if-env-changed=LLVM_CONFIG");
}