Skip to content

Commit d9abc46

Browse files
committed
Mark ___asan_globals_registered as an exported symbol for LTO
Fixes #113404
1 parent 66b15fc commit d9abc46

File tree

4 files changed

+67
-10
lines changed

4 files changed

+67
-10
lines changed

compiler/rustc_codegen_ssa/src/back/metadata.rs

+1-10
Original file line numberDiff line numberDiff line change
@@ -214,16 +214,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
214214
// Unsupported architecture.
215215
_ => return None,
216216
};
217-
let binary_format = if sess.target.is_like_osx {
218-
BinaryFormat::MachO
219-
} else if sess.target.is_like_windows {
220-
BinaryFormat::Coff
221-
} else if sess.target.is_like_aix {
222-
BinaryFormat::Xcoff
223-
} else {
224-
BinaryFormat::Elf
225-
};
226-
217+
let binary_format = sess.target.binary_format();
227218
let mut file = write::Object::new(binary_format, architecture, endianness);
228219
if sess.target.is_like_osx {
229220
if let Some(build_version) = macho_object_build_version_for_target(&sess.target) {

compiler/rustc_codegen_ssa/src/back/symbol_export.rs

+10
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::base::allocator_kind_for_codegen;
22

33
use std::collections::hash_map::Entry::*;
44

5+
use object::BinaryFormat;
56
use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE};
67
use rustc_data_structures::fx::FxHashMap;
78
use rustc_hir::def::DefKind;
@@ -265,6 +266,15 @@ fn exported_symbols_provider_local(
265266
externally_injected_weak_symbols.push("__msan_track_origins");
266267
}
267268
}
269+
if tcx.sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::ADDRESS) {
270+
// Similar to profiling, preserve weak asan symbols during LTO.
271+
match tcx.sess.target.binary_format() {
272+
BinaryFormat::Elf | BinaryFormat::MachO => {
273+
externally_injected_weak_symbols.push("___asan_globals_registered")
274+
}
275+
_ => (),
276+
}
277+
}
268278
symbols.extend(externally_injected_weak_symbols.into_iter().map(|sym| {
269279
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym));
270280
(

compiler/rustc_target/src/spec/mod.rs

+14
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use crate::abi::{Endian, Integer, Size, TargetDataLayout, TargetDataLayoutErrors
3939
use crate::json::{Json, ToJson};
4040
use crate::spec::abi::{lookup as lookup_abi, Abi};
4141
use crate::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault};
42+
use object::BinaryFormat;
4243
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
4344
use rustc_fs_util::try_canonicalize;
4445
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
@@ -2053,6 +2054,19 @@ fn add_link_args(link_args: &mut LinkArgs, flavor: LinkerFlavor, args: &[&'stati
20532054
}
20542055

20552056
impl TargetOptions {
2057+
/// Binary format (e.g. ELF) implied by the `TargetOptions`.
2058+
pub fn binary_format(&self) -> BinaryFormat {
2059+
if self.is_like_osx {
2060+
BinaryFormat::MachO
2061+
} else if self.is_like_windows {
2062+
BinaryFormat::Coff
2063+
} else if self.is_like_aix {
2064+
BinaryFormat::Xcoff
2065+
} else {
2066+
BinaryFormat::Elf
2067+
}
2068+
}
2069+
20562070
fn link_args(flavor: LinkerFlavor, args: &[&'static str]) -> LinkArgs {
20572071
let mut link_args = LinkArgs::new();
20582072
add_link_args(&mut link_args, flavor, args);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Verifies that AddressSanitizer symbols show up as expected in LLVM IR with -Zsanitizer.
2+
//
3+
// Notes about the `compile-flags` below:
4+
//
5+
// * The original issue only reproed with LTO - this is why this angle has
6+
// extra test coverage via different `revisions`
7+
// * To observe the failure/repro at LLVM-IR level we need to use `staticlib`
8+
// which necessitates `-C prefer-dynamic=false` - without the latter flag,
9+
// we would have run into "cannot prefer dynamic linking when performing LTO".
10+
//
11+
// The test is restricted to `only-linux`, because the sanitizer-related instrumentation
12+
// is target specific. In particular, `___asan_globals_registered` is only used in the
13+
// `InstrumentGlobalsELF` and `InstrumentGlobalsMachO` code paths.
14+
//
15+
// needs-sanitizer-address
16+
// only-linux
17+
//
18+
// revisions:ASAN ASAN-LTO
19+
//[ASAN] compile-flags: -Zsanitizer=address
20+
//[ASAN-LTO] compile-flags: -Zsanitizer=address -C prefer-dynamic=false -C lto
21+
22+
#![crate_type="staticlib"]
23+
24+
// The test below mimics `CACHED_POW10` from `library/core/src/num/flt2dec/strategy/grisu.rs` which
25+
// (because of incorrect handling of `___asan_globals_registered` during LTO) was incorrectly
26+
// reported as an ODR violation in https://crbug.com/1459233#c1. Before this bug was fixed,
27+
// `___asan_globals_registered` would show up as `internal global i64` rather than `common hidden
28+
// global i64`. (The test expectations ignore the exact type because on `arm-android` the type
29+
// is `i32` rather than `i64`.)
30+
//
31+
// See https://github.com/rust-lang/rust/issues/113404 for more discussion.
32+
//
33+
// CHECK: @___asan_globals_registered = common hidden global
34+
// CHECK: @__start_asan_globals = extern_weak hidden global
35+
// CHECK: @__stop_asan_globals = extern_weak hidden global
36+
#[no_mangle]
37+
pub static CACHED_POW10: [(u64, i16, i16); 4] = [
38+
(0xe61acf033d1a45df, -1087, -308),
39+
(0xab70fe17c79ac6ca, -1060, -300),
40+
(0xff77b1fcbebcdc4f, -1034, -292),
41+
(0xbe5691ef416bd60c, -1007, -284),
42+
];

0 commit comments

Comments
 (0)