Skip to content

Commit 9af6aa3

Browse files
author
Jorge Aparicio
committed
sanitizer support
1 parent c14f87e commit 9af6aa3

File tree

45 files changed

+810
-6
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+810
-6
lines changed

src/Cargo.lock

Lines changed: 40 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/bootstrap/check.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,10 @@ pub fn krate(build: &Build,
332332
krate: Option<&str>) {
333333
let (name, path, features, root) = match mode {
334334
Mode::Libstd => {
335-
("libstd", "src/rustc/std_shim", build.std_features(), "std_shim")
335+
("libstd",
336+
"src/rustc/std_shim",
337+
build.std_features(),
338+
"std_shim")
336339
}
337340
Mode::Libtest => {
338341
("libtest", "src/rustc/test_shim", String::new(), "test_shim")

src/bootstrap/compile.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,18 @@ pub fn std(build: &Build, target: &str, compiler: &Compiler) {
5151
if compiler.stage == 0 && build.local_rebuild && !build.config.use_jemalloc {
5252
features.push_str(" force_alloc_system");
5353
}
54+
55+
if compiler.stage != 0 && !build.system_llvm(target) {
56+
// This variable is used by the sanitizer runtime crates, e.g.
57+
// rustc_lsan, to build the sanitizer runtime from C code
58+
// When this variable is missing, those crates won't compile the C code,
59+
// so we don't set this variable during stage0 where llvm-config is
60+
// missing
61+
// We also don't build the runtimes when compiling against system llvm
62+
// because some distributions ship llvm packages that have a directory
63+
// layout different from the one that the runtime's build system expects
64+
cargo.env("LLVM_CONFIG", build.llvm_config(target));
65+
}
5466
cargo.arg("--features").arg(features)
5567
.arg("--manifest-path")
5668
.arg(build.src.join("src/rustc/std_shim/Cargo.toml"));

src/bootstrap/config.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ pub struct Config {
108108
/// Per-target configuration stored in the global configuration structure.
109109
#[derive(Default)]
110110
pub struct Target {
111+
// `true` if compiling against system LLVM or a pre-built LLVM
112+
pub system_llvm: bool,
111113
pub llvm_config: Option<PathBuf>,
112114
pub jemalloc: Option<PathBuf>,
113115
pub cc: Option<PathBuf>,
@@ -512,6 +514,7 @@ impl Config {
512514
.or_insert(Target::default());
513515
let root = parse_configure_path(value);
514516
target.llvm_config = Some(push_exe_path(root, &["bin", "llvm-config"]));
517+
target.system_llvm = true;
515518
}
516519
"CFG_JEMALLOC_ROOT" if value.len() > 0 => {
517520
let target = self.target_config.entry(self.build.clone())

src/bootstrap/lib.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,8 @@ impl Build {
599599
/// Get the space-separated set of activated features for the standard
600600
/// library.
601601
fn std_features(&self) -> String {
602-
let mut features = "panic-unwind".to_string();
602+
let mut features = "panic-unwind asan lsan msan tsan".to_string();
603+
603604
if self.config.debug_jemalloc {
604605
features.push_str(" debug-jemalloc");
605606
}
@@ -716,6 +717,10 @@ impl Build {
716717
}
717718
}
718719

720+
fn system_llvm(&self, target: &str) -> bool {
721+
self.config.target_config.get(target).map(|t| t.system_llvm).unwrap_or(false)
722+
}
723+
719724
/// Returns the path to `FileCheck` binary for the specified target
720725
fn llvm_filecheck(&self, target: &str) -> PathBuf {
721726
let target_config = self.config.target_config.get(target);

src/librustc/middle/cstore.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ pub trait CrateStore<'tcx> {
229229
fn is_allocator(&self, cnum: CrateNum) -> bool;
230230
fn is_panic_runtime(&self, cnum: CrateNum) -> bool;
231231
fn is_compiler_builtins(&self, cnum: CrateNum) -> bool;
232+
fn is_sanitizer_runtime(&self, cnum: CrateNum) -> bool;
232233
fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy;
233234
fn extern_crate(&self, cnum: CrateNum) -> Option<ExternCrate>;
234235
/// The name of the crate as it is referred to in source code of the current
@@ -390,6 +391,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
390391
fn is_allocator(&self, cnum: CrateNum) -> bool { bug!("is_allocator") }
391392
fn is_panic_runtime(&self, cnum: CrateNum) -> bool { bug!("is_panic_runtime") }
392393
fn is_compiler_builtins(&self, cnum: CrateNum) -> bool { bug!("is_compiler_builtins") }
394+
fn is_sanitizer_runtime(&self, cnum: CrateNum) -> bool { bug!("is_sanitizer_runtime") }
393395
fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy {
394396
bug!("panic_strategy")
395397
}

src/librustc/session/config.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ pub struct Config {
5151
pub uint_type: UintTy,
5252
}
5353

54+
#[derive(Clone)]
55+
pub enum Sanitizer {
56+
Address,
57+
Leak,
58+
Memory,
59+
Thread,
60+
}
61+
5462
#[derive(Clone, Copy, PartialEq, Hash)]
5563
pub enum OptLevel {
5664
No, // -O0
@@ -626,11 +634,13 @@ macro_rules! options {
626634
Some("a number");
627635
pub const parse_panic_strategy: Option<&'static str> =
628636
Some("either `panic` or `abort`");
637+
pub const parse_sanitizer: Option<&'static str> =
638+
Some("one of: `address`, `leak`, `memory` or `thread`");
629639
}
630640

631641
#[allow(dead_code)]
632642
mod $mod_set {
633-
use super::{$struct_name, Passes, SomePasses, AllPasses};
643+
use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer};
634644
use rustc_back::PanicStrategy;
635645

636646
$(
@@ -751,6 +761,17 @@ macro_rules! options {
751761
}
752762
true
753763
}
764+
765+
fn parse_sanitizer(slote: &mut Option<Sanitizer>, v: Option<&str>) -> bool {
766+
match v {
767+
Some("address") => *slote = Some(Sanitizer::Address),
768+
Some("leak") => *slote = Some(Sanitizer::Leak),
769+
Some("memory") => *slote = Some(Sanitizer::Memory),
770+
Some("thread") => *slote = Some(Sanitizer::Thread),
771+
_ => return false,
772+
}
773+
true
774+
}
754775
}
755776
) }
756777

@@ -949,6 +970,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
949970
"encode MIR of all functions into the crate metadata"),
950971
osx_rpath_install_name: bool = (false, parse_bool, [TRACKED],
951972
"pass `-install_name @rpath/...` to the OSX linker"),
973+
sanitizer: Option<Sanitizer> = (None, parse_sanitizer, [UNTRACKED],
974+
"Use a sanitizer"),
952975
}
953976

954977
pub fn default_lib_output() -> CrateType {

src/librustc_asan/Cargo.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[package]
2+
authors = ["The Rust Project Developers"]
3+
build = "build.rs"
4+
name = "rustc_asan"
5+
version = "0.0.0"
6+
7+
[lib]
8+
name = "rustc_asan"
9+
path = "lib.rs"
10+
11+
[build-dependencies]
12+
cmake = "0.1.18"
13+
14+
[dependencies]
15+
alloc_system = { path = "../liballoc_system" }
16+
core = { path = "../libcore" }

src/librustc_asan/build.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
extern crate cmake;
12+
13+
use std::path::PathBuf;
14+
use std::env;
15+
16+
use cmake::Config;
17+
18+
fn main() {
19+
if let Some(llvm_config) = env::var_os("LLVM_CONFIG") {
20+
let dst = Config::new("../compiler-rt")
21+
.define("COMPILER_RT_BUILD_SANITIZERS", "ON")
22+
.define("COMPILER_RT_BUILD_BUILTINS", "OFF")
23+
.define("COMPILER_RT_BUILD_XRAY", "OFF")
24+
.define("LLVM_CONFIG_PATH", llvm_config)
25+
.build_target("asan")
26+
.build();
27+
28+
println!("cargo:rustc-link-search=native={}",
29+
dst.join("build/lib/linux").display());
30+
println!("cargo:rustc-link-lib=static=clang_rt.asan-x86_64");
31+
32+
let src_dir = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap());
33+
let mut stack = src_dir.join("../compiler-rt")
34+
.read_dir()
35+
.unwrap()
36+
.map(|e| e.unwrap())
37+
.filter(|e| &*e.file_name() != ".git")
38+
.collect::<Vec<_>>();
39+
while let Some(entry) = stack.pop() {
40+
let path = entry.path();
41+
if entry.file_type().unwrap().is_dir() {
42+
stack.extend(path.read_dir().unwrap().map(|e| e.unwrap()));
43+
} else {
44+
println!("cargo:rerun-if-changed={}", path.display());
45+
}
46+
}
47+
}
48+
49+
println!("cargo:rerun-if-changed=build.rs");
50+
}

0 commit comments

Comments
 (0)