diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index 6676d88602c45..50fd53481f745 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -4,7 +4,6 @@ use std::path::PathBuf; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; -use rustc_codegen_ssa::back::linker::LinkerInfo; use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; @@ -296,8 +295,7 @@ pub(crate) fn run_aot( allocator_module, metadata_module, metadata, - linker_info: LinkerInfo::new(tcx, crate::target_triple(tcx.sess).to_string()), - crate_info: CrateInfo::new(tcx), + crate_info: CrateInfo::new(tcx, crate::target_triple(tcx.sess).to_string()), }, work_products, )) diff --git a/compiler/rustc_codegen_cranelift/src/driver/jit.rs b/compiler/rustc_codegen_cranelift/src/driver/jit.rs index 3f96e741d350f..04ec01ad28148 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/jit.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/jit.rs @@ -178,7 +178,7 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> { let mut dylib_paths = Vec::new(); - let crate_info = CrateInfo::new(tcx); + let crate_info = CrateInfo::new(tcx, "dummy_target_cpu".to_string()); let formats = tcx.dependency_formats(()); let data = &formats .iter() diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index b817bf4aff771..ebf98e8694b78 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -219,7 +219,6 @@ impl CodegenBackend for CraneliftCodegenBackend { sess, &codegen_results, outputs, - &codegen_results.crate_info.local_crate_name.as_str(), ); Ok(()) diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index fc890f2385303..26fd1cfbcd08e 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -292,12 +292,7 @@ impl CodegenBackend for LlvmCodegenBackend { // Run the linker on any artifacts that resulted from the LLVM run. // This should produce either a finished executable or library. - link_binary::>( - sess, - &codegen_results, - outputs, - &codegen_results.crate_info.local_crate_name.as_str(), - ); + link_binary::>(sess, &codegen_results, outputs); Ok(()) } diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 8c246f1dac31b..59447e9de1350 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -54,7 +54,6 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>( sess: &'a Session, codegen_results: &CodegenResults, outputs: &OutputFilenames, - crate_name: &str, ) { let _timer = sess.timer("link_binary"); let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata); @@ -87,7 +86,12 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>( .tempdir() .unwrap_or_else(|err| sess.fatal(&format!("couldn't create a temp dir: {}", err))); let path = MaybeTempDir::new(tmpdir, sess.opts.cg.save_temps); - let out_filename = out_filename(sess, crate_type, outputs, crate_name); + let out_filename = out_filename( + sess, + crate_type, + outputs, + &codegen_results.crate_info.local_crate_name.as_str(), + ); match crate_type { CrateType::Rlib => { let _timer = sess.timer("link_rlib"); @@ -143,97 +147,6 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>( }); } -// The third parameter is for env vars, used on windows to set up the -// path for MSVC to find its DLLs, and gcc to find its bundled -// toolchain -fn get_linker( - sess: &Session, - linker: &Path, - flavor: LinkerFlavor, - self_contained: bool, -) -> Command { - let msvc_tool = windows_registry::find_tool(&sess.opts.target_triple.triple(), "link.exe"); - - // If our linker looks like a batch script on Windows then to execute this - // we'll need to spawn `cmd` explicitly. This is primarily done to handle - // emscripten where the linker is `emcc.bat` and needs to be spawned as - // `cmd /c emcc.bat ...`. - // - // This worked historically but is needed manually since #42436 (regression - // was tagged as #42791) and some more info can be found on #44443 for - // emscripten itself. - let mut cmd = match linker.to_str() { - Some(linker) if cfg!(windows) && linker.ends_with(".bat") => Command::bat_script(linker), - _ => match flavor { - LinkerFlavor::Lld(f) => Command::lld(linker, f), - LinkerFlavor::Msvc if sess.opts.cg.linker.is_none() && sess.target.linker.is_none() => { - Command::new(msvc_tool.as_ref().map_or(linker, |t| t.path())) - } - _ => Command::new(linker), - }, - }; - - // UWP apps have API restrictions enforced during Store submissions. - // To comply with the Windows App Certification Kit, - // MSVC needs to link with the Store versions of the runtime libraries (vcruntime, msvcrt, etc). - let t = &sess.target; - if (flavor == LinkerFlavor::Msvc || flavor == LinkerFlavor::Lld(LldFlavor::Link)) - && t.vendor == "uwp" - { - if let Some(ref tool) = msvc_tool { - let original_path = tool.path(); - if let Some(ref root_lib_path) = original_path.ancestors().nth(4) { - let arch = match t.arch.as_str() { - "x86_64" => Some("x64"), - "x86" => Some("x86"), - "aarch64" => Some("arm64"), - "arm" => Some("arm"), - _ => None, - }; - if let Some(ref a) = arch { - // FIXME: Move this to `fn linker_with_args`. - let mut arg = OsString::from("/LIBPATH:"); - arg.push(format!("{}\\lib\\{}\\store", root_lib_path.display(), a)); - cmd.arg(&arg); - } else { - warn!("arch is not supported"); - } - } else { - warn!("MSVC root path lib location not found"); - } - } else { - warn!("link.exe not found"); - } - } - - // The compiler's sysroot often has some bundled tools, so add it to the - // PATH for the child. - let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths(self_contained); - let mut msvc_changed_path = false; - if sess.target.is_like_msvc { - if let Some(ref tool) = msvc_tool { - cmd.args(tool.args()); - for &(ref k, ref v) in tool.env() { - if k == "PATH" { - new_path.extend(env::split_paths(v)); - msvc_changed_path = true; - } else { - cmd.env(k, v); - } - } - } - } - - if !msvc_changed_path { - if let Some(path) = env::var_os("PATH") { - new_path.extend(env::split_paths(&path)); - } - } - cmd.env("PATH", env::join_paths(new_path).unwrap()); - - cmd -} - pub fn each_linked_rlib( info: &CrateInfo, f: &mut dyn FnMut(CrateNum, &Path), @@ -1800,11 +1713,13 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( codegen_results: &CodegenResults, ) -> Command { let crt_objects_fallback = crt_objects_fallback(sess, crate_type); - let base_cmd = get_linker(sess, path, flavor, crt_objects_fallback); - // FIXME: Move `/LIBPATH` addition for uwp targets from the linker construction - // to the linker args construction. - assert!(base_cmd.get_args().is_empty() || sess.target.vendor == "uwp"); - let cmd = &mut *codegen_results.linker_info.to_linker(base_cmd, &sess, flavor); + let cmd = &mut *super::linker::get_linker( + sess, + path, + flavor, + crt_objects_fallback, + &codegen_results.crate_info.target_cpu, + ); let link_output_kind = link_output_kind(sess, crate_type); // ------------ Early order-dependent options ------------ @@ -1814,7 +1729,11 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( // dynamic library. // Must be passed before any libraries to prevent the symbols to export from being thrown away, // at least on some platforms (e.g. windows-gnu). - cmd.export_symbols(tmpdir, crate_type); + cmd.export_symbols( + tmpdir, + crate_type, + &codegen_results.crate_info.exported_symbols[&crate_type], + ); // Can be used for adding custom CRT objects or overriding order-dependent options above. // FIXME: In practice built-in target specs use this for arbitrary order-independent options, @@ -1986,10 +1905,10 @@ fn add_order_independent_options( if flavor == LinkerFlavor::PtxLinker { // Provide the linker with fallback to internal `target-cpu`. cmd.arg("--fallback-arch"); - cmd.arg(&codegen_results.linker_info.target_cpu); + cmd.arg(&codegen_results.crate_info.target_cpu); } else if flavor == LinkerFlavor::BpfLinker { cmd.arg("--cpu"); - cmd.arg(&codegen_results.linker_info.target_cpu); + cmd.arg(&codegen_results.crate_info.target_cpu); cmd.arg("--cpu-features"); cmd.arg(match &sess.opts.cg.target_feature { feat if !feat.is_empty() => feat, diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 43ff664c3e641..9e1c6a169f152 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -7,19 +7,21 @@ use std::ffi::{OsStr, OsString}; use std::fs::{self, File}; use std::io::prelude::*; use std::io::{self, BufWriter}; -use std::mem; use std::path::{Path, PathBuf}; +use std::{env, mem, str}; -use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::ty::TyCtxt; use rustc_serialize::{json, Encoder}; use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip}; +use rustc_session::search_paths::PathKind; use rustc_session::Session; use rustc_span::symbol::Symbol; use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor}; +use cc::windows_registry; + /// Disables non-English messages from localized linkers. /// Such messages may cause issues with text encoding on Windows (#35785) /// and prevent inspection of linker output in case of errors, which we occasionally do. @@ -33,60 +35,121 @@ pub fn disable_localization(linker: &mut Command) { linker.env("VSLANG", "1033"); } -/// For all the linkers we support, and information they might -/// need out of the shared crate context before we get rid of it. -#[derive(Encodable, Decodable)] -pub struct LinkerInfo { - pub(super) target_cpu: String, - exports: FxHashMap>, -} - -impl LinkerInfo { - pub fn new(tcx: TyCtxt<'_>, target_cpu: String) -> LinkerInfo { - LinkerInfo { - target_cpu, - exports: tcx - .sess - .crate_types() - .iter() - .map(|&c| (c, exported_symbols(tcx, c))) - .collect(), +// The third parameter is for env vars, used on windows to set up the +// path for MSVC to find its DLLs, and gcc to find its bundled +// toolchain +pub fn get_linker<'a>( + sess: &'a Session, + linker: &Path, + flavor: LinkerFlavor, + self_contained: bool, + target_cpu: &'a str, +) -> Box { + let msvc_tool = windows_registry::find_tool(&sess.opts.target_triple.triple(), "link.exe"); + + // If our linker looks like a batch script on Windows then to execute this + // we'll need to spawn `cmd` explicitly. This is primarily done to handle + // emscripten where the linker is `emcc.bat` and needs to be spawned as + // `cmd /c emcc.bat ...`. + // + // This worked historically but is needed manually since #42436 (regression + // was tagged as #42791) and some more info can be found on #44443 for + // emscripten itself. + let mut cmd = match linker.to_str() { + Some(linker) if cfg!(windows) && linker.ends_with(".bat") => Command::bat_script(linker), + _ => match flavor { + LinkerFlavor::Lld(f) => Command::lld(linker, f), + LinkerFlavor::Msvc if sess.opts.cg.linker.is_none() && sess.target.linker.is_none() => { + Command::new(msvc_tool.as_ref().map_or(linker, |t| t.path())) + } + _ => Command::new(linker), + }, + }; + + // UWP apps have API restrictions enforced during Store submissions. + // To comply with the Windows App Certification Kit, + // MSVC needs to link with the Store versions of the runtime libraries (vcruntime, msvcrt, etc). + let t = &sess.target; + if (flavor == LinkerFlavor::Msvc || flavor == LinkerFlavor::Lld(LldFlavor::Link)) + && t.vendor == "uwp" + { + if let Some(ref tool) = msvc_tool { + let original_path = tool.path(); + if let Some(ref root_lib_path) = original_path.ancestors().nth(4) { + let arch = match t.arch.as_str() { + "x86_64" => Some("x64"), + "x86" => Some("x86"), + "aarch64" => Some("arm64"), + "arm" => Some("arm"), + _ => None, + }; + if let Some(ref a) = arch { + // FIXME: Move this to `fn linker_with_args`. + let mut arg = OsString::from("/LIBPATH:"); + arg.push(format!("{}\\lib\\{}\\store", root_lib_path.display(), a)); + cmd.arg(&arg); + } else { + warn!("arch is not supported"); + } + } else { + warn!("MSVC root path lib location not found"); + } + } else { + warn!("link.exe not found"); } } - pub fn to_linker<'a>( - &'a self, - cmd: Command, - sess: &'a Session, - flavor: LinkerFlavor, - ) -> Box { - match flavor { - LinkerFlavor::Lld(LldFlavor::Link) | LinkerFlavor::Msvc => { - Box::new(MsvcLinker { cmd, sess, info: self }) as Box - } - LinkerFlavor::Em => Box::new(EmLinker { cmd, sess, info: self }) as Box, - LinkerFlavor::Gcc => { - Box::new(GccLinker { cmd, sess, info: self, hinted_static: false, is_ld: false }) - as Box + // The compiler's sysroot often has some bundled tools, so add it to the + // PATH for the child. + let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths(self_contained); + let mut msvc_changed_path = false; + if sess.target.is_like_msvc { + if let Some(ref tool) = msvc_tool { + cmd.args(tool.args()); + for &(ref k, ref v) in tool.env() { + if k == "PATH" { + new_path.extend(env::split_paths(v)); + msvc_changed_path = true; + } else { + cmd.env(k, v); + } } + } + } - LinkerFlavor::Lld(LldFlavor::Ld) - | LinkerFlavor::Lld(LldFlavor::Ld64) - | LinkerFlavor::Ld => { - Box::new(GccLinker { cmd, sess, info: self, hinted_static: false, is_ld: true }) - as Box - } + if !msvc_changed_path { + if let Some(path) = env::var_os("PATH") { + new_path.extend(env::split_paths(&path)); + } + } + cmd.env("PATH", env::join_paths(new_path).unwrap()); - LinkerFlavor::Lld(LldFlavor::Wasm) => { - Box::new(WasmLd::new(cmd, sess, self)) as Box - } + // FIXME: Move `/LIBPATH` addition for uwp targets from the linker construction + // to the linker args construction. + assert!(cmd.get_args().is_empty() || sess.target.vendor == "uwp"); - LinkerFlavor::PtxLinker => Box::new(PtxLinker { cmd, sess }) as Box, + match flavor { + LinkerFlavor::Lld(LldFlavor::Link) | LinkerFlavor::Msvc => { + Box::new(MsvcLinker { cmd, sess }) as Box + } + LinkerFlavor::Em => Box::new(EmLinker { cmd, sess }) as Box, + LinkerFlavor::Gcc => { + Box::new(GccLinker { cmd, sess, target_cpu, hinted_static: false, is_ld: false }) + as Box + } - LinkerFlavor::BpfLinker => { - Box::new(BpfLinker { cmd, sess, info: self }) as Box - } + LinkerFlavor::Lld(LldFlavor::Ld) + | LinkerFlavor::Lld(LldFlavor::Ld64) + | LinkerFlavor::Ld => { + Box::new(GccLinker { cmd, sess, target_cpu, hinted_static: false, is_ld: true }) + as Box } + + LinkerFlavor::Lld(LldFlavor::Wasm) => Box::new(WasmLd::new(cmd, sess)) as Box, + + LinkerFlavor::PtxLinker => Box::new(PtxLinker { cmd, sess }) as Box, + + LinkerFlavor::BpfLinker => Box::new(BpfLinker { cmd, sess }) as Box, } } @@ -122,7 +185,7 @@ pub trait Linker { fn debuginfo(&mut self, strip: Strip); fn no_crt_objects(&mut self); fn no_default_libraries(&mut self); - fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType); + fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]); fn subsystem(&mut self, subsystem: &str); fn group_start(&mut self); fn group_end(&mut self); @@ -150,7 +213,7 @@ impl dyn Linker + '_ { pub struct GccLinker<'a> { cmd: Command, sess: &'a Session, - info: &'a LinkerInfo, + target_cpu: &'a str, hinted_static: bool, // Keeps track of the current hinting mode. // Link as ld is_ld: bool, @@ -225,7 +288,7 @@ impl<'a> GccLinker<'a> { }; self.linker_arg(&format!("-plugin-opt={}", opt_level)); - self.linker_arg(&format!("-plugin-opt=mcpu={}", self.info.target_cpu)); + self.linker_arg(&format!("-plugin-opt=mcpu={}", self.target_cpu)); } fn build_dylib(&mut self, out_filename: &Path) { @@ -554,7 +617,7 @@ impl<'a> Linker for GccLinker<'a> { } } - fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType) { + fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]) { // Symbol visibility in object files typically takes care of this. if crate_type == CrateType::Executable && self.sess.target.override_export_symbols.is_none() { @@ -583,7 +646,7 @@ impl<'a> Linker for GccLinker<'a> { // Write a plain, newline-separated list of symbols let res: io::Result<()> = try { let mut f = BufWriter::new(File::create(&path)?); - for sym in self.info.exports[&crate_type].iter() { + for sym in symbols { debug!(" _{}", sym); writeln!(f, "_{}", sym)?; } @@ -598,7 +661,7 @@ impl<'a> Linker for GccLinker<'a> { // .def file similar to MSVC one but without LIBRARY section // because LD doesn't like when it's empty writeln!(f, "EXPORTS")?; - for symbol in self.info.exports[&crate_type].iter() { + for symbol in symbols { debug!(" _{}", symbol); writeln!(f, " {}", symbol)?; } @@ -611,9 +674,9 @@ impl<'a> Linker for GccLinker<'a> { let res: io::Result<()> = try { let mut f = BufWriter::new(File::create(&path)?); writeln!(f, "{{")?; - if !self.info.exports[&crate_type].is_empty() { + if !symbols.is_empty() { writeln!(f, " global:")?; - for sym in self.info.exports[&crate_type].iter() { + for sym in symbols { debug!(" {};", sym); writeln!(f, " {};", sym)?; } @@ -713,7 +776,6 @@ impl<'a> Linker for GccLinker<'a> { pub struct MsvcLinker<'a> { cmd: Command, sess: &'a Session, - info: &'a LinkerInfo, } impl<'a> Linker for MsvcLinker<'a> { @@ -887,7 +949,7 @@ impl<'a> Linker for MsvcLinker<'a> { // crates. Upstream rlibs may be linked statically to this dynamic library, // in which case they may continue to transitively be used and hence need // their symbols exported. - fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType) { + fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]) { // Symbol visibility takes care of this typically if crate_type == CrateType::Executable { return; @@ -901,7 +963,7 @@ impl<'a> Linker for MsvcLinker<'a> { // straight to exports. writeln!(f, "LIBRARY")?; writeln!(f, "EXPORTS")?; - for symbol in self.info.exports[&crate_type].iter() { + for symbol in symbols { debug!(" _{}", symbol); writeln!(f, " {}", symbol)?; } @@ -954,7 +1016,6 @@ impl<'a> Linker for MsvcLinker<'a> { pub struct EmLinker<'a> { cmd: Command, sess: &'a Session, - info: &'a LinkerInfo, } impl<'a> Linker for EmLinker<'a> { @@ -1066,9 +1127,7 @@ impl<'a> Linker for EmLinker<'a> { self.cmd.args(&["-s", "DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=[]"]); } - fn export_symbols(&mut self, _tmpdir: &Path, crate_type: CrateType) { - let symbols = &self.info.exports[&crate_type]; - + fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) { debug!("EXPORTED SYMBOLS:"); self.cmd.arg("-s"); @@ -1110,11 +1169,10 @@ impl<'a> Linker for EmLinker<'a> { pub struct WasmLd<'a> { cmd: Command, sess: &'a Session, - info: &'a LinkerInfo, } impl<'a> WasmLd<'a> { - fn new(mut cmd: Command, sess: &'a Session, info: &'a LinkerInfo) -> WasmLd<'a> { + fn new(mut cmd: Command, sess: &'a Session) -> WasmLd<'a> { // If the atomics feature is enabled for wasm then we need a whole bunch // of flags: // @@ -1147,7 +1205,7 @@ impl<'a> WasmLd<'a> { cmd.arg("--export=__tls_align"); cmd.arg("--export=__tls_base"); } - WasmLd { cmd, sess, info } + WasmLd { cmd, sess } } } @@ -1263,8 +1321,8 @@ impl<'a> Linker for WasmLd<'a> { fn no_default_libraries(&mut self) {} - fn export_symbols(&mut self, _tmpdir: &Path, crate_type: CrateType) { - for sym in self.info.exports[&crate_type].iter() { + fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) { + for sym in symbols { self.cmd.arg("--export").arg(&sym); } @@ -1287,7 +1345,7 @@ impl<'a> Linker for WasmLd<'a> { } } -fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec { +pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec { if let Some(ref exports) = tcx.sess.target.override_export_symbols { return exports.clone(); } @@ -1416,7 +1474,7 @@ impl<'a> Linker for PtxLinker<'a> { fn control_flow_guard(&mut self) {} - fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType) {} + fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, _symbols: &[String]) {} fn subsystem(&mut self, _subsystem: &str) {} @@ -1430,7 +1488,6 @@ impl<'a> Linker for PtxLinker<'a> { pub struct BpfLinker<'a> { cmd: Command, sess: &'a Session, - info: &'a LinkerInfo, } impl<'a> Linker for BpfLinker<'a> { @@ -1517,11 +1574,11 @@ impl<'a> Linker for BpfLinker<'a> { fn control_flow_guard(&mut self) {} - fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType) { + fn export_symbols(&mut self, tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) { let path = tmpdir.join("symbols"); let res: io::Result<()> = try { let mut f = BufWriter::new(File::create(&path)?); - for sym in self.info.exports[&crate_type].iter() { + for sym in symbols { writeln!(f, "{}", sym)?; } }; diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index d27eb7da810be..41823f7d80d69 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1,5 +1,4 @@ use super::link::{self, ensure_removed}; -use super::linker::LinkerInfo; use super::lto::{self, SerializedModule}; use super::symbol_export::symbol_name_for_instance_in_crate; @@ -430,8 +429,7 @@ pub fn start_async_codegen( let no_builtins = tcx.sess.contains_name(crate_attrs, sym::no_builtins); let is_compiler_builtins = tcx.sess.contains_name(crate_attrs, sym::compiler_builtins); - let linker_info = LinkerInfo::new(tcx, target_cpu); - let crate_info = CrateInfo::new(tcx); + let crate_info = CrateInfo::new(tcx, target_cpu); let regular_config = ModuleConfig::new(ModuleKind::Regular, sess, no_builtins, is_compiler_builtins); @@ -461,7 +459,6 @@ pub fn start_async_codegen( OngoingCodegen { backend, metadata, - linker_info, crate_info, coordinator_send, @@ -1799,7 +1796,6 @@ impl SharedEmitterMain { pub struct OngoingCodegen { pub backend: B, pub metadata: EncodedMetadata, - pub linker_info: LinkerInfo, pub crate_info: CrateInfo, pub coordinator_send: Sender>, pub codegen_worker_receive: Receiver>, @@ -1842,7 +1838,6 @@ impl OngoingCodegen { ( CodegenResults { metadata: self.metadata, - linker_info: self.linker_info, crate_info: self.crate_info, modules: compiled_modules.modules, diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 0036935be67e4..7df17bd20b992 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -754,7 +754,13 @@ impl Drop for AbortCodegenOnDrop { } impl CrateInfo { - pub fn new(tcx: TyCtxt<'_>) -> CrateInfo { + pub fn new(tcx: TyCtxt<'_>, target_cpu: String) -> CrateInfo { + let exported_symbols = tcx + .sess + .crate_types() + .iter() + .map(|&c| (c, crate::back::linker::exported_symbols(tcx, c))) + .collect(); let local_crate_name = tcx.crate_name(LOCAL_CRATE); let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID); let subsystem = tcx.sess.first_attr_value_str_by_name(crate_attrs, sym::windows_subsystem); @@ -770,8 +776,9 @@ impl CrateInfo { }); let mut info = CrateInfo { + target_cpu, + exported_symbols, local_crate_name, - panic_runtime: None, compiler_builtins: None, profiler_runtime: None, is_no_builtins: Default::default(), @@ -800,9 +807,6 @@ impl CrateInfo { .insert(cnum, tcx.native_libraries(cnum).iter().map(Into::into).collect()); info.crate_name.insert(cnum, tcx.crate_name(cnum).to_string()); info.used_crate_source.insert(cnum, tcx.used_crate_source(cnum)); - if tcx.is_panic_runtime(cnum) { - info.panic_runtime = Some(cnum); - } if tcx.is_compiler_builtins(cnum) { info.compiler_builtins = Some(cnum); } diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 6413e03bea469..b6ee70c419b16 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -27,7 +27,7 @@ use rustc_middle::dep_graph::WorkProduct; use rustc_middle::middle::cstore::{self, CrateSource}; use rustc_middle::middle::dependency_format::Dependencies; use rustc_middle::ty::query::Providers; -use rustc_session::config::{OutputFilenames, OutputType, RUST_CGU_EXT}; +use rustc_session::config::{CrateType, OutputFilenames, OutputType, RUST_CGU_EXT}; use rustc_session::utils::NativeLibKind; use rustc_span::symbol::Symbol; use std::path::{Path, PathBuf}; @@ -135,8 +135,9 @@ impl From<&cstore::NativeLib> for NativeLib { /// and the corresponding properties without referencing information outside of a `CrateInfo`. #[derive(Debug, Encodable, Decodable)] pub struct CrateInfo { + pub target_cpu: String, + pub exported_symbols: FxHashMap>, pub local_crate_name: Symbol, - pub panic_runtime: Option, pub compiler_builtins: Option, pub profiler_runtime: Option, pub is_no_builtins: FxHashSet, @@ -157,7 +158,6 @@ pub struct CodegenResults { pub allocator_module: Option, pub metadata_module: Option, pub metadata: rustc_middle::middle::cstore::EncodedMetadata, - pub linker_info: back::linker::LinkerInfo, pub crate_info: CrateInfo, } diff --git a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs index 443e2df357fb4..d3862309ce46f 100644 --- a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs +++ b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs @@ -12,7 +12,6 @@ extern crate rustc_span; extern crate rustc_symbol_mangling; extern crate rustc_target; -use rustc_codegen_ssa::back::linker::LinkerInfo; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::{CodegenResults, CrateInfo}; use rustc_data_structures::fx::FxHashMap; @@ -38,8 +37,7 @@ impl CodegenBackend for TheBackend { allocator_module: None, metadata_module: None, metadata, - linker_info: LinkerInfo::new(tcx, "fake_target_cpu".to_string()), - crate_info: CrateInfo::new(tcx), + crate_info: CrateInfo::new(tcx, "fake_target_cpu".to_string()), }) }