diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 826c09cd948f..54f722f394c9 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1070,9 +1070,12 @@ fn add_sanitizer_libraries(sess: &Session, crate_type: CrateType, linker: &mut d // both executables and dynamic shared objects. Everywhere else the runtimes // are currently distributed as static liraries which should be linked to // executables only. + // On Windows there are both static and dynamic runtimes available. let needs_runtime = match crate_type { CrateType::Executable => true, - CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro => sess.target.is_like_osx, + CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro => { + sess.target.is_like_osx || sess.target.is_like_windows + } CrateType::Rlib | CrateType::Staticlib => false, }; @@ -1082,23 +1085,28 @@ fn add_sanitizer_libraries(sess: &Session, crate_type: CrateType, linker: &mut d let sanitizer = sess.opts.debugging_opts.sanitizer; if sanitizer.contains(SanitizerSet::ADDRESS) { - link_sanitizer_runtime(sess, linker, "asan"); + link_sanitizer_runtime(sess, crate_type, linker, "asan"); } if sanitizer.contains(SanitizerSet::LEAK) { - link_sanitizer_runtime(sess, linker, "lsan"); + link_sanitizer_runtime(sess, crate_type, linker, "lsan"); } if sanitizer.contains(SanitizerSet::MEMORY) { - link_sanitizer_runtime(sess, linker, "msan"); + link_sanitizer_runtime(sess, crate_type, linker, "msan"); } if sanitizer.contains(SanitizerSet::THREAD) { - link_sanitizer_runtime(sess, linker, "tsan"); + link_sanitizer_runtime(sess, crate_type, linker, "tsan"); } if sanitizer.contains(SanitizerSet::HWADDRESS) { - link_sanitizer_runtime(sess, linker, "hwasan"); + link_sanitizer_runtime(sess, crate_type, linker, "hwasan"); } } -fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) { +fn link_sanitizer_runtime( + sess: &Session, + crate_type: CrateType, + linker: &mut dyn Linker, + name: &str, +) { fn find_sanitizer_runtime(sess: &Session, filename: &String) -> PathBuf { let session_tlib = filesearch::make_target_lib_path(&sess.sysroot, sess.opts.target_triple.triple()); @@ -1119,7 +1127,26 @@ fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) { .map(|channel| format!("-{}", channel)) .unwrap_or_default(); - if sess.target.is_like_osx { + if sess.target.is_like_windows { + let arch = &sess.target.arch; + if sess.crt_static(Some(crate_type)) { + if crate_type == CrateType::Executable { + linker.link_whole_rlib(&PathBuf::from(format!("clang_rt.{}-{}.lib", name, arch))); + } else { + linker.link_whole_rlib(&PathBuf::from(format!( + "clang_rt.{}_dll_thunk-{}.lib", + name, arch + ))); + } + } else { + linker + .link_whole_rlib(&PathBuf::from(format!("clang_rt.{}_dynamic-{}.lib", name, arch))); + linker.link_whole_rlib(&PathBuf::from(format!( + "clang_rt.{}_dynamic_runtime_thunk-{}.lib", + name, arch + ))); + } + } else if sess.target.is_like_osx { // On Apple platforms, the sanitizer is always built as a dylib, and // LLVM will link to `@rpath/*.dylib`, so we need to specify an // rpath to the library as well (the rpath should be absolute, see diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index d6f4a3ae4f12..d2a71e9b4f09 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1397,7 +1397,10 @@ fn validate_commandline_args_with_session_available(sess: &Session) { } // Cannot enable crt-static with sanitizers on Linux - if sess.crt_static(None) && !sess.opts.debugging_opts.sanitizer.is_empty() { + if sess.crt_static(None) + && !sess.opts.debugging_opts.sanitizer.is_empty() + && !sess.target.is_like_windows + { sess.err( "Sanitizer is incompatible with statically linked libc, \ disable it using `-C target-feature=-crt-static`", diff --git a/compiler/rustc_target/src/spec/x86_64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/x86_64_pc_windows_msvc.rs index 72bbb10323c3..e2a5008cd3ae 100644 --- a/compiler/rustc_target/src/spec/x86_64_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/x86_64_pc_windows_msvc.rs @@ -1,10 +1,11 @@ -use crate::spec::Target; +use crate::spec::{SanitizerSet, Target}; pub fn target() -> Target { let mut base = super::windows_msvc_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.has_elf_tls = true; + base.supported_sanitizers = SanitizerSet::ADDRESS; Target { llvm_target: "x86_64-pc-windows-msvc".to_string(),