Skip to content

Commit

Permalink
Fold LinkerInfo into CrateInfo
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorn3 committed Jul 6, 2021
1 parent b4a12f9 commit b21cbfd
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 86 deletions.
12 changes: 8 additions & 4 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Expand Up @@ -1718,7 +1718,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
path,
flavor,
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);

Expand All @@ -1729,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,
Expand Down Expand Up @@ -1901,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.crate_info.linker_info.target_cpu);
cmd.arg(&codegen_results.crate_info.target_cpu);
} else if flavor == LinkerFlavor::BpfLinker {
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(match &sess.opts.cg.target_feature {
feat if !feat.is_empty() => feat,
Expand Down
106 changes: 29 additions & 77 deletions compiler/rustc_codegen_ssa/src/back/linker.rs
Expand Up @@ -10,7 +10,6 @@ use std::io::{self, BufWriter};
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;
Expand All @@ -36,28 +35,6 @@ 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(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
// path for MSVC to find its DLLs, and gcc to find its bundled
// toolchain
Expand All @@ -66,7 +43,7 @@ pub fn get_linker<'a>(
linker: &Path,
flavor: LinkerFlavor,
self_contained: bool,
info: &'a LinkerInfo,
target_cpu: &'a str,
) -> Box<dyn Linker + 'a> {
let msvc_tool = windows_registry::find_tool(&sess.opts.target_triple.triple(), "link.exe");

Expand Down Expand Up @@ -153,40 +130,26 @@ pub fn get_linker<'a>(

match flavor {
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 => {
Box::new(EmLinker { cmd, sess, exports: &info.exports }) as Box<dyn Linker>
LinkerFlavor::Em => Box::new(EmLinker { cmd, sess }) 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::Ld64)
| LinkerFlavor::Ld => Box::new(GccLinker {
cmd,
sess,
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::Ld => {
Box::new(GccLinker { cmd, sess, target_cpu, hinted_static: false, is_ld: true })
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::BpfLinker => {
Box::new(BpfLinker { cmd, sess, exports: &info.exports }) as Box<dyn Linker>
}
LinkerFlavor::BpfLinker => Box::new(BpfLinker { cmd, sess }) as Box<dyn Linker>,
}
}

Expand Down Expand Up @@ -222,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);
Expand Down Expand Up @@ -250,7 +213,6 @@ impl dyn Linker + '_ {
pub struct GccLinker<'a> {
cmd: Command,
sess: &'a Session,
exports: &'a FxHashMap<CrateType, Vec<String>>,
target_cpu: &'a str,
hinted_static: bool, // Keeps track of the current hinting mode.
// Link as ld
Expand Down Expand Up @@ -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.
if crate_type == CrateType::Executable && self.sess.target.override_export_symbols.is_none()
{
Expand Down Expand Up @@ -684,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.exports[&crate_type].iter() {
for sym in symbols {
debug!(" _{}", sym);
writeln!(f, "_{}", sym)?;
}
Expand All @@ -699,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.exports[&crate_type].iter() {
for symbol in symbols {
debug!(" _{}", symbol);
writeln!(f, " {}", symbol)?;
}
Expand All @@ -712,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.exports[&crate_type].is_empty() {
if !symbols.is_empty() {
writeln!(f, " global:")?;
for sym in self.exports[&crate_type].iter() {
for sym in symbols {
debug!(" {};", sym);
writeln!(f, " {};", sym)?;
}
Expand Down Expand Up @@ -814,7 +776,6 @@ impl<'a> Linker for GccLinker<'a> {
pub struct MsvcLinker<'a> {
cmd: Command,
sess: &'a Session,
exports: &'a FxHashMap<CrateType, Vec<String>>,
}

impl<'a> Linker for MsvcLinker<'a> {
Expand Down Expand Up @@ -988,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;
Expand All @@ -1002,7 +963,7 @@ impl<'a> Linker for MsvcLinker<'a> {
// straight to exports.
writeln!(f, "LIBRARY")?;
writeln!(f, "EXPORTS")?;
for symbol in self.exports[&crate_type].iter() {
for symbol in symbols {
debug!(" _{}", symbol);
writeln!(f, " {}", symbol)?;
}
Expand Down Expand Up @@ -1055,7 +1016,6 @@ impl<'a> Linker for MsvcLinker<'a> {
pub struct EmLinker<'a> {
cmd: Command,
sess: &'a Session,
exports: &'a FxHashMap<CrateType, Vec<String>>,
}

impl<'a> Linker for EmLinker<'a> {
Expand Down Expand Up @@ -1167,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.exports[&crate_type];

fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
debug!("EXPORTED SYMBOLS:");

self.cmd.arg("-s");
Expand Down Expand Up @@ -1211,15 +1169,10 @@ impl<'a> Linker for EmLinker<'a> {
pub struct WasmLd<'a> {
cmd: Command,
sess: &'a Session,
exports: &'a FxHashMap<CrateType, Vec<String>>,
}

impl<'a> WasmLd<'a> {
fn new(
mut cmd: Command,
sess: &'a Session,
exports: &'a FxHashMap<CrateType, Vec<String>>,
) -> 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:
//
Expand Down Expand Up @@ -1252,7 +1205,7 @@ impl<'a> WasmLd<'a> {
cmd.arg("--export=__tls_align");
cmd.arg("--export=__tls_base");
}
WasmLd { cmd, sess, exports }
WasmLd { cmd, sess }
}
}

Expand Down Expand Up @@ -1368,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.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);
}

Expand All @@ -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 {
return exports.clone();
}
Expand Down Expand Up @@ -1521,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) {}

Expand All @@ -1535,7 +1488,6 @@ impl<'a> Linker for PtxLinker<'a> {
pub struct BpfLinker<'a> {
cmd: Command,
sess: &'a Session,
exports: &'a FxHashMap<CrateType, Vec<String>>,
}

impl<'a> Linker for BpfLinker<'a> {
Expand Down Expand Up @@ -1622,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.exports[&crate_type].iter() {
for sym in symbols {
writeln!(f, "{}", sym)?;
}
};
Expand Down
11 changes: 8 additions & 3 deletions compiler/rustc_codegen_ssa/src/base.rs
@@ -1,4 +1,3 @@
use crate::back::linker::LinkerInfo;
use crate::back::write::{
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,
Expand Down Expand Up @@ -756,7 +755,12 @@ impl<B: ExtraBackendMethods> Drop for AbortCodegenOnDrop<B> {

impl 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 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);
Expand All @@ -772,7 +776,8 @@ impl CrateInfo {
});

let mut info = CrateInfo {
linker_info,
target_cpu,
exported_symbols,
local_crate_name,
compiler_builtins: None,
profiler_runtime: None,
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_codegen_ssa/src/lib.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -135,7 +135,8 @@ 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 linker_info: back::linker::LinkerInfo,
pub target_cpu: String,
pub exported_symbols: FxHashMap<CrateType, Vec<String>>,
pub local_crate_name: Symbol,
pub compiler_builtins: Option<CrateNum>,
pub profiler_runtime: Option<CrateNum>,
Expand Down

0 comments on commit b21cbfd

Please sign in to comment.