From ba60af3bbdde527c7944e67218bff4c6b283ad3b Mon Sep 17 00:00:00 2001 From: Chris Krycho Date: Mon, 21 Nov 2016 20:19:52 -0500 Subject: [PATCH 01/19] Document RFC 1623: static lifetime elision. --- src/doc/reference.md | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index 9898c31282c3..713e6f1ab99e 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -1271,7 +1271,8 @@ guaranteed to refer to the same memory address. Constant values must not have destructors, and otherwise permit most forms of data. Constants may refer to the address of other constants, in which case the -address will have the `static` lifetime. The compiler is, however, still at +address will have the `static` lifetime. (See below on [static lifetime +elision](#static-lifetime-elision).) The compiler is, however, still at liberty to translate the constant many times, so the address referred to may not be stable. @@ -1279,7 +1280,7 @@ Constants must be explicitly typed. The type may be `bool`, `char`, a number, or a type derived from those primitive types. The derived types are references with the `static` lifetime, fixed-size arrays, tuples, enum variants, and structs. -``` +```rust const BIT1: u32 = 1 << 0; const BIT2: u32 = 1 << 1; @@ -1331,7 +1332,7 @@ running in the same process. Mutable statics are still very useful, however. They can be used with C libraries and can also be bound from C libraries (in an `extern` block). -``` +```rust # fn atomic_add(_: &mut u32, _: u32) -> u32 { 2 } static mut LEVELS: u32 = 0; @@ -1355,6 +1356,31 @@ unsafe fn bump_levels_unsafe2() -> u32 { Mutable statics have the same restrictions as normal statics, except that the type of the value is not required to ascribe to `Sync`. +#### `'static` lifetime elision + +Both constant and static declarations of reference types have *implicit* +`'static` lifetimes unless an explicit lifetime is specified. As such, the +constant declarations involving `'static` above may be written without the +lifetimes. Returning to our previous example: + +```rust +const BIT1: u32 = 1 << 0; +const BIT2: u32 = 1 << 1; + +const BITS: [u32; 2] = [BIT1, BIT2]; +const STRING: &str = "bitstring"; + +struct BitsNStrings<'a> { + mybits: [u32; 2], + mystring: &'a str, +} + +const BITS_N_STRINGS: BitsNStrings = BitsNStrings { + mybits: BITS, + mystring: STRING, +}; +``` + ### Traits A _trait_ describes an abstract interface that types can @@ -2458,9 +2484,6 @@ The currently implemented features of the reference compiler are: into a Rust program. This capability, especially the signature for the annotated function, is subject to change. -* `static_in_const` - Enables lifetime elision with a `'static` default for - `const` and `static` item declarations. - * `thread_local` - The usage of the `#[thread_local]` attribute is experimental and should be seen as unstable. This attribute is used to declare a `static` as being unique per-thread leveraging From e8cb83a8237d79f4c8523f4b8df5e73688cfb8bb Mon Sep 17 00:00:00 2001 From: Chris Krycho Date: Sat, 28 Jan 2017 09:42:32 -0500 Subject: [PATCH 02/19] Add feature flag to reference docs for RFC 1623. --- src/doc/reference.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index 713e6f1ab99e..c6fc2ea40590 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -1356,7 +1356,7 @@ unsafe fn bump_levels_unsafe2() -> u32 { Mutable statics have the same restrictions as normal statics, except that the type of the value is not required to ascribe to `Sync`. -#### `'static` lifetime elision +#### `'static` lifetime elision [unstable] Both constant and static declarations of reference types have *implicit* `'static` lifetimes unless an explicit lifetime is specified. As such, the @@ -1364,6 +1364,7 @@ constant declarations involving `'static` above may be written without the lifetimes. Returning to our previous example: ```rust +#[feature(static_in_const)] const BIT1: u32 = 1 << 0; const BIT2: u32 = 1 << 1; From 3f0ca5578051f67046abb04d053118439b162f87 Mon Sep 17 00:00:00 2001 From: Chris Krycho Date: Sat, 28 Jan 2017 12:45:54 -0500 Subject: [PATCH 03/19] Change placement of `[Unstable]` marker in RFC 1623 docs. --- src/doc/reference.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index c6fc2ea40590..dd3ccb82211f 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -1356,12 +1356,12 @@ unsafe fn bump_levels_unsafe2() -> u32 { Mutable statics have the same restrictions as normal statics, except that the type of the value is not required to ascribe to `Sync`. -#### `'static` lifetime elision [unstable] +#### `'static` lifetime elision -Both constant and static declarations of reference types have *implicit* -`'static` lifetimes unless an explicit lifetime is specified. As such, the -constant declarations involving `'static` above may be written without the -lifetimes. Returning to our previous example: +[Unstable] Both constant and static declarations of reference types have +*implicit* `'static` lifetimes unless an explicit lifetime is specified. As +such, the constant declarations involving `'static` above may be written +without the lifetimes. Returning to our previous example: ```rust #[feature(static_in_const)] From 05eef36fa5ff9235ea8124a6396c7973015b4b8b Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Mon, 6 Feb 2017 17:50:30 +0000 Subject: [PATCH 04/19] rustdoc: Improve impl disambiguation * Don't disambiguate if there are multiple impls for the same type. * Disambiguate for impls of &Foo and &mut Foo. * Don't try to disambiguate generic types. --- src/librustdoc/html/format.rs | 6 ++-- src/librustdoc/html/render.rs | 32 ++++++++++++++------ src/test/rustdoc/impl-disambiguation.rs | 40 +++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 11 deletions(-) create mode 100644 src/test/rustdoc/impl-disambiguation.rs diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 60dae19d876c..c591c09bf20e 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -671,9 +671,11 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt: } _ => { if f.alternate() { - write!(f, "&{}{}{:#}", lt, m, **ty) + write!(f, "&{}{}", lt, m)?; + fmt_type(&ty, f, use_absolute) } else { - write!(f, "&{}{}{}", lt, m, **ty) + write!(f, "&{}{}", lt, m)?; + fmt_type(&ty, f, use_absolute) } } } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 40eb7e5ab78c..6234d8902444 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2132,10 +2132,23 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean::
    ")?; if let Some(implementors) = cache.implementors.get(&it.def_id) { - let mut implementor_count: FxHashMap<&str, usize> = FxHashMap(); + // The DefId is for the first Type found with that name. The bool is + // if any Types with the same name but different DefId have been found. + let mut implementor_dups: FxHashMap<&str, (DefId, bool)> = FxHashMap(); for implementor in implementors { - if let clean::Type::ResolvedPath {ref path, ..} = implementor.impl_.for_ { - *implementor_count.entry(path.last_name()).or_insert(0) += 1; + match implementor.impl_.for_ { + clean::ResolvedPath { ref path, did, is_generic: false, .. } | + clean::BorrowedRef { + type_: box clean::ResolvedPath { ref path, did, is_generic: false, .. }, + .. + } => { + let &mut (prev_did, ref mut has_duplicates) = + implementor_dups.entry(path.last_name()).or_insert((did, false)); + if prev_did != did { + *has_duplicates = true; + } + } + _ => {} } } @@ -2143,12 +2156,13 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean:: write!(w, "
  • ")?; // If there's already another implementor that has the same abbridged name, use the // full path, for example in `std::iter::ExactSizeIterator` - let use_absolute = if let clean::Type::ResolvedPath { - ref path, .. - } = implementor.impl_.for_ { - implementor_count[path.last_name()] > 1 - } else { - false + let use_absolute = match implementor.impl_.for_ { + clean::ResolvedPath { ref path, is_generic: false, .. } | + clean::BorrowedRef { + type_: box clean::ResolvedPath { ref path, is_generic: false, .. }, + .. + } => implementor_dups[path.last_name()].1, + _ => false, }; fmt_impl_for_trait_page(&implementor.impl_, w, use_absolute)?; writeln!(w, "
  • ")?; diff --git a/src/test/rustdoc/impl-disambiguation.rs b/src/test/rustdoc/impl-disambiguation.rs new file mode 100644 index 000000000000..afe1daf5983a --- /dev/null +++ b/src/test/rustdoc/impl-disambiguation.rs @@ -0,0 +1,40 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_name = "foo"] + +pub trait Foo {} + +pub struct Bar { field: T } + +// @has foo/trait.Foo.html '//*[@class="item-list"]//code' \ +// "impl Foo for Bar" +impl Foo for Bar {} +// @has foo/trait.Foo.html '//*[@class="item-list"]//code' \ +// "impl Foo for Bar" +impl Foo for Bar {} +// @has foo/trait.Foo.html '//*[@class="item-list"]//code' \ +// "impl<'a> Foo for &'a Bar" +impl<'a> Foo for &'a Bar {} + +pub mod mod1 { + pub struct Baz {} +} + +pub mod mod2 { + pub enum Baz {} +} + +// @has foo/trait.Foo.html '//*[@class="item-list"]//code' \ +// "impl Foo for foo::mod1::Baz" +impl Foo for mod1::Baz {} +// @has foo/trait.Foo.html '//*[@class="item-list"]//code' \ +// "impl<'a> Foo for &'a foo::mod2::Baz" +impl<'a> Foo for &'a mod2::Baz {} From 19bbd855ef73c28b381fd98553aedb0a7423efc4 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 4 Feb 2017 16:53:17 -0800 Subject: [PATCH 05/19] Fix branch name Cargo's downloaded from This landed on beta in #39546 and this is bringing the patch back to master. --- src/bootstrap/dist.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 9327cc0cf7fa..9878d1c08bac 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -517,9 +517,7 @@ pub fn cargo(build: &Build, stage: u32, target: &str) { let branch = match &build.config.channel[..] { "stable" | - "beta" => { - build.release.split(".").take(2).collect::>().join(".") - } + "beta" => format!("rust-{}", build.release_num), _ => "master".to_string(), }; From bf126d244e28ba9bb6ce56127ebe6d5703d87a39 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 6 Feb 2017 13:33:03 -0800 Subject: [PATCH 06/19] Fix a manifest-generation bug on beta Right now all Cargo release tarballs are 'nightly', they're not on the standard channels yet. --- src/tools/build-manifest/src/main.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 8c15a6630a33..3eaac82d9fa8 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -317,6 +317,8 @@ fn url(&self, component: &str, target: &str) -> String { fn filename(&self, component: &str, target: &str) -> String { if component == "rust-src" { format!("rust-src-{}.tar.gz", self.channel) + } else if component == "cargo" { + format!("cargo-nightly-{}.tar.gz", target) } else { format!("{}-{}-{}.tar.gz", component, self.channel, target) } From 52a887e12b2d5eaaedfee6843826960f4eee42a8 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Wed, 8 Feb 2017 10:56:42 +0100 Subject: [PATCH 07/19] Remove some leftover makefiles. --- mk/cfg/aarch64-unknown-freebsd.mk | 1 - mk/cfg/i686-unknown-netbsd.mk | 1 - 2 files changed, 2 deletions(-) delete mode 100644 mk/cfg/aarch64-unknown-freebsd.mk delete mode 100644 mk/cfg/i686-unknown-netbsd.mk diff --git a/mk/cfg/aarch64-unknown-freebsd.mk b/mk/cfg/aarch64-unknown-freebsd.mk deleted file mode 100644 index 34aee77ae210..000000000000 --- a/mk/cfg/aarch64-unknown-freebsd.mk +++ /dev/null @@ -1 +0,0 @@ -# rustbuild-only target diff --git a/mk/cfg/i686-unknown-netbsd.mk b/mk/cfg/i686-unknown-netbsd.mk deleted file mode 100644 index 34aee77ae210..000000000000 --- a/mk/cfg/i686-unknown-netbsd.mk +++ /dev/null @@ -1 +0,0 @@ -# rustbuild-only target From 4096dd684c5f11dea5bd231a97adfb7205a82213 Mon Sep 17 00:00:00 2001 From: Chris Krycho Date: Wed, 8 Feb 2017 14:30:31 -0500 Subject: [PATCH 08/19] Add more examples, get everything passing at last. --- src/doc/reference.md | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index dd3ccb82211f..4910313af930 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -1271,10 +1271,12 @@ guaranteed to refer to the same memory address. Constant values must not have destructors, and otherwise permit most forms of data. Constants may refer to the address of other constants, in which case the -address will have the `static` lifetime. (See below on [static lifetime -elision](#static-lifetime-elision).) The compiler is, however, still at -liberty to translate the constant many times, so the address referred to may not -be stable. +address will have elided lifetimes where applicable, otherwise – in most cases – +defaulting to the `static` lifetime. (See below on [static lifetime elision].) +The compiler is, however, still at liberty to translate the constant many times, +so the address referred to may not be stable. + +[static lifetime elision]: #static-lifetime-elision Constants must be explicitly typed. The type may be `bool`, `char`, a number, or a type derived from those primitive types. The derived types are references with @@ -1298,6 +1300,8 @@ const BITS_N_STRINGS: BitsNStrings<'static> = BitsNStrings { }; ``` + + ### Static items A *static item* is similar to a *constant*, except that it represents a precise @@ -1364,7 +1368,7 @@ such, the constant declarations involving `'static` above may be written without the lifetimes. Returning to our previous example: ```rust -#[feature(static_in_const)] +# #![feature(static_in_const)] const BIT1: u32 = 1 << 0; const BIT2: u32 = 1 << 1; @@ -1382,6 +1386,27 @@ const BITS_N_STRINGS: BitsNStrings = BitsNStrings { }; ``` +Note that if the `static` or `const` items include function or closure +references, which themselves include references, the compiler will first try the +standard elision rules ([see discussion in the nomicon][elision-nomicon]). If it +is unable to resolve the lifetimes by its usual rules, it will default to using +the `'static` lifetime. By way of example: + +[elision-nomicon]: https://doc.rust-lang.org/nomicon/lifetime-elision.html + +```rust,ignore +// Resolved as `fn<'a>(&'a str) -> &'a str`. +const RESOLVED_SINGLE: fn(&str) -> &str = .. + +// Resolved as `Fn<'a, 'b, 'c>(&'a Foo, &'b Bar, &'c Baz) -> usize`. +const RESOLVED_MULTIPLE: Fn(&Foo, &Bar, &Baz) -> usize = .. + +// There is insufficient information to bound the return reference lifetime +// relative to the argument lifetimes, so the signature is resolved as +// `Fn(&'static Foo, &'static Bar) -> &'static Baz`. +const RESOLVED_STATIC: Fn(&Foo, &Bar) -> &Baz = .. +``` + ### Traits A _trait_ describes an abstract interface that types can @@ -2079,7 +2104,9 @@ macro scope. ### Miscellaneous attributes -- `deprecated` - mark the item as deprecated; the full attribute is `#[deprecated(since = "crate version", note = "...")`, where both arguments are optional. +- `deprecated` - mark the item as deprecated; the full attribute is + `#[deprecated(since = "crate version", note = "...")`, where both arguments + are optional. - `export_name` - on statics and functions, this determines the name of the exported symbol. - `link_section` - on statics and functions, this specifies the section of the From ab3da976150726fe88a05b65e8fca96e37d3e82a Mon Sep 17 00:00:00 2001 From: Jan Zerebecki Date: Wed, 8 Feb 2017 21:50:29 +0100 Subject: [PATCH 09/19] Add test for #27433 --- src/test/compile-fail/issue-27433.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/test/compile-fail/issue-27433.rs diff --git a/src/test/compile-fail/issue-27433.rs b/src/test/compile-fail/issue-27433.rs new file mode 100644 index 000000000000..78d96398b958 --- /dev/null +++ b/src/test/compile-fail/issue-27433.rs @@ -0,0 +1,15 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let foo = 42u32; + const FOO : u32 = foo; + //~^ ERROR attempt to use a non-constant value in a constant +} From 3022614ec3c602a5812286c855633ea34683b038 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 8 Feb 2017 18:42:01 +0100 Subject: [PATCH 10/19] Add missing urls on join_paths --- src/libstd/env.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/libstd/env.rs b/src/libstd/env.rs index e26415392949..1ef2cb4ed153 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -400,15 +400,19 @@ pub struct JoinPathsError { inner: os_imp::JoinPathsError } -/// Joins a collection of `Path`s appropriately for the `PATH` +/// Joins a collection of [`Path`]s appropriately for the `PATH` /// environment variable. /// -/// Returns an `OsString` on success. +/// Returns an [`OsString`] on success. /// -/// Returns an `Err` (containing an error message) if one of the input -/// `Path`s contains an invalid character for constructing the `PATH` +/// Returns an [`Err`][err] (containing an error message) if one of the input +/// [`Path`]s contains an invalid character for constructing the `PATH` /// variable (a double quote on Windows or a colon on Unix). /// +/// [`Path`]: ../../std/path/struct.Path.html +/// [`OsString`]: ../../std/ffi/struct.OsString.html +/// [err]: ../../std/result/enum.Result.html#variant.Err +/// /// # Examples /// /// ``` From 9af6aa38895d3c1d263c52984666893b9ca22fe1 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 29 Dec 2016 23:28:11 -0500 Subject: [PATCH 11/19] sanitizer support --- src/Cargo.lock | 40 ++++++++++++ src/bootstrap/check.rs | 5 +- src/bootstrap/compile.rs | 12 ++++ src/bootstrap/config.rs | 3 + src/bootstrap/lib.rs | 7 +- src/compiler-rt | 2 +- src/librustc/middle/cstore.rs | 2 + src/librustc/session/config.rs | 25 +++++++- src/librustc_asan/Cargo.toml | 16 +++++ src/librustc_asan/build.rs | 50 +++++++++++++++ src/librustc_asan/lib.rs | 20 ++++++ src/librustc_llvm/ffi.rs | 3 + src/librustc_lsan/Cargo.toml | 16 +++++ src/librustc_lsan/build.rs | 50 +++++++++++++++ src/librustc_lsan/lib.rs | 20 ++++++ src/librustc_metadata/creader.rs | 64 ++++++++++++++++++- src/librustc_metadata/cstore.rs | 5 ++ src/librustc_metadata/cstore_impl.rs | 4 ++ src/librustc_msan/Cargo.toml | 16 +++++ src/librustc_msan/build.rs | 50 +++++++++++++++ src/librustc_msan/lib.rs | 20 ++++++ src/librustc_trans/back/link.rs | 33 ++++++++++ src/librustc_trans/back/write.rs | 18 +++++- src/librustc_trans/declare.rs | 16 +++++ src/librustc_tsan/Cargo.toml | 16 +++++ src/librustc_tsan/build.rs | 50 +++++++++++++++ src/librustc_tsan/lib.rs | 20 ++++++ src/libstd/Cargo.toml | 10 +++ src/libsyntax/feature_gate.rs | 10 +++ src/rustc/std_shim/Cargo.toml | 4 ++ src/rustllvm/RustWrapper.cpp | 6 ++ src/rustllvm/rustllvm.h | 3 + .../feature-gate-sanitizer-runtime.rs | 13 ++++ src/test/run-make/sanitizer-address/Makefile | 21 ++++++ .../run-make/sanitizer-address/overflow.rs | 14 ++++ src/test/run-make/sanitizer-dylib/Makefile | 4 ++ src/test/run-make/sanitizer-dylib/hello.rs | 13 ++++ .../sanitizer-invalid-target/Makefile | 4 ++ .../sanitizer-invalid-target/hello.rs | 13 ++++ src/test/run-make/sanitizer-leak/Makefile | 23 +++++++ src/test/run-make/sanitizer-leak/leak.rs | 16 +++++ src/test/run-make/sanitizer-memory/Makefile | 21 ++++++ src/test/run-make/sanitizer-memory/uninit.rs | 16 +++++ src/test/run-make/sanitizer-thread/Makefile | 21 ++++++ src/test/run-make/sanitizer-thread/racy.rs | 21 ++++++ 45 files changed, 810 insertions(+), 6 deletions(-) create mode 100644 src/librustc_asan/Cargo.toml create mode 100644 src/librustc_asan/build.rs create mode 100644 src/librustc_asan/lib.rs create mode 100644 src/librustc_lsan/Cargo.toml create mode 100644 src/librustc_lsan/build.rs create mode 100644 src/librustc_lsan/lib.rs create mode 100644 src/librustc_msan/Cargo.toml create mode 100644 src/librustc_msan/build.rs create mode 100644 src/librustc_msan/lib.rs create mode 100644 src/librustc_tsan/Cargo.toml create mode 100644 src/librustc_tsan/build.rs create mode 100644 src/librustc_tsan/lib.rs create mode 100644 src/test/compile-fail/feature-gate-sanitizer-runtime.rs create mode 100644 src/test/run-make/sanitizer-address/Makefile create mode 100644 src/test/run-make/sanitizer-address/overflow.rs create mode 100644 src/test/run-make/sanitizer-dylib/Makefile create mode 100644 src/test/run-make/sanitizer-dylib/hello.rs create mode 100644 src/test/run-make/sanitizer-invalid-target/Makefile create mode 100644 src/test/run-make/sanitizer-invalid-target/hello.rs create mode 100644 src/test/run-make/sanitizer-leak/Makefile create mode 100644 src/test/run-make/sanitizer-leak/leak.rs create mode 100644 src/test/run-make/sanitizer-memory/Makefile create mode 100644 src/test/run-make/sanitizer-memory/uninit.rs create mode 100644 src/test/run-make/sanitizer-thread/Makefile create mode 100644 src/test/run-make/sanitizer-thread/racy.rs diff --git a/src/Cargo.lock b/src/Cargo.lock index 06cf32ad0f6b..8e987ba3b7f1 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -268,6 +268,15 @@ name = "rustc-serialize" version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rustc_asan" +version = "0.0.0" +dependencies = [ + "alloc_system 0.0.0", + "cmake 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "core 0.0.0", +] + [[package]] name = "rustc_back" version = "0.0.0" @@ -401,6 +410,15 @@ dependencies = [ "rustc_bitflags 0.0.0", ] +[[package]] +name = "rustc_lsan" +version = "0.0.0" +dependencies = [ + "alloc_system 0.0.0", + "cmake 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "core 0.0.0", +] + [[package]] name = "rustc_metadata" version = "0.0.0" @@ -435,6 +453,15 @@ dependencies = [ "syntax_pos 0.0.0", ] +[[package]] +name = "rustc_msan" +version = "0.0.0" +dependencies = [ + "alloc_system 0.0.0", + "cmake 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "core 0.0.0", +] + [[package]] name = "rustc_passes" version = "0.0.0" @@ -516,6 +543,15 @@ dependencies = [ "syntax_pos 0.0.0", ] +[[package]] +name = "rustc_tsan" +version = "0.0.0" +dependencies = [ + "alloc_system 0.0.0", + "cmake 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", + "core 0.0.0", +] + [[package]] name = "rustc_typeck" version = "0.0.0" @@ -577,6 +613,10 @@ dependencies = [ "panic_abort 0.0.0", "panic_unwind 0.0.0", "rand 0.0.0", + "rustc_asan 0.0.0", + "rustc_lsan 0.0.0", + "rustc_msan 0.0.0", + "rustc_tsan 0.0.0", "std_unicode 0.0.0", "unwind 0.0.0", ] diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 19aac0f36bb2..573d0df0cee2 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -332,7 +332,10 @@ pub fn krate(build: &Build, krate: Option<&str>) { let (name, path, features, root) = match mode { Mode::Libstd => { - ("libstd", "src/rustc/std_shim", build.std_features(), "std_shim") + ("libstd", + "src/rustc/std_shim", + build.std_features(), + "std_shim") } Mode::Libtest => { ("libtest", "src/rustc/test_shim", String::new(), "test_shim") diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 776b91028a1a..3e29339a75b4 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -51,6 +51,18 @@ pub fn std(build: &Build, target: &str, compiler: &Compiler) { if compiler.stage == 0 && build.local_rebuild && !build.config.use_jemalloc { features.push_str(" force_alloc_system"); } + + if compiler.stage != 0 && !build.system_llvm(target) { + // This variable is used by the sanitizer runtime crates, e.g. + // rustc_lsan, to build the sanitizer runtime from C code + // When this variable is missing, those crates won't compile the C code, + // so we don't set this variable during stage0 where llvm-config is + // missing + // We also don't build the runtimes when compiling against system llvm + // because some distributions ship llvm packages that have a directory + // layout different from the one that the runtime's build system expects + cargo.env("LLVM_CONFIG", build.llvm_config(target)); + } cargo.arg("--features").arg(features) .arg("--manifest-path") .arg(build.src.join("src/rustc/std_shim/Cargo.toml")); diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 6e077691b3a0..b171c89c20ad 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -108,6 +108,8 @@ pub struct Config { /// Per-target configuration stored in the global configuration structure. #[derive(Default)] pub struct Target { + // `true` if compiling against system LLVM or a pre-built LLVM + pub system_llvm: bool, pub llvm_config: Option, pub jemalloc: Option, pub cc: Option, @@ -512,6 +514,7 @@ macro_rules! check { .or_insert(Target::default()); let root = parse_configure_path(value); target.llvm_config = Some(push_exe_path(root, &["bin", "llvm-config"])); + target.system_llvm = true; } "CFG_JEMALLOC_ROOT" if value.len() > 0 => { let target = self.target_config.entry(self.build.clone()) diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index df1218752d1c..21dd4b1520a8 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -599,7 +599,8 @@ fn prepare_tool_cmd(&self, compiler: &Compiler, cmd: &mut Command) { /// Get the space-separated set of activated features for the standard /// library. fn std_features(&self) -> String { - let mut features = "panic-unwind".to_string(); + let mut features = "panic-unwind asan lsan msan tsan".to_string(); + if self.config.debug_jemalloc { features.push_str(" debug-jemalloc"); } @@ -716,6 +717,10 @@ fn llvm_config(&self, target: &str) -> PathBuf { } } + fn system_llvm(&self, target: &str) -> bool { + self.config.target_config.get(target).map(|t| t.system_llvm).unwrap_or(false) + } + /// Returns the path to `FileCheck` binary for the specified target fn llvm_filecheck(&self, target: &str) -> PathBuf { let target_config = self.config.target_config.get(target); diff --git a/src/compiler-rt b/src/compiler-rt index a8fc4c169fac..d30da544a8af 160000 --- a/src/compiler-rt +++ b/src/compiler-rt @@ -1 +1 @@ -Subproject commit a8fc4c169fac43a5dc204d4fd56ddb1739f8c178 +Subproject commit d30da544a8afc5d78391dee270bdf40e74a215d3 diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 6537cc1adce0..2d80fc32c469 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -229,6 +229,7 @@ fn dylib_dependency_formats(&self, cnum: CrateNum) fn is_allocator(&self, cnum: CrateNum) -> bool; fn is_panic_runtime(&self, cnum: CrateNum) -> bool; fn is_compiler_builtins(&self, cnum: CrateNum) -> bool; + fn is_sanitizer_runtime(&self, cnum: CrateNum) -> bool; fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy; fn extern_crate(&self, cnum: CrateNum) -> Option; /// The name of the crate as it is referred to in source code of the current @@ -390,6 +391,7 @@ fn export_macros(&self, cnum: CrateNum) { bug!("export_macros") } fn is_allocator(&self, cnum: CrateNum) -> bool { bug!("is_allocator") } fn is_panic_runtime(&self, cnum: CrateNum) -> bool { bug!("is_panic_runtime") } fn is_compiler_builtins(&self, cnum: CrateNum) -> bool { bug!("is_compiler_builtins") } + fn is_sanitizer_runtime(&self, cnum: CrateNum) -> bool { bug!("is_sanitizer_runtime") } fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy { bug!("panic_strategy") } diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index d41c2ba93b93..24615f2fa699 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -51,6 +51,14 @@ pub struct Config { pub uint_type: UintTy, } +#[derive(Clone)] +pub enum Sanitizer { + Address, + Leak, + Memory, + Thread, +} + #[derive(Clone, Copy, PartialEq, Hash)] pub enum OptLevel { No, // -O0 @@ -626,11 +634,13 @@ mod $mod_desc { Some("a number"); pub const parse_panic_strategy: Option<&'static str> = Some("either `panic` or `abort`"); + pub const parse_sanitizer: Option<&'static str> = + Some("one of: `address`, `leak`, `memory` or `thread`"); } #[allow(dead_code)] mod $mod_set { - use super::{$struct_name, Passes, SomePasses, AllPasses}; + use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer}; use rustc_back::PanicStrategy; $( @@ -751,6 +761,17 @@ fn parse_panic_strategy(slot: &mut Option, v: Option<&str>) -> bo } true } + + fn parse_sanitizer(slote: &mut Option, v: Option<&str>) -> bool { + match v { + Some("address") => *slote = Some(Sanitizer::Address), + Some("leak") => *slote = Some(Sanitizer::Leak), + Some("memory") => *slote = Some(Sanitizer::Memory), + Some("thread") => *slote = Some(Sanitizer::Thread), + _ => return false, + } + true + } } ) } @@ -949,6 +970,8 @@ fn parse_panic_strategy(slot: &mut Option, v: Option<&str>) -> bo "encode MIR of all functions into the crate metadata"), osx_rpath_install_name: bool = (false, parse_bool, [TRACKED], "pass `-install_name @rpath/...` to the OSX linker"), + sanitizer: Option = (None, parse_sanitizer, [UNTRACKED], + "Use a sanitizer"), } pub fn default_lib_output() -> CrateType { diff --git a/src/librustc_asan/Cargo.toml b/src/librustc_asan/Cargo.toml new file mode 100644 index 000000000000..abbd7cc0966e --- /dev/null +++ b/src/librustc_asan/Cargo.toml @@ -0,0 +1,16 @@ +[package] +authors = ["The Rust Project Developers"] +build = "build.rs" +name = "rustc_asan" +version = "0.0.0" + +[lib] +name = "rustc_asan" +path = "lib.rs" + +[build-dependencies] +cmake = "0.1.18" + +[dependencies] +alloc_system = { path = "../liballoc_system" } +core = { path = "../libcore" } diff --git a/src/librustc_asan/build.rs b/src/librustc_asan/build.rs new file mode 100644 index 000000000000..3e33efcadb80 --- /dev/null +++ b/src/librustc_asan/build.rs @@ -0,0 +1,50 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern crate cmake; + +use std::path::PathBuf; +use std::env; + +use cmake::Config; + +fn main() { + if let Some(llvm_config) = env::var_os("LLVM_CONFIG") { + let dst = Config::new("../compiler-rt") + .define("COMPILER_RT_BUILD_SANITIZERS", "ON") + .define("COMPILER_RT_BUILD_BUILTINS", "OFF") + .define("COMPILER_RT_BUILD_XRAY", "OFF") + .define("LLVM_CONFIG_PATH", llvm_config) + .build_target("asan") + .build(); + + println!("cargo:rustc-link-search=native={}", + dst.join("build/lib/linux").display()); + println!("cargo:rustc-link-lib=static=clang_rt.asan-x86_64"); + + let src_dir = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()); + let mut stack = src_dir.join("../compiler-rt") + .read_dir() + .unwrap() + .map(|e| e.unwrap()) + .filter(|e| &*e.file_name() != ".git") + .collect::>(); + while let Some(entry) = stack.pop() { + let path = entry.path(); + if entry.file_type().unwrap().is_dir() { + stack.extend(path.read_dir().unwrap().map(|e| e.unwrap())); + } else { + println!("cargo:rerun-if-changed={}", path.display()); + } + } + } + + println!("cargo:rerun-if-changed=build.rs"); +} diff --git a/src/librustc_asan/lib.rs b/src/librustc_asan/lib.rs new file mode 100644 index 000000000000..71a166b91ebc --- /dev/null +++ b/src/librustc_asan/lib.rs @@ -0,0 +1,20 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![cfg_attr(not(stage0), feature(sanitizer_runtime))] +#![cfg_attr(not(stage0), sanitizer_runtime)] +#![feature(alloc_system)] +#![feature(staged_api)] +#![no_std] +#![unstable(feature = "sanitizer_runtime_lib", + reason = "internal implementation detail of sanitizers", + issue = "0")] + +extern crate alloc_system; diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index 8510b9f523cb..6c9976ca3f8e 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -126,6 +126,9 @@ pub enum Attribute { UWTable = 17, ZExt = 18, InReg = 19, + SanitizeThread = 20, + SanitizeAddress = 21, + SanitizeMemory = 22, } /// LLVMIntPredicate diff --git a/src/librustc_lsan/Cargo.toml b/src/librustc_lsan/Cargo.toml new file mode 100644 index 000000000000..ac53f3fe73a7 --- /dev/null +++ b/src/librustc_lsan/Cargo.toml @@ -0,0 +1,16 @@ +[package] +authors = ["The Rust Project Developers"] +build = "build.rs" +name = "rustc_lsan" +version = "0.0.0" + +[lib] +name = "rustc_lsan" +path = "lib.rs" + +[build-dependencies] +cmake = "0.1.18" + +[dependencies] +alloc_system = { path = "../liballoc_system" } +core = { path = "../libcore" } diff --git a/src/librustc_lsan/build.rs b/src/librustc_lsan/build.rs new file mode 100644 index 000000000000..f13928d2bd45 --- /dev/null +++ b/src/librustc_lsan/build.rs @@ -0,0 +1,50 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern crate cmake; + +use std::path::PathBuf; +use std::env; + +use cmake::Config; + +fn main() { + if let Some(llvm_config) = env::var_os("LLVM_CONFIG") { + let dst = Config::new("../compiler-rt") + .define("COMPILER_RT_BUILD_SANITIZERS", "ON") + .define("COMPILER_RT_BUILD_BUILTINS", "OFF") + .define("COMPILER_RT_BUILD_XRAY", "OFF") + .define("LLVM_CONFIG_PATH", llvm_config) + .build_target("lsan") + .build(); + + println!("cargo:rustc-link-search=native={}", + dst.join("build/lib/linux").display()); + println!("cargo:rustc-link-lib=static=clang_rt.lsan-x86_64"); + + let src_dir = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()); + let mut stack = src_dir.join("../compiler-rt") + .read_dir() + .unwrap() + .map(|e| e.unwrap()) + .filter(|e| &*e.file_name() != ".git") + .collect::>(); + while let Some(entry) = stack.pop() { + let path = entry.path(); + if entry.file_type().unwrap().is_dir() { + stack.extend(path.read_dir().unwrap().map(|e| e.unwrap())); + } else { + println!("cargo:rerun-if-changed={}", path.display()); + } + } + } + + println!("cargo:rerun-if-changed=build.rs"); +} diff --git a/src/librustc_lsan/lib.rs b/src/librustc_lsan/lib.rs new file mode 100644 index 000000000000..71a166b91ebc --- /dev/null +++ b/src/librustc_lsan/lib.rs @@ -0,0 +1,20 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![cfg_attr(not(stage0), feature(sanitizer_runtime))] +#![cfg_attr(not(stage0), sanitizer_runtime)] +#![feature(alloc_system)] +#![feature(staged_api)] +#![no_std] +#![unstable(feature = "sanitizer_runtime_lib", + reason = "internal implementation detail of sanitizers", + issue = "0")] + +extern crate alloc_system; diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 81a4f7c93b6e..55dc5aa2876f 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -17,7 +17,8 @@ use rustc::hir::def_id::{CrateNum, DefIndex}; use rustc::hir::svh::Svh; use rustc::middle::cstore::DepKind; -use rustc::session::{config, Session}; +use rustc::session::Session; +use rustc::session::config::{Sanitizer, self}; use rustc_back::PanicStrategy; use rustc::session::search_paths::PathKind; use rustc::middle; @@ -786,6 +787,64 @@ fn inject_panic_runtime(&mut self, krate: &ast::Crate) { &|data| data.needs_panic_runtime()); } + fn inject_sanitizer_runtime(&mut self) { + if let Some(ref sanitizer) = self.sess.opts.debugging_opts.sanitizer { + // Sanitizers can only be used with x86_64 Linux executables linked + // to `std` + if self.sess.target.target.llvm_target != "x86_64-unknown-linux-gnu" { + self.sess.err(&format!("Sanitizers only work with the \ + `x86_64-unknown-linux-gnu` target.")); + return + } + + if !self.sess.crate_types.borrow().iter().all(|ct| { + match *ct { + // Link the runtime + config::CrateTypeExecutable => true, + // This crate will be compiled with the required + // instrumentation pass + config::CrateTypeRlib => false, + _ => { + self.sess.err(&format!("Only executables and rlibs can be \ + compiled with `-Z sanitizer`")); + false + } + } + }) { + return + } + + let mut uses_std = false; + self.cstore.iter_crate_data(|_, data| { + if data.name == "std" { + uses_std = true; + } + }); + + if uses_std { + let name = match *sanitizer { + Sanitizer::Address => "rustc_asan", + Sanitizer::Leak => "rustc_lsan", + Sanitizer::Memory => "rustc_msan", + Sanitizer::Thread => "rustc_tsan", + }; + info!("loading sanitizer: {}", name); + + let symbol = Symbol::intern(name); + let dep_kind = DepKind::Implicit; + let (_, data) = + self.resolve_crate(&None, symbol, symbol, None, DUMMY_SP, + PathKind::Crate, dep_kind); + + // Sanity check the loaded crate to ensure it is indeed a sanitizer runtime + if !data.is_sanitizer_runtime() { + self.sess.err(&format!("the crate `{}` is not a sanitizer runtime", + name)); + } + } + } + } + fn inject_allocator_crate(&mut self) { // Make sure that we actually need an allocator, if none of our // dependencies need one then we definitely don't! @@ -982,6 +1041,9 @@ fn process_foreign_mod(&mut self, i: &ast::Item, fm: &ast::ForeignMod, impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> { fn postprocess(&mut self, krate: &ast::Crate) { + // inject the sanitizer runtime before the allocator runtime because all + // sanitizers force the use of the `alloc_system` allocator + self.inject_sanitizer_runtime(); self.inject_allocator_crate(); self.inject_panic_runtime(krate); diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index beba5faf3d03..4709ca6101c7 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -297,6 +297,11 @@ pub fn is_compiler_builtins(&self) -> bool { attr::contains_name(&attrs, "compiler_builtins") } + pub fn is_sanitizer_runtime(&self) -> bool { + let attrs = self.get_item_attrs(CRATE_DEF_INDEX); + attr::contains_name(&attrs, "sanitizer_runtime") + } + pub fn is_no_builtins(&self) -> bool { let attrs = self.get_item_attrs(CRATE_DEF_INDEX); attr::contains_name(&attrs, "no_builtins") diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 39581a469608..7b0177bfd23e 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -297,6 +297,10 @@ fn is_compiler_builtins(&self, cnum: CrateNum) -> bool { self.get_crate_data(cnum).is_compiler_builtins() } + fn is_sanitizer_runtime(&self, cnum: CrateNum) -> bool { + self.get_crate_data(cnum).is_sanitizer_runtime() + } + fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy { self.get_crate_data(cnum).panic_strategy() } diff --git a/src/librustc_msan/Cargo.toml b/src/librustc_msan/Cargo.toml new file mode 100644 index 000000000000..628746ac232d --- /dev/null +++ b/src/librustc_msan/Cargo.toml @@ -0,0 +1,16 @@ +[package] +authors = ["The Rust Project Developers"] +build = "build.rs" +name = "rustc_msan" +version = "0.0.0" + +[lib] +name = "rustc_msan" +path = "lib.rs" + +[build-dependencies] +cmake = "0.1.18" + +[dependencies] +alloc_system = { path = "../liballoc_system" } +core = { path = "../libcore" } diff --git a/src/librustc_msan/build.rs b/src/librustc_msan/build.rs new file mode 100644 index 000000000000..bf630c7844a2 --- /dev/null +++ b/src/librustc_msan/build.rs @@ -0,0 +1,50 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern crate cmake; + +use std::path::PathBuf; +use std::env; + +use cmake::Config; + +fn main() { + if let Some(llvm_config) = env::var_os("LLVM_CONFIG") { + let dst = Config::new("../compiler-rt") + .define("COMPILER_RT_BUILD_SANITIZERS", "ON") + .define("COMPILER_RT_BUILD_BUILTINS", "OFF") + .define("COMPILER_RT_BUILD_XRAY", "OFF") + .define("LLVM_CONFIG_PATH", llvm_config) + .build_target("msan") + .build(); + + println!("cargo:rustc-link-search=native={}", + dst.join("build/lib/linux").display()); + println!("cargo:rustc-link-lib=static=clang_rt.msan-x86_64"); + + let src_dir = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()); + let mut stack = src_dir.join("../compiler-rt") + .read_dir() + .unwrap() + .map(|e| e.unwrap()) + .filter(|e| &*e.file_name() != ".git") + .collect::>(); + while let Some(entry) = stack.pop() { + let path = entry.path(); + if entry.file_type().unwrap().is_dir() { + stack.extend(path.read_dir().unwrap().map(|e| e.unwrap())); + } else { + println!("cargo:rerun-if-changed={}", path.display()); + } + } + } + + println!("cargo:rerun-if-changed=build.rs"); +} diff --git a/src/librustc_msan/lib.rs b/src/librustc_msan/lib.rs new file mode 100644 index 000000000000..71a166b91ebc --- /dev/null +++ b/src/librustc_msan/lib.rs @@ -0,0 +1,20 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![cfg_attr(not(stage0), feature(sanitizer_runtime))] +#![cfg_attr(not(stage0), sanitizer_runtime)] +#![feature(alloc_system)] +#![feature(staged_api)] +#![no_std] +#![unstable(feature = "sanitizer_runtime_lib", + reason = "internal implementation detail of sanitizers", + issue = "0")] + +extern crate alloc_system; diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 4ddf8a883bc4..1cbfa26b705a 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -1031,6 +1031,9 @@ fn add_upstream_rust_crates(cmd: &mut Linker, // symbols from the dylib. let src = sess.cstore.used_crate_source(cnum); match data[cnum.as_usize() - 1] { + _ if sess.cstore.is_sanitizer_runtime(cnum) => { + link_sanitizer_runtime(cmd, sess, tmpdir, cnum); + } // compiler-builtins are always placed last to ensure that they're // linked correctly. _ if sess.cstore.is_compiler_builtins(cnum) => { @@ -1048,6 +1051,8 @@ fn add_upstream_rust_crates(cmd: &mut Linker, } } + // compiler-builtins are always placed last to ensure that they're + // linked correctly. // We must always link the `compiler_builtins` crate statically. Even if it // was already "included" in a dylib (e.g. `libstd` when `-C prefer-dynamic` // is used) @@ -1064,6 +1069,34 @@ fn unlib<'a>(config: &config::Config, stem: &'a str) -> &'a str { } } + // We must link the sanitizer runtime using -Wl,--whole-archive but since + // it's packed in a .rlib, it contains stuff that are not objects that will + // make the linker error. So we must remove those bits from the .rlib before + // linking it. + fn link_sanitizer_runtime(cmd: &mut Linker, + sess: &Session, + tmpdir: &Path, + cnum: CrateNum) { + let src = sess.cstore.used_crate_source(cnum); + let cratepath = &src.rlib.unwrap().0; + let dst = tmpdir.join(cratepath.file_name().unwrap()); + let cfg = archive_config(sess, &dst, Some(cratepath)); + let mut archive = ArchiveBuilder::new(cfg); + archive.update_symbols(); + + for f in archive.src_files() { + if f.ends_with("bytecode.deflate") || + f == sess.cstore.metadata_filename() { + archive.remove_file(&f); + continue + } + } + + archive.build(); + + cmd.link_whole_rlib(&dst); + } + // Adds the static "rlib" versions of all crates to the command line. // There's a bit of magic which happens here specifically related to LTO and // dynamic libraries. Specifically: diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index b3a2d66a07c1..8e71c5710951 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -12,7 +12,7 @@ use back::link::{get_linker, remove}; use back::symbol_export::ExportedSymbols; use rustc_incremental::{save_trans_partition, in_incr_comp_dir}; -use session::config::{OutputFilenames, OutputTypes, Passes, SomePasses, AllPasses}; +use session::config::{OutputFilenames, OutputTypes, Passes, SomePasses, AllPasses, Sanitizer}; use session::Session; use session::config::{self, OutputType}; use llvm; @@ -678,6 +678,22 @@ pub fn run_passes(sess: &Session, let mut modules_config = ModuleConfig::new(tm, sess.opts.cg.passes.clone()); let mut metadata_config = ModuleConfig::new(tm, 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()) + } + _ => {} + } + } + modules_config.opt_level = Some(get_llvm_opt_level(sess.opts.optimize)); modules_config.opt_size = Some(get_llvm_opt_size(sess.opts.optimize)); diff --git a/src/librustc_trans/declare.rs b/src/librustc_trans/declare.rs index bf7a02eb0f19..7ac482459ee3 100644 --- a/src/librustc_trans/declare.rs +++ b/src/librustc_trans/declare.rs @@ -23,6 +23,7 @@ use llvm::{self, ValueRef}; use llvm::AttributePlace::Function; use rustc::ty; +use rustc::session::config::Sanitizer; use abi::{Abi, FnType}; use attributes; use context::CrateContext; @@ -72,6 +73,21 @@ fn declare_raw_fn(ccx: &CrateContext, name: &str, callconv: llvm::CallConv, ty: llvm::Attribute::NoRedZone.apply_llfn(Function, llfn); } + if let Some(ref sanitizer) = ccx.tcx().sess.opts.debugging_opts.sanitizer { + match *sanitizer { + Sanitizer::Address => { + llvm::Attribute::SanitizeAddress.apply_llfn(Function, llfn); + }, + Sanitizer::Memory => { + llvm::Attribute::SanitizeMemory.apply_llfn(Function, llfn); + }, + Sanitizer::Thread => { + llvm::Attribute::SanitizeThread.apply_llfn(Function, llfn); + }, + _ => {} + } + } + // If we're compiling the compiler-builtins crate, e.g. the equivalent of // compiler-rt, then we want to implicitly compile everything with hidden // visibility as we're going to link this object all over the place but diff --git a/src/librustc_tsan/Cargo.toml b/src/librustc_tsan/Cargo.toml new file mode 100644 index 000000000000..2af0ae3f7341 --- /dev/null +++ b/src/librustc_tsan/Cargo.toml @@ -0,0 +1,16 @@ +[package] +authors = ["The Rust Project Developers"] +build = "build.rs" +name = "rustc_tsan" +version = "0.0.0" + +[lib] +name = "rustc_tsan" +path = "lib.rs" + +[build-dependencies] +cmake = "0.1.18" + +[dependencies] +alloc_system = { path = "../liballoc_system" } +core = { path = "../libcore" } diff --git a/src/librustc_tsan/build.rs b/src/librustc_tsan/build.rs new file mode 100644 index 000000000000..2ba5866ab9d4 --- /dev/null +++ b/src/librustc_tsan/build.rs @@ -0,0 +1,50 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern crate cmake; + +use std::path::PathBuf; +use std::env; + +use cmake::Config; + +fn main() { + if let Some(llvm_config) = env::var_os("LLVM_CONFIG") { + let dst = Config::new("../compiler-rt") + .define("COMPILER_RT_BUILD_SANITIZERS", "ON") + .define("COMPILER_RT_BUILD_BUILTINS", "OFF") + .define("COMPILER_RT_BUILD_XRAY", "OFF") + .define("LLVM_CONFIG_PATH", llvm_config) + .build_target("tsan") + .build(); + + println!("cargo:rustc-link-search=native={}", + dst.join("build/lib/linux").display()); + println!("cargo:rustc-link-lib=static=clang_rt.tsan-x86_64"); + + let src_dir = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()); + let mut stack = src_dir.join("../compiler-rt") + .read_dir() + .unwrap() + .map(|e| e.unwrap()) + .filter(|e| &*e.file_name() != ".git") + .collect::>(); + while let Some(entry) = stack.pop() { + let path = entry.path(); + if entry.file_type().unwrap().is_dir() { + stack.extend(path.read_dir().unwrap().map(|e| e.unwrap())); + } else { + println!("cargo:rerun-if-changed={}", path.display()); + } + } + } + + println!("cargo:rerun-if-changed=build.rs"); +} diff --git a/src/librustc_tsan/lib.rs b/src/librustc_tsan/lib.rs new file mode 100644 index 000000000000..71a166b91ebc --- /dev/null +++ b/src/librustc_tsan/lib.rs @@ -0,0 +1,20 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![cfg_attr(not(stage0), feature(sanitizer_runtime))] +#![cfg_attr(not(stage0), sanitizer_runtime)] +#![feature(alloc_system)] +#![feature(staged_api)] +#![no_std] +#![unstable(feature = "sanitizer_runtime_lib", + reason = "internal implementation detail of sanitizers", + issue = "0")] + +extern crate alloc_system; diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 8146e7fb1eda..2ba7517d3d20 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -23,13 +23,23 @@ compiler_builtins = { path = "../libcompiler_builtins" } std_unicode = { path = "../libstd_unicode" } unwind = { path = "../libunwind" } +[target.x86_64-unknown-linux-gnu.dependencies] +rustc_asan = { path = "../librustc_asan", optional = true } +rustc_lsan = { path = "../librustc_lsan", optional = true } +rustc_msan = { path = "../librustc_msan", optional = true } +rustc_tsan = { path = "../librustc_tsan", optional = true } + [build-dependencies] build_helper = { path = "../build_helper" } gcc = "0.3.27" [features] +asan = ["rustc_asan"] backtrace = [] debug-jemalloc = ["alloc_jemalloc/debug"] jemalloc = ["alloc_jemalloc"] force_alloc_system = [] +lsan = ["rustc_lsan"] +msan = ["rustc_msan"] panic-unwind = ["panic_unwind"] +tsan = ["rustc_tsan"] diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 52ef2a05fcf1..6a16a0ef353a 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -328,6 +328,10 @@ pub fn new() -> Features { // `extern "msp430-interrupt" fn()` (active, abi_msp430_interrupt, "1.16.0", Some(38487)), + + // Used to identify crates that contain sanitizer runtimes + // rustc internal + (active, sanitizer_runtime, "1.17.0", None), ); declare_features! ( @@ -647,6 +651,12 @@ pub fn is_builtin_attr(attr: &ast::Attribute) -> bool { contains compiler-rt intrinsics and will never be \ stable", cfg_fn!(compiler_builtins))), + ("sanitizer_runtime", Whitelisted, Gated(Stability::Unstable, + "sanitizer_runtime", + "the `#[sanitizer_runtime]` attribute is used to \ + identify crates that contain the runtime of a \ + sanitizer and will never be stable", + cfg_fn!(sanitizer_runtime))), ("allow_internal_unstable", Normal, Gated(Stability::Unstable, "allow_internal_unstable", diff --git a/src/rustc/std_shim/Cargo.toml b/src/rustc/std_shim/Cargo.toml index 14c9c5544b18..db96079d3e91 100644 --- a/src/rustc/std_shim/Cargo.toml +++ b/src/rustc/std_shim/Cargo.toml @@ -35,8 +35,12 @@ core = { path = "../../libcore" } # Reexport features from std [features] +asan = ["std/asan"] backtrace = ["std/backtrace"] debug-jemalloc = ["std/debug-jemalloc"] jemalloc = ["std/jemalloc"] force_alloc_system = ["std/force_alloc_system"] +lsan = ["std/lsan"] +msan = ["std/msan"] panic-unwind = ["std/panic-unwind"] +tsan = ["std/tsan"] diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index c7bcd2558186..58dfe0a3d38f 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -148,6 +148,12 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) { return Attribute::ZExt; case InReg: return Attribute::InReg; + case SanitizeThread: + return Attribute::SanitizeThread; + case SanitizeAddress: + return Attribute::SanitizeAddress; + case SanitizeMemory: + return Attribute::SanitizeMemory; } llvm_unreachable("bad AttributeKind"); } diff --git a/src/rustllvm/rustllvm.h b/src/rustllvm/rustllvm.h index a30fa3133e28..0baf5528e935 100644 --- a/src/rustllvm/rustllvm.h +++ b/src/rustllvm/rustllvm.h @@ -98,6 +98,9 @@ enum LLVMRustAttribute { UWTable = 17, ZExt = 18, InReg = 19, + SanitizeThread = 20, + SanitizeAddress = 21, + SanitizeMemory = 22, }; typedef struct OpaqueRustString *RustStringRef; diff --git a/src/test/compile-fail/feature-gate-sanitizer-runtime.rs b/src/test/compile-fail/feature-gate-sanitizer-runtime.rs new file mode 100644 index 000000000000..a18641d82469 --- /dev/null +++ b/src/test/compile-fail/feature-gate-sanitizer-runtime.rs @@ -0,0 +1,13 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![sanitizer_runtime] //~ ERROR the `#[sanitizer_runtime]` attribute is + +fn main() {} diff --git a/src/test/run-make/sanitizer-address/Makefile b/src/test/run-make/sanitizer-address/Makefile new file mode 100644 index 000000000000..c490f490cdf7 --- /dev/null +++ b/src/test/run-make/sanitizer-address/Makefile @@ -0,0 +1,21 @@ +-include ../tools.mk + +# NOTE the address sanitizer only supports x86_64 linux +ifndef IS_WINDOWS +ifeq ($(shell uname),Linux) +ifeq ($(shell uname -m),x86_64) +all: + $(RUSTC) -g -Z sanitizer=address -Z print-link-args overflow.rs | grep -q librustc_asan + $(TMPDIR)/overflow 2>&1 | grep -q stack-buffer-overflow +else +all: + +endif +else +all: + +endif +else +all: + +endif diff --git a/src/test/run-make/sanitizer-address/overflow.rs b/src/test/run-make/sanitizer-address/overflow.rs new file mode 100644 index 000000000000..e35c3873f7eb --- /dev/null +++ b/src/test/run-make/sanitizer-address/overflow.rs @@ -0,0 +1,14 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let xs = [0, 1, 2, 3]; + let y = unsafe { *xs.as_ptr().offset(4) }; +} diff --git a/src/test/run-make/sanitizer-dylib/Makefile b/src/test/run-make/sanitizer-dylib/Makefile new file mode 100644 index 000000000000..70a8254a6a65 --- /dev/null +++ b/src/test/run-make/sanitizer-dylib/Makefile @@ -0,0 +1,4 @@ +-include ../tools.mk + +all: + $(RUSTC) -Z sanitizer=leak --crate-type dylib hello.rs 2>&1 | grep -q 'Only executables and rlibs can be compiled with `-Z sanitizer`' diff --git a/src/test/run-make/sanitizer-dylib/hello.rs b/src/test/run-make/sanitizer-dylib/hello.rs new file mode 100644 index 000000000000..41782851a1a6 --- /dev/null +++ b/src/test/run-make/sanitizer-dylib/hello.rs @@ -0,0 +1,13 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + println!("Hello, world!"); +} diff --git a/src/test/run-make/sanitizer-invalid-target/Makefile b/src/test/run-make/sanitizer-invalid-target/Makefile new file mode 100644 index 000000000000..6a1ce8bab2fb --- /dev/null +++ b/src/test/run-make/sanitizer-invalid-target/Makefile @@ -0,0 +1,4 @@ +-include ../tools.mk + +all: + $(RUSTC) -Z sanitizer=leak --target i686-unknown-linux-gnu hello.rs 2>&1 | grep -q 'Sanitizers only work with the `x86_64-unknown-linux-gnu` target' diff --git a/src/test/run-make/sanitizer-invalid-target/hello.rs b/src/test/run-make/sanitizer-invalid-target/hello.rs new file mode 100644 index 000000000000..e9e46b7702a8 --- /dev/null +++ b/src/test/run-make/sanitizer-invalid-target/hello.rs @@ -0,0 +1,13 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(no_core)] +#![no_core] +#![no_main] diff --git a/src/test/run-make/sanitizer-leak/Makefile b/src/test/run-make/sanitizer-leak/Makefile new file mode 100644 index 000000000000..492e328fab23 --- /dev/null +++ b/src/test/run-make/sanitizer-leak/Makefile @@ -0,0 +1,23 @@ +-include ../tools.mk + +# NOTE the leak sanitizer only supports x86_64 linux +# Also, this particular sanitizer sometimes doesn't work so we are not going to +# run the binary +ifndef IS_WINDOWS +ifeq ($(shell uname),Linux) +ifeq ($(shell uname -m),x86_64) +all: + $(RUSTC) -C opt-level=1 -g -Z sanitizer=leak -Z print-link-args leak.rs | grep -q librustc_lsan + $(TMPDIR)/leak 2>&1 | grep -q 'detected memory leaks' +else +all: + +endif +else +all: + +endif +else +all: + +endif diff --git a/src/test/run-make/sanitizer-leak/leak.rs b/src/test/run-make/sanitizer-leak/leak.rs new file mode 100644 index 000000000000..279da6aaae70 --- /dev/null +++ b/src/test/run-make/sanitizer-leak/leak.rs @@ -0,0 +1,16 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::mem; + +fn main() { + let xs = vec![1, 2, 3, 4]; + mem::forget(xs); +} diff --git a/src/test/run-make/sanitizer-memory/Makefile b/src/test/run-make/sanitizer-memory/Makefile new file mode 100644 index 000000000000..f8960992a0df --- /dev/null +++ b/src/test/run-make/sanitizer-memory/Makefile @@ -0,0 +1,21 @@ +-include ../tools.mk + +# NOTE the memory sanitizer only supports x86_64 linux +ifndef IS_WINDOWS +ifeq ($(shell uname),Linux) +ifeq ($(shell uname -m),x86_64) +all: + $(RUSTC) -g -Z sanitizer=memory -Z print-link-args uninit.rs | grep -q librustc_msan + $(TMPDIR)/uninit 2>&1 | grep -q use-of-uninitialized-value +else +all: + +endif +else +all: + +endif +else +all: + +endif diff --git a/src/test/run-make/sanitizer-memory/uninit.rs b/src/test/run-make/sanitizer-memory/uninit.rs new file mode 100644 index 000000000000..8350c7de3aca --- /dev/null +++ b/src/test/run-make/sanitizer-memory/uninit.rs @@ -0,0 +1,16 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::mem; + +fn main() { + let xs: [u8; 4] = unsafe { mem::uninitialized() }; + let y = xs[0] + xs[1]; +} diff --git a/src/test/run-make/sanitizer-thread/Makefile b/src/test/run-make/sanitizer-thread/Makefile new file mode 100644 index 000000000000..e32247c4a9b2 --- /dev/null +++ b/src/test/run-make/sanitizer-thread/Makefile @@ -0,0 +1,21 @@ +-include ../tools.mk + +# NOTE the leak sanitizer only supports x86_64 linux +ifndef IS_WINDOWS +ifeq ($(shell uname),Linux) +ifeq ($(shell uname -m),x86_64) +all: + $(RUSTC) -g -Z sanitizer=thread -Z print-link-args racy.rs | grep -q librustc_tsan + $(TMPDIR)/racy 2>&1 | grep -q 'data race' +else +all: + +endif +else +all: + +endif +else +all: + +endif diff --git a/src/test/run-make/sanitizer-thread/racy.rs b/src/test/run-make/sanitizer-thread/racy.rs new file mode 100644 index 000000000000..dc929e004a47 --- /dev/null +++ b/src/test/run-make/sanitizer-thread/racy.rs @@ -0,0 +1,21 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::thread; + +static mut ANSWER: i32 = 0; + +fn main() { + let t1 = thread::spawn(|| unsafe { ANSWER = 42 }); + unsafe { + ANSWER = 24; + } + t1.join().ok(); +} From 775a93646cb6db5affff24f2260fb60a7723deba Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 3 Feb 2017 18:58:47 -0500 Subject: [PATCH 12/19] build/test the sanitizers only when --enable-sanitizers is used --- configure | 1 + src/bootstrap/check.rs | 9 +++++---- src/bootstrap/compile.rs | 7 +++---- src/bootstrap/config.rs | 7 ++++--- src/bootstrap/config.toml.example | 3 +++ src/bootstrap/lib.rs | 4 ---- src/librustc_llvm/ffi.rs | 2 +- src/test/run-make/sanitizer-address/Makefile | 12 +----------- src/test/run-make/sanitizer-leak/Makefile | 15 +-------------- src/test/run-make/sanitizer-memory/Makefile | 13 +------------ src/test/run-make/sanitizer-thread/Makefile | 13 +------------ 11 files changed, 21 insertions(+), 65 deletions(-) diff --git a/configure b/configure index 4ce80a5e8491..0904143a7b5f 100755 --- a/configure +++ b/configure @@ -649,6 +649,7 @@ opt codegen-tests 1 "run the src/test/codegen tests" opt option-checking 1 "complain about unrecognized options in this configure script" opt ninja 0 "build LLVM using the Ninja generator (for MSVC, requires building in the correct environment)" opt vendor 0 "enable usage of vendored Rust crates" +opt sanitizers 0 "build the sanitizer runtimes (asan, lsan, msan, tsan)" # Optimization and debugging options. These may be overridden by the release channel, etc. opt_nosave optimize 1 "build optimized rust code" diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 573d0df0cee2..32cce45e067a 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -236,6 +236,10 @@ pub fn compiletest(build: &Build, cmd.env("RUSTC_BOOTSTRAP", "1"); build.add_rust_test_threads(&mut cmd); + if build.config.sanitizers { + cmd.env("SANITIZER_SUPPORT", "1"); + } + cmd.arg("--adb-path").arg("adb"); cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR); if target.contains("android") { @@ -332,10 +336,7 @@ pub fn krate(build: &Build, krate: Option<&str>) { let (name, path, features, root) = match mode { Mode::Libstd => { - ("libstd", - "src/rustc/std_shim", - build.std_features(), - "std_shim") + ("libstd", "src/rustc/std_shim", build.std_features(), "std_shim") } Mode::Libtest => { ("libtest", "src/rustc/test_shim", String::new(), "test_shim") diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 3e29339a75b4..d329f9c06904 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -52,15 +52,14 @@ pub fn std(build: &Build, target: &str, compiler: &Compiler) { features.push_str(" force_alloc_system"); } - if compiler.stage != 0 && !build.system_llvm(target) { + if compiler.stage != 0 && build.config.sanitizers { // This variable is used by the sanitizer runtime crates, e.g. // rustc_lsan, to build the sanitizer runtime from C code // When this variable is missing, those crates won't compile the C code, // so we don't set this variable during stage0 where llvm-config is // missing - // We also don't build the runtimes when compiling against system llvm - // because some distributions ship llvm packages that have a directory - // layout different from the one that the runtime's build system expects + // We also only build the runtimes when --enable-sanitizers (or its + // config.toml equivalent) is used cargo.env("LLVM_CONFIG", build.llvm_config(target)); } cargo.arg("--features").arg(features) diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index b171c89c20ad..a31b202a0ae7 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -48,6 +48,7 @@ pub struct Config { pub target_config: HashMap, pub full_bootstrap: bool, pub extended: bool, + pub sanitizers: bool, // llvm codegen options pub llvm_assertions: bool, @@ -108,8 +109,6 @@ pub struct Config { /// Per-target configuration stored in the global configuration structure. #[derive(Default)] pub struct Target { - // `true` if compiling against system LLVM or a pre-built LLVM - pub system_llvm: bool, pub llvm_config: Option, pub jemalloc: Option, pub cc: Option, @@ -150,6 +149,7 @@ struct Build { python: Option, full_bootstrap: Option, extended: Option, + sanitizers: Option, } /// TOML representation of various global install decisions. @@ -294,6 +294,7 @@ pub fn parse(build: &str, file: Option) -> Config { set(&mut config.vendor, build.vendor); set(&mut config.full_bootstrap, build.full_bootstrap); set(&mut config.extended, build.extended); + set(&mut config.sanitizers, build.sanitizers); if let Some(ref install) = toml.install { config.prefix = install.prefix.clone().map(PathBuf::from); @@ -437,6 +438,7 @@ macro_rules! check { ("VENDOR", self.vendor), ("FULL_BOOTSTRAP", self.full_bootstrap), ("EXTENDED", self.extended), + ("SANITIZERS", self.sanitizers), } match key { @@ -514,7 +516,6 @@ macro_rules! check { .or_insert(Target::default()); let root = parse_configure_path(value); target.llvm_config = Some(push_exe_path(root, &["bin", "llvm-config"])); - target.system_llvm = true; } "CFG_JEMALLOC_ROOT" if value.len() > 0 => { let target = self.target_config.entry(self.build.clone()) diff --git a/src/bootstrap/config.toml.example b/src/bootstrap/config.toml.example index a53419ad7fd7..025fe990f91d 100644 --- a/src/bootstrap/config.toml.example +++ b/src/bootstrap/config.toml.example @@ -124,6 +124,9 @@ # disabled by default. #extended = false +# Build the sanitizer runtimes +#sanitizers = false + # ============================================================================= # General install configuration options # ============================================================================= diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 21dd4b1520a8..1d01b8773cec 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -717,10 +717,6 @@ fn llvm_config(&self, target: &str) -> PathBuf { } } - fn system_llvm(&self, target: &str) -> bool { - self.config.target_config.get(target).map(|t| t.system_llvm).unwrap_or(false) - } - /// Returns the path to `FileCheck` binary for the specified target fn llvm_filecheck(&self, target: &str) -> PathBuf { let target_config = self.config.target_config.get(target); diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index 6c9976ca3f8e..bd24f7657e76 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -127,7 +127,7 @@ pub enum Attribute { ZExt = 18, InReg = 19, SanitizeThread = 20, - SanitizeAddress = 21, + SanitizeAddress = 21, SanitizeMemory = 22, } diff --git a/src/test/run-make/sanitizer-address/Makefile b/src/test/run-make/sanitizer-address/Makefile index c490f490cdf7..5931145f3a47 100644 --- a/src/test/run-make/sanitizer-address/Makefile +++ b/src/test/run-make/sanitizer-address/Makefile @@ -1,9 +1,7 @@ -include ../tools.mk # NOTE the address sanitizer only supports x86_64 linux -ifndef IS_WINDOWS -ifeq ($(shell uname),Linux) -ifeq ($(shell uname -m),x86_64) +ifdef SANITIZER_SUPPORT all: $(RUSTC) -g -Z sanitizer=address -Z print-link-args overflow.rs | grep -q librustc_asan $(TMPDIR)/overflow 2>&1 | grep -q stack-buffer-overflow @@ -11,11 +9,3 @@ else all: endif -else -all: - -endif -else -all: - -endif diff --git a/src/test/run-make/sanitizer-leak/Makefile b/src/test/run-make/sanitizer-leak/Makefile index 492e328fab23..f02d948fdc84 100644 --- a/src/test/run-make/sanitizer-leak/Makefile +++ b/src/test/run-make/sanitizer-leak/Makefile @@ -1,11 +1,6 @@ -include ../tools.mk -# NOTE the leak sanitizer only supports x86_64 linux -# Also, this particular sanitizer sometimes doesn't work so we are not going to -# run the binary -ifndef IS_WINDOWS -ifeq ($(shell uname),Linux) -ifeq ($(shell uname -m),x86_64) +ifdef SANITIZER_SUPPORT all: $(RUSTC) -C opt-level=1 -g -Z sanitizer=leak -Z print-link-args leak.rs | grep -q librustc_lsan $(TMPDIR)/leak 2>&1 | grep -q 'detected memory leaks' @@ -13,11 +8,3 @@ else all: endif -else -all: - -endif -else -all: - -endif diff --git a/src/test/run-make/sanitizer-memory/Makefile b/src/test/run-make/sanitizer-memory/Makefile index f8960992a0df..08682e5975e5 100644 --- a/src/test/run-make/sanitizer-memory/Makefile +++ b/src/test/run-make/sanitizer-memory/Makefile @@ -1,9 +1,6 @@ -include ../tools.mk -# NOTE the memory sanitizer only supports x86_64 linux -ifndef IS_WINDOWS -ifeq ($(shell uname),Linux) -ifeq ($(shell uname -m),x86_64) +ifdef SANITIZER_SUPPORT all: $(RUSTC) -g -Z sanitizer=memory -Z print-link-args uninit.rs | grep -q librustc_msan $(TMPDIR)/uninit 2>&1 | grep -q use-of-uninitialized-value @@ -11,11 +8,3 @@ else all: endif -else -all: - -endif -else -all: - -endif diff --git a/src/test/run-make/sanitizer-thread/Makefile b/src/test/run-make/sanitizer-thread/Makefile index e32247c4a9b2..8bb89a241cb0 100644 --- a/src/test/run-make/sanitizer-thread/Makefile +++ b/src/test/run-make/sanitizer-thread/Makefile @@ -1,9 +1,6 @@ -include ../tools.mk -# NOTE the leak sanitizer only supports x86_64 linux -ifndef IS_WINDOWS -ifeq ($(shell uname),Linux) -ifeq ($(shell uname -m),x86_64) +ifdef SANITIZER_SUPPORT all: $(RUSTC) -g -Z sanitizer=thread -Z print-link-args racy.rs | grep -q librustc_tsan $(TMPDIR)/racy 2>&1 | grep -q 'data race' @@ -11,11 +8,3 @@ else all: endif -else -all: - -endif -else -all: - -endif From 22097e6827b726f517e94c31df0728b481f57245 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sat, 4 Feb 2017 20:10:29 -0500 Subject: [PATCH 13/19] use helper function in the rebuild logic of the rustc_*san crates --- src/Cargo.lock | 4 ++++ src/librustc_asan/Cargo.toml | 1 + src/librustc_asan/build.rs | 19 ++++--------------- src/librustc_lsan/Cargo.toml | 1 + src/librustc_lsan/build.rs | 19 ++++--------------- src/librustc_msan/Cargo.toml | 1 + src/librustc_msan/build.rs | 19 ++++--------------- src/librustc_tsan/Cargo.toml | 1 + src/librustc_tsan/build.rs | 19 ++++--------------- 9 files changed, 24 insertions(+), 60 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 8e987ba3b7f1..c1222dc444a2 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -273,6 +273,7 @@ name = "rustc_asan" version = "0.0.0" dependencies = [ "alloc_system 0.0.0", + "build_helper 0.1.0", "cmake 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -415,6 +416,7 @@ name = "rustc_lsan" version = "0.0.0" dependencies = [ "alloc_system 0.0.0", + "build_helper 0.1.0", "cmake 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -458,6 +460,7 @@ name = "rustc_msan" version = "0.0.0" dependencies = [ "alloc_system 0.0.0", + "build_helper 0.1.0", "cmake 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -548,6 +551,7 @@ name = "rustc_tsan" version = "0.0.0" dependencies = [ "alloc_system 0.0.0", + "build_helper 0.1.0", "cmake 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] diff --git a/src/librustc_asan/Cargo.toml b/src/librustc_asan/Cargo.toml index abbd7cc0966e..2d4872b1fc94 100644 --- a/src/librustc_asan/Cargo.toml +++ b/src/librustc_asan/Cargo.toml @@ -9,6 +9,7 @@ name = "rustc_asan" path = "lib.rs" [build-dependencies] +build_helper = { path = "../build_helper" } cmake = "0.1.18" [dependencies] diff --git a/src/librustc_asan/build.rs b/src/librustc_asan/build.rs index 3e33efcadb80..015be14bd495 100644 --- a/src/librustc_asan/build.rs +++ b/src/librustc_asan/build.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +extern crate build_helper; extern crate cmake; use std::path::PathBuf; @@ -29,21 +30,9 @@ fn main() { dst.join("build/lib/linux").display()); println!("cargo:rustc-link-lib=static=clang_rt.asan-x86_64"); - let src_dir = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()); - let mut stack = src_dir.join("../compiler-rt") - .read_dir() - .unwrap() - .map(|e| e.unwrap()) - .filter(|e| &*e.file_name() != ".git") - .collect::>(); - while let Some(entry) = stack.pop() { - let path = entry.path(); - if entry.file_type().unwrap().is_dir() { - stack.extend(path.read_dir().unwrap().map(|e| e.unwrap())); - } else { - println!("cargo:rerun-if-changed={}", path.display()); - } - } + build_helper::rerun_if_changed_anything_in_dir(&PathBuf::from(env::var("CARGO_MANIFEST_DIR") + .unwrap()) + .join("../compiler-rt")); } println!("cargo:rerun-if-changed=build.rs"); diff --git a/src/librustc_lsan/Cargo.toml b/src/librustc_lsan/Cargo.toml index ac53f3fe73a7..bc1f2ead7688 100644 --- a/src/librustc_lsan/Cargo.toml +++ b/src/librustc_lsan/Cargo.toml @@ -9,6 +9,7 @@ name = "rustc_lsan" path = "lib.rs" [build-dependencies] +build_helper = { path = "../build_helper" } cmake = "0.1.18" [dependencies] diff --git a/src/librustc_lsan/build.rs b/src/librustc_lsan/build.rs index f13928d2bd45..5773777d1f81 100644 --- a/src/librustc_lsan/build.rs +++ b/src/librustc_lsan/build.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +extern crate build_helper; extern crate cmake; use std::path::PathBuf; @@ -29,21 +30,9 @@ fn main() { dst.join("build/lib/linux").display()); println!("cargo:rustc-link-lib=static=clang_rt.lsan-x86_64"); - let src_dir = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()); - let mut stack = src_dir.join("../compiler-rt") - .read_dir() - .unwrap() - .map(|e| e.unwrap()) - .filter(|e| &*e.file_name() != ".git") - .collect::>(); - while let Some(entry) = stack.pop() { - let path = entry.path(); - if entry.file_type().unwrap().is_dir() { - stack.extend(path.read_dir().unwrap().map(|e| e.unwrap())); - } else { - println!("cargo:rerun-if-changed={}", path.display()); - } - } + build_helper::rerun_if_changed_anything_in_dir(&PathBuf::from(env::var("CARGO_MANIFEST_DIR") + .unwrap()) + .join("../compiler-rt")); } println!("cargo:rerun-if-changed=build.rs"); diff --git a/src/librustc_msan/Cargo.toml b/src/librustc_msan/Cargo.toml index 628746ac232d..45cc6b9839fb 100644 --- a/src/librustc_msan/Cargo.toml +++ b/src/librustc_msan/Cargo.toml @@ -9,6 +9,7 @@ name = "rustc_msan" path = "lib.rs" [build-dependencies] +build_helper = { path = "../build_helper" } cmake = "0.1.18" [dependencies] diff --git a/src/librustc_msan/build.rs b/src/librustc_msan/build.rs index bf630c7844a2..7a4c8f707393 100644 --- a/src/librustc_msan/build.rs +++ b/src/librustc_msan/build.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +extern crate build_helper; extern crate cmake; use std::path::PathBuf; @@ -29,21 +30,9 @@ fn main() { dst.join("build/lib/linux").display()); println!("cargo:rustc-link-lib=static=clang_rt.msan-x86_64"); - let src_dir = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()); - let mut stack = src_dir.join("../compiler-rt") - .read_dir() - .unwrap() - .map(|e| e.unwrap()) - .filter(|e| &*e.file_name() != ".git") - .collect::>(); - while let Some(entry) = stack.pop() { - let path = entry.path(); - if entry.file_type().unwrap().is_dir() { - stack.extend(path.read_dir().unwrap().map(|e| e.unwrap())); - } else { - println!("cargo:rerun-if-changed={}", path.display()); - } - } + build_helper::rerun_if_changed_anything_in_dir(&PathBuf::from(env::var("CARGO_MANIFEST_DIR") + .unwrap()) + .join("../compiler-rt")); } println!("cargo:rerun-if-changed=build.rs"); diff --git a/src/librustc_tsan/Cargo.toml b/src/librustc_tsan/Cargo.toml index 2af0ae3f7341..66d6236361ea 100644 --- a/src/librustc_tsan/Cargo.toml +++ b/src/librustc_tsan/Cargo.toml @@ -9,6 +9,7 @@ name = "rustc_tsan" path = "lib.rs" [build-dependencies] +build_helper = { path = "../build_helper" } cmake = "0.1.18" [dependencies] diff --git a/src/librustc_tsan/build.rs b/src/librustc_tsan/build.rs index 2ba5866ab9d4..84326ae8a710 100644 --- a/src/librustc_tsan/build.rs +++ b/src/librustc_tsan/build.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +extern crate build_helper; extern crate cmake; use std::path::PathBuf; @@ -29,21 +30,9 @@ fn main() { dst.join("build/lib/linux").display()); println!("cargo:rustc-link-lib=static=clang_rt.tsan-x86_64"); - let src_dir = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()); - let mut stack = src_dir.join("../compiler-rt") - .read_dir() - .unwrap() - .map(|e| e.unwrap()) - .filter(|e| &*e.file_name() != ".git") - .collect::>(); - while let Some(entry) = stack.pop() { - let path = entry.path(); - if entry.file_type().unwrap().is_dir() { - stack.extend(path.read_dir().unwrap().map(|e| e.unwrap())); - } else { - println!("cargo:rerun-if-changed={}", path.display()); - } - } + build_helper::rerun_if_changed_anything_in_dir(&PathBuf::from(env::var("CARGO_MANIFEST_DIR") + .unwrap()) + .join("../compiler-rt")); } println!("cargo:rerun-if-changed=build.rs"); From 72058e4f4cff46daf5c60cbd7c7978734ecb13cc Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sat, 4 Feb 2017 20:15:20 -0500 Subject: [PATCH 14/19] enable sanitizers on x86_64-linux releases --- src/ci/docker/dist-x86-linux/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/dist-x86-linux/Dockerfile b/src/ci/docker/dist-x86-linux/Dockerfile index 4e4f5dd6f1e5..7238888a4af4 100644 --- a/src/ci/docker/dist-x86-linux/Dockerfile +++ b/src/ci/docker/dist-x86-linux/Dockerfile @@ -76,5 +76,5 @@ RUN curl -L https://api.pub.build.mozilla.org/tooltool/sha512/$SCCACHE_DIGEST | ENV HOSTS=i686-unknown-linux-gnu ENV HOSTS=$HOSTS,x86_64-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended +ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended --enable-sanitizers ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS From 47ae2393e63e0d78118262b70245d34b8c8ba929 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sun, 5 Feb 2017 19:09:32 -0500 Subject: [PATCH 15/19] enable sanitizers on build job that tests x86_64 linux --- src/ci/docker/x86_64-gnu/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/x86_64-gnu/Dockerfile b/src/ci/docker/x86_64-gnu/Dockerfile index 6919487e17c3..e903b6ddc64c 100644 --- a/src/ci/docker/x86_64-gnu/Dockerfile +++ b/src/ci/docker/x86_64-gnu/Dockerfile @@ -22,5 +22,5 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini rm dumb-init_*.deb ENTRYPOINT ["/usr/bin/dumb-init", "--"] -ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu +ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu --enable-sanitizers ENV SCRIPT python2.7 ../x.py test && python2.7 ../x.py dist From 1914c8e0aca19b844b14a8b8032bc9376c6d37f0 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Mon, 6 Feb 2017 14:12:56 -0500 Subject: [PATCH 16/19] dist-x86-linux: install newer kernel headers --- src/ci/docker/dist-x86-linux/Dockerfile | 5 ++++ src/ci/docker/dist-x86-linux/build-headers.sh | 25 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100755 src/ci/docker/dist-x86-linux/build-headers.sh diff --git a/src/ci/docker/dist-x86-linux/Dockerfile b/src/ci/docker/dist-x86-linux/Dockerfile index 7238888a4af4..a06e47c3bc92 100644 --- a/src/ci/docker/dist-x86-linux/Dockerfile +++ b/src/ci/docker/dist-x86-linux/Dockerfile @@ -63,6 +63,11 @@ RUN ./build-git.sh COPY build-cmake.sh /tmp/ RUN ./build-cmake.sh +# for sanitizers, we need kernel headers files newer than the ones CentOS ships +# with so we install newer ones here +COPY build-headers.sh /tmp/ +RUN ./build-headers.sh + RUN curl -Lo /rustroot/dumb-init \ https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64 && \ chmod +x /rustroot/dumb-init diff --git a/src/ci/docker/dist-x86-linux/build-headers.sh b/src/ci/docker/dist-x86-linux/build-headers.sh new file mode 100755 index 000000000000..4ce38fd9205e --- /dev/null +++ b/src/ci/docker/dist-x86-linux/build-headers.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# Copyright 2017 The Rust Project Developers. See the COPYRIGHT +# file at the top-level directory of this distribution and at +# http://rust-lang.org/COPYRIGHT. +# +# Licensed under the Apache License, Version 2.0 or the MIT license +# , at your +# option. This file may not be copied, modified, or distributed +# except according to those terms. + +set -ex +source shared.sh + +curl https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-3.2.84.tar.xz | unxz | tar x + +cd linux-3.2.84 +hide_output make mrproper +hide_output make INSTALL_HDR_PATH=dest headers_install + +find dest/include \( -name .install -o -name ..install.cmd \) -delete +yes | cp -fr dest/include/* /usr/include + +cd .. +rm -rf linux-3.2.84 From 78a11f1b97f3ab3fa8c9e225f800489051777bc4 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Tue, 7 Feb 2017 22:47:03 -0500 Subject: [PATCH 17/19] fix the sanitizer-dylib test on non x86_64 linux hosts --- src/test/run-make/sanitizer-dylib/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-make/sanitizer-dylib/Makefile b/src/test/run-make/sanitizer-dylib/Makefile index 70a8254a6a65..34fdf3b9709d 100644 --- a/src/test/run-make/sanitizer-dylib/Makefile +++ b/src/test/run-make/sanitizer-dylib/Makefile @@ -1,4 +1,4 @@ -include ../tools.mk all: - $(RUSTC) -Z sanitizer=leak --crate-type dylib hello.rs 2>&1 | grep -q 'Only executables and rlibs can be compiled with `-Z sanitizer`' + $(RUSTC) -Z sanitizer=leak --crate-type dylib --target x86_64-unknown-linux-gnu hello.rs 2>&1 | grep -q 'Only executables and rlibs can be compiled with `-Z sanitizer`' From 8fc0b37428e23dd031af5209bc8a22b9657ec66f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 8 Feb 2017 17:13:46 -0800 Subject: [PATCH 18/19] travis: Fix build order of dist-x86-linux I just tried to build this container locally but it looks like connecting to ftp.gnu.org requires SNI, so let's build curl/OpenSSL first to ensure that we've got an SNI-capable client to download gcc/binutils with. --- src/ci/docker/dist-x86-linux/Dockerfile | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ci/docker/dist-x86-linux/Dockerfile b/src/ci/docker/dist-x86-linux/Dockerfile index 4e4f5dd6f1e5..d5bb8ea77e32 100644 --- a/src/ci/docker/dist-x86-linux/Dockerfile +++ b/src/ci/docker/dist-x86-linux/Dockerfile @@ -21,17 +21,7 @@ RUN yum upgrade -y && yum install -y \ ENV PATH=/rustroot/bin:$PATH ENV LD_LIBRARY_PATH=/rustroot/lib64:/rustroot/lib WORKDIR /tmp - -# binutils < 2.22 has a bug where the 32-bit executables it generates -# immediately segfault in Rust, so we need to install our own binutils. -# -# See https://github.com/rust-lang/rust/issues/20440 for more info COPY shared.sh build-binutils.sh /tmp/ -RUN ./build-binutils.sh - -# Need a newer version of gcc than centos has to compile LLVM nowadays -COPY build-gcc.sh /tmp/ -RUN ./build-gcc.sh # We need a build of openssl which supports SNI to download artifacts from # static.rust-lang.org. This'll be used to link into libcurl below (and used @@ -49,6 +39,16 @@ RUN ./build-openssl.sh COPY build-curl.sh /tmp/ RUN ./build-curl.sh +# binutils < 2.22 has a bug where the 32-bit executables it generates +# immediately segfault in Rust, so we need to install our own binutils. +# +# See https://github.com/rust-lang/rust/issues/20440 for more info +RUN ./build-binutils.sh + +# Need a newer version of gcc than centos has to compile LLVM nowadays +COPY build-gcc.sh /tmp/ +RUN ./build-gcc.sh + # CentOS 5.5 has Python 2.4 by default, but LLVM needs 2.7+ COPY build-python.sh /tmp/ RUN ./build-python.sh From e180dd541a8ae48e4aaf8934765f67955932252f Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 8 Feb 2017 22:58:53 -0500 Subject: [PATCH 19/19] sanitizer-dylib: only run where std for x86_64-linux is available --- src/test/run-make/sanitizer-dylib/Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/test/run-make/sanitizer-dylib/Makefile b/src/test/run-make/sanitizer-dylib/Makefile index 34fdf3b9709d..835d5b0d9d8c 100644 --- a/src/test/run-make/sanitizer-dylib/Makefile +++ b/src/test/run-make/sanitizer-dylib/Makefile @@ -1,4 +1,8 @@ -include ../tools.mk +ifeq ($(TARGET),x86_64-unknown-linux-gnu) all: - $(RUSTC) -Z sanitizer=leak --crate-type dylib --target x86_64-unknown-linux-gnu hello.rs 2>&1 | grep -q 'Only executables and rlibs can be compiled with `-Z sanitizer`' + $(RUSTC) -Z sanitizer=leak --crate-type dylib --target $(TARGET) hello.rs 2>&1 | grep -q 'Only executables and rlibs can be compiled with `-Z sanitizer`' +else +all: +endif