Skip to content

Commit 4348447

Browse files
committed
Mangle symbols with a mangled name close to PDB limits with v0
instead of legacy mangling to avoid linker errors
1 parent 6a884ad commit 4348447

File tree

2 files changed

+29
-1
lines changed
  • compiler

2 files changed

+29
-1
lines changed

compiler/rustc_symbol_mangling/src/lib.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,31 @@ fn compute_symbol_name<'tcx>(
291291
export::compute_hash_of_export_fn(tcx, instance)
292292
),
293293
false => match mangling_version {
294-
SymbolManglingVersion::Legacy => legacy::mangle(tcx, instance, instantiating_crate),
294+
SymbolManglingVersion::Legacy => {
295+
let mangled_name = legacy::mangle(tcx, instance, instantiating_crate);
296+
297+
let mangled_name_too_long = {
298+
// The PDB debug info format cannot store mangled symbol names for which its
299+
// internal record exceeds u16::MAX bytes, a limit multiple Rust projects have been
300+
// hitting due to the verbosity of legacy name manglng. Depending on the linker version
301+
// in use, such symbol names can lead to linker crashes or incomprehensible linker error
302+
// about a limit being hit.
303+
// Mangle those symbols with v0 mangling instead, which gives us more room to breathe
304+
// as v0 mangling is more compact.
305+
// Empirical testing has shown the limit for the symbol name to be 65521 bytes; use
306+
// 65000 bytes to leave some room for prefixes / suffixes as well as unknown scenarios
307+
// with a different limit.
308+
const MAX_SYMBOL_LENGTH: usize = 65000;
309+
310+
tcx.sess.target.uses_pdb_debuginfo() && mangled_name.len() > MAX_SYMBOL_LENGTH
311+
};
312+
313+
if mangled_name_too_long {
314+
v0::mangle(tcx, instance, instantiating_crate, false)
315+
} else {
316+
mangled_name
317+
}
318+
}
295319
SymbolManglingVersion::V0 => v0::mangle(tcx, instance, instantiating_crate, false),
296320
SymbolManglingVersion::Hashed => {
297321
hashed::mangle(tcx, instance, instantiating_crate, || {

compiler/rustc_target/src/spec/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2397,6 +2397,10 @@ impl TargetOptions {
23972397
// XCOFF and MachO don't support COMDAT.
23982398
!self.is_like_aix && !self.is_like_darwin
23992399
}
2400+
2401+
pub fn uses_pdb_debuginfo(&self) -> bool {
2402+
self.debuginfo_kind == DebuginfoKind::Pdb
2403+
}
24002404
}
24012405

24022406
impl TargetOptions {

0 commit comments

Comments
 (0)