Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 3e5d88c

Browse files
authoredAug 11, 2023
Rollup merge of rust-lang#114642 - anforowicz:fix-asan-lto, r=tmiasko
Mark `___asan_globals_registered` as an exported symbol for LTO Export a weak symbol defined by AddressSanitizer instrumentation. Previously, when using LTO, the symbol would get internalized and eliminated. Fixes rust-lang#113404. --------------- FWIW, let me list similar PRs from the past + who reviewed them: * rust-lang#68410 (fixing `__msan_keep_going` and `__msan_track_origins`; reviewed by `@varkor)` * rust-lang#60038 and rust-lang#48346 (fixing `__llvm_profile_raw_version` and `__llvm_profile_filename`; reviewed by `@alexcrichton)`
2 parents b03864d + 73b5842 commit 3e5d88c

File tree

2 files changed

+59
-32
lines changed

2 files changed

+59
-32
lines changed
 

‎compiler/rustc_codegen_ssa/src/back/symbol_export.rs

+23-32
Original file line numberDiff line numberDiff line change
@@ -245,50 +245,41 @@ fn exported_symbols_provider_local(
245245
))
246246
}
247247

248+
// Rust assumes that all code provided to (non-plugin) LTO comes from Rust, so it knows about
249+
// all symbols that are involved. This doesn't hold up for symbols that get injected by LLVM,
250+
// so they need to be special-cased.
251+
let mut externally_injected_weak_symbols = Vec::new();
248252
if tcx.sess.instrument_coverage() || tcx.sess.opts.cg.profile_generate.enabled() {
249253
// These are weak symbols that point to the profile version and the
250254
// profile name, which need to be treated as exported so LTO doesn't nix
251255
// them.
252-
const PROFILER_WEAK_SYMBOLS: [&str; 2] =
253-
["__llvm_profile_raw_version", "__llvm_profile_filename"];
254-
255-
symbols.extend(PROFILER_WEAK_SYMBOLS.iter().map(|sym| {
256-
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym));
257-
(
258-
exported_symbol,
259-
SymbolExportInfo {
260-
level: SymbolExportLevel::C,
261-
kind: SymbolExportKind::Data,
262-
used: false,
263-
},
264-
)
265-
}));
256+
externally_injected_weak_symbols.push("__llvm_profile_raw_version");
257+
externally_injected_weak_symbols.push("__llvm_profile_filename");
266258
}
267-
268259
if tcx.sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::MEMORY) {
269-
let mut msan_weak_symbols = Vec::new();
270-
271260
// Similar to profiling, preserve weak msan symbol during LTO.
272261
if tcx.sess.opts.unstable_opts.sanitizer_recover.contains(SanitizerSet::MEMORY) {
273-
msan_weak_symbols.push("__msan_keep_going");
262+
externally_injected_weak_symbols.push("__msan_keep_going");
274263
}
275-
276264
if tcx.sess.opts.unstable_opts.sanitizer_memory_track_origins != 0 {
277-
msan_weak_symbols.push("__msan_track_origins");
265+
externally_injected_weak_symbols.push("__msan_track_origins");
278266
}
279-
280-
symbols.extend(msan_weak_symbols.into_iter().map(|sym| {
281-
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym));
282-
(
283-
exported_symbol,
284-
SymbolExportInfo {
285-
level: SymbolExportLevel::C,
286-
kind: SymbolExportKind::Data,
287-
used: false,
288-
},
289-
)
290-
}));
291267
}
268+
if tcx.sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::ADDRESS) {
269+
// Similar to profiling, preserve weak asan symbols during LTO.
270+
externally_injected_weak_symbols.push("___asan_globals_registered");
271+
}
272+
symbols.extend(externally_injected_weak_symbols.into_iter().map(|sym| {
273+
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym));
274+
(
275+
exported_symbol,
276+
SymbolExportInfo {
277+
level: SymbolExportLevel::C,
278+
kind: SymbolExportKind::Data,
279+
used: false,
280+
},
281+
)
282+
}));
292283

293284
if tcx.crate_types().contains(&CrateType::Dylib)
294285
|| tcx.crate_types().contains(&CrateType::ProcMacro)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Verifies that AddressSanitizer symbols show up as expected in LLVM IR
2+
// with -Zsanitizer (DO NOT SUBMIT: add ASAN (no LTO) and ASAN-LTO2 (lto=fat) tests).
3+
//
4+
// Notes about the `compile-flags` below:
5+
//
6+
// * The original issue only reproed with LTO - this is why this angle has
7+
// extra test coverage via different `revisions`
8+
// * To observe the failure/repro at LLVM-IR level we need to use `staticlib`
9+
// which necessitates `-C prefer-dynamic=false` - without the latter flag,
10+
// we would have run into "cannot prefer dynamic linking when performing LTO".
11+
//
12+
// needs-sanitizer-address
13+
//
14+
// revisions:ASAN ASAN-LTO
15+
//[ASAN] compile-flags: -Zsanitizer=address
16+
//[ASAN-LTO] compile-flags: -Zsanitizer=address -C prefer-dynamic=false -C lto
17+
18+
#![crate_type="staticlib"]
19+
20+
// The test below mimics `CACHED_POW10` from `library/core/src/num/flt2dec/strategy/grisu.rs` which
21+
// (because of incorrect handling of `___asan_globals_registered` during LTO) was incorrectly
22+
// reported as an ODR violation in https://crbug.com/1459233#c1. Before this bug was fixed,
23+
// `___asan_globals_registered` would show up as `internal global i64`.
24+
//
25+
// See https://github.com/rust-lang/rust/issues/113404 for more discussion.
26+
//
27+
// CHECK: @___asan_globals_registered = common hidden global i64 0
28+
// CHECK: @__start_asan_globals = extern_weak hidden global i64
29+
// CHECK: @__stop_asan_globals = extern_weak hidden global i64
30+
#[no_mangle]
31+
pub static CACHED_POW10: [(u64, i16, i16); 4] = [
32+
(0xe61acf033d1a45df, -1087, -308),
33+
(0xab70fe17c79ac6ca, -1060, -300),
34+
(0xff77b1fcbebcdc4f, -1034, -292),
35+
(0xbe5691ef416bd60c, -1007, -284),
36+
];

0 commit comments

Comments
 (0)
Please sign in to comment.