From d9abc46a680750c63e0f14e19d900fa51cfbd094 Mon Sep 17 00:00:00 2001 From: Lukasz Anforowicz Date: Tue, 8 Aug 2023 18:07:25 +0000 Subject: [PATCH] Mark `___asan_globals_registered` as an exported symbol for LTO Fixes https://github.com/rust-lang/rust/issues/113404 --- .../rustc_codegen_ssa/src/back/metadata.rs | 11 +---- .../src/back/symbol_export.rs | 10 +++++ compiler/rustc_target/src/spec/mod.rs | 14 +++++++ .../address-sanitizer-globals-tracking.rs | 42 +++++++++++++++++++ 4 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index 4c8547407531d..49497a889a255 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -214,16 +214,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option return None, }; - let binary_format = if sess.target.is_like_osx { - BinaryFormat::MachO - } else if sess.target.is_like_windows { - BinaryFormat::Coff - } else if sess.target.is_like_aix { - BinaryFormat::Xcoff - } else { - BinaryFormat::Elf - }; - + let binary_format = sess.target.binary_format(); let mut file = write::Object::new(binary_format, architecture, endianness); if sess.target.is_like_osx { if let Some(build_version) = macho_object_build_version_for_target(&sess.target) { diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 0ba2833484c29..8532910f84c34 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -2,6 +2,7 @@ use crate::base::allocator_kind_for_codegen; use std::collections::hash_map::Entry::*; +use object::BinaryFormat; use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE}; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::DefKind; @@ -265,6 +266,15 @@ fn exported_symbols_provider_local( externally_injected_weak_symbols.push("__msan_track_origins"); } } + if tcx.sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::ADDRESS) { + // Similar to profiling, preserve weak asan symbols during LTO. + match tcx.sess.target.binary_format() { + BinaryFormat::Elf | BinaryFormat::MachO => { + 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)); ( diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 31b6961bb6220..0c327eec1543f 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -39,6 +39,7 @@ use crate::abi::{Endian, Integer, Size, TargetDataLayout, TargetDataLayoutErrors use crate::json::{Json, ToJson}; use crate::spec::abi::{lookup as lookup_abi, Abi}; use crate::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault}; +use object::BinaryFormat; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_fs_util::try_canonicalize; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; @@ -2053,6 +2054,19 @@ fn add_link_args(link_args: &mut LinkArgs, flavor: LinkerFlavor, args: &[&'stati } impl TargetOptions { + /// Binary format (e.g. ELF) implied by the `TargetOptions`. + pub fn binary_format(&self) -> BinaryFormat { + if self.is_like_osx { + BinaryFormat::MachO + } else if self.is_like_windows { + BinaryFormat::Coff + } else if self.is_like_aix { + BinaryFormat::Xcoff + } else { + BinaryFormat::Elf + } + } + fn link_args(flavor: LinkerFlavor, args: &[&'static str]) -> LinkArgs { let mut link_args = LinkArgs::new(); add_link_args(&mut link_args, flavor, args); diff --git a/tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs b/tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs new file mode 100644 index 0000000000000..8088beea6a6f4 --- /dev/null +++ b/tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs @@ -0,0 +1,42 @@ +// Verifies that AddressSanitizer symbols show up as expected in LLVM IR with -Zsanitizer. +// +// 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". +// +// The test is restricted to `only-linux`, because the sanitizer-related instrumentation +// is target specific. In particular, `___asan_globals_registered` is only used in the +// `InstrumentGlobalsELF` and `InstrumentGlobalsMachO` code paths. +// +// needs-sanitizer-address +// only-linux +// +// 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` rather than `common hidden +// global i64`. (The test expectations ignore the exact type because on `arm-android` the type +// is `i32` rather than `i64`.) +// +// See https://github.com/rust-lang/rust/issues/113404 for more discussion. +// +// CHECK: @___asan_globals_registered = common hidden global +// CHECK: @__start_asan_globals = extern_weak hidden global +// CHECK: @__stop_asan_globals = extern_weak hidden global +#[no_mangle] +pub static CACHED_POW10: [(u64, i16, i16); 4] = [ + (0xe61acf033d1a45df, -1087, -308), + (0xab70fe17c79ac6ca, -1060, -300), + (0xff77b1fcbebcdc4f, -1034, -292), + (0xbe5691ef416bd60c, -1007, -284), +];