Skip to content

Commit 317f68a

Browse files
committed
Move sanitizer passes creation from ssa to llvm
1 parent bd816fd commit 317f68a

File tree

4 files changed

+61
-21
lines changed

4 files changed

+61
-21
lines changed

src/librustc_codegen_llvm/back/write.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::LlvmCodegenBackend;
1313
use rustc::hir::def_id::LOCAL_CRATE;
1414
use rustc_codegen_ssa::back::write::{CodegenContext, ModuleConfig, run_assembler};
1515
use rustc_codegen_ssa::traits::*;
16-
use rustc::session::config::{self, OutputType, Passes, Lto, SwitchWithOptPath};
16+
use rustc::session::config::{self, OutputType, Passes, Lto, Sanitizer, SwitchWithOptPath};
1717
use rustc::session::Session;
1818
use rustc::ty::TyCtxt;
1919
use rustc_codegen_ssa::{RLIB_BYTECODE_EXTENSION, ModuleCodegen, CompiledModule};
@@ -323,7 +323,7 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext<LlvmCodegenBackend>,
323323
llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
324324
}
325325

326-
if config.opt_level.is_some() {
326+
if let Some(opt_level) = config.opt_level {
327327
// Create the two optimizing pass managers. These mirror what clang
328328
// does, and are by populated by LLVM's default PassManagerBuilder.
329329
// Each manager has a different set of passes, but they also share
@@ -363,6 +363,28 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext<LlvmCodegenBackend>,
363363
}
364364
}
365365

366+
if let Some(sanitizer) = &config.sanitizer {
367+
match sanitizer {
368+
Sanitizer::Address => {
369+
let recover = false;
370+
extra_passes.push(llvm::LLVMRustCreateAddressSanitizerFunctionPass(
371+
recover));
372+
extra_passes.push(llvm::LLVMRustCreateModuleAddressSanitizerPass(
373+
recover));
374+
}
375+
Sanitizer::Memory => {
376+
let track_origins = 0;
377+
let recover = false;
378+
extra_passes.push(llvm::LLVMRustCreateMemorySanitizerPass(
379+
track_origins, recover));
380+
}
381+
Sanitizer::Thread => {
382+
extra_passes.push(llvm::LLVMRustCreateThreadSanitizerPass());
383+
}
384+
_ => {}
385+
}
386+
}
387+
366388
for pass_name in &cgcx.plugin_passes {
367389
if let Some(pass) = find_pass(pass_name) {
368390
extra_passes.push(pass);
@@ -384,8 +406,7 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext<LlvmCodegenBackend>,
384406
if !config.no_prepopulate_passes {
385407
llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod);
386408
llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod);
387-
let opt_level = config.opt_level.map(|x| to_llvm_opt_settings(x).0)
388-
.unwrap_or(llvm::CodeGenOptLevel::None);
409+
let opt_level = to_llvm_opt_settings(opt_level).0;
389410
let prepare_for_thin_lto = cgcx.lto == Lto::Thin || cgcx.lto == Lto::ThinLocal ||
390411
(cgcx.lto != Lto::Fat && cgcx.opts.cg.linker_plugin_lto.enabled());
391412
with_llvm_pmb(llmod, &config, opt_level, prepare_for_thin_lto, &mut |b| {

src/librustc_codegen_llvm/llvm/ffi.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,6 +1670,11 @@ extern "C" {
16701670

16711671
pub fn LLVMRustPassKind(Pass: &Pass) -> PassKind;
16721672
pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> Option<&'static mut Pass>;
1673+
pub fn LLVMRustCreateAddressSanitizerFunctionPass(Recover: bool) -> &'static mut Pass;
1674+
pub fn LLVMRustCreateModuleAddressSanitizerPass(Recover: bool) -> &'static mut Pass;
1675+
pub fn LLVMRustCreateMemorySanitizerPass(TrackOrigins: c_int,
1676+
Recover: bool) -> &'static mut Pass;
1677+
pub fn LLVMRustCreateThreadSanitizerPass() -> &'static mut Pass;
16731678
pub fn LLVMRustAddPass(PM: &PassManager<'_>, Pass: &'static mut Pass);
16741679
pub fn LLVMRustAddLastExtensionPasses(PMB: &PassManagerBuilder,
16751680
Passes: *const &'static mut Pass,

src/librustc_codegen_ssa/back/write.rs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ pub struct ModuleConfig {
5959
pub pgo_gen: SwitchWithOptPath,
6060
pub pgo_use: Option<PathBuf>,
6161

62+
pub sanitizer: Option<Sanitizer>,
63+
6264
// Flags indicating which outputs to produce.
6365
pub emit_pre_lto_bc: bool,
6466
pub emit_no_opt_bc: bool,
@@ -97,6 +99,8 @@ impl ModuleConfig {
9799
pgo_gen: SwitchWithOptPath::Disabled,
98100
pgo_use: None,
99101

102+
sanitizer: None,
103+
100104
emit_no_opt_bc: false,
101105
emit_pre_lto_bc: false,
102106
emit_bc: false,
@@ -345,29 +349,13 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
345349
let mut metadata_config = ModuleConfig::new(vec![]);
346350
let mut allocator_config = ModuleConfig::new(vec![]);
347351

348-
if let Some(ref sanitizer) = sess.opts.debugging_opts.sanitizer {
349-
match *sanitizer {
350-
Sanitizer::Address => {
351-
modules_config.passes.push("asan".to_owned());
352-
modules_config.passes.push("asan-module".to_owned());
353-
}
354-
Sanitizer::Memory => {
355-
modules_config.passes.push("msan".to_owned())
356-
}
357-
Sanitizer::Thread => {
358-
modules_config.passes.push("tsan".to_owned())
359-
}
360-
_ => {}
361-
}
362-
}
363-
364352
if sess.opts.debugging_opts.profile {
365353
modules_config.passes.push("insert-gcov-profiling".to_owned())
366354
}
367355

368356
modules_config.pgo_gen = sess.opts.cg.profile_generate.clone();
369357
modules_config.pgo_use = sess.opts.cg.profile_use.clone();
370-
358+
modules_config.sanitizer = sess.opts.debugging_opts.sanitizer.clone();
371359
modules_config.opt_level = Some(sess.opts.optimize);
372360
modules_config.opt_size = Some(sess.opts.optimize);
373361

src/rustllvm/PassWrapper.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
1919
#include "llvm/Transforms/IPO/AlwaysInliner.h"
2020
#include "llvm/Transforms/IPO/FunctionImport.h"
21+
#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
22+
#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
23+
#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
2124
#include "llvm/Transforms/Utils/FunctionImportUtils.h"
2225
#include "llvm/LTO/LTO.h"
2326

@@ -76,6 +79,29 @@ extern "C" LLVMPassRef LLVMRustFindAndCreatePass(const char *PassName) {
7679
return nullptr;
7780
}
7881

82+
extern "C" LLVMPassRef LLVMRustCreateAddressSanitizerFunctionPass(bool Recover) {
83+
const bool CompileKernel = false;
84+
85+
return wrap(createAddressSanitizerFunctionPass(CompileKernel, Recover));
86+
}
87+
88+
extern "C" LLVMPassRef LLVMRustCreateModuleAddressSanitizerPass(bool Recover) {
89+
const bool CompileKernel = false;
90+
91+
return wrap(createModuleAddressSanitizerLegacyPassPass(CompileKernel, Recover));
92+
}
93+
94+
extern "C" LLVMPassRef LLVMRustCreateMemorySanitizerPass(int TrackOrigins, bool Recover) {
95+
const bool CompileKernel = false;
96+
97+
return wrap(createMemorySanitizerLegacyPassPass(
98+
MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel}));
99+
}
100+
101+
extern "C" LLVMPassRef LLVMRustCreateThreadSanitizerPass() {
102+
return wrap(createThreadSanitizerLegacyPassPass());
103+
}
104+
79105
extern "C" LLVMRustPassKind LLVMRustPassKind(LLVMPassRef RustPass) {
80106
assert(RustPass);
81107
Pass *Pass = unwrap(RustPass);

0 commit comments

Comments
 (0)