Skip to content

Commit 493c38b

Browse files
committed
Auto merge of rust-lang#127173 - bjorn3:mangle_rustc_std_internal_symbol, r=wesleywiser,jieyouxu
Mangle rustc_std_internal_symbols functions This reduces the risk of issues when using a staticlib or rust dylib compiled with a different rustc version in a rust program. Currently this will either (in the case of staticlib) cause a linker error due to duplicate symbol definitions, or (in the case of rust dylibs) cause rustc_std_internal_symbols functions to be silently overridden. As rust gets more commonly used inside the implementation of libraries consumed with a C interface (like Spidermonkey, Ruby YJIT (curently has to do partial linking of all rust code to hide all symbols not part of the C api), the Rusticl OpenCL implementation in mesa) this is becoming much more of an issue. With this PR the only symbols remaining with an unmangled name are rust_eh_personality (LLVM doesn't allow renaming it) and `__rust_no_alloc_shim_is_unstable`. Helps mitigate rust-lang#104707 try-job: aarch64-gnu-debug try-job: aarch64-apple try-job: x86_64-apple-1 try-job: x86_64-mingw-1 try-job: i686-mingw-1 try-job: x86_64-msvc-1 try-job: i686-msvc-1 try-job: test-various try-job: armhf-gnu
2 parents 43a2e9d + bebc502 commit 493c38b

39 files changed

+342
-76
lines changed

compiler/rustc_codegen_cranelift/src/allocator.rs

+23-7
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ use rustc_ast::expand::allocator::{
77
};
88
use rustc_codegen_ssa::base::allocator_kind_for_codegen;
99
use rustc_session::config::OomStrategy;
10+
use rustc_symbol_mangling::mangle_internal_symbol;
1011

1112
use crate::prelude::*;
1213

1314
/// Returns whether an allocator shim was created
1415
pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool {
1516
let Some(kind) = allocator_kind_for_codegen(tcx) else { return false };
1617
codegen_inner(
18+
tcx,
1719
module,
1820
kind,
1921
tcx.alloc_error_handler_kind(()).unwrap(),
@@ -23,6 +25,7 @@ pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool {
2325
}
2426

2527
fn codegen_inner(
28+
tcx: TyCtxt<'_>,
2629
module: &mut dyn Module,
2730
kind: AllocatorKind,
2831
alloc_error_handler_kind: AllocatorKind,
@@ -62,8 +65,8 @@ fn codegen_inner(
6265
crate::common::create_wrapper_function(
6366
module,
6467
sig,
65-
&global_fn_name(method.name),
66-
&default_fn_name(method.name),
68+
&mangle_internal_symbol(tcx, &global_fn_name(method.name)),
69+
&mangle_internal_symbol(tcx, &default_fn_name(method.name)),
6770
);
6871
}
6972
}
@@ -76,19 +79,32 @@ fn codegen_inner(
7679
crate::common::create_wrapper_function(
7780
module,
7881
sig,
79-
"__rust_alloc_error_handler",
80-
&alloc_error_handler_name(alloc_error_handler_kind),
82+
&mangle_internal_symbol(tcx, "__rust_alloc_error_handler"),
83+
&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)),
8184
);
8285

83-
let data_id = module.declare_data(OomStrategy::SYMBOL, Linkage::Export, false, false).unwrap();
86+
let data_id = module
87+
.declare_data(
88+
&mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
89+
Linkage::Export,
90+
false,
91+
false,
92+
)
93+
.unwrap();
8494
let mut data = DataDescription::new();
8595
data.set_align(1);
8696
let val = oom_strategy.should_panic();
8797
data.define(Box::new([val]));
8898
module.define_data(data_id, &data).unwrap();
8999

90-
let data_id =
91-
module.declare_data(NO_ALLOC_SHIM_IS_UNSTABLE, Linkage::Export, false, false).unwrap();
100+
let data_id = module
101+
.declare_data(
102+
&mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE),
103+
Linkage::Export,
104+
false,
105+
false,
106+
)
107+
.unwrap();
92108
let mut data = DataDescription::new();
93109
data.set_align(1);
94110
data.define(Box::new([0]));

compiler/rustc_codegen_cranelift/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ extern crate rustc_index;
2626
extern crate rustc_metadata;
2727
extern crate rustc_session;
2828
extern crate rustc_span;
29+
extern crate rustc_symbol_mangling;
2930
extern crate rustc_target;
3031
#[macro_use]
3132
extern crate tracing;

compiler/rustc_codegen_gcc/src/allocator.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_ast::expand::allocator::{
88
use rustc_middle::bug;
99
use rustc_middle::ty::TyCtxt;
1010
use rustc_session::config::OomStrategy;
11+
use rustc_symbol_mangling::mangle_internal_symbol;
1112

1213
use crate::GccContext;
1314
#[cfg(feature = "master")]
@@ -53,8 +54,8 @@ pub(crate) unsafe fn codegen(
5354
panic!("invalid allocator output")
5455
}
5556
};
56-
let from_name = global_fn_name(method.name);
57-
let to_name = default_fn_name(method.name);
57+
let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name));
58+
let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name));
5859

5960
create_wrapper_function(tcx, context, &from_name, &to_name, &types, output);
6061
}
@@ -64,13 +65,13 @@ pub(crate) unsafe fn codegen(
6465
create_wrapper_function(
6566
tcx,
6667
context,
67-
"__rust_alloc_error_handler",
68-
alloc_error_handler_name(alloc_error_handler_kind),
68+
&mangle_internal_symbol(tcx, "__rust_alloc_error_handler"),
69+
&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)),
6970
&[usize, usize],
7071
None,
7172
);
7273

73-
let name = OomStrategy::SYMBOL.to_string();
74+
let name = mangle_internal_symbol(tcx, OomStrategy::SYMBOL);
7475
let global = context.new_global(None, GlobalKind::Exported, i8, name);
7576
#[cfg(feature = "master")]
7677
global.add_attribute(VarAttribute::Visibility(symbol_visibility_to_gcc(
@@ -80,7 +81,7 @@ pub(crate) unsafe fn codegen(
8081
let value = context.new_rvalue_from_int(i8, value as i32);
8182
global.global_set_initializer_rvalue(value);
8283

83-
let name = NO_ALLOC_SHIM_IS_UNSTABLE.to_string();
84+
let name = mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE);
8485
let global = context.new_global(None, GlobalKind::Exported, i8, name);
8586
#[cfg(feature = "master")]
8687
global.add_attribute(VarAttribute::Visibility(symbol_visibility_to_gcc(

compiler/rustc_codegen_gcc/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ extern crate rustc_metadata;
5252
extern crate rustc_middle;
5353
extern crate rustc_session;
5454
extern crate rustc_span;
55+
extern crate rustc_symbol_mangling;
5556
extern crate rustc_target;
5657

5758
// This prevents duplicating functions and statics that are already part of the host rustc process.

compiler/rustc_codegen_llvm/src/allocator.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_codegen_ssa::traits::BaseTypeCodegenMethods as _;
77
use rustc_middle::bug;
88
use rustc_middle::ty::TyCtxt;
99
use rustc_session::config::{DebugInfo, OomStrategy};
10+
use rustc_symbol_mangling::mangle_internal_symbol;
1011

1112
use crate::builder::SBuilder;
1213
use crate::declare::declare_simple_fn;
@@ -53,8 +54,8 @@ pub(crate) unsafe fn codegen(
5354
}
5455
};
5556

56-
let from_name = global_fn_name(method.name);
57-
let to_name = default_fn_name(method.name);
57+
let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name));
58+
let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name));
5859

5960
create_wrapper_function(tcx, &cx, &from_name, &to_name, &args, output, false);
6061
}
@@ -64,24 +65,24 @@ pub(crate) unsafe fn codegen(
6465
create_wrapper_function(
6566
tcx,
6667
&cx,
67-
"__rust_alloc_error_handler",
68-
alloc_error_handler_name(alloc_error_handler_kind),
68+
&mangle_internal_symbol(tcx, "__rust_alloc_error_handler"),
69+
&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)),
6970
&[usize, usize], // size, align
7071
None,
7172
true,
7273
);
7374

7475
unsafe {
7576
// __rust_alloc_error_handler_should_panic
76-
let name = OomStrategy::SYMBOL;
77-
let ll_g = cx.declare_global(name, i8);
77+
let name = mangle_internal_symbol(tcx, OomStrategy::SYMBOL);
78+
let ll_g = cx.declare_global(&name, i8);
7879
llvm::set_visibility(ll_g, llvm::Visibility::from_generic(tcx.sess.default_visibility()));
7980
let val = tcx.sess.opts.unstable_opts.oom.should_panic();
8081
let llval = llvm::LLVMConstInt(i8, val as u64, False);
8182
llvm::set_initializer(ll_g, llval);
8283

83-
let name = NO_ALLOC_SHIM_IS_UNSTABLE;
84-
let ll_g = cx.declare_global(name, i8);
84+
let name = mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE);
85+
let ll_g = cx.declare_global(&name, i8);
8586
llvm::set_visibility(ll_g, llvm::Visibility::from_generic(tcx.sess.default_visibility()));
8687
let llval = llvm::LLVMConstInt(i8, 0, False);
8788
llvm::set_initializer(ll_g, llval);

compiler/rustc_codegen_llvm/src/context.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use rustc_session::config::{
2727
};
2828
use rustc_span::source_map::Spanned;
2929
use rustc_span::{DUMMY_SP, Span};
30+
use rustc_symbol_mangling::mangle_internal_symbol;
3031
use rustc_target::spec::{HasTargetSpec, RelocModel, SmallDataThresholdSupport, Target, TlsModel};
3132
use smallvec::SmallVec;
3233

@@ -1199,7 +1200,7 @@ impl<'ll> CodegenCx<'ll, '_> {
11991200
Some(def_id) => self.get_static(def_id),
12001201
_ => {
12011202
let ty = self.type_struct(&[self.type_ptr(), self.type_ptr()], false);
1202-
self.declare_global("rust_eh_catch_typeinfo", ty)
1203+
self.declare_global(&mangle_internal_symbol(self.tcx, "rust_eh_catch_typeinfo"), ty)
12031204
}
12041205
};
12051206
self.eh_catch_typeinfo.set(Some(eh_catch_typeinfo));

compiler/rustc_codegen_llvm/src/intrinsic.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf};
1414
use rustc_middle::ty::{self, GenericArgsRef, Ty};
1515
use rustc_middle::{bug, span_bug};
1616
use rustc_span::{Span, Symbol, sym};
17+
use rustc_symbol_mangling::mangle_internal_symbol;
1718
use rustc_target::callconv::{FnAbi, PassMode};
1819
use rustc_target::spec::{HasTargetSpec, PanicStrategy};
1920
use tracing::debug;
@@ -812,7 +813,10 @@ fn codegen_msvc_try<'ll>(
812813
let type_name = bx.const_bytes(b"rust_panic\0");
813814
let type_info =
814815
bx.const_struct(&[type_info_vtable, bx.const_null(bx.type_ptr()), type_name], false);
815-
let tydesc = bx.declare_global("__rust_panic_type_info", bx.val_ty(type_info));
816+
let tydesc = bx.declare_global(
817+
&mangle_internal_symbol(bx.tcx, "__rust_panic_type_info"),
818+
bx.val_ty(type_info),
819+
);
816820

817821
llvm::set_linkage(tydesc, llvm::Linkage::LinkOnceODRLinkage);
818822
if bx.cx.tcx.sess.target.supports_comdat() {

compiler/rustc_codegen_ssa/src/back/symbol_export.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::collections::hash_map::Entry::*;
22

3-
use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE};
3+
use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE, global_fn_name};
44
use rustc_data_structures::unord::UnordMap;
55
use rustc_hir::def::DefKind;
66
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE, LocalDefId};
@@ -13,6 +13,7 @@ use rustc_middle::query::LocalCrate;
1313
use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, Instance, SymbolName, Ty, TyCtxt};
1414
use rustc_middle::util::Providers;
1515
use rustc_session::config::{CrateType, OomStrategy};
16+
use rustc_symbol_mangling::mangle_internal_symbol;
1617
use rustc_target::callconv::Conv;
1718
use rustc_target::spec::{SanitizerSet, TlsModel};
1819
use tracing::debug;
@@ -219,8 +220,11 @@ fn exported_symbols_provider_local(
219220
if allocator_kind_for_codegen(tcx).is_some() {
220221
for symbol_name in ALLOCATOR_METHODS
221222
.iter()
222-
.map(|method| format!("__rust_{}", method.name))
223-
.chain(["__rust_alloc_error_handler".to_string(), OomStrategy::SYMBOL.to_string()])
223+
.map(|method| mangle_internal_symbol(tcx, global_fn_name(method.name).as_str()))
224+
.chain([
225+
mangle_internal_symbol(tcx, "__rust_alloc_error_handler"),
226+
mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
227+
])
224228
{
225229
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name));
226230

@@ -234,8 +238,10 @@ fn exported_symbols_provider_local(
234238
));
235239
}
236240

237-
let exported_symbol =
238-
ExportedSymbol::NoDefId(SymbolName::new(tcx, NO_ALLOC_SHIM_IS_UNSTABLE));
241+
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(
242+
tcx,
243+
&mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE),
244+
));
239245
symbols.push((
240246
exported_symbol,
241247
SymbolExportInfo {

compiler/rustc_codegen_ssa/src/base.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
2828
use rustc_session::Session;
2929
use rustc_session::config::{self, CrateType, EntryFnType, OutputType};
3030
use rustc_span::{DUMMY_SP, Symbol, sym};
31+
use rustc_symbol_mangling::mangle_internal_symbol;
3132
use rustc_trait_selection::infer::{BoundRegionConversionTime, TyCtxtInferExt};
3233
use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
3334
use tracing::{debug, info};
@@ -989,7 +990,12 @@ impl CrateInfo {
989990
.for_each(|(_, linked_symbols)| {
990991
let mut symbols = missing_weak_lang_items
991992
.iter()
992-
.map(|item| (format!("{prefix}{item}"), SymbolExportKind::Text))
993+
.map(|item| {
994+
(
995+
format!("{prefix}{}", mangle_internal_symbol(tcx, item.as_str())),
996+
SymbolExportKind::Text,
997+
)
998+
})
993999
.collect::<Vec<_>>();
9941000
symbols.sort_unstable_by(|a, b| a.0.cmp(&b.0));
9951001
linked_symbols.extend(symbols);
@@ -1002,7 +1008,13 @@ impl CrateInfo {
10021008
// errors.
10031009
linked_symbols.extend(ALLOCATOR_METHODS.iter().map(|method| {
10041010
(
1005-
format!("{prefix}{}", global_fn_name(method.name).as_str()),
1011+
format!(
1012+
"{prefix}{}",
1013+
mangle_internal_symbol(
1014+
tcx,
1015+
global_fn_name(method.name).as_str()
1016+
)
1017+
),
10061018
SymbolExportKind::Text,
10071019
)
10081020
}));

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

+7-13
Original file line numberDiff line numberDiff line change
@@ -601,25 +601,19 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
601601
// strippable by the linker.
602602
//
603603
// Additionally weak lang items have predetermined symbol names.
604-
if WEAK_LANG_ITEMS.iter().any(|&l| tcx.lang_items().get(l) == Some(did.to_def_id())) {
605-
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
606-
}
607604
if let Some((name, _)) = lang_items::extract(attrs)
608605
&& let Some(lang_item) = LangItem::from_name(name)
609-
&& let Some(link_name) = lang_item.link_name()
610606
{
611-
codegen_fn_attrs.export_name = Some(link_name);
612-
codegen_fn_attrs.link_name = Some(link_name);
607+
if WEAK_LANG_ITEMS.iter().any(|&l| l == lang_item) {
608+
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
609+
}
610+
if let Some(link_name) = lang_item.link_name() {
611+
codegen_fn_attrs.export_name = Some(link_name);
612+
codegen_fn_attrs.link_name = Some(link_name);
613+
}
613614
}
614615
check_link_name_xor_ordinal(tcx, &codegen_fn_attrs, link_ordinal_span);
615616

616-
// Internal symbols to the standard library all have no_mangle semantics in
617-
// that they have defined symbol names present in the function name. This
618-
// also applies to weak symbols where they all have known symbol names.
619-
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
620-
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
621-
}
622-
623617
// Any linkage to LLVM intrinsics for now forcibly marks them all as never
624618
// unwinds since LLVM sometimes can't handle codegen which `invoke`s
625619
// intrinsic functions.

compiler/rustc_middle/src/middle/codegen_fn_attrs.rs

+1
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ impl CodegenFnAttrs {
174174
/// * `#[linkage]` is present
175175
pub fn contains_extern_indicator(&self) -> bool {
176176
self.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
177+
|| self.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
177178
|| self.export_name.is_some()
178179
|| match self.linkage {
179180
// These are private, so make sure we don't try to consider

compiler/rustc_passes/src/check_attr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2203,7 +2203,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
22032203

22042204
fn check_rustc_std_internal_symbol(&self, attr: &Attribute, span: Span, target: Target) {
22052205
match target {
2206-
Target::Fn | Target::Static => {}
2206+
Target::Fn | Target::Static | Target::ForeignFn | Target::ForeignStatic => {}
22072207
_ => {
22082208
self.tcx
22092209
.dcx()

compiler/rustc_passes/src/reachable.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,7 @@ impl<'tcx> ReachableContext<'tcx> {
184184
CodegenFnAttrs::EMPTY
185185
};
186186
let is_extern = codegen_attrs.contains_extern_indicator();
187-
let std_internal =
188-
codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL);
189-
if is_extern || std_internal {
187+
if is_extern {
190188
self.reachable_symbols.insert(search_item);
191189
}
192190
} else {
@@ -426,7 +424,6 @@ fn has_custom_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
426424
}
427425
let codegen_attrs = tcx.codegen_fn_attrs(def_id);
428426
codegen_attrs.contains_extern_indicator()
429-
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
430427
// FIXME(nbdd0121): `#[used]` are marked as reachable here so it's picked up by
431428
// `linked_symbols` in cg_ssa. They won't be exported in binary or cdylib due to their
432429
// `SymbolExportLevel::Rust` export level but may end up being exported in dylibs.

0 commit comments

Comments
 (0)