diff options
Diffstat (limited to 'compiler/rustc_codegen_ssa/src/back/symbol_export.rs')
-rw-r--r-- | compiler/rustc_codegen_ssa/src/back/symbol_export.rs | 69 |
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); |