summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_ssa/src/back/symbol_export.rs')
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs69
1 files changed, 49 insertions, 20 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index 067a3e167..d0fd3cd76 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -1,3 +1,5 @@
+use crate::base::allocator_kind_for_codegen;
+
use std::collections::hash_map::Entry::*;
use rustc_ast::expand::allocator::ALLOCATOR_METHODS;
@@ -8,10 +10,11 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::middle::exported_symbols::{
metadata_symbol_name, ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel,
};
+use rustc_middle::query::LocalCrate;
use rustc_middle::ty::query::{ExternProviders, Providers};
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
use rustc_middle::ty::Instance;
-use rustc_middle::ty::{self, DefIdTree, SymbolName, TyCtxt};
+use rustc_middle::ty::{self, SymbolName, TyCtxt};
use rustc_session::config::{CrateType, OomStrategy};
use rustc_target::spec::SanitizerSet;
@@ -39,9 +42,7 @@ pub fn crates_export_threshold(crate_types: &[CrateType]) -> SymbolExportLevel {
}
}
-fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<SymbolExportInfo> {
- assert_eq!(cnum, LOCAL_CRATE);
-
+fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<SymbolExportInfo> {
if !tcx.sess.opts.output_types.should_codegen() {
return Default::default();
}
@@ -58,7 +59,7 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
let mut reachable_non_generics: DefIdMap<_> = tcx
.reachable_set(())
- .iter()
+ .items()
.filter_map(|&def_id| {
// We want to ignore some FFI functions that are not exposed from
// this crate. Reachable FFI functions can be lumped into two
@@ -136,7 +137,7 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
};
(def_id.to_def_id(), info)
})
- .collect();
+ .into();
if let Some(id) = tcx.proc_macro_decls_static(()) {
reachable_non_generics.insert(
@@ -152,10 +153,10 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
reachable_non_generics
}
-fn is_reachable_non_generic_provider_local(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
+fn is_reachable_non_generic_provider_local(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
let export_threshold = threshold(tcx);
- if let Some(&info) = tcx.reachable_non_generics(def_id.krate).get(&def_id) {
+ if let Some(&info) = tcx.reachable_non_generics(LOCAL_CRATE).get(&def_id.to_def_id()) {
info.level.is_below_threshold(export_threshold)
} else {
false
@@ -168,24 +169,37 @@ fn is_reachable_non_generic_provider_extern(tcx: TyCtxt<'_>, def_id: DefId) -> b
fn exported_symbols_provider_local(
tcx: TyCtxt<'_>,
- cnum: CrateNum,
+ _: LocalCrate,
) -> &[(ExportedSymbol<'_>, SymbolExportInfo)] {
- assert_eq!(cnum, LOCAL_CRATE);
-
if !tcx.sess.opts.output_types.should_codegen() {
return &[];
}
// FIXME: Sorting this is unnecessary since we are sorting later anyway.
// Can we skip the later sorting?
- let mut symbols: Vec<_> = tcx.with_stable_hashing_context(|hcx| {
- tcx.reachable_non_generics(LOCAL_CRATE)
- .to_sorted(&hcx, true)
- .into_iter()
- .map(|(&def_id, &info)| (ExportedSymbol::NonGeneric(def_id), info))
- .collect()
+ let sorted = tcx.with_stable_hashing_context(|hcx| {
+ tcx.reachable_non_generics(LOCAL_CRATE).to_sorted(&hcx, true)
});
+ let mut symbols: Vec<_> =
+ sorted.iter().map(|(&def_id, &info)| (ExportedSymbol::NonGeneric(def_id), info)).collect();
+
+ // Export TLS shims
+ if !tcx.sess.target.dll_tls_export {
+ symbols.extend(sorted.iter().filter_map(|(&def_id, &info)| {
+ tcx.needs_thread_local_shim(def_id).then(|| {
+ (
+ ExportedSymbol::ThreadLocalShim(def_id),
+ SymbolExportInfo {
+ level: info.level,
+ kind: SymbolExportKind::Text,
+ used: info.used,
+ },
+ )
+ })
+ }))
+ }
+
if tcx.entry_fn(()).is_some() {
let exported_symbol =
ExportedSymbol::NoDefId(SymbolName::new(tcx, tcx.sess.target.entry_name.as_ref()));
@@ -200,7 +214,8 @@ fn exported_symbols_provider_local(
));
}
- if tcx.allocator_kind(()).is_some() {
+ // Mark allocator shim symbols as exported only if they were generated.
+ if allocator_kind_for_codegen(tcx).is_some() {
for symbol_name in ALLOCATOR_METHODS
.iter()
.map(|method| format!("__rust_{}", method.name))
@@ -380,7 +395,9 @@ fn upstream_monomorphizations_provider(
continue;
}
}
- ExportedSymbol::NonGeneric(..) | ExportedSymbol::NoDefId(..) => {
+ ExportedSymbol::NonGeneric(..)
+ | ExportedSymbol::ThreadLocalShim(..)
+ | ExportedSymbol::NoDefId(..) => {
// These are no monomorphizations
continue;
}
@@ -500,6 +517,16 @@ pub fn symbol_name_for_instance_in_crate<'tcx>(
instantiating_crate,
)
}
+ ExportedSymbol::ThreadLocalShim(def_id) => {
+ rustc_symbol_mangling::symbol_name_for_instance_in_crate(
+ tcx,
+ ty::Instance {
+ def: ty::InstanceDef::ThreadLocalShim(def_id),
+ substs: ty::InternalSubsts::empty(),
+ },
+ instantiating_crate,
+ )
+ }
ExportedSymbol::DropGlue(ty) => rustc_symbol_mangling::symbol_name_for_instance_in_crate(
tcx,
Instance::resolve_drop_in_place(tcx, ty),
@@ -548,6 +575,8 @@ pub fn linking_symbol_name_for_instance_in_crate<'tcx>(
ExportedSymbol::DropGlue(..) => None,
// NoDefId always follow the target's default symbol decoration scheme.
ExportedSymbol::NoDefId(..) => None,
+ // ThreadLocalShim always follow the target's default symbol decoration scheme.
+ ExportedSymbol::ThreadLocalShim(..) => None,
};
let (conv, args) = instance
@@ -592,7 +621,7 @@ fn wasm_import_module_map(tcx: TyCtxt<'_>, cnum: CrateNum) -> FxHashMap<DefId, S
let mut ret = FxHashMap::default();
for (def_id, lib) in tcx.foreign_modules(cnum).iter() {
- let module = def_id_to_native_lib.get(&def_id).and_then(|s| s.wasm_import_module);
+ let module = def_id_to_native_lib.get(&def_id).and_then(|s| s.wasm_import_module());
let Some(module) = module else { continue };
ret.extend(lib.foreign_items.iter().map(|id| {
assert_eq!(id.krate, cnum);