Skip to content

Commit 9d11b08

Browse files
author
Jorge Aparicio
committed
-Z linker-flavor
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke the linker using a different interface. For example, by default rustc assumes that all the Linux targets will be linked using GCC. This makes it impossible to use LLD as a linker using just `-C linker=ld.lld` because that will invoke LLD with invalid command line arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't understand that; --gc-sections would be the right argument) With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker using a LD-like interface. This way, `rustc -C linker=ld.lld -Z linker-flavor=ld` will invoke LLD with the right arguments. `-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`, `gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD. This patch also changes target specifications. `linker-flavor` is now a mandatory field that specifies the *default* linker flavor that the target will use. This change also makes the linker interface *explicit*; before, it used to be derived from other fields like linker-is-gnu, is-like-msvc, is-like-emscripten, etc. Another change to target specifications is that the fields `pre-link-args`, `post-link-args` and `late-link-args` now expect a map from flavor to linker arguments. ``` diff - "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"], + "pre-link-args": { + "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"], + "ld": ["--as-needed", "-z,-noexecstack"], + }, ``` [breaking-change] for users of custom targets specifications
1 parent c438c1f commit 9d11b08

File tree

89 files changed

+598
-240
lines changed

Some content is hidden

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

89 files changed

+598
-240
lines changed

src/librustc/session/config.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub use self::DebugInfoLevel::*;
1919
use session::{early_error, early_warn, Session};
2020
use session::search_paths::SearchPaths;
2121

22-
use rustc_back::PanicStrategy;
22+
use rustc_back::{LinkerFlavor, PanicStrategy};
2323
use rustc_back::target::Target;
2424
use lint;
2525
use middle::cstore;
@@ -641,12 +641,14 @@ macro_rules! options {
641641
Some("either `panic` or `abort`");
642642
pub const parse_sanitizer: Option<&'static str> =
643643
Some("one of: `address`, `leak`, `memory` or `thread`");
644+
pub const parse_linker_flavor: Option<&'static str> =
645+
Some(::rustc_back::LinkerFlavor::one_of());
644646
}
645647

646648
#[allow(dead_code)]
647649
mod $mod_set {
648650
use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer};
649-
use rustc_back::PanicStrategy;
651+
use rustc_back::{LinkerFlavor, PanicStrategy};
650652

651653
$(
652654
pub fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool {
@@ -777,6 +779,14 @@ macro_rules! options {
777779
}
778780
true
779781
}
782+
783+
fn parse_linker_flavor(slote: &mut Option<LinkerFlavor>, v: Option<&str>) -> bool {
784+
match v.and_then(LinkerFlavor::from_str) {
785+
Some(lf) => *slote = Some(lf),
786+
_ => return false,
787+
}
788+
true
789+
}
780790
}
781791
) }
782792

@@ -979,6 +989,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
979989
"pass `-install_name @rpath/...` to the macOS linker"),
980990
sanitizer: Option<Sanitizer> = (None, parse_sanitizer, [TRACKED],
981991
"Use a sanitizer"),
992+
linker_flavor: Option<LinkerFlavor> = (None, parse_linker_flavor, [UNTRACKED],
993+
"Linker flavor"),
982994
}
983995

984996
pub fn default_lib_output() -> CrateType {

src/librustc/session/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use syntax::{ast, codemap};
3636
use syntax::feature_gate::AttributeType;
3737
use syntax_pos::{Span, MultiSpan};
3838

39-
use rustc_back::PanicStrategy;
39+
use rustc_back::{LinkerFlavor, PanicStrategy};
4040
use rustc_back::target::Target;
4141
use rustc_data_structures::flock;
4242
use llvm;
@@ -363,6 +363,9 @@ impl Session {
363363
pub fn panic_strategy(&self) -> PanicStrategy {
364364
self.opts.cg.panic.unwrap_or(self.target.target.options.panic_strategy)
365365
}
366+
pub fn linker_flavor(&self) -> LinkerFlavor {
367+
self.opts.debugging_opts.linker_flavor.unwrap_or(self.target.target.linker_flavor)
368+
}
366369
pub fn no_landing_pads(&self) -> bool {
367370
self.opts.debugging_opts.no_landing_pads || self.panic_strategy() == PanicStrategy::Abort
368371
}

src/librustc_back/lib.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,48 @@ pub mod dynamic_lib;
5252

5353
use serialize::json::{Json, ToJson};
5454

55+
macro_rules! linker_flavor {
56+
($(($variant:ident, $string:expr),)+) => {
57+
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash,
58+
RustcEncodable, RustcDecodable)]
59+
pub enum LinkerFlavor {
60+
$($variant,)+
61+
}
62+
63+
impl LinkerFlavor {
64+
pub const fn one_of() -> &'static str {
65+
concat!("one of: ", $($string, " ",)+)
66+
}
67+
68+
pub fn from_str(s: &str) -> Option<Self> {
69+
Some(match s {
70+
$($string => LinkerFlavor::$variant,)+
71+
_ => return None,
72+
})
73+
}
74+
75+
pub fn desc(&self) -> &str {
76+
match *self {
77+
$(LinkerFlavor::$variant => $string,)+
78+
}
79+
}
80+
}
81+
82+
impl ToJson for LinkerFlavor {
83+
fn to_json(&self) -> Json {
84+
self.desc().to_json()
85+
}
86+
}
87+
}
88+
}
89+
90+
linker_flavor! {
91+
(Em, "em"),
92+
(Gcc, "gcc"),
93+
(Ld, "ld"),
94+
(Msvc, "msvc"),
95+
}
96+
5597
#[derive(Clone, Copy, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
5698
pub enum PanicStrategy {
5799
Unwind,

src/librustc_back/target/aarch64_apple_ios.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use LinkerFlavor;
1112
use target::{Target, TargetOptions, TargetResult};
1213
use super::apple_ios_base::{opts, Arch};
1314

@@ -22,6 +23,7 @@ pub fn target() -> TargetResult {
2223
target_os: "ios".to_string(),
2324
target_env: "".to_string(),
2425
target_vendor: "apple".to_string(),
26+
linker_flavor: LinkerFlavor::Gcc,
2527
options: TargetOptions {
2628
features: "+neon,+fp-armv8,+cyclone".to_string(),
2729
eliminate_frame_pointer: false,

src/librustc_back/target/aarch64_linux_android.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use LinkerFlavor;
1112
use target::{Target, TargetOptions, TargetResult};
1213

1314
// See https://developer.android.com/ndk/guides/abis.html#arm64-v8a
@@ -28,6 +29,7 @@ pub fn target() -> TargetResult {
2829
target_os: "android".to_string(),
2930
target_env: "".to_string(),
3031
target_vendor: "unknown".to_string(),
32+
linker_flavor: LinkerFlavor::Gcc,
3133
options: TargetOptions {
3234
abi_blacklist: super::arm_base::abi_blacklist(),
3335
.. base

src/librustc_back/target/aarch64_unknown_freebsd.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use LinkerFlavor;
1112
use target::{Target, TargetOptions, TargetResult};
1213

1314
pub fn target() -> TargetResult {
@@ -26,6 +27,7 @@ pub fn target() -> TargetResult {
2627
target_os: "freebsd".to_string(),
2728
target_env: "".to_string(),
2829
target_vendor: "unknown".to_string(),
30+
linker_flavor: LinkerFlavor::Gcc,
2931
options: TargetOptions {
3032
abi_blacklist: super::arm_base::abi_blacklist(),
3133
.. base

src/librustc_back/target/aarch64_unknown_fuchsia.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use LinkerFlavor;
1112
use target::{Target, TargetOptions, TargetResult};
1213

1314
pub fn target() -> TargetResult {
@@ -23,6 +24,7 @@ pub fn target() -> TargetResult {
2324
target_os: "fuchsia".to_string(),
2425
target_env: "".to_string(),
2526
target_vendor: "unknown".to_string(),
27+
linker_flavor: LinkerFlavor::Gcc,
2628
options: TargetOptions {
2729
abi_blacklist: super::arm_base::abi_blacklist(),
2830
.. base

src/librustc_back/target/aarch64_unknown_linux_gnu.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use LinkerFlavor;
1112
use target::{Target, TargetOptions, TargetResult};
1213

1314
pub fn target() -> TargetResult {
@@ -26,6 +27,7 @@ pub fn target() -> TargetResult {
2627
arch: "aarch64".to_string(),
2728
target_os: "linux".to_string(),
2829
target_vendor: "unknown".to_string(),
30+
linker_flavor: LinkerFlavor::Gcc,
2931
options: TargetOptions {
3032
abi_blacklist: super::arm_base::abi_blacklist(),
3133
.. base

src/librustc_back/target/android_base.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use LinkerFlavor;
1112
use target::TargetOptions;
1213

1314
pub fn opts() -> TargetOptions {
1415
let mut base = super::linux_base::opts();
1516
// Many of the symbols defined in compiler-rt are also defined in libgcc.
1617
// Android's linker doesn't like that by default.
17-
base.pre_link_args.push("-Wl,--allow-multiple-definition".to_string());
18+
base.pre_link_args
19+
.get_mut(&LinkerFlavor::Gcc).unwrap().push("-Wl,--allow-multiple-definition".to_string());
1820
base.is_like_android = true;
1921
base.position_independent_executables = true;
2022
base.has_elf_tls = false;

src/librustc_back/target/apple_base.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use std::env;
1212

13-
use target::TargetOptions;
13+
use target::{LinkArgs, TargetOptions};
1414

1515
pub fn opts() -> TargetOptions {
1616
// ELF TLS is only available in macOS 10.7+. If you try to compile for 10.6
@@ -43,7 +43,7 @@ pub fn opts() -> TargetOptions {
4343
dll_prefix: "lib".to_string(),
4444
dll_suffix: ".dylib".to_string(),
4545
archive_format: "bsd".to_string(),
46-
pre_link_args: Vec::new(),
46+
pre_link_args: LinkArgs::new(),
4747
exe_allocation_crate: super::maybe_jemalloc(),
4848
has_elf_tls: version >= (10, 7),
4949
.. Default::default()

src/librustc_back/target/apple_ios_base.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use LinkerFlavor;
1112
use std::io;
1213
use std::process::Command;
13-
use target::TargetOptions;
14+
use target::{LinkArgs, TargetOptions};
1415

1516
use self::Arch::*;
1617

@@ -60,7 +61,7 @@ pub fn get_sdk_root(sdk_name: &str) -> Result<String, String> {
6061
}
6162
}
6263

63-
fn build_pre_link_args(arch: Arch) -> Result<Vec<String>, String> {
64+
fn build_pre_link_args(arch: Arch) -> Result<LinkArgs, String> {
6465
let sdk_name = match arch {
6566
Armv7 | Armv7s | Arm64 => "iphoneos",
6667
I386 | X86_64 => "iphonesimulator"
@@ -70,8 +71,14 @@ fn build_pre_link_args(arch: Arch) -> Result<Vec<String>, String> {
7071

7172
let sdk_root = get_sdk_root(sdk_name)?;
7273

73-
Ok(vec!["-arch".to_string(), arch_name.to_string(),
74-
"-Wl,-syslibroot".to_string(), sdk_root])
74+
let mut args = LinkArgs::new();
75+
args.insert(LinkerFlavor::Gcc,
76+
vec!["-arch".to_string(),
77+
arch_name.to_string(),
78+
"-Wl,-syslibroot".to_string(),
79+
sdk_root]);
80+
81+
Ok(args)
7582
}
7683

7784
fn target_cpu(arch: Arch) -> String {

src/librustc_back/target/arm_linux_androideabi.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use LinkerFlavor;
1112
use target::{Target, TargetOptions, TargetResult};
1213

1314
pub fn target() -> TargetResult {
@@ -24,6 +25,7 @@ pub fn target() -> TargetResult {
2425
target_os: "android".to_string(),
2526
target_env: "".to_string(),
2627
target_vendor: "unknown".to_string(),
28+
linker_flavor: LinkerFlavor::Gcc,
2729
options: TargetOptions {
2830
abi_blacklist: super::arm_base::abi_blacklist(),
2931
.. base

src/librustc_back/target/arm_unknown_linux_gnueabi.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use LinkerFlavor;
1112
use target::{Target, TargetOptions, TargetResult};
1213

1314
pub fn target() -> TargetResult {
@@ -22,6 +23,7 @@ pub fn target() -> TargetResult {
2223
target_os: "linux".to_string(),
2324
target_env: "gnu".to_string(),
2425
target_vendor: "unknown".to_string(),
26+
linker_flavor: LinkerFlavor::Gcc,
2527

2628
options: TargetOptions {
2729
features: "+v6".to_string(),

src/librustc_back/target/arm_unknown_linux_gnueabihf.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use LinkerFlavor;
1112
use target::{Target, TargetOptions, TargetResult};
1213

1314
pub fn target() -> TargetResult {
@@ -22,6 +23,7 @@ pub fn target() -> TargetResult {
2223
target_os: "linux".to_string(),
2324
target_env: "gnu".to_string(),
2425
target_vendor: "unknown".to_string(),
26+
linker_flavor: LinkerFlavor::Gcc,
2527

2628
options: TargetOptions {
2729
features: "+v6,+vfp2".to_string(),

src/librustc_back/target/arm_unknown_linux_musleabi.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use LinkerFlavor;
1112
use target::{Target, TargetOptions, TargetResult};
1213

1314
pub fn target() -> TargetResult {
@@ -29,6 +30,7 @@ pub fn target() -> TargetResult {
2930
target_os: "linux".to_string(),
3031
target_env: "musl".to_string(),
3132
target_vendor: "unknown".to_string(),
33+
linker_flavor: LinkerFlavor::Gcc,
3234
options: TargetOptions {
3335
abi_blacklist: super::arm_base::abi_blacklist(),
3436
.. base

src/librustc_back/target/arm_unknown_linux_musleabihf.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use LinkerFlavor;
1112
use target::{Target, TargetOptions, TargetResult};
1213

1314
pub fn target() -> TargetResult {
@@ -29,6 +30,7 @@ pub fn target() -> TargetResult {
2930
target_os: "linux".to_string(),
3031
target_env: "musl".to_string(),
3132
target_vendor: "unknown".to_string(),
33+
linker_flavor: LinkerFlavor::Gcc,
3234
options: TargetOptions {
3335
abi_blacklist: super::arm_base::abi_blacklist(),
3436
.. base

src/librustc_back/target/armv5te_unknown_linux_gnueabi.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use LinkerFlavor;
1112
use target::{Target, TargetOptions, TargetResult};
1213

1314
pub fn target() -> TargetResult {
@@ -21,6 +22,7 @@ pub fn target() -> TargetResult {
2122
target_os: "linux".to_string(),
2223
target_env: "gnu".to_string(),
2324
target_vendor: "unknown".to_string(),
25+
linker_flavor: LinkerFlavor::Gcc,
2426

2527
options: TargetOptions {
2628
features: "+soft-float".to_string(),
@@ -31,4 +33,3 @@ pub fn target() -> TargetResult {
3133
}
3234
})
3335
}
34-

src/librustc_back/target/armv7_apple_ios.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use LinkerFlavor;
1112
use target::{Target, TargetOptions, TargetResult};
1213
use super::apple_ios_base::{opts, Arch};
1314

@@ -22,6 +23,7 @@ pub fn target() -> TargetResult {
2223
target_os: "ios".to_string(),
2324
target_env: "".to_string(),
2425
target_vendor: "apple".to_string(),
26+
linker_flavor: LinkerFlavor::Gcc,
2527
options: TargetOptions {
2628
features: "+v7,+vfp3,+neon".to_string(),
2729
max_atomic_width: Some(64),

0 commit comments

Comments
 (0)