@@ -112,6 +112,8 @@ mod v0;
112112pub mod errors;
113113pub mod test;
114114
115+ pub use v0:: mangle_internal_symbol;
116+
115117/// This function computes the symbol name for the given `instance` and the
116118/// given instantiating crate. That is, if you know that instance X is
117119/// instantiated in crate Y, this is the symbol name this instance would have.
@@ -183,6 +185,39 @@ fn compute_symbol_name<'tcx>(
183185 CodegenFnAttrs :: EMPTY
184186 } ;
185187
188+ if attrs. flags . contains ( CodegenFnAttrFlags :: RUSTC_STD_INTERNAL_SYMBOL ) {
189+ // Items marked as #[rustc_std_internal_symbol] need to have a fixed
190+ // symbol name because it is used to import items from another crate
191+ // without a direct dependency. As such it is not possible to look up
192+ // the mangled name for the `Instance` from the crate metadata of the
193+ // defining crate.
194+ // Weak lang items automatically get #[rustc_std_internal_symbol]
195+ // applied by the code computing the CodegenFnAttrs.
196+ // We are mangling all #[rustc_std_internal_symbol] items that don't
197+ // also have #[no_mangle] as a combination of the rustc version and the
198+ // unmangled linkage name. This is to ensure that if we link against a
199+ // staticlib compiled by a different rustc version, we don't get symbol
200+ // conflicts or even UB due to a different implementation/ABI. Rust
201+ // staticlibs currently export all symbols, including those that are
202+ // hidden in cdylibs.
203+ // We are using the v0 symbol mangling scheme here as we need to be
204+ // consistent across all crates and in some contexts the legacy symbol
205+ // mangling scheme can't be used. For example both the GCC backend and
206+ // Rust-for-Linux don't support some of the characters used by the
207+ // legacy symbol mangling scheme.
208+ let name = if tcx. is_foreign_item ( def_id) {
209+ if let Some ( name) = attrs. link_name { name } else { tcx. item_name ( def_id) }
210+ } else {
211+ if let Some ( name) = attrs. export_name { name } else { tcx. item_name ( def_id) }
212+ } ;
213+
214+ if attrs. flags . contains ( CodegenFnAttrFlags :: NO_MANGLE ) {
215+ return name. to_string ( ) ;
216+ } else {
217+ return v0:: mangle_internal_symbol ( tcx, name. as_str ( ) ) ;
218+ }
219+ }
220+
186221 // Foreign items by default use no mangling for their symbol name. There's a
187222 // few exceptions to this rule though:
188223 //
@@ -198,6 +233,8 @@ fn compute_symbol_name<'tcx>(
198233 // is present we mangle everything on wasm because the demangled form will
199234 // show up in the `wasm-import-name` custom attribute in LLVM IR.
200235 //
236+ // * `#[rustc_std_internal_symbol]` mangles the symbol name in a special way
237+ // both for exports and imports through foreign items. This is handled above.
201238 // [1]: https://bugs.llvm.org/show_bug.cgi?id=44316
202239 if tcx. is_foreign_item ( def_id)
203240 && ( !tcx. sess . target . is_like_wasm
0 commit comments