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 9898c31282c34..713e6f1ab99eb 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 713e6f1ab99eb..c6fc2ea40590c 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 c6fc2ea40590c..dd3ccb82211f5 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 60dae19d876c9..c591c09bf20e2 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 40eb7e5ab78c3..6234d89024441 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2132,10 +2132,23 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
    ")?; 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 item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, 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 0000000000000..afe1daf5983a2 --- /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 9327cc0cf7faf..9878d1c08bac1 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 8c15a6630a33c..3eaac82d9fa85 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -317,6 +317,8 @@ impl Builder { 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 34aee77ae2107..0000000000000 --- 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 34aee77ae2107..0000000000000 --- 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 dd3ccb82211f5..4910313af9303 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 0000000000000..78d96398b9587 --- /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 e264153929491..1ef2cb4ed153c 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 06cf32ad0f6b5..8e987ba3b7f15 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 19aac0f36bb27..573d0df0cee20 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 776b91028a1a3..3e29339a75b47 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 6e077691b3a05..b171c89c20ad3 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 @@ impl Config { .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 df1218752d1c9..21dd4b1520a88 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -599,7 +599,8 @@ impl Build { /// 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 @@ impl Build { } } + 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 a8fc4c169fac4..d30da544a8afc 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 6537cc1adce00..2d80fc32c469d 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -229,6 +229,7 @@ pub trait CrateStore<'tcx> { 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 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { 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 d41c2ba93b935..24615f2fa6992 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 @@ macro_rules! options { 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 @@ macro_rules! options { } 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 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "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 0000000000000..abbd7cc0966ea --- /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 0000000000000..3e33efcadb807 --- /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 0000000000000..71a166b91ebcb --- /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 8510b9f523cb5..6c9976ca3f8e4 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 0000000000000..ac53f3fe73a75 --- /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 0000000000000..f13928d2bd457 --- /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 0000000000000..71a166b91ebcb --- /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 81a4f7c93b6e9..55dc5aa2876f6 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -17,7 +17,8 @@ use schema::CrateRoot; 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 @@ impl<'a> CrateLoader<'a> { &|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 @@ impl<'a> CrateLoader<'a> { 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 beba5faf3d034..4709ca6101c79 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -297,6 +297,11 @@ impl CrateMetadata { 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 39581a4696088..7b0177bfd23ed 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -297,6 +297,10 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { 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 0000000000000..628746ac232df --- /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 0000000000000..bf630c7844a22 --- /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 0000000000000..71a166b91ebcb --- /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 4ddf8a883bc48..1cbfa26b705ac 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 add_upstream_rust_crates(cmd: &mut Linker, } } + // 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 b3a2d66a07c11..8e71c57109519 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -12,7 +12,7 @@ use back::lto; 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 bf7a02eb0f196..7ac482459ee39 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 0000000000000..2af0ae3f73411 --- /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 0000000000000..2ba5866ab9d44 --- /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 0000000000000..71a166b91ebcb --- /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 8146e7fb1edaf..2ba7517d3d202 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 52ef2a05fcf19..6a16a0ef353a4 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -328,6 +328,10 @@ declare_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 const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG 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 14c9c5544b188..db96079d3e916 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 c7bcd2558186e..58dfe0a3d38f3 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 a30fa3133e282..0baf5528e9356 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 0000000000000..a18641d824691 --- /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 0000000000000..c490f490cdf7f --- /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 0000000000000..e35c3873f7eb5 --- /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 0000000000000..70a8254a6a655 --- /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 0000000000000..41782851a1a6d --- /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 0000000000000..6a1ce8bab2fb6 --- /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 0000000000000..e9e46b7702a80 --- /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 0000000000000..492e328fab239 --- /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 0000000000000..279da6aaae707 --- /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 0000000000000..f8960992a0df0 --- /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 0000000000000..8350c7de3acab --- /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 0000000000000..e32247c4a9b24 --- /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 0000000000000..dc929e004a479 --- /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 4ce80a5e84919..0904143a7b5f6 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 573d0df0cee20..32cce45e067ad 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 3e29339a75b47..d329f9c069043 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 b171c89c20ad3..a31b202a0ae7b 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 @@ impl 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 @@ impl Config { ("VENDOR", self.vendor), ("FULL_BOOTSTRAP", self.full_bootstrap), ("EXTENDED", self.extended), + ("SANITIZERS", self.sanitizers), } match key { @@ -514,7 +516,6 @@ impl Config { .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 a53419ad7fd78..025fe990f91da 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 21dd4b1520a88..1d01b8773cec8 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -717,10 +717,6 @@ impl Build { } } - 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 6c9976ca3f8e4..bd24f7657e761 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 c490f490cdf7f..5931145f3a47d 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 492e328fab239..f02d948fdc84f 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 f8960992a0df0..08682e5975e51 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 e32247c4a9b24..8bb89a241cb05 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 8e987ba3b7f15..c1222dc444a22 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 abbd7cc0966ea..2d4872b1fc942 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 3e33efcadb807..015be14bd495a 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 ac53f3fe73a75..bc1f2ead76884 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 f13928d2bd457..5773777d1f81b 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 628746ac232df..45cc6b9839fb8 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 bf630c7844a22..7a4c8f7073933 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 2af0ae3f73411..66d6236361ea2 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 2ba5866ab9d44..84326ae8a7106 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 4e4f5dd6f1e53..7238888a4af4f 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 6919487e17c3e..e903b6ddc64cd 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 7238888a4af4f..a06e47c3bc922 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 0000000000000..4ce38fd9205e2 --- /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 70a8254a6a655..34fdf3b9709d7 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 4e4f5dd6f1e53..d5bb8ea77e32b 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 34fdf3b9709d7..835d5b0d9d8cd 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