diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/emit.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/emit.rs index cc1efef287517..e80145d1b6df8 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/emit.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/emit.rs @@ -93,8 +93,11 @@ impl WriterRelocate { // HACK rust_eh_personality is likely not defined in the same crate, // so get_finalized_function won't work. Use the rust_eh_personality // of cg_clif itself, which is likely ABI compatible. - if jit_module.declarations().get_function_decl(func_id).name.as_deref() - == Some("rust_eh_personality") + if jit_module + .declarations() + .get_function_decl(func_id) + .name + .is_some_and(|name| name.ends_with("rust_eh_personality")) { unsafe extern "C" { fn rust_eh_personality() -> !; diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs index 1ce424332db20..260600864eb84 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, tcx: TyCtxt<'_>, 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", + &rustc_symbol_mangling::eh_personality_symbol(tcx), Linkage::Import, &Signature { params: vec![ diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index 3781ad7b3b83f..32ffca885a6cc 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -129,9 +129,8 @@ impl OngoingCodegen { } } -fn make_module(sess: &Session, name: String) -> UnwindModule { - let isa = crate::build_isa(sess, false); - +fn make_module(tcx: TyCtxt<'_>, name: String) -> UnwindModule { + let isa = crate::build_isa(tcx.sess, false); let mut builder = ObjectBuilder::new(isa, name + ".o", cranelift_module::default_libcall_names()).unwrap(); @@ -140,12 +139,13 @@ fn make_module(sess: &Session, name: String) -> UnwindModule { // explicitly disable it on MinGW as rustc already disables it by default on MinGW and as such // isn't tested. If rustc enables it in the future on MinGW, we can re-enable it too once it has // been on MinGW. - let default_function_sections = sess.target.function_sections && !sess.target.is_like_windows; + let default_function_sections = + tcx.sess.target.function_sections && !tcx.sess.target.is_like_windows; builder.per_function_section( - sess.opts.unstable_opts.function_sections.unwrap_or(default_function_sections), + tcx.sess.opts.unstable_opts.function_sections.unwrap_or(default_function_sections), ); - UnwindModule::new(ObjectModule::new(builder), true) + UnwindModule::new(ObjectModule::new(builder), tcx, true) } fn emit_cgu( @@ -378,7 +378,7 @@ fn module_codegen( cgu_name: rustc_span::Symbol, token: ConcurrencyLimiterToken, ) -> OngoingModuleCodegen { - let mut module = make_module(tcx.sess, cgu_name.as_str().to_string()); + let mut module = make_module(tcx, cgu_name.as_str().to_string()); let (mut debug_context, codegened_functions, mut global_asm) = codegen_cgu_content(tcx, &mut module, cgu_name); @@ -435,7 +435,7 @@ fn module_codegen( } fn emit_allocator_module(tcx: TyCtxt<'_>) -> Option { - let mut allocator_module = make_module(tcx.sess, "allocator_shim".to_string()); + let mut allocator_module = make_module(tcx, "allocator_shim".to_string()); let created_alloc_shim = crate::allocator::codegen(tcx, &mut allocator_module); if created_alloc_shim { diff --git a/compiler/rustc_codegen_cranelift/src/unwind_module.rs b/compiler/rustc_codegen_cranelift/src/unwind_module.rs index b4eb939cf2560..b294122d1a964 100644 --- a/compiler/rustc_codegen_cranelift/src/unwind_module.rs +++ b/compiler/rustc_codegen_cranelift/src/unwind_module.rs @@ -7,6 +7,7 @@ use cranelift_module::{ ModuleReloc, ModuleResult, }; use cranelift_object::{ObjectModule, ObjectProduct}; +use rustc_middle::ty::TyCtxt; use crate::UnwindContext; @@ -17,8 +18,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, tcx: TyCtxt<'_>, pic_eh_frame: bool) -> Self { + let unwind_context = UnwindContext::new(&mut module, tcx, 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 e0810a35b040b..0b71374faa5c0 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -458,10 +458,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()) { "__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 4174eebcf7b02..376890f0ccfd0 100644 --- a/compiler/rustc_codegen_gcc/src/declare.rs +++ b/compiler/rustc_codegen_gcc/src/declare.rs @@ -179,7 +179,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 6ca2ef88ef291..e5f677314fa1e 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -250,8 +250,6 @@ impl CodegenBackend for GccCodegenBackend { { let lto_supported = gccjit::is_lto_supported(); self.lto_supported.store(lto_supported, Ordering::SeqCst); - - gccjit::set_global_personality_function_name(b"rust_eh_personality\0"); } #[cfg(not(feature = "master"))] @@ -292,6 +290,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)) } @@ -313,6 +313,17 @@ impl CodegenBackend for GccCodegenBackend { } } +impl GccCodegenBackend { + #[cfg(feature = "master")] + fn set_personality_function(&self, tcx: TyCtxt<'_>) { + let personality_symbol = + CString::new(rustc_symbol_mangling::eh_personality_symbol(tcx)).unwrap(); + // FIXME: Change gccjit to store an owned string internally (https://github.com/rust-lang/rust/pull/148413#discussion_r2749777937) + let personality_symbol = Box::leak(personality_symbol.into_boxed_c_str()); + gccjit::set_global_personality_function_name(personality_symbol.to_bytes_with_nul()); + } +} + fn new_context<'gcc, 'tcx>(tcx: TyCtxt<'tcx>) -> Context<'gcc> { let context = Context::default(); if matches!(tcx.sess.target.arch, Arch::X86 | Arch::X86_64) { diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 020c6668fb9d3..f075fb13ec365 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 3e575f969afab..236ee2f94efc7 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -883,7 +883,14 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { DUMMY_SP, )), _ => { - 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_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index a697f8fe70bbc..9ce02ec2828d7 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -318,6 +318,11 @@ impl CodegenBackend for LlvmCodegenBackend { llvm_util::target_has_mnemonic(sess, mnemonic) } + fn can_mangle_eh_personality(&self) -> bool { + // https://github.com/llvm/llvm-project/pull/166095 + llvm_util::get_version() > (22, 0, 0) + } + fn target_config(&self, sess: &Session) -> TargetConfig { target_config(sess) } diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 7b22ac231df1c..3d65ae3f518a1 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -341,6 +341,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, @@ -1275,6 +1276,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: backend.supports_parallel() && !sess.opts.unstable_opts.no_parallel_backend, diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index cbb75836f979b..7a042bb4ede38 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -100,6 +100,12 @@ pub trait CodegenBackend { false } + /// Whether the `rust_eh_personality` symbol can be mangled (this is false if the codegen + /// backend hardcodes the name for certain checks). + fn can_mangle_eh_personality(&self) -> bool { + true + } + /// The metadata loader used to load rlib and dylib metadata. /// /// Alternative codegen backends may want to use different rlib or dylib formats than the diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 875ed4ae5d307..3a41967a1ba60 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -450,6 +450,8 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se codegen_backend.init(&sess); sess.replaced_intrinsics = FxHashSet::from_iter(codegen_backend.replaced_intrinsics()); sess.thin_lto_supported = codegen_backend.thin_lto_supported(); + sess.codegen_backend_supports_eh_personality_mangling = + codegen_backend.can_mangle_eh_personality(); let cfg = parse_cfg(sess.dcx(), config.crate_cfg); let mut cfg = config::build_configuration(&sess, cfg); diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 0837e7767605c..73d1c35af7da8 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -76,6 +76,7 @@ where "", None, &USING_INTERNAL_FEATURES, + true, ); let cfg = parse_cfg(sess.dcx(), matches.opt_strs("cfg")); let cfg = build_configuration(&sess, cfg); diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 003164e8f9054..596eff9a519ef 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -134,6 +134,10 @@ pub struct Session { /// drown everything else in noise. miri_unleashed_features: Lock)>>, + /// Whether the codegen backend supports mangling of the personality. + /// See `CodegenBackend::can_mangle_eh_personality`. + pub codegen_backend_supports_eh_personality_mangling: bool, + /// Architecture to use for interpreting asm!. pub asm_arch: Option, @@ -1114,6 +1118,7 @@ pub fn build_session( driver_lint_caps, ctfe_backtrace, miri_unleashed_features: Lock::new(Default::default()), + codegen_backend_supports_eh_personality_mangling: false, // filled by `run_compiler` asm_arch, target_features: Default::default(), unstable_target_features: Default::default(), diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index c052037f05b39..d0bf2c08d7cfd 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -103,7 +103,7 @@ mod v0; pub mod test; -pub use v0::mangle_internal_symbol; +pub use v0::{eh_personality_symbol, mangle_internal_symbol}; /// This function computes the symbol name for the given `instance` and the /// given instantiating crate. That is, if you know that instance X is diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 61c1c83c3f8f6..229eef65fa0e4 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -84,10 +84,15 @@ pub(super) fn mangle<'tcx>( std::mem::take(&mut p.out) } +pub fn eh_personality_symbol<'tcx>(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(), + "rust_eh_personality" if !tcx.sess.codegen_backend_supports_eh_personality_mangling => { + 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/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs index 1044683ae6426..6b5b01f3171ff 100644 --- a/src/tools/compiletest/src/runtest/run_make.rs +++ b/src/tools/compiletest/src/runtest/run_make.rs @@ -222,6 +222,10 @@ impl TestCx<'_> { cmd.env("LLVM_BIN_DIR", llvm_bin_dir); } + if let Some(ref llvm_version) = self.config.llvm_version { + cmd.env("LLVM_VERSION", llvm_version.to_string()); + } + if let Some(ref remote_test_client) = self.config.remote_test_client { cmd.env("REMOTE_TEST_CLIENT", remote_test_client); } diff --git a/src/tools/run-make-support/src/external_deps/llvm.rs b/src/tools/run-make-support/src/external_deps/llvm.rs index 70bed5a471ab2..29752c0e7653c 100644 --- a/src/tools/run-make-support/src/external_deps/llvm.rs +++ b/src/tools/run-make-support/src/external_deps/llvm.rs @@ -3,6 +3,19 @@ use std::path::{Path, PathBuf}; use crate::command::Command; use crate::env::env_var; +pub fn llvm_version() -> (u32, u32, u32) { + let version_string = env_var("LLVM_VERSION"); + let mut parts = version_string.split("."); + let mut part = || { + parts + .next() + .expect(&format!("invalid LLVM version: {version_string}")) + .parse::() + .expect(&format!("invalid LLVM version: {version_string}")) + }; + (part(), part(), part()) +} + /// Construct a new `llvm-readobj` invocation with the `GNU` output style. /// This assumes that `llvm-readobj` is available at `$LLVM_BIN_DIR/llvm-readobj`. #[track_caller] diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index a686b25c34322..5ea2ad7a5118b 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -76,7 +76,7 @@ pub use crate::external_deps::llvm::{ self, LlvmAr, LlvmBcanalyzer, LlvmDis, LlvmDwarfdump, LlvmFilecheck, LlvmNm, LlvmObjcopy, LlvmObjdump, LlvmProfdata, LlvmReadobj, llvm_ar, llvm_as, llvm_bcanalyzer, llvm_dis, llvm_dwarfdump, llvm_filecheck, llvm_nm, llvm_objcopy, llvm_objdump, llvm_profdata, - llvm_readobj, + llvm_readobj, llvm_version, }; pub use crate::external_deps::python::python_command; pub use crate::external_deps::rustc::{self, Rustc, bare_rustc, rustc, rustc_minicore, rustc_path}; 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..247b73f47c9c6 100644 --- a/tests/run-make/no-alloc-shim/foo.rs +++ b/tests/run-make/no-alloc-shim/foo.rs @@ -1,4 +1,4 @@ -#![feature(rustc_attrs)] +#![feature(rustc_attrs, lang_items)] #![no_std] #![no_main] @@ -11,7 +11,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/repr128-dwarf/rmake.rs b/tests/run-make/repr128-dwarf/rmake.rs index 38c69d5107337..dead49265797f 100644 --- a/tests/run-make/repr128-dwarf/rmake.rs +++ b/tests/run-make/repr128-dwarf/rmake.rs @@ -10,7 +10,7 @@ use std::rc::Rc; use gimli::read::DebuggingInformationEntry; use gimli::{AttributeValue, EndianRcSlice, Reader, RunTimeEndian}; use object::{Object, ObjectSection}; -use run_make_support::{gimli, object, rfs, rustc}; +use run_make_support::{gimli, llvm_version, object, rfs, rustc}; fn main() { let output = PathBuf::from("repr128"); diff --git a/tests/run-make/symbols-all-mangled/rmake.rs b/tests/run-make/symbols-all-mangled/rmake.rs index 2cf579758002a..4bfee6a136297 100644 --- a/tests/run-make/symbols-all-mangled/rmake.rs +++ b/tests/run-make/symbols-all-mangled/rmake.rs @@ -4,7 +4,9 @@ //@ ignore-cross-compile (host-only) use run_make_support::object::read::{Object, ObjectSymbol}; -use run_make_support::{bin_name, dynamic_lib_name, object, rfs, rustc, static_lib_name}; +use run_make_support::{ + bin_name, dynamic_lib_name, llvm_version, object, rfs, rustc, static_lib_name, +}; fn main() { let staticlib_name = static_lib_name("a_lib"); @@ -19,13 +21,35 @@ 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; + } + + if llvm_version() < (22, 0, 0) && sym.contains("rust_eh_personality") { + return true; // LLVM before 22 doesn't allow us to mangle this symbol + } + + 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 +59,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 +73,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 +85,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..52256cd834da7 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,7 +6,7 @@ //@ ignore-backends: gcc #![allow(incomplete_features)] -#![feature(raw_dylib_elf)] +#![feature(raw_dylib_elf, lang_items)] #![no_std] #![no_main] @@ -69,7 +69,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,