diff options
| -rw-r--r-- | src/librustc_codegen_llvm/back/write.rs | 29 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/llvm/ffi.rs | 5 | ||||
| -rw-r--r-- | src/librustc_codegen_ssa/back/write.rs | 22 | ||||
| -rw-r--r-- | src/rustllvm/PassWrapper.cpp | 26 |
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); |
