about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_codegen_llvm/back/write.rs29
-rw-r--r--src/librustc_codegen_llvm/llvm/ffi.rs5
-rw-r--r--src/librustc_codegen_ssa/back/write.rs22
-rw-r--r--src/rustllvm/PassWrapper.cpp26
4 files changed, 61 insertions, 21 deletions
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index fa14ce7b03c..89728245eea 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -13,7 +13,7 @@ use crate::LlvmCodegenBackend;
 use rustc::hir::def_id::LOCAL_CRATE;
 use rustc_codegen_ssa::back::write::{CodegenContext, ModuleConfig, run_assembler};
 use rustc_codegen_ssa::traits::*;
-use rustc::session::config::{self, OutputType, Passes, Lto, SwitchWithOptPath};
+use rustc::session::config::{self, OutputType, Passes, Lto, Sanitizer, SwitchWithOptPath};
 use rustc::session::Session;
 use rustc::ty::TyCtxt;
 use rustc_codegen_ssa::{RLIB_BYTECODE_EXTENSION, ModuleCodegen, CompiledModule};
@@ -323,7 +323,7 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext<LlvmCodegenBackend>,
         llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
     }
 
-    if config.opt_level.is_some() {
+    if let Some(opt_level) = config.opt_level {
         // Create the two optimizing pass managers. These mirror what clang
         // does, and are by populated by LLVM's default PassManagerBuilder.
         // Each manager has a different set of passes, but they also share
@@ -363,6 +363,28 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext<LlvmCodegenBackend>,
                 }
             }
 
+            if let Some(sanitizer) = &config.sanitizer {
+                match sanitizer {
+                    Sanitizer::Address => {
+                        let recover = false;
+                        extra_passes.push(llvm::LLVMRustCreateAddressSanitizerFunctionPass(
+                                recover));
+                        extra_passes.push(llvm::LLVMRustCreateModuleAddressSanitizerPass(
+                                recover));
+                    }
+                    Sanitizer::Memory => {
+                        let track_origins = 0;
+                        let recover = false;
+                        extra_passes.push(llvm::LLVMRustCreateMemorySanitizerPass(
+                                track_origins, recover));
+                    }
+                    Sanitizer::Thread => {
+                        extra_passes.push(llvm::LLVMRustCreateThreadSanitizerPass());
+                    }
+                    _ => {}
+                }
+            }
+
             for pass_name in &cgcx.plugin_passes {
                 if let Some(pass) = find_pass(pass_name) {
                     extra_passes.push(pass);
@@ -384,8 +406,7 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext<LlvmCodegenBackend>,
             if !config.no_prepopulate_passes {
                 llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod);
                 llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod);
-                let opt_level = config.opt_level.map(|x| to_llvm_opt_settings(x).0)
-                    .unwrap_or(llvm::CodeGenOptLevel::None);
+                let opt_level = to_llvm_opt_settings(opt_level).0;
                 let prepare_for_thin_lto = cgcx.lto == Lto::Thin || cgcx.lto == Lto::ThinLocal ||
                     (cgcx.lto != Lto::Fat && cgcx.opts.cg.linker_plugin_lto.enabled());
                 with_llvm_pmb(llmod, &config, opt_level, prepare_for_thin_lto, &mut |b| {
diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs
index 548e8c732a7..241ca695e5f 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/src/librustc_codegen_llvm/llvm/ffi.rs
@@ -1670,6 +1670,11 @@ extern "C" {
 
     pub fn LLVMRustPassKind(Pass: &Pass) -> PassKind;
     pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> Option<&'static mut Pass>;
+    pub fn LLVMRustCreateAddressSanitizerFunctionPass(Recover: bool) -> &'static mut Pass;
+    pub fn LLVMRustCreateModuleAddressSanitizerPass(Recover: bool) -> &'static mut Pass;
+    pub fn LLVMRustCreateMemorySanitizerPass(TrackOrigins: c_int,
+                                             Recover: bool) -> &'static mut Pass;
+    pub fn LLVMRustCreateThreadSanitizerPass() -> &'static mut Pass;
     pub fn LLVMRustAddPass(PM: &PassManager<'_>, Pass: &'static mut Pass);
     pub fn LLVMRustAddLastExtensionPasses(PMB: &PassManagerBuilder,
                                           Passes: *const &'static mut Pass,
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index f35a31d59fe..e11a1ab6ee8 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -59,6 +59,8 @@ pub struct ModuleConfig {
     pub pgo_gen: SwitchWithOptPath,
     pub pgo_use: Option<PathBuf>,
 
+    pub sanitizer: Option<Sanitizer>,
+
     // Flags indicating which outputs to produce.
     pub emit_pre_lto_bc: bool,
     pub emit_no_opt_bc: bool,
@@ -97,6 +99,8 @@ impl ModuleConfig {
             pgo_gen: SwitchWithOptPath::Disabled,
             pgo_use: None,
 
+            sanitizer: None,
+
             emit_no_opt_bc: false,
             emit_pre_lto_bc: false,
             emit_bc: false,
@@ -345,29 +349,13 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
     let mut metadata_config = ModuleConfig::new(vec![]);
     let mut allocator_config = ModuleConfig::new(vec![]);
 
-    if let Some(ref sanitizer) = sess.opts.debugging_opts.sanitizer {
-        match *sanitizer {
-            Sanitizer::Address => {
-                modules_config.passes.push("asan".to_owned());
-                modules_config.passes.push("asan-module".to_owned());
-            }
-            Sanitizer::Memory => {
-                modules_config.passes.push("msan".to_owned())
-            }
-            Sanitizer::Thread => {
-                modules_config.passes.push("tsan".to_owned())
-            }
-            _ => {}
-        }
-    }
-
     if sess.opts.debugging_opts.profile {
         modules_config.passes.push("insert-gcov-profiling".to_owned())
     }
 
     modules_config.pgo_gen = sess.opts.cg.profile_generate.clone();
     modules_config.pgo_use = sess.opts.cg.profile_use.clone();
-
+    modules_config.sanitizer = sess.opts.debugging_opts.sanitizer.clone();
     modules_config.opt_level = Some(sess.opts.optimize);
     modules_config.opt_size = Some(sess.opts.optimize);
 
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index 3451346869d..48cdb6beccc 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -18,6 +18,9 @@
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
 #include "llvm/Transforms/IPO/AlwaysInliner.h"
 #include "llvm/Transforms/IPO/FunctionImport.h"
+#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
+#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
+#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
 #include "llvm/Transforms/Utils/FunctionImportUtils.h"
 #include "llvm/LTO/LTO.h"
 
@@ -76,6 +79,29 @@ extern "C" LLVMPassRef LLVMRustFindAndCreatePass(const char *PassName) {
   return nullptr;
 }
 
+extern "C" LLVMPassRef LLVMRustCreateAddressSanitizerFunctionPass(bool Recover) {
+  const bool CompileKernel = false;
+
+  return wrap(createAddressSanitizerFunctionPass(CompileKernel, Recover));
+}
+
+extern "C" LLVMPassRef LLVMRustCreateModuleAddressSanitizerPass(bool Recover) {
+  const bool CompileKernel = false;
+
+  return wrap(createModuleAddressSanitizerLegacyPassPass(CompileKernel, Recover));
+}
+
+extern "C" LLVMPassRef LLVMRustCreateMemorySanitizerPass(int TrackOrigins, bool Recover) {
+  const bool CompileKernel = false;
+
+  return wrap(createMemorySanitizerLegacyPassPass(
+      MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel}));
+}
+
+extern "C" LLVMPassRef LLVMRustCreateThreadSanitizerPass() {
+  return wrap(createThreadSanitizerLegacyPassPass());
+}
+
 extern "C" LLVMRustPassKind LLVMRustPassKind(LLVMPassRef RustPass) {
   assert(RustPass);
   Pass *Pass = unwrap(RustPass);