-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Closed
Labels
A-linkageArea: linking into static, shared libraries and binariesArea: linking into static, shared libraries and binariesC-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
Otherwise with -Zsymbol-mangling-version=v0
and no -Cmetadata
, symbols from the same crate compiled with different versions of rustc are named the same. This makes it possible to replace a rust dylib compiled with one version of rustc with one compiled by another version of rustc even if the ABI doesn't match.
The crate disambiguator is calculated at
rust/compiler/rustc_interface/src/util.rs
Lines 500 to 531 in 354cc75
pub(crate) fn compute_crate_disambiguator(session: &Session) -> CrateDisambiguator { | |
use std::hash::Hasher; | |
// The crate_disambiguator is a 128 bit hash. The disambiguator is fed | |
// into various other hashes quite a bit (symbol hashes, incr. comp. hashes, | |
// debuginfo type IDs, etc), so we don't want it to be too wide. 128 bits | |
// should still be safe enough to avoid collisions in practice. | |
let mut hasher = StableHasher::new(); | |
let mut metadata = session.opts.cg.metadata.clone(); | |
// We don't want the crate_disambiguator to dependent on the order | |
// -C metadata arguments, so sort them: | |
metadata.sort(); | |
// Every distinct -C metadata value is only incorporated once: | |
metadata.dedup(); | |
hasher.write(b"metadata"); | |
for s in &metadata { | |
// Also incorporate the length of a metadata string, so that we generate | |
// different values for `-Cmetadata=ab -Cmetadata=c` and | |
// `-Cmetadata=a -Cmetadata=bc` | |
hasher.write_usize(s.len()); | |
hasher.write(s.as_bytes()); | |
} | |
// Also incorporate crate type, so that we don't get symbol conflicts when | |
// linking against a library of the same name, if this is an executable. | |
let is_exe = session.crate_types().contains(&CrateType::Executable); | |
hasher.write(if is_exe { b"exe" } else { b"lib" }); | |
CrateDisambiguator::from(hasher.finish::<Fingerprint>()) | |
} |
option_env!("CFG_VERSION").unwrap_or("unknown version")
in the hash. This matches what the version info included in the rustc metadata header.
Metadata
Metadata
Assignees
Labels
A-linkageArea: linking into static, shared libraries and binariesArea: linking into static, shared libraries and binariesC-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.