Skip to content

Commit 9866540

Browse files
committed
Correctly handle different crate types disagreeing if the allocator shim is exported
Previously it would attempt to export the allocator shim even linking for a crate type which pulls in the allocator shim from a dylib rather than locally defining it.
1 parent 8bd5fb7 commit 9866540

File tree

3 files changed

+46
-29
lines changed

3 files changed

+46
-29
lines changed

compiler/rustc_codegen_ssa/src/back/linker.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ use rustc_metadata::{
1111
};
1212
use rustc_middle::bug;
1313
use rustc_middle::middle::dependency_format::Linkage;
14-
use rustc_middle::middle::exported_symbols;
15-
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo, SymbolExportKind};
14+
use rustc_middle::middle::exported_symbols::{
15+
self, ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel,
16+
};
1617
use rustc_middle::ty::TyCtxt;
1718
use rustc_session::Session;
1819
use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip};
@@ -22,6 +23,8 @@ use tracing::{debug, warn};
2223

2324
use super::command::Command;
2425
use super::symbol_export;
26+
use crate::back::symbol_export::allocator_shim_symbols;
27+
use crate::base::needs_allocator_shim_for_linking;
2528
use crate::errors;
2629

2730
#[cfg(test)]
@@ -1838,6 +1841,14 @@ fn exported_symbols_for_non_proc_macro(
18381841
}
18391842
});
18401843

1844+
// Mark allocator shim symbols as exported only if they were generated.
1845+
if export_threshold == SymbolExportLevel::Rust
1846+
&& needs_allocator_shim_for_linking(tcx.dependency_formats(()), crate_type)
1847+
&& tcx.allocator_kind(()).is_some()
1848+
{
1849+
symbols.extend(allocator_shim_symbols(tcx));
1850+
}
1851+
18411852
symbols
18421853
}
18431854

compiler/rustc_codegen_ssa/src/back/lto.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ use rustc_middle::ty::TyCtxt;
88
use rustc_session::config::{CrateType, Lto};
99
use tracing::info;
1010

11-
use crate::back::symbol_export::{self, symbol_name_for_instance_in_crate};
11+
use crate::back::symbol_export::{self, allocator_shim_symbols, symbol_name_for_instance_in_crate};
1212
use crate::back::write::CodegenContext;
13+
use crate::base::allocator_kind_for_codegen;
1314
use crate::errors::{DynamicLinkingWithLTO, LtoDisallowed, LtoDylib, LtoProcMacro};
1415
use crate::traits::*;
1516

@@ -115,6 +116,11 @@ pub(super) fn exported_symbols_for_lto(
115116
}
116117
}
117118

119+
// Mark allocator shim symbols as exported only if they were generated.
120+
if export_threshold == SymbolExportLevel::Rust && allocator_kind_for_codegen(tcx).is_some() {
121+
symbols_below_threshold.extend(allocator_shim_symbols(tcx).map(|(name, _kind)| name));
122+
}
123+
118124
symbols_below_threshold
119125
}
120126

compiler/rustc_codegen_ssa/src/back/symbol_export.rs

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use rustc_symbol_mangling::mangle_internal_symbol;
1818
use rustc_target::spec::{SanitizerSet, TlsModel};
1919
use tracing::debug;
2020

21-
use crate::base::allocator_kind_for_codegen;
21+
use crate::back::symbol_export;
2222

2323
fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel {
2424
crates_export_threshold(tcx.crate_types())
@@ -217,31 +217,6 @@ fn exported_non_generic_symbols_provider_local<'tcx>(
217217
));
218218
}
219219

220-
// Mark allocator shim symbols as exported only if they were generated.
221-
if allocator_kind_for_codegen(tcx).is_some() {
222-
for symbol_name in ALLOCATOR_METHODS
223-
.iter()
224-
.map(|method| mangle_internal_symbol(tcx, global_fn_name(method.name).as_str()))
225-
.chain([
226-
mangle_internal_symbol(tcx, "__rust_alloc_error_handler"),
227-
mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
228-
mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE),
229-
])
230-
{
231-
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name));
232-
233-
symbols.push((
234-
exported_symbol,
235-
SymbolExportInfo {
236-
level: SymbolExportLevel::Rust,
237-
kind: SymbolExportKind::Text,
238-
used: false,
239-
rustc_std_internal_symbol: true,
240-
},
241-
));
242-
}
243-
}
244-
245220
if tcx.sess.instrument_coverage() || tcx.sess.opts.cg.profile_generate.enabled() {
246221
// These are weak symbols that point to the profile version and the
247222
// profile name, which need to be treated as exported so LTO doesn't nix
@@ -563,6 +538,31 @@ pub(crate) fn provide(providers: &mut Providers) {
563538
upstream_monomorphizations_for_provider;
564539
}
565540

541+
pub(crate) fn allocator_shim_symbols(
542+
tcx: TyCtxt<'_>,
543+
) -> impl Iterator<Item = (String, SymbolExportKind)> {
544+
ALLOCATOR_METHODS
545+
.iter()
546+
.map(move |method| mangle_internal_symbol(tcx, global_fn_name(method.name).as_str()))
547+
.chain([
548+
mangle_internal_symbol(tcx, "__rust_alloc_error_handler"),
549+
mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
550+
mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE),
551+
])
552+
.map(move |symbol_name| {
553+
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name));
554+
555+
(
556+
symbol_export::exporting_symbol_name_for_instance_in_crate(
557+
tcx,
558+
exported_symbol,
559+
LOCAL_CRATE,
560+
),
561+
SymbolExportKind::Text,
562+
)
563+
})
564+
}
565+
566566
fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel {
567567
// We export anything that's not mangled at the "C" layer as it probably has
568568
// to do with ABI concerns. We do not, however, apply such treatment to

0 commit comments

Comments
 (0)