Skip to content

Commit

Permalink
Rollup merge of rust-lang#114642 - anforowicz:fix-asan-lto, r=tmiasko
Browse files Browse the repository at this point in the history
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)``
  • Loading branch information
matthiaskrgr authored Aug 12, 2023
2 parents 7879823 + 73b5842 commit 6cdb399
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 32 deletions.
55 changes: 23 additions & 32 deletions compiler/rustc_codegen_ssa/src/back/symbol_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,50 +245,41 @@ fn exported_symbols_provider_local(
))
}

// Rust assumes that all code provided to (non-plugin) LTO comes from Rust, so it knows about
// all symbols that are involved. This doesn't hold up for symbols that get injected by LLVM,
// so they need to be special-cased.
let mut externally_injected_weak_symbols = Vec::new();
if tcx.sess.instrument_coverage() || tcx.sess.opts.cg.profile_generate.enabled() {
// These are weak symbols that point to the profile version and the
// profile name, which need to be treated as exported so LTO doesn't nix
// them.
const PROFILER_WEAK_SYMBOLS: [&str; 2] =
["__llvm_profile_raw_version", "__llvm_profile_filename"];

symbols.extend(PROFILER_WEAK_SYMBOLS.iter().map(|sym| {
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym));
(
exported_symbol,
SymbolExportInfo {
level: SymbolExportLevel::C,
kind: SymbolExportKind::Data,
used: false,
},
)
}));
externally_injected_weak_symbols.push("__llvm_profile_raw_version");
externally_injected_weak_symbols.push("__llvm_profile_filename");
}

if tcx.sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::MEMORY) {
let mut msan_weak_symbols = Vec::new();

// Similar to profiling, preserve weak msan symbol during LTO.
if tcx.sess.opts.unstable_opts.sanitizer_recover.contains(SanitizerSet::MEMORY) {
msan_weak_symbols.push("__msan_keep_going");
externally_injected_weak_symbols.push("__msan_keep_going");
}

if tcx.sess.opts.unstable_opts.sanitizer_memory_track_origins != 0 {
msan_weak_symbols.push("__msan_track_origins");
externally_injected_weak_symbols.push("__msan_track_origins");
}

symbols.extend(msan_weak_symbols.into_iter().map(|sym| {
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym));
(
exported_symbol,
SymbolExportInfo {
level: SymbolExportLevel::C,
kind: SymbolExportKind::Data,
used: false,
},
)
}));
}
if tcx.sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::ADDRESS) {
// Similar to profiling, preserve weak asan symbols during LTO.
externally_injected_weak_symbols.push("___asan_globals_registered");
}
symbols.extend(externally_injected_weak_symbols.into_iter().map(|sym| {
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym));
(
exported_symbol,
SymbolExportInfo {
level: SymbolExportLevel::C,
kind: SymbolExportKind::Data,
used: false,
},
)
}));

if tcx.crate_types().contains(&CrateType::Dylib)
|| tcx.crate_types().contains(&CrateType::ProcMacro)
Expand Down
36 changes: 36 additions & 0 deletions tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Verifies that AddressSanitizer symbols show up as expected in LLVM IR
// with -Zsanitizer (DO NOT SUBMIT: add ASAN (no LTO) and ASAN-LTO2 (lto=fat) tests).
//
// Notes about the `compile-flags` below:
//
// * The original issue only reproed with LTO - this is why this angle has
// extra test coverage via different `revisions`
// * To observe the failure/repro at LLVM-IR level we need to use `staticlib`
// which necessitates `-C prefer-dynamic=false` - without the latter flag,
// we would have run into "cannot prefer dynamic linking when performing LTO".
//
// needs-sanitizer-address
//
// revisions:ASAN ASAN-LTO
//[ASAN] compile-flags: -Zsanitizer=address
//[ASAN-LTO] compile-flags: -Zsanitizer=address -C prefer-dynamic=false -C lto

#![crate_type="staticlib"]

// The test below mimics `CACHED_POW10` from `library/core/src/num/flt2dec/strategy/grisu.rs` which
// (because of incorrect handling of `___asan_globals_registered` during LTO) was incorrectly
// reported as an ODR violation in https://crbug.com/1459233#c1. Before this bug was fixed,
// `___asan_globals_registered` would show up as `internal global i64`.
//
// See https://github.com/rust-lang/rust/issues/113404 for more discussion.
//
// CHECK: @___asan_globals_registered = common hidden global i64 0
// CHECK: @__start_asan_globals = extern_weak hidden global i64
// CHECK: @__stop_asan_globals = extern_weak hidden global i64
#[no_mangle]
pub static CACHED_POW10: [(u64, i16, i16); 4] = [
(0xe61acf033d1a45df, -1087, -308),
(0xab70fe17c79ac6ca, -1060, -300),
(0xff77b1fcbebcdc4f, -1034, -292),
(0xbe5691ef416bd60c, -1007, -284),
];

0 comments on commit 6cdb399

Please sign in to comment.