Skip to content

Commit 2227d27

Browse files
committed
WIP
1 parent e45d997 commit 2227d27

File tree

104 files changed

+663
-534
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+663
-534
lines changed

compiler/rustc_codegen_ssa/src/back/command.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use std::io;
77
use std::mem;
88
use std::process::{self, Output};
99

10+
use rustc_session::config::LldFlavor;
1011
use rustc_span::symbol::Symbol;
11-
use rustc_target::spec::LldFlavor;
1212

1313
#[derive(Clone)]
1414
pub struct Command {

compiler/rustc_codegen_ssa/src/back/link.rs

+115-101
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use rustc_hir::def_id::CrateNum;
99
use rustc_middle::middle::dependency_format::Linkage;
1010
use rustc_middle::middle::exported_symbols::SymbolExportKind;
1111
use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Strip};
12+
use rustc_session::config::{LegacyLinkerFlavor, LldFlavor};
1213
use rustc_session::config::{OutputFilenames, OutputType, PrintRequest, SplitDwarfKind};
1314
use rustc_session::cstore::DllImport;
1415
use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename};
@@ -20,7 +21,8 @@ use rustc_session::{filesearch, Session};
2021
use rustc_span::symbol::Symbol;
2122
use rustc_span::DebuggerVisualizerFile;
2223
use rustc_target::spec::crt_objects::{CrtObjects, CrtObjectsFallback};
23-
use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor, SplitDebuginfo};
24+
use rustc_target::spec::CoarseGrainedLinkerFlavor;
25+
use rustc_target::spec::{LinkOutputKind, SplitDebuginfo};
2426
use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, SanitizerSet, Target};
2527

2628
use super::archive::{find_library, ArchiveBuilder};
@@ -665,10 +667,11 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
665667
tmpdir: &Path,
666668
) {
667669
info!("preparing {:?} to {:?}", crate_type, out_filename);
668-
let (linker_path, flavor) = linker_and_flavor(sess);
670+
let (linker_path, full_flavor) = linker_and_flavor(sess);
671+
let flavor = *full_flavor;
669672
let mut cmd = linker_with_args::<B>(
670673
&linker_path,
671-
flavor,
674+
full_flavor,
672675
sess,
673676
crate_type,
674677
tmpdir,
@@ -719,7 +722,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
719722
// versions of gcc seem to use different quotes in the error message so
720723
// don't check for them.
721724
if sess.target.linker_is_gnu
722-
&& flavor != LinkerFlavor::Ld
725+
&& flavor == CoarseGrainedLinkerFlavor::TargetLinkerCalledThroughCCompiler
723726
&& unknown_arg_regex.is_match(&out)
724727
&& out.contains("-no-pie")
725728
&& cmd.get_args().iter().any(|e| e.to_string_lossy() == "-no-pie")
@@ -738,7 +741,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
738741
// Detect '-static-pie' used with an older version of gcc or clang not supporting it.
739742
// Fallback from '-static-pie' to '-static' in that case.
740743
if sess.target.linker_is_gnu
741-
&& flavor != LinkerFlavor::Ld
744+
&& flavor == CoarseGrainedLinkerFlavor::TargetLinkerCalledThroughCCompiler
742745
&& unknown_arg_regex.is_match(&out)
743746
&& (out.contains("-static-pie") || out.contains("--no-dynamic-linker"))
744747
&& cmd.get_args().iter().any(|e| e.to_string_lossy() == "-static-pie")
@@ -873,7 +876,6 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
873876
// install the Visual Studio build tools.
874877
if let Some(code) = prog.status.code() {
875878
if sess.target.is_like_msvc
876-
&& flavor == LinkerFlavor::Msvc
877879
// Respect the command line override
878880
&& sess.opts.cg.linker.is_none()
879881
// Match exactly "link.exe"
@@ -1139,94 +1141,103 @@ pub fn ignored_for_lto(sess: &Session, info: &CrateInfo, cnum: CrateNum) -> bool
11391141
&& (info.compiler_builtins == Some(cnum) || info.is_no_builtins.contains(&cnum))
11401142
}
11411143

1142-
// This functions tries to determine the appropriate linker (and corresponding LinkerFlavor) to use
1143-
pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
1144-
fn infer_from(
1145-
sess: &Session,
1146-
linker: Option<PathBuf>,
1147-
flavor: Option<LinkerFlavor>,
1148-
) -> Option<(PathBuf, LinkerFlavor)> {
1149-
match (linker, flavor) {
1150-
(Some(linker), Some(flavor)) => Some((linker, flavor)),
1151-
// only the linker flavor is known; use the default linker for the selected flavor
1152-
(None, Some(flavor)) => Some((
1153-
PathBuf::from(match flavor {
1154-
LinkerFlavor::Em => {
1155-
if cfg!(windows) {
1156-
"emcc.bat"
1157-
} else {
1158-
"emcc"
1159-
}
1160-
}
1161-
LinkerFlavor::Gcc => {
1162-
if cfg!(any(target_os = "solaris", target_os = "illumos")) {
1163-
// On historical Solaris systems, "cc" may have
1164-
// been Sun Studio, which is not flag-compatible
1165-
// with "gcc". This history casts a long shadow,
1166-
// and many modern illumos distributions today
1167-
// ship GCC as "gcc" without also making it
1168-
// available as "cc".
1169-
"gcc"
1170-
} else {
1171-
"cc"
1172-
}
1173-
}
1174-
LinkerFlavor::Ld => "ld",
1175-
LinkerFlavor::Msvc => "link.exe",
1176-
LinkerFlavor::Lld(_) => "lld",
1177-
LinkerFlavor::PtxLinker => "rust-ptx-linker",
1178-
LinkerFlavor::BpfLinker => "bpf-linker",
1179-
LinkerFlavor::L4Bender => "l4-bender",
1180-
}),
1181-
flavor,
1182-
)),
1183-
(Some(linker), None) => {
1184-
let stem = linker.file_stem().and_then(|stem| stem.to_str()).unwrap_or_else(|| {
1185-
sess.fatal("couldn't extract file stem from specified linker")
1186-
});
1187-
1188-
let flavor = if stem == "emcc" {
1189-
LinkerFlavor::Em
1190-
} else if stem == "gcc"
1191-
|| stem.ends_with("-gcc")
1192-
|| stem == "clang"
1193-
|| stem.ends_with("-clang")
1194-
{
1195-
LinkerFlavor::Gcc
1196-
} else if stem == "wasm-ld" || stem.ends_with("-wasm-ld") {
1197-
LinkerFlavor::Lld(LldFlavor::Wasm)
1198-
} else if stem == "ld" || stem == "ld.lld" || stem.ends_with("-ld") {
1199-
LinkerFlavor::Ld
1200-
} else if stem == "link" || stem == "lld-link" {
1201-
LinkerFlavor::Msvc
1202-
} else if stem == "lld" || stem == "rust-lld" {
1203-
LinkerFlavor::Lld(sess.target.lld_flavor)
1204-
} else {
1205-
// fall back to the value in the target spec
1206-
sess.target.linker_flavor
1207-
};
1144+
fn flavor_from_linker_str(linker: &Path, sess: &Session) -> Option<LegacyLinkerFlavor> {
1145+
let stem = linker
1146+
.file_stem()
1147+
.and_then(|stem| stem.to_str())
1148+
.unwrap_or_else(|| sess.fatal("couldn't extract file stem from specified linker"));
1149+
1150+
Some(if stem == "emcc" {
1151+
LegacyLinkerFlavor::Em
1152+
} else if stem == "gcc"
1153+
|| stem.ends_with("-gcc")
1154+
|| stem == "clang"
1155+
|| stem.ends_with("-clang")
1156+
|| stem == "cc"
1157+
|| stem.ends_with("-cc")
1158+
|| stem == "c++"
1159+
|| stem.ends_with("-c++")
1160+
{
1161+
LegacyLinkerFlavor::Gcc
1162+
} else if stem == "wasm-ld" || stem.ends_with("-wasm-ld") {
1163+
LegacyLinkerFlavor::Lld(LldFlavor::Wasm)
1164+
} else if stem == "ld" || stem == "ld.lld" || stem.ends_with("-ld") {
1165+
LegacyLinkerFlavor::Ld
1166+
} else if stem == "link" || stem == "lld-link" {
1167+
LegacyLinkerFlavor::Msvc
1168+
} else if stem == "lld" || stem == "rust-lld" {
1169+
LegacyLinkerFlavor::Lld(LldFlavor::from_sess(sess))
1170+
} else if stem == "l4-bender" {
1171+
LegacyLinkerFlavor::L4Bender
1172+
} else if stem == "rust-ptx-linker" {
1173+
LegacyLinkerFlavor::PtxLinker
1174+
} else if stem == "bpf-linker" {
1175+
LegacyLinkerFlavor::BpfLinker
1176+
} else {
1177+
return None;
1178+
})
1179+
}
12081180

1209-
Some((linker, flavor))
1181+
fn flavor_to_linker_str(flavor: LegacyLinkerFlavor) -> PathBuf {
1182+
PathBuf::from(match flavor {
1183+
LegacyLinkerFlavor::Em => {
1184+
if cfg!(windows) {
1185+
"emcc.bat"
1186+
} else {
1187+
"emcc"
12101188
}
1211-
(None, None) => None,
12121189
}
1213-
}
1190+
LegacyLinkerFlavor::Gcc => {
1191+
if cfg!(any(target_os = "solaris", target_os = "illumos")) {
1192+
// On historical Solaris systems, "cc" may have
1193+
// been Sun Studio, which is not flag-compatible
1194+
// with "gcc". This history casts a long shadow,
1195+
// and many modern illumos distributions today
1196+
// ship GCC as "gcc" without also making it
1197+
// available as "cc".
1198+
"gcc"
1199+
} else {
1200+
"cc"
1201+
}
1202+
}
1203+
LegacyLinkerFlavor::Ld => "ld",
1204+
LegacyLinkerFlavor::Msvc => "link.exe",
1205+
LegacyLinkerFlavor::Lld(_) => "lld",
1206+
LegacyLinkerFlavor::PtxLinker => "rust-ptx-linker",
1207+
LegacyLinkerFlavor::BpfLinker => "bpf-linker",
1208+
LegacyLinkerFlavor::L4Bender => "l4-bender",
1209+
})
1210+
}
12141211

1215-
// linker and linker flavor specified via command line have precedence over what the target
1216-
// specification specifies
1217-
if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), sess.opts.cg.linker_flavor) {
1218-
return ret;
1212+
// This functions tries to determine the appropriate linker (and corresponding LegacyLinkerFlavor) to use
1213+
pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LegacyLinkerFlavor) {
1214+
if let (Some(linker), Some(flavor)) = (&sess.opts.cg.linker, sess.opts.cg.linker_flavor) {
1215+
return (linker.to_owned(), flavor);
12191216
}
1220-
1221-
if let Some(ret) = infer_from(
1222-
sess,
1223-
sess.target.linker.as_deref().map(PathBuf::from),
1224-
Some(sess.target.linker_flavor),
1225-
) {
1226-
return ret;
1217+
if let (None, Some(flavor)) = (&sess.opts.cg.linker, sess.opts.cg.linker_flavor) {
1218+
return (flavor_to_linker_str(flavor), flavor);
12271219
}
1228-
1229-
bug!("Not enough information provided to determine how to invoke the linker");
1220+
if let (Some(linker), None) = (&sess.opts.cg.linker, sess.opts.cg.linker_flavor) {
1221+
if let Some(flavor) = flavor_from_linker_str(linker, sess) {
1222+
return (linker.to_owned(), flavor);
1223+
}
1224+
if let Some(default_linker) = &sess.target.linker {
1225+
if let Some(flavor) = flavor_from_linker_str(Path::new(default_linker.as_ref()), sess) {
1226+
return (linker.to_owned(), flavor);
1227+
}
1228+
}
1229+
// FIXME: From system
1230+
return (linker.to_owned(), LegacyLinkerFlavor::Gcc);
1231+
}
1232+
if let Some(default_linker) = &sess.target.linker {
1233+
if let Some(flavor) = flavor_from_linker_str(Path::new(default_linker.as_ref()), sess) {
1234+
return (PathBuf::from(default_linker.clone().into_owned()), flavor);
1235+
}
1236+
// FIXME: From system
1237+
return (PathBuf::from(default_linker.clone().into_owned()), LegacyLinkerFlavor::Gcc);
1238+
}
1239+
// FIXME: From system
1240+
return (PathBuf::from("cc"), LegacyLinkerFlavor::Gcc);
12301241
}
12311242

12321243
/// Returns a pair of boolean indicating whether we should preserve the object and
@@ -1588,7 +1599,7 @@ fn add_post_link_objects(
15881599

15891600
/// Add arbitrary "pre-link" args defined by the target spec or from command line.
15901601
/// FIXME: Determine where exactly these args need to be inserted.
1591-
fn add_pre_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
1602+
fn add_pre_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: CoarseGrainedLinkerFlavor) {
15921603
if let Some(args) = sess.target.pre_link_args.get(&flavor) {
15931604
cmd.args(args.iter().map(Deref::deref));
15941605
}
@@ -1628,7 +1639,7 @@ fn add_user_defined_link_args(cmd: &mut dyn Linker, sess: &Session) {
16281639
fn add_late_link_args(
16291640
cmd: &mut dyn Linker,
16301641
sess: &Session,
1631-
flavor: LinkerFlavor,
1642+
flavor: CoarseGrainedLinkerFlavor,
16321643
crate_type: CrateType,
16331644
codegen_results: &CodegenResults,
16341645
) {
@@ -1652,7 +1663,7 @@ fn add_late_link_args(
16521663

16531664
/// Add arbitrary "post-link" args defined by the target spec.
16541665
/// FIXME: Determine where exactly these args need to be inserted.
1655-
fn add_post_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
1666+
fn add_post_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: CoarseGrainedLinkerFlavor) {
16561667
if let Some(args) = sess.target.post_link_args.get(&flavor) {
16571668
cmd.args(args.iter().map(Deref::deref));
16581669
}
@@ -1851,18 +1862,19 @@ fn add_rpath_args(
18511862
/// e.g `--foo=yes --foo=no` may be equivalent to `--foo=no`.
18521863
fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
18531864
path: &Path,
1854-
flavor: LinkerFlavor,
1865+
full_flavor: LegacyLinkerFlavor,
18551866
sess: &'a Session,
18561867
crate_type: CrateType,
18571868
tmpdir: &Path,
18581869
out_filename: &Path,
18591870
codegen_results: &CodegenResults,
18601871
) -> Command {
1872+
let flavor = *full_flavor;
18611873
let crt_objects_fallback = crt_objects_fallback(sess, crate_type);
18621874
let cmd = &mut *super::linker::get_linker(
18631875
sess,
18641876
path,
1865-
flavor,
1877+
full_flavor,
18661878
crt_objects_fallback,
18671879
&codegen_results.crate_info.target_cpu,
18681880
);
@@ -2015,7 +2027,7 @@ fn add_order_independent_options(
20152027
sess: &Session,
20162028
link_output_kind: LinkOutputKind,
20172029
crt_objects_fallback: bool,
2018-
flavor: LinkerFlavor,
2030+
flavor: CoarseGrainedLinkerFlavor,
20192031
crate_type: CrateType,
20202032
codegen_results: &CodegenResults,
20212033
out_filename: &Path,
@@ -2056,11 +2068,11 @@ fn add_order_independent_options(
20562068
});
20572069
}
20582070

2059-
if flavor == LinkerFlavor::PtxLinker {
2071+
if sess.target.arch == "nvptx64" {
20602072
// Provide the linker with fallback to internal `target-cpu`.
20612073
cmd.arg("--fallback-arch");
20622074
cmd.arg(&codegen_results.crate_info.target_cpu);
2063-
} else if flavor == LinkerFlavor::BpfLinker {
2075+
} else if sess.target.arch == "bpf" {
20642076
cmd.arg("--cpu");
20652077
cmd.arg(&codegen_results.crate_info.target_cpu);
20662078
cmd.arg("--cpu-features");
@@ -2597,13 +2609,13 @@ fn are_upstream_rust_objects_already_included(sess: &Session) -> bool {
25972609
}
25982610
}
25992611

2600-
fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
2612+
fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: CoarseGrainedLinkerFlavor) {
26012613
let arch = &sess.target.arch;
26022614
let os = &sess.target.os;
26032615
let llvm_target = &sess.target.llvm_target;
26042616
if sess.target.vendor != "apple"
26052617
|| !matches!(os.as_ref(), "ios" | "tvos")
2606-
|| flavor != LinkerFlavor::Gcc
2618+
|| flavor == CoarseGrainedLinkerFlavor::TargetLinker
26072619
{
26082620
return;
26092621
}
@@ -2687,9 +2699,9 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result<String, String> {
26872699
}
26882700
}
26892701

2690-
fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
2702+
fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: CoarseGrainedLinkerFlavor) {
26912703
if let Some(ld_impl) = sess.opts.debugging_opts.gcc_ld {
2692-
if let LinkerFlavor::Gcc = flavor {
2704+
if flavor == CoarseGrainedLinkerFlavor::TargetLinkerCalledThroughCCompiler {
26932705
match ld_impl {
26942706
LdImpl::Lld => {
26952707
let tools_path = sess.get_tools_search_paths(false);
@@ -2705,7 +2717,9 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
27052717
arg.push(gcc_ld_dir);
27062718
arg
27072719
});
2708-
cmd.arg(format!("-Wl,-rustc-lld-flavor={}", sess.target.lld_flavor.as_str()));
2720+
2721+
let lld_flavor = LldFlavor::from_sess(sess);
2722+
cmd.arg(format!("-Wl,-rustc-lld-flavor={}", lld_flavor.as_str()));
27092723
}
27102724
}
27112725
} else {

0 commit comments

Comments
 (0)