Mangle #[rustc_std_internal_symbol] to include the rustc version unless #[no_mangle] is used
This commit is contained in:
parent
42de015549
commit
c0639ef8e4
2 changed files with 79 additions and 0 deletions
|
@ -112,6 +112,8 @@ mod v0;
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
pub mod test;
|
pub mod test;
|
||||||
|
|
||||||
|
pub use v0::mangle_internal_symbol;
|
||||||
|
|
||||||
/// This function computes the symbol name for the given `instance` and the
|
/// This function computes the symbol name for the given `instance` and the
|
||||||
/// given instantiating crate. That is, if you know that instance X is
|
/// given instantiating crate. That is, if you know that instance X is
|
||||||
/// instantiated in crate Y, this is the symbol name this instance would have.
|
/// instantiated in crate Y, this is the symbol name this instance would have.
|
||||||
|
@ -183,6 +185,39 @@ fn compute_symbol_name<'tcx>(
|
||||||
CodegenFnAttrs::EMPTY
|
CodegenFnAttrs::EMPTY
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
|
||||||
|
// Items marked as #[rustc_std_internal_symbol] need to have a fixed
|
||||||
|
// symbol name because it is used to import items from another crate
|
||||||
|
// without a direct dependency. As such it is not possible to look up
|
||||||
|
// the mangled name for the `Instance` from the crate metadata of the
|
||||||
|
// defining crate.
|
||||||
|
// Weak lang items automatically get #[rustc_std_internal_symbol]
|
||||||
|
// applied by the code computing the CodegenFnAttrs.
|
||||||
|
// We are mangling all #[rustc_std_internal_symbol] items that don't
|
||||||
|
// also have #[no_mangle] as a combination of the rustc version and the
|
||||||
|
// unmangled linkage name. This is to ensure that if we link against a
|
||||||
|
// staticlib compiled by a different rustc version, we don't get symbol
|
||||||
|
// conflicts or even UB due to a different implementation/ABI. Rust
|
||||||
|
// staticlibs currently export all symbols, including those that are
|
||||||
|
// hidden in cdylibs.
|
||||||
|
// We are using the v0 symbol mangling scheme here as we need to be
|
||||||
|
// consistent across all crates and in some contexts the legacy symbol
|
||||||
|
// mangling scheme can't be used. For example both the GCC backend and
|
||||||
|
// Rust-for-Linux don't support some of the characters used by the
|
||||||
|
// legacy symbol mangling scheme.
|
||||||
|
let name = if tcx.is_foreign_item(def_id) {
|
||||||
|
if let Some(name) = attrs.link_name { name } else { tcx.item_name(def_id) }
|
||||||
|
} else {
|
||||||
|
if let Some(name) = attrs.export_name { name } else { tcx.item_name(def_id) }
|
||||||
|
};
|
||||||
|
|
||||||
|
if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) {
|
||||||
|
return name.to_string();
|
||||||
|
} else {
|
||||||
|
return v0::mangle_internal_symbol(tcx, name.as_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Foreign items by default use no mangling for their symbol name. There's a
|
// Foreign items by default use no mangling for their symbol name. There's a
|
||||||
// few exceptions to this rule though:
|
// few exceptions to this rule though:
|
||||||
//
|
//
|
||||||
|
@ -198,6 +233,8 @@ fn compute_symbol_name<'tcx>(
|
||||||
// is present we mangle everything on wasm because the demangled form will
|
// is present we mangle everything on wasm because the demangled form will
|
||||||
// show up in the `wasm-import-name` custom attribute in LLVM IR.
|
// show up in the `wasm-import-name` custom attribute in LLVM IR.
|
||||||
//
|
//
|
||||||
|
// * `#[rustc_std_internal_symbol]` mangles the symbol name in a special way
|
||||||
|
// both for exports and imports through foreign items. This is handled above.
|
||||||
// [1]: https://bugs.llvm.org/show_bug.cgi?id=44316
|
// [1]: https://bugs.llvm.org/show_bug.cgi?id=44316
|
||||||
if tcx.is_foreign_item(def_id)
|
if tcx.is_foreign_item(def_id)
|
||||||
&& (!tcx.sess.target.is_like_wasm
|
&& (!tcx.sess.target.is_like_wasm
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
use std::hash::Hasher;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
|
@ -6,6 +7,8 @@ use rustc_abi::{ExternAbi, Integer};
|
||||||
use rustc_data_structures::base_n::ToBaseN;
|
use rustc_data_structures::base_n::ToBaseN;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::intern::Interned;
|
use rustc_data_structures::intern::Interned;
|
||||||
|
use rustc_data_structures::stable_hasher::StableHasher;
|
||||||
|
use rustc_hashes::Hash64;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::CtorKind;
|
use rustc_hir::def::CtorKind;
|
||||||
use rustc_hir::def_id::{CrateNum, DefId};
|
use rustc_hir::def_id::{CrateNum, DefId};
|
||||||
|
@ -70,6 +73,45 @@ pub(super) fn mangle<'tcx>(
|
||||||
std::mem::take(&mut cx.out)
|
std::mem::take(&mut cx.out)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn mangle_internal_symbol<'tcx>(tcx: TyCtxt<'tcx>, item_name: &str) -> String {
|
||||||
|
let prefix = "_R";
|
||||||
|
let mut cx: SymbolMangler<'_> = SymbolMangler {
|
||||||
|
tcx,
|
||||||
|
start_offset: prefix.len(),
|
||||||
|
paths: FxHashMap::default(),
|
||||||
|
types: FxHashMap::default(),
|
||||||
|
consts: FxHashMap::default(),
|
||||||
|
binders: vec![],
|
||||||
|
out: String::from(prefix),
|
||||||
|
};
|
||||||
|
|
||||||
|
cx.path_append_ns(
|
||||||
|
|cx| {
|
||||||
|
cx.push("C");
|
||||||
|
cx.push_disambiguator({
|
||||||
|
let mut hasher = StableHasher::new();
|
||||||
|
// Incorporate the rustc version to ensure #[rustc_std_internal_symbol] functions
|
||||||
|
// get a different symbol name depending on the rustc version.
|
||||||
|
//
|
||||||
|
// RUSTC_FORCE_RUSTC_VERSION is ignored here as otherwise different we would get an
|
||||||
|
// abi incompatibility with the standard library.
|
||||||
|
hasher.write(tcx.sess.cfg_version.as_bytes());
|
||||||
|
|
||||||
|
let hash: Hash64 = hasher.finish();
|
||||||
|
hash.as_u64()
|
||||||
|
});
|
||||||
|
cx.push_ident("__rustc");
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
'v',
|
||||||
|
0,
|
||||||
|
item_name,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
std::mem::take(&mut cx.out)
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn mangle_typeid_for_trait_ref<'tcx>(
|
pub(super) fn mangle_typeid_for_trait_ref<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
trait_ref: ty::ExistentialTraitRef<'tcx>,
|
trait_ref: ty::ExistentialTraitRef<'tcx>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue