Skip to content

Commit e9c966b

Browse files
committed
Mangle personality symbol
Previously, std-internal symbols (like `__rust_alloc` or `rust_panic`) were changed to now be mangled via a v0 scheme with the compiler version hash (`_RNvCs4CIB29Id3dw_7___rustc10rust_panic`) to make it possible to have multiple staticlibs (as long as they have different version hashes) in the same program without symbol conflicts. But the personality function remained unmangled, because LLVM hardcodes that name. I made a change in LLVM that makes LLVM now check the suffix instead of an exact match, so we can mangle the personality function with this scheme. This removes the last completely unmangled symbol from Rust staticlibs! (though the mangling is still quite weak, so it's still not as nice as it would ideally be). Before, on a trivial staticlib: ``` readelf -s liblib.a | rg GLOBAL | rg -v " UND | HIDDEN " | rg -v ' _ZN' 8: 0000000000000000 5 FUNC GLOBAL DEFAULT 3 _RNvCseCSg29WUqSe_7___rustc12___rust_alloc 10: 0000000000000000 5 FUNC GLOBAL DEFAULT 5 _RNvCseCSg29WUqSe_7___rustc14___rust_dealloc 12: 0000000000000000 5 FUNC GLOBAL DEFAULT 7 _RNvCseCSg29WUqSe_7___rustc14___rust_realloc 14: 0000000000000000 5 FUNC GLOBAL DEFAULT 9 _RNvCseCSg29WUqSe_7___rustc19___rust_alloc_zeroed 16: 0000000000000000 3 FUNC GLOBAL DEFAULT 11 _RNvCseCSg29WUqSe_7___rustc42___rust_alloc_error_handler_should_panic_v2 17: 0000000000000000 1 FUNC GLOBAL DEFAULT 12 _RNvCseCSg29WUqSe_7___rustc35___rust_no_alloc_shim_is_unstable_v2 3383: 0000000000000000 111 FUNC GLOBAL DEFAULT 5 _RNvCseCSg29WUqSe_7___rustc10rust_panic 3387: 0000000000000000 93 FUNC GLOBAL DEFAULT 7 _RNvCseCSg29WUqSe_7___rustc11___rdl_alloc 3390: 0000000000000000 10 FUNC GLOBAL DEFAULT 9 _RNvCseCSg29WUqSe_7___rustc12___rust_abort 3391: 0000000000000000 6 FUNC GLOBAL DEFAULT 11 _RNvCseCSg29WUqSe_7___rustc13___rdl_dealloc 3393: 0000000000000000 167 FUNC GLOBAL DEFAULT 13 _RNvCseCSg29WUqSe_7___rustc13___rdl_realloc 3396: 0000000000000000 203 FUNC GLOBAL DEFAULT 15 _RNvCseCSg29WUqSe_7___rustc17___rust_drop_panic 3399: 0000000000000000 29 FUNC GLOBAL DEFAULT 18 _RNvCseCSg29WUqSe_7___rustc17rust_begin_unwind 3401: 0000000000000000 140 FUNC GLOBAL DEFAULT 20 _RNvCseCSg29WUqSe_7___rustc18___rdl_alloc_zeroed 3404: 0000000000000000 203 FUNC GLOBAL DEFAULT 22 _RNvCseCSg29WUqSe_7___rustc24___rust_foreign_exception 3405: 0000000000000000 19 FUNC GLOBAL DEFAULT 25 _RNvCseCSg29WUqSe_7___rustc26___rust_alloc_error_handler 4410: 0000000000000000 1471 FUNC GLOBAL DEFAULT 2752 rust_eh_personality 25: 0000000000000000 161 FUNC GLOBAL DEFAULT 5 _RNvCseCSg29WUqSe_7___rustc18___rust_start_panic 32: 0000000000000000 82 FUNC GLOBAL DEFAULT 8 _RNvCseCSg29WUqSe_7___rustc20___rust_panic_cleanup 249: 0000000000000000 182 FUNC GLOBAL DEFAULT 5 _RNvCseCSg29WUqSe_7___rustc25___rdl_alloc_error_handler 3: 0000000000000000 57 FUNC GLOBAL DEFAULT 3 _RNvCseCSg29WUqSe_7___rustc17___rust_probestack ``` After: ``` 8: 0000000000000000 5 FUNC GLOBAL DEFAULT 3 _RNvCs4CIB29Id3dw_7___rustc12___rust_alloc 10: 0000000000000000 5 FUNC GLOBAL DEFAULT 5 _RNvCs4CIB29Id3dw_7___rustc14___rust_dealloc 12: 0000000000000000 5 FUNC GLOBAL DEFAULT 7 _RNvCs4CIB29Id3dw_7___rustc14___rust_realloc 14: 0000000000000000 5 FUNC GLOBAL DEFAULT 9 _RNvCs4CIB29Id3dw_7___rustc19___rust_alloc_zeroed 16: 0000000000000000 3 FUNC GLOBAL DEFAULT 11 _RNvCs4CIB29Id3dw_7___rustc42___rust_alloc_error_handler_should_panic_v2 17: 0000000000000000 1 FUNC GLOBAL DEFAULT 12 _RNvCs4CIB29Id3dw_7___rustc35___rust_no_alloc_shim_is_unstable_v2 422: 0000000000000000 19 FUNC GLOBAL DEFAULT 5 _RNvCs4CIB29Id3dw_7___rustc26___rust_alloc_error_handler 429: 0000000000000000 308 FUNC GLOBAL DEFAULT 5 _RNvCs4CIB29Id3dw_7___rustc19rust_eh_personality 349: 0000000000000000 10 FUNC GLOBAL DEFAULT 5 _RNvCs4CIB29Id3dw_7___rustc12___rust_abort 164: 0000000000000000 93 FUNC GLOBAL DEFAULT 5 _RNvCs4CIB29Id3dw_7___rustc11___rdl_alloc 167: 0000000000000000 11 FUNC GLOBAL DEFAULT 7 _RNvCs4CIB29Id3dw_7___rustc13___rdl_dealloc 169: 0000000000000000 167 FUNC GLOBAL DEFAULT 9 _RNvCs4CIB29Id3dw_7___rustc13___rdl_realloc 172: 0000000000000000 140 FUNC GLOBAL DEFAULT 11 _RNvCs4CIB29Id3dw_7___rustc18___rdl_alloc_zeroed 688: 0000000000000000 106 FUNC GLOBAL DEFAULT 5 _RNvCs4CIB29Id3dw_7___rustc10rust_panic 693: 0000000000000000 207 FUNC GLOBAL DEFAULT 7 _RNvCs4CIB29Id3dw_7___rustc17___rust_drop_panic 696: 0000000000000000 29 FUNC GLOBAL DEFAULT 10 _RNvCs4CIB29Id3dw_7___rustc17rust_begin_unwind 698: 0000000000000000 207 FUNC GLOBAL DEFAULT 12 _RNvCs4CIB29Id3dw_7___rustc24___rust_foreign_exception 26: 0000000000000000 161 FUNC GLOBAL DEFAULT 5 _RNvCs4CIB29Id3dw_7___rustc18___rust_start_panic 33: 0000000000000000 82 FUNC GLOBAL DEFAULT 8 _RNvCs4CIB29Id3dw_7___rustc20___rust_panic_cleanup 88: 0000000000000000 182 FUNC GLOBAL DEFAULT 5 _RNvCs4CIB29Id3dw_7___rustc25___rdl_alloc_error_handler 3: 0000000000000000 57 FUNC GLOBAL DEFAULT 3 _RNvCs4CIB29Id3dw_7___rustc17___rust_probestack ```
1 parent 271951b commit e9c966b

21 files changed

Lines changed: 94 additions & 36 deletions

File tree

compiler/rustc_codegen_cranelift/src/debuginfo/emit.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,11 @@ impl WriterRelocate {
9393
// HACK rust_eh_personality is likely not defined in the same crate,
9494
// so get_finalized_function won't work. Use the rust_eh_personality
9595
// of cg_clif itself, which is likely ABI compatible.
96-
if jit_module.declarations().get_function_decl(func_id).name.as_deref()
97-
== Some("rust_eh_personality")
96+
if jit_module
97+
.declarations()
98+
.get_function_decl(func_id)
99+
.name
100+
.is_some_and(|name| name.ends_with("rust_eh_personality"))
98101
{
99102
unsafe extern "C" {
100103
fn rust_eh_personality() -> !;

compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub(crate) struct UnwindContext {
2525
}
2626

2727
impl UnwindContext {
28-
pub(crate) fn new(module: &mut dyn Module, pic_eh_frame: bool) -> Self {
28+
pub(crate) fn new(module: &mut dyn Module, tcx: TyCtxt<'_>, pic_eh_frame: bool) -> Self {
2929
let endian = match module.isa().endianness() {
3030
Endianness::Little => RunTimeEndian::Little,
3131
Endianness::Big => RunTimeEndian::Big,
@@ -70,7 +70,7 @@ impl UnwindContext {
7070
// FIXME use eh_personality lang item instead
7171
let personality = module
7272
.declare_function(
73-
"rust_eh_personality",
73+
&rustc_symbol_mangling::mangle_internal_symbol(tcx, "rust_eh_personality"),
7474
Linkage::Import,
7575
&Signature {
7676
params: vec![

compiler/rustc_codegen_cranelift/src/driver/aot.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,8 @@ fn produce_final_output_artifacts(
322322
// These are used in linking steps and will be cleaned up afterward.
323323
}
324324

325-
fn make_module(sess: &Session, name: String) -> UnwindModule<ObjectModule> {
326-
let isa = crate::build_isa(sess, false);
325+
fn make_module(tcx: TyCtxt<'_>, name: String) -> UnwindModule<ObjectModule> {
326+
let isa = crate::build_isa(tcx.sess, false);
327327

328328
let mut builder =
329329
ObjectBuilder::new(isa, name + ".o", cranelift_module::default_libcall_names()).unwrap();
@@ -333,12 +333,13 @@ fn make_module(sess: &Session, name: String) -> UnwindModule<ObjectModule> {
333333
// explicitly disable it on MinGW as rustc already disables it by default on MinGW and as such
334334
// isn't tested. If rustc enables it in the future on MinGW, we can re-enable it too once it has
335335
// been on MinGW.
336-
let default_function_sections = sess.target.function_sections && !sess.target.is_like_windows;
336+
let default_function_sections =
337+
tcx.sess.target.function_sections && !tcx.sess.target.is_like_windows;
337338
builder.per_function_section(
338-
sess.opts.unstable_opts.function_sections.unwrap_or(default_function_sections),
339+
tcx.sess.opts.unstable_opts.function_sections.unwrap_or(default_function_sections),
339340
);
340341

341-
UnwindModule::new(ObjectModule::new(builder), true)
342+
UnwindModule::new(ObjectModule::new(builder), tcx, true)
342343
}
343344

344345
fn emit_cgu(
@@ -579,7 +580,7 @@ fn module_codegen(
579580
ConcurrencyLimiterToken,
580581
),
581582
) -> OngoingModuleCodegen {
582-
let mut module = make_module(tcx.sess, cgu_name.as_str().to_string());
583+
let mut module = make_module(tcx, cgu_name.as_str().to_string());
583584

584585
let (mut debug_context, codegened_functions, mut global_asm) =
585586
codegen_cgu_content(tcx, &mut module, cgu_name);
@@ -643,7 +644,7 @@ fn module_codegen(
643644
}
644645

645646
fn emit_allocator_module(tcx: TyCtxt<'_>) -> Option<CompiledModule> {
646-
let mut allocator_module = make_module(tcx.sess, "allocator_shim".to_string());
647+
let mut allocator_module = make_module(tcx, "allocator_shim".to_string());
647648
let created_alloc_shim = crate::allocator::codegen(tcx, &mut allocator_module);
648649

649650
if created_alloc_shim {

compiler/rustc_codegen_cranelift/src/unwind_module.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use cranelift_module::{
77
ModuleReloc, ModuleResult,
88
};
99
use cranelift_object::{ObjectModule, ObjectProduct};
10+
use rustc_middle::ty::TyCtxt;
1011

1112
use crate::UnwindContext;
1213

@@ -17,8 +18,8 @@ pub(crate) struct UnwindModule<T> {
1718
}
1819

1920
impl<T: Module> UnwindModule<T> {
20-
pub(crate) fn new(mut module: T, pic_eh_frame: bool) -> Self {
21-
let unwind_context = UnwindContext::new(&mut module, pic_eh_frame);
21+
pub(crate) fn new(mut module: T, tcx: TyCtxt<'_>, pic_eh_frame: bool) -> Self {
22+
let unwind_context = UnwindContext::new(&mut module, tcx, pic_eh_frame);
2223
UnwindModule { module, unwind_context }
2324
}
2425
}

compiler/rustc_codegen_gcc/src/context.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,10 +457,13 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
457457
self.declare_fn(symbol_name, fn_abi)
458458
}
459459
_ => {
460+
let rust_name;
460461
let name = if wants_msvc_seh(self.sess()) {
461462
"__CxxFrameHandler3"
462463
} else {
463-
"rust_eh_personality"
464+
rust_name =
465+
rustc_symbol_mangling::mangle_internal_symbol(tcx, "rust_eh_personality");
466+
&rust_name
464467
};
465468
self.declare_func(name, self.type_i32(), &[], true)
466469
}

compiler/rustc_codegen_gcc/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ impl CodegenBackend for GccCodegenBackend {
258258
LTO_SUPPORTED.store(lto_supported, Ordering::SeqCst);
259259
self.lto_supported.store(lto_supported, Ordering::SeqCst);
260260

261+
// FIXME: This needs to mangle the personality, but that requires a tcx.
261262
gccjit::set_global_personality_function_name(b"rust_eh_personality\0");
262263
}
263264

compiler/rustc_codegen_llvm/src/back/lto.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ fn prepare_lto(
7878
symbols_below_threshold.push(c"__llvm_profile_counter_bias".to_owned());
7979

8080
// LTO seems to discard this otherwise under certain circumstances.
81-
symbols_below_threshold.push(c"rust_eh_personality".to_owned());
81+
symbols_below_threshold.push(CString::new(cgcx.rust_eh_personality_symbol.clone()).unwrap());
8282

8383
// If we're performing LTO for the entire crate graph, then for each of our
8484
// upstream dependencies, find the corresponding rlib and load the bitcode

compiler/rustc_codegen_llvm/src/context.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -901,7 +901,17 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
901901
DUMMY_SP,
902902
)),
903903
_ => {
904-
let name = name.unwrap_or("rust_eh_personality");
904+
let mangled_symbol;
905+
let name = match name {
906+
Some(name) => name,
907+
None => {
908+
mangled_symbol = rustc_symbol_mangling::mangle_internal_symbol(
909+
tcx,
910+
"rust_eh_personality",
911+
);
912+
mangled_symbol.as_str()
913+
}
914+
};
905915
if let Some(llfn) = self.get_declared_value(name) {
906916
llfn
907917
} else {

compiler/rustc_codegen_llvm/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,11 @@ impl CodegenBackend for LlvmCodegenBackend {
346346
llvm::LLVMRustLLVMHasZstdCompression()
347347
}
348348

349+
fn can_mangle_eh_personality(&self) -> bool {
350+
// https://github.com/llvm/llvm-project/pull/166095
351+
llvm_util::get_version() > (22, 0, 0)
352+
}
353+
349354
fn target_config(&self, sess: &Session) -> TargetConfig {
350355
target_config(sess)
351356
}

compiler/rustc_codegen_ssa/src/back/write.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ pub struct CodegenContext<B: WriteBackendMethods> {
348348
pub split_debuginfo: rustc_target::spec::SplitDebuginfo,
349349
pub split_dwarf_kind: rustc_session::config::SplitDwarfKind,
350350
pub pointer_size: Size,
351+
pub rust_eh_personality_symbol: String,
351352

352353
/// LLVM optimizations for which we want to print remarks.
353354
pub remark: Passes,
@@ -1328,6 +1329,10 @@ fn start_executing_work<B: ExtraBackendMethods>(
13281329
target_is_like_darwin: tcx.sess.target.is_like_darwin,
13291330
target_is_like_aix: tcx.sess.target.is_like_aix,
13301331
target_is_like_gpu: tcx.sess.target.is_like_gpu,
1332+
rust_eh_personality_symbol: rustc_symbol_mangling::mangle_internal_symbol(
1333+
tcx,
1334+
"rust_eh_personality",
1335+
),
13311336
split_debuginfo: tcx.sess.split_debuginfo(),
13321337
split_dwarf_kind: tcx.sess.opts.unstable_opts.split_dwarf_kind,
13331338
parallel: backend.supports_parallel() && !sess.opts.unstable_opts.no_parallel_backend,

0 commit comments

Comments
 (0)