Fold LinkerInfo into CrateInfo

This commit is contained in:
bjorn3 2021-07-06 18:28:07 +02:00
parent b4a12f95c1
commit b21cbfd77d
4 changed files with 48 additions and 86 deletions

View file

@ -1718,7 +1718,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
path, path,
flavor, flavor,
crt_objects_fallback, crt_objects_fallback,
&codegen_results.crate_info.linker_info, &codegen_results.crate_info.target_cpu,
); );
let link_output_kind = link_output_kind(sess, crate_type); let link_output_kind = link_output_kind(sess, crate_type);
@ -1729,7 +1729,11 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
// dynamic library. // dynamic library.
// Must be passed before any libraries to prevent the symbols to export from being thrown away, // 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). // 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. // 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, // FIXME: In practice built-in target specs use this for arbitrary order-independent options,
@ -1901,10 +1905,10 @@ fn add_order_independent_options(
if flavor == LinkerFlavor::PtxLinker { if flavor == LinkerFlavor::PtxLinker {
// Provide the linker with fallback to internal `target-cpu`. // Provide the linker with fallback to internal `target-cpu`.
cmd.arg("--fallback-arch"); cmd.arg("--fallback-arch");
cmd.arg(&codegen_results.crate_info.linker_info.target_cpu); cmd.arg(&codegen_results.crate_info.target_cpu);
} else if flavor == LinkerFlavor::BpfLinker { } else if flavor == LinkerFlavor::BpfLinker {
cmd.arg("--cpu"); cmd.arg("--cpu");
cmd.arg(&codegen_results.crate_info.linker_info.target_cpu); cmd.arg(&codegen_results.crate_info.target_cpu);
cmd.arg("--cpu-features"); cmd.arg("--cpu-features");
cmd.arg(match &sess.opts.cg.target_feature { cmd.arg(match &sess.opts.cg.target_feature {
feat if !feat.is_empty() => feat, feat if !feat.is_empty() => feat,

View file

@ -10,7 +10,6 @@ use std::io::{self, BufWriter};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::{env, mem, str}; use std::{env, mem, str};
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::middle::dependency_format::Linkage;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
@ -36,28 +35,6 @@ pub fn disable_localization(linker: &mut Command) {
linker.env("VSLANG", "1033"); 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(Debug, Encodable, Decodable)]
pub struct LinkerInfo {
pub(super) target_cpu: String,
exports: FxHashMap<CrateType, Vec<String>>,
}
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 // 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 // path for MSVC to find its DLLs, and gcc to find its bundled
// toolchain // toolchain
@ -66,7 +43,7 @@ pub fn get_linker<'a>(
linker: &Path, linker: &Path,
flavor: LinkerFlavor, flavor: LinkerFlavor,
self_contained: bool, self_contained: bool,
info: &'a LinkerInfo, target_cpu: &'a str,
) -> Box<dyn Linker + 'a> { ) -> Box<dyn Linker + 'a> {
let msvc_tool = windows_registry::find_tool(&sess.opts.target_triple.triple(), "link.exe"); let msvc_tool = windows_registry::find_tool(&sess.opts.target_triple.triple(), "link.exe");
@ -153,40 +130,26 @@ pub fn get_linker<'a>(
match flavor { match flavor {
LinkerFlavor::Lld(LldFlavor::Link) | LinkerFlavor::Msvc => { LinkerFlavor::Lld(LldFlavor::Link) | LinkerFlavor::Msvc => {
Box::new(MsvcLinker { cmd, sess, exports: &info.exports }) as Box<dyn Linker> Box::new(MsvcLinker { cmd, sess }) as Box<dyn Linker>
} }
LinkerFlavor::Em => { LinkerFlavor::Em => Box::new(EmLinker { cmd, sess }) as Box<dyn Linker>,
Box::new(EmLinker { cmd, sess, exports: &info.exports }) as Box<dyn Linker> LinkerFlavor::Gcc => {
Box::new(GccLinker { cmd, sess, target_cpu, hinted_static: false, is_ld: false })
as Box<dyn Linker>
} }
LinkerFlavor::Gcc => Box::new(GccLinker {
cmd,
sess,
exports: &info.exports,
target_cpu: &info.target_cpu,
hinted_static: false,
is_ld: false,
}) as Box<dyn Linker>,
LinkerFlavor::Lld(LldFlavor::Ld) LinkerFlavor::Lld(LldFlavor::Ld)
| LinkerFlavor::Lld(LldFlavor::Ld64) | LinkerFlavor::Lld(LldFlavor::Ld64)
| LinkerFlavor::Ld => Box::new(GccLinker { | LinkerFlavor::Ld => {
cmd, Box::new(GccLinker { cmd, sess, target_cpu, hinted_static: false, is_ld: true })
sess, as Box<dyn Linker>
exports: &info.exports,
target_cpu: &info.target_cpu,
hinted_static: false,
is_ld: true,
}) as Box<dyn Linker>,
LinkerFlavor::Lld(LldFlavor::Wasm) => {
Box::new(WasmLd::new(cmd, sess, &info.exports)) as Box<dyn Linker>
} }
LinkerFlavor::Lld(LldFlavor::Wasm) => Box::new(WasmLd::new(cmd, sess)) as Box<dyn Linker>,
LinkerFlavor::PtxLinker => Box::new(PtxLinker { cmd, sess }) as Box<dyn Linker>, LinkerFlavor::PtxLinker => Box::new(PtxLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::BpfLinker => { LinkerFlavor::BpfLinker => Box::new(BpfLinker { cmd, sess }) as Box<dyn Linker>,
Box::new(BpfLinker { cmd, sess, exports: &info.exports }) as Box<dyn Linker>
}
} }
} }
@ -222,7 +185,7 @@ pub trait Linker {
fn debuginfo(&mut self, strip: Strip); fn debuginfo(&mut self, strip: Strip);
fn no_crt_objects(&mut self); fn no_crt_objects(&mut self);
fn no_default_libraries(&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 subsystem(&mut self, subsystem: &str);
fn group_start(&mut self); fn group_start(&mut self);
fn group_end(&mut self); fn group_end(&mut self);
@ -250,7 +213,6 @@ impl dyn Linker + '_ {
pub struct GccLinker<'a> { pub struct GccLinker<'a> {
cmd: Command, cmd: Command,
sess: &'a Session, sess: &'a Session,
exports: &'a FxHashMap<CrateType, Vec<String>>,
target_cpu: &'a str, target_cpu: &'a str,
hinted_static: bool, // Keeps track of the current hinting mode. hinted_static: bool, // Keeps track of the current hinting mode.
// Link as ld // Link as ld
@ -655,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. // Symbol visibility in object files typically takes care of this.
if crate_type == CrateType::Executable && self.sess.target.override_export_symbols.is_none() if crate_type == CrateType::Executable && self.sess.target.override_export_symbols.is_none()
{ {
@ -684,7 +646,7 @@ impl<'a> Linker for GccLinker<'a> {
// Write a plain, newline-separated list of symbols // Write a plain, newline-separated list of symbols
let res: io::Result<()> = try { let res: io::Result<()> = try {
let mut f = BufWriter::new(File::create(&path)?); let mut f = BufWriter::new(File::create(&path)?);
for sym in self.exports[&crate_type].iter() { for sym in symbols {
debug!(" _{}", sym); debug!(" _{}", sym);
writeln!(f, "_{}", sym)?; writeln!(f, "_{}", sym)?;
} }
@ -699,7 +661,7 @@ impl<'a> Linker for GccLinker<'a> {
// .def file similar to MSVC one but without LIBRARY section // .def file similar to MSVC one but without LIBRARY section
// because LD doesn't like when it's empty // because LD doesn't like when it's empty
writeln!(f, "EXPORTS")?; writeln!(f, "EXPORTS")?;
for symbol in self.exports[&crate_type].iter() { for symbol in symbols {
debug!(" _{}", symbol); debug!(" _{}", symbol);
writeln!(f, " {}", symbol)?; writeln!(f, " {}", symbol)?;
} }
@ -712,9 +674,9 @@ impl<'a> Linker for GccLinker<'a> {
let res: io::Result<()> = try { let res: io::Result<()> = try {
let mut f = BufWriter::new(File::create(&path)?); let mut f = BufWriter::new(File::create(&path)?);
writeln!(f, "{{")?; writeln!(f, "{{")?;
if !self.exports[&crate_type].is_empty() { if !symbols.is_empty() {
writeln!(f, " global:")?; writeln!(f, " global:")?;
for sym in self.exports[&crate_type].iter() { for sym in symbols {
debug!(" {};", sym); debug!(" {};", sym);
writeln!(f, " {};", sym)?; writeln!(f, " {};", sym)?;
} }
@ -814,7 +776,6 @@ impl<'a> Linker for GccLinker<'a> {
pub struct MsvcLinker<'a> { pub struct MsvcLinker<'a> {
cmd: Command, cmd: Command,
sess: &'a Session, sess: &'a Session,
exports: &'a FxHashMap<CrateType, Vec<String>>,
} }
impl<'a> Linker for MsvcLinker<'a> { impl<'a> Linker for MsvcLinker<'a> {
@ -988,7 +949,7 @@ impl<'a> Linker for MsvcLinker<'a> {
// crates. Upstream rlibs may be linked statically to this dynamic library, // crates. Upstream rlibs may be linked statically to this dynamic library,
// in which case they may continue to transitively be used and hence need // in which case they may continue to transitively be used and hence need
// their symbols exported. // 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 // Symbol visibility takes care of this typically
if crate_type == CrateType::Executable { if crate_type == CrateType::Executable {
return; return;
@ -1002,7 +963,7 @@ impl<'a> Linker for MsvcLinker<'a> {
// straight to exports. // straight to exports.
writeln!(f, "LIBRARY")?; writeln!(f, "LIBRARY")?;
writeln!(f, "EXPORTS")?; writeln!(f, "EXPORTS")?;
for symbol in self.exports[&crate_type].iter() { for symbol in symbols {
debug!(" _{}", symbol); debug!(" _{}", symbol);
writeln!(f, " {}", symbol)?; writeln!(f, " {}", symbol)?;
} }
@ -1055,7 +1016,6 @@ impl<'a> Linker for MsvcLinker<'a> {
pub struct EmLinker<'a> { pub struct EmLinker<'a> {
cmd: Command, cmd: Command,
sess: &'a Session, sess: &'a Session,
exports: &'a FxHashMap<CrateType, Vec<String>>,
} }
impl<'a> Linker for EmLinker<'a> { impl<'a> Linker for EmLinker<'a> {
@ -1167,9 +1127,7 @@ impl<'a> Linker for EmLinker<'a> {
self.cmd.args(&["-s", "DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=[]"]); self.cmd.args(&["-s", "DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=[]"]);
} }
fn export_symbols(&mut self, _tmpdir: &Path, crate_type: CrateType) { fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
let symbols = &self.exports[&crate_type];
debug!("EXPORTED SYMBOLS:"); debug!("EXPORTED SYMBOLS:");
self.cmd.arg("-s"); self.cmd.arg("-s");
@ -1211,15 +1169,10 @@ impl<'a> Linker for EmLinker<'a> {
pub struct WasmLd<'a> { pub struct WasmLd<'a> {
cmd: Command, cmd: Command,
sess: &'a Session, sess: &'a Session,
exports: &'a FxHashMap<CrateType, Vec<String>>,
} }
impl<'a> WasmLd<'a> { impl<'a> WasmLd<'a> {
fn new( fn new(mut cmd: Command, sess: &'a Session) -> WasmLd<'a> {
mut cmd: Command,
sess: &'a Session,
exports: &'a FxHashMap<CrateType, Vec<String>>,
) -> WasmLd<'a> {
// If the atomics feature is enabled for wasm then we need a whole bunch // If the atomics feature is enabled for wasm then we need a whole bunch
// of flags: // of flags:
// //
@ -1252,7 +1205,7 @@ impl<'a> WasmLd<'a> {
cmd.arg("--export=__tls_align"); cmd.arg("--export=__tls_align");
cmd.arg("--export=__tls_base"); cmd.arg("--export=__tls_base");
} }
WasmLd { cmd, sess, exports } WasmLd { cmd, sess }
} }
} }
@ -1368,8 +1321,8 @@ impl<'a> Linker for WasmLd<'a> {
fn no_default_libraries(&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]) {
for sym in self.exports[&crate_type].iter() { for sym in symbols {
self.cmd.arg("--export").arg(&sym); self.cmd.arg("--export").arg(&sym);
} }
@ -1392,7 +1345,7 @@ impl<'a> Linker for WasmLd<'a> {
} }
} }
fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> { pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> {
if let Some(ref exports) = tcx.sess.target.override_export_symbols { if let Some(ref exports) = tcx.sess.target.override_export_symbols {
return exports.clone(); return exports.clone();
} }
@ -1521,7 +1474,7 @@ impl<'a> Linker for PtxLinker<'a> {
fn control_flow_guard(&mut self) {} 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) {} fn subsystem(&mut self, _subsystem: &str) {}
@ -1535,7 +1488,6 @@ impl<'a> Linker for PtxLinker<'a> {
pub struct BpfLinker<'a> { pub struct BpfLinker<'a> {
cmd: Command, cmd: Command,
sess: &'a Session, sess: &'a Session,
exports: &'a FxHashMap<CrateType, Vec<String>>,
} }
impl<'a> Linker for BpfLinker<'a> { impl<'a> Linker for BpfLinker<'a> {
@ -1622,11 +1574,11 @@ impl<'a> Linker for BpfLinker<'a> {
fn control_flow_guard(&mut self) {} 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 path = tmpdir.join("symbols");
let res: io::Result<()> = try { let res: io::Result<()> = try {
let mut f = BufWriter::new(File::create(&path)?); let mut f = BufWriter::new(File::create(&path)?);
for sym in self.exports[&crate_type].iter() { for sym in symbols {
writeln!(f, "{}", sym)?; writeln!(f, "{}", sym)?;
} }
}; };

View file

@ -1,4 +1,3 @@
use crate::back::linker::LinkerInfo;
use crate::back::write::{ use crate::back::write::{
compute_per_cgu_lto_type, start_async_codegen, submit_codegened_module_to_llvm, compute_per_cgu_lto_type, start_async_codegen, submit_codegened_module_to_llvm,
submit_post_lto_module_to_llvm, submit_pre_lto_module_to_llvm, ComputedLtoType, OngoingCodegen, submit_post_lto_module_to_llvm, submit_pre_lto_module_to_llvm, ComputedLtoType, OngoingCodegen,
@ -756,7 +755,12 @@ impl<B: ExtraBackendMethods> Drop for AbortCodegenOnDrop<B> {
impl CrateInfo { impl CrateInfo {
pub fn new(tcx: TyCtxt<'_>, target_cpu: String) -> CrateInfo { pub fn new(tcx: TyCtxt<'_>, target_cpu: String) -> CrateInfo {
let linker_info = LinkerInfo::new(tcx, target_cpu); 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 local_crate_name = tcx.crate_name(LOCAL_CRATE);
let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID); 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); let subsystem = tcx.sess.first_attr_value_str_by_name(crate_attrs, sym::windows_subsystem);
@ -772,7 +776,8 @@ impl CrateInfo {
}); });
let mut info = CrateInfo { let mut info = CrateInfo {
linker_info, target_cpu,
exported_symbols,
local_crate_name, local_crate_name,
compiler_builtins: None, compiler_builtins: None,
profiler_runtime: None, profiler_runtime: None,

View file

@ -27,7 +27,7 @@ use rustc_middle::dep_graph::WorkProduct;
use rustc_middle::middle::cstore::{self, CrateSource}; use rustc_middle::middle::cstore::{self, CrateSource};
use rustc_middle::middle::dependency_format::Dependencies; use rustc_middle::middle::dependency_format::Dependencies;
use rustc_middle::ty::query::Providers; 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_session::utils::NativeLibKind;
use rustc_span::symbol::Symbol; use rustc_span::symbol::Symbol;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@ -135,7 +135,8 @@ impl From<&cstore::NativeLib> for NativeLib {
/// and the corresponding properties without referencing information outside of a `CrateInfo`. /// and the corresponding properties without referencing information outside of a `CrateInfo`.
#[derive(Debug, Encodable, Decodable)] #[derive(Debug, Encodable, Decodable)]
pub struct CrateInfo { pub struct CrateInfo {
pub linker_info: back::linker::LinkerInfo, pub target_cpu: String,
pub exported_symbols: FxHashMap<CrateType, Vec<String>>,
pub local_crate_name: Symbol, pub local_crate_name: Symbol,
pub compiler_builtins: Option<CrateNum>, pub compiler_builtins: Option<CrateNum>,
pub profiler_runtime: Option<CrateNum>, pub profiler_runtime: Option<CrateNum>,