diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs index ad0a15bf7f6e5..18eb85289e520 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs @@ -25,7 +25,7 @@ pub(crate) struct UnwindContext { } impl UnwindContext { - pub(crate) fn new(module: &mut dyn Module, pic_eh_frame: bool) -> Self { + pub(crate) fn new(module: &mut dyn Module, eh_personality: &str, pic_eh_frame: bool) -> Self { let endian = match module.isa().endianness() { Endianness::Little => RunTimeEndian::Little, Endianness::Big => RunTimeEndian::Big, @@ -70,7 +70,7 @@ impl UnwindContext { // FIXME use eh_personality lang item instead let personality = module .declare_function( - "rust_eh_personality", + eh_personality, Linkage::Import, &Signature { params: vec![ @@ -89,7 +89,7 @@ impl UnwindContext { // Use indirection here to support PIC the case where rust_eh_personality is defined in // another DSO. let personality_ref = module - .declare_data("DW.ref.rust_eh_personality", Linkage::Local, false, false) + .declare_data(&format!("DW.ref.{eh_personality}"), Linkage::Local, false, false) .unwrap(); let mut personality_ref_data = DataDescription::new(); diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index a62dff641cfec..06a7f28a7d830 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -62,7 +62,11 @@ fn make_module(tcx: TyCtxt<'_>, cgu_name: &str) -> AotModule { tcx.sess.opts.unstable_opts.function_sections.unwrap_or(default_function_sections), ); - let module = UnwindModule::new(ObjectModule::new(builder), true); + let module = UnwindModule::new( + ObjectModule::new(builder), + &rustc_symbol_mangling::eh_personality_symbol(tcx), + true, + ); let producer = crate::debuginfo::producer(tcx.sess); let global_asm_config = GlobalAsmConfig::new(tcx.sess); diff --git a/compiler/rustc_codegen_cranelift/src/driver/jit.rs b/compiler/rustc_codegen_cranelift/src/driver/jit.rs index 8bf1cd9bf85bc..9864cefbf9368 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/jit.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/jit.rs @@ -25,7 +25,11 @@ fn create_jit_module( let mut jit_builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names()); crate::compiler_builtins::register_functions_for_jit(&mut jit_builder); jit_builder.symbol_lookup_fn(dep_symbol_lookup_fn(tcx.sess, crate_info.clone())); - let mut jit_module = UnwindModule::new(JITModule::new(jit_builder), false); + let mut jit_module = UnwindModule::new( + JITModule::new(jit_builder), + &rustc_symbol_mangling::eh_personality_symbol(tcx), + false, + ); let cx = DebugContext::new(tcx, jit_module.isa(), false, "dummy_cgu_name"); diff --git a/compiler/rustc_codegen_cranelift/src/unwind_module.rs b/compiler/rustc_codegen_cranelift/src/unwind_module.rs index b4eb939cf2560..d79960f418128 100644 --- a/compiler/rustc_codegen_cranelift/src/unwind_module.rs +++ b/compiler/rustc_codegen_cranelift/src/unwind_module.rs @@ -17,8 +17,8 @@ pub(crate) struct UnwindModule { } impl UnwindModule { - pub(crate) fn new(mut module: T, pic_eh_frame: bool) -> Self { - let unwind_context = UnwindContext::new(&mut module, pic_eh_frame); + pub(crate) fn new(mut module: T, eh_personality: &str, pic_eh_frame: bool) -> Self { + let unwind_context = UnwindContext::new(&mut module, eh_personality, pic_eh_frame); UnwindModule { module, unwind_context } } } diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index 5f342e8b2dc33..3607a5053bdfa 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -516,10 +516,12 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { self.declare_fn(symbol_name, fn_abi) } _ => { + let rust_name; let name = if wants_msvc_seh(&self.sess().target) { "__CxxFrameHandler3" } else { - "rust_eh_personality" + rust_name = rustc_symbol_mangling::eh_personality_symbol(tcx); + &rust_name }; self.declare_func(name, self.type_i32(), &[], true) } diff --git a/compiler/rustc_codegen_gcc/src/declare.rs b/compiler/rustc_codegen_gcc/src/declare.rs index 32bb7c3aa349e..a0c73bed0c7ed 100644 --- a/compiler/rustc_codegen_gcc/src/declare.rs +++ b/compiler/rustc_codegen_gcc/src/declare.rs @@ -187,7 +187,7 @@ fn declare_raw_fn<'gcc>( cx.functions.borrow_mut().insert(name.to_string(), func); #[cfg(feature = "master")] - if name == "rust_eh_personality" { + if name.ends_with("rust_eh_personality") { // NOTE: GCC will sometimes change the personality function set on a function from // rust_eh_personality to __gcc_personality_v0 as an optimization. // As such, we need to create a weak alias from __gcc_personality_v0 to diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index b82d05dc211aa..9be81fafce7ac 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -154,6 +154,14 @@ impl GccCodegenBackend { fn config(&self) -> &BackendConfig { self.config.as_ref().expect("target info not initialized") } + + #[cfg(feature = "master")] + fn set_personality_function(&self, tcx: TyCtxt<'_>) { + let personality_symbol = rustc_symbol_mangling::eh_personality_symbol(tcx); + gccjit::set_global_personality_function_name( + &CString::new(personality_symbol).expect("symbol name shouldn't contain NUL"), + ); + } } fn load_libgccjit_if_needed(libgccjit_target_lib_file: &Path) { @@ -236,8 +244,6 @@ impl CodegenBackend for GccCodegenBackend { target_info: Arc::new(IntoDynSyncSend(context.get_target_info())), lto_supported: gccjit::is_lto_supported(), }); - - gccjit::set_global_personality_function_name(c"rust_eh_personality"); } #[cfg(not(feature = "master"))] @@ -273,6 +279,8 @@ impl CodegenBackend for GccCodegenBackend { } fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box { + #[cfg(feature = "master")] + self.set_personality_function(tcx); Box::new(codegen_crate(self.clone(), tcx)) } diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index d52e34d30fb7d..67311f1153e75 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -82,7 +82,7 @@ fn prepare_lto( symbols_below_threshold.push(c"__llvm_profile_counter_bias".to_owned()); // LTO seems to discard this otherwise under certain circumstances. - symbols_below_threshold.push(c"rust_eh_personality".to_owned()); + symbols_below_threshold.push(CString::new(cgcx.rust_eh_personality_symbol.clone()).unwrap()); // If we're performing LTO for the entire crate graph, then for each of our // upstream dependencies, find the corresponding rlib and load the bitcode diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index d64c8de6ed7aa..ffcca98acf17e 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -1031,7 +1031,14 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { tcx.sess.pointer_authentication_functions(), ), _ => { - let name = name.unwrap_or("rust_eh_personality"); + let mangled_symbol; + let name = match name { + Some(name) => name, + None => { + mangled_symbol = rustc_symbol_mangling::eh_personality_symbol(tcx); + mangled_symbol.as_str() + } + }; if let Some(llfn) = self.get_declared_value(name) { llfn } else { diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 04be7956e8278..18968f0f89960 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -342,6 +342,7 @@ pub struct CodegenContext { pub split_debuginfo: rustc_target::spec::SplitDebuginfo, pub split_dwarf_kind: rustc_session::config::SplitDwarfKind, pub pointer_size: Size, + pub rust_eh_personality_symbol: String, /// LLVM optimizations for which we want to print remarks. pub remark: Passes, @@ -1284,6 +1285,7 @@ fn start_executing_work( target_is_like_darwin: tcx.sess.target.is_like_darwin, target_is_like_aix: tcx.sess.target.is_like_aix, target_is_like_gpu: tcx.sess.target.is_like_gpu, + rust_eh_personality_symbol: rustc_symbol_mangling::eh_personality_symbol(tcx), split_debuginfo: tcx.sess.split_debuginfo(), split_dwarf_kind: tcx.sess.opts.unstable_opts.split_dwarf_kind, parallel, diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 93db093f630bd..9c465b409ca85 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -104,7 +104,7 @@ mod v0; pub mod test; -pub use v0::{mangle_cgu, mangle_internal_symbol}; +pub use v0::{eh_personality_symbol, mangle_cgu, mangle_internal_symbol}; /// Offload kernels need custom v0 symbol treatment because the host /// and device compilation passes run with different `stable_crate_id`s diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index fb9f242f60085..2b9a346eec912 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -127,10 +127,12 @@ pub fn mangle_cgu<'tcx>(tcx: TyCtxt<'tcx>, krate: CrateNum, cgu_name: Either(tcx: TyCtxt<'tcx>) -> String { + mangle_internal_symbol(tcx, "rust_eh_personality") +} + pub fn mangle_internal_symbol<'tcx>(tcx: TyCtxt<'tcx>, item_name: &str) -> String { match item_name { - // rust_eh_personality must not be renamed as LLVM hard-codes the name - "rust_eh_personality" => return item_name.to_owned(), // Apple availability symbols need to not be mangled to be usable by // C/Objective-C code. "__isPlatformVersionAtLeast" | "__isOSVersionAtLeast" => return item_name.to_owned(), diff --git a/tests/codegen-llvm/gdb_debug_script_load.rs b/tests/codegen-llvm/gdb_debug_script_load.rs index 3e92eba10b121..044d8577df6a9 100644 --- a/tests/codegen-llvm/gdb_debug_script_load.rs +++ b/tests/codegen-llvm/gdb_debug_script_load.rs @@ -14,7 +14,7 @@ fn panic_handler(_: &core::panic::PanicInfo) -> ! { loop {} } -#[no_mangle] +#[lang = "eh_personality"] extern "C" fn rust_eh_personality() { loop {} } diff --git a/tests/run-make/no-alloc-shim/foo.rs b/tests/run-make/no-alloc-shim/foo.rs index a22307f41b39e..6604574d0fa5f 100644 --- a/tests/run-make/no-alloc-shim/foo.rs +++ b/tests/run-make/no-alloc-shim/foo.rs @@ -1,3 +1,4 @@ +#![feature(lang_items)] #![feature(rustc_attrs)] #![no_std] #![no_main] @@ -11,7 +12,7 @@ fn panic_handler(_: &core::panic::PanicInfo) -> ! { loop {} } -#[no_mangle] +#[lang = "eh_personality"] extern "C" fn rust_eh_personality( _version: i32, _actions: i32, diff --git a/tests/run-make/symbols-all-mangled/rmake.rs b/tests/run-make/symbols-all-mangled/rmake.rs index 2cf579758002a..99281d8be3bbf 100644 --- a/tests/run-make/symbols-all-mangled/rmake.rs +++ b/tests/run-make/symbols-all-mangled/rmake.rs @@ -19,13 +19,31 @@ fn main() { symbols_check(&exe_name); } +fn is_symbol_ok(sym: &str) -> bool { + let sym = strip_underscore_if_apple(sym); + // There are debuginfo helper symbols that get prefixed with DW.ref. + let sym = sym.strip_prefix("DW.ref.").unwrap_or(sym); + + if sym.starts_with("_ZN") || sym.starts_with("_R") { + return true; // Correctly mangled + } + + if sym.contains(".llvm.") { + // Starting in LLVM 21 we get various implementation-detail functions which + // contain .llvm. that are not a problem. + return true; + } + + false +} + fn symbols_check_archive(path: &str) { let binary_data = rfs::read(path); let file = object::read::archive::ArchiveFile::parse(&*binary_data).unwrap(); for symbol in file.symbols().unwrap().unwrap() { let symbol = symbol.unwrap(); - let name = strip_underscore_if_apple(std::str::from_utf8(symbol.name()).unwrap()); - if name.starts_with("_ZN") || name.starts_with("_R") { + let name = std::str::from_utf8(symbol.name()).unwrap(); + if is_symbol_ok(name) { continue; // Correctly mangled } @@ -35,16 +53,6 @@ fn symbols_check_archive(path: &str) { continue; // All compiler-builtins symbols must remain unmangled } - if name.contains("rust_eh_personality") { - continue; // Unfortunately LLVM doesn't allow us to mangle this symbol - } - - if name.contains(".llvm.") { - // Starting in LLVM 21 we get various implementation-detail functions which - // contain .llvm. that are not a problem. - continue; - } - panic!("Unmangled symbol found in {path}: {name}"); } } @@ -59,8 +67,8 @@ fn symbols_check(path: &str) { if symbol.is_weak() { continue; // Likely an intrinsic from compiler-builtins } - let name = strip_underscore_if_apple(symbol.name().unwrap()); - if name.starts_with("_ZN") || name.starts_with("_R") { + let name = symbol.name().unwrap(); + if is_symbol_ok(name) { continue; // Correctly mangled } @@ -71,16 +79,6 @@ fn symbols_check(path: &str) { continue; } - if name.contains("rust_eh_personality") { - continue; // Unfortunately LLVM doesn't allow us to mangle this symbol - } - - if name.contains(".llvm.") { - // Starting in LLVM 21 we get various implementation-detail functions which - // contain .llvm. that are not a problem. - continue; - } - panic!("Unmangled symbol found in {path}: {name}"); } } diff --git a/tests/ui/linkage-attr/raw-dylib/elf/glibc-x86_64.rs b/tests/ui/linkage-attr/raw-dylib/elf/glibc-x86_64.rs index 62d352facd178..150dcfbf6e922 100644 --- a/tests/ui/linkage-attr/raw-dylib/elf/glibc-x86_64.rs +++ b/tests/ui/linkage-attr/raw-dylib/elf/glibc-x86_64.rs @@ -6,6 +6,7 @@ //@ ignore-backends: gcc #![allow(incomplete_features)] +#![feature(lang_items)] #![feature(raw_dylib_elf)] #![no_std] #![no_main] @@ -69,7 +70,7 @@ fn panic_handler(_: &core::panic::PanicInfo<'_>) -> ! { exit(1); } -#[unsafe(no_mangle)] +#[lang = "eh_personality"] extern "C" fn rust_eh_personality( _version: i32, _actions: i32, diff --git a/tests/ui/panic-runtime/auxiliary/panic-runtime-abort.rs b/tests/ui/panic-runtime/auxiliary/panic-runtime-abort.rs index 36db32f281a4f..cd748c86d3966 100644 --- a/tests/ui/panic-runtime/auxiliary/panic-runtime-abort.rs +++ b/tests/ui/panic-runtime/auxiliary/panic-runtime-abort.rs @@ -2,8 +2,8 @@ //@ no-prefer-dynamic #![feature(panic_runtime)] +#![feature(rustc_attrs)] #![crate_type = "rlib"] - #![no_std] #![panic_runtime] @@ -13,5 +13,5 @@ pub extern "C" fn __rust_maybe_catch_panic() {} #[no_mangle] pub extern "C" fn __rust_start_panic() {} -#[no_mangle] +#[rustc_std_internal_symbol] pub extern "C" fn rust_eh_personality() {} diff --git a/tests/ui/panic-runtime/auxiliary/panic-runtime-unwind.rs b/tests/ui/panic-runtime/auxiliary/panic-runtime-unwind.rs index aea42d1f103fb..b7e062164b985 100644 --- a/tests/ui/panic-runtime/auxiliary/panic-runtime-unwind.rs +++ b/tests/ui/panic-runtime/auxiliary/panic-runtime-unwind.rs @@ -2,8 +2,8 @@ //@ no-prefer-dynamic #![feature(panic_runtime)] +#![feature(rustc_attrs)] #![crate_type = "rlib"] - #![no_std] #![panic_runtime] @@ -13,5 +13,5 @@ pub extern "C" fn __rust_maybe_catch_panic() {} #[no_mangle] pub extern "C" fn __rust_start_panic() {} -#[no_mangle] +#[rustc_std_internal_symbol] pub extern "C" fn rust_eh_personality() {} diff --git a/tests/ui/panic-runtime/auxiliary/panic-runtime-unwind2.rs b/tests/ui/panic-runtime/auxiliary/panic-runtime-unwind2.rs index aea42d1f103fb..b7e062164b985 100644 --- a/tests/ui/panic-runtime/auxiliary/panic-runtime-unwind2.rs +++ b/tests/ui/panic-runtime/auxiliary/panic-runtime-unwind2.rs @@ -2,8 +2,8 @@ //@ no-prefer-dynamic #![feature(panic_runtime)] +#![feature(rustc_attrs)] #![crate_type = "rlib"] - #![no_std] #![panic_runtime] @@ -13,5 +13,5 @@ pub extern "C" fn __rust_maybe_catch_panic() {} #[no_mangle] pub extern "C" fn __rust_start_panic() {} -#[no_mangle] +#[rustc_std_internal_symbol] pub extern "C" fn rust_eh_personality() {} diff --git a/tests/ui/panic-runtime/incompatible-type.rs b/tests/ui/panic-runtime/incompatible-type.rs index f82c23d68c2c7..ad8760a5fdab7 100644 --- a/tests/ui/panic-runtime/incompatible-type.rs +++ b/tests/ui/panic-runtime/incompatible-type.rs @@ -7,6 +7,7 @@ //@ compile-flags: --crate-type=lib -Ccodegen-units=1 #![no_std] #![panic_runtime] +#![feature(lang_items)] #![feature(panic_runtime)] #![feature(rustc_attrs)] @@ -20,7 +21,7 @@ pub fn test(_: DropMe) { unreachable!(); } -#[rustc_std_internal_symbol] +#[lang = "eh_personality"] pub unsafe extern "C" fn rust_eh_personality( _version: i32, _actions: i32, diff --git a/tests/ui/sanitizer/dataflow-abilist.txt b/tests/ui/sanitizer/dataflow-abilist.txt index 1fa78ebd55939..0e9b643c98254 100644 --- a/tests/ui/sanitizer/dataflow-abilist.txt +++ b/tests/ui/sanitizer/dataflow-abilist.txt @@ -494,5 +494,4 @@ fun:_ZN4core*=uninstrumented fun:_R*4core*=uninstrumented fun:_ZN3std*=uninstrumented fun:_R*3std*=uninstrumented -fun:rust_eh_personality=uninstrumented fun:_R*__rustc*=uninstrumented