rustc_target: Add convenience functions for adding linker arguments

They ensure that lld and non-lld linker flavors get the same set of arguments
This commit is contained in:
Vadim Petrochenkov 2022-06-17 17:38:42 +03:00
parent 8aab472d52
commit 46aba8850b
74 changed files with 347 additions and 419 deletions

View file

@ -8,7 +8,7 @@ pub fn target() -> Target {
// FIXME: The leak sanitizer currently fails the tests, see #88132. // FIXME: The leak sanitizer currently fails the tests, see #88132.
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD; base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD;
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-arch".into(), "arm64".into()]); base.add_pre_link_args(LinkerFlavor::Gcc, &["-arch", "arm64"]);
base.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove()); base.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove());
// Clang automatically chooses a more specific target based on // Clang automatically chooses a more specific target based on

View file

@ -2,20 +2,13 @@
// uefi-base module for generic UEFI options. // uefi-base module for generic UEFI options.
use super::uefi_msvc_base; use super::uefi_msvc_base;
use crate::spec::{LinkerFlavor, LldFlavor, Target}; use crate::spec::{LinkerFlavor, Target};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = uefi_msvc_base::opts(); let mut base = uefi_msvc_base::opts();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.add_pre_link_args(LinkerFlavor::Msvc, &["/machine:arm64"]);
let pre_link_args_msvc = vec!["/machine:arm64".into()];
base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().extend(pre_link_args_msvc.clone());
base.pre_link_args
.get_mut(&LinkerFlavor::Lld(LldFlavor::Link))
.unwrap()
.extend(pre_link_args_msvc);
Target { Target {
llvm_target: "aarch64-unknown-windows".into(), llvm_target: "aarch64-unknown-windows".into(),

View file

@ -1,19 +1,13 @@
use crate::spec::{cvs, LinkArgs, LinkerFlavor, RelocModel, Target, TargetOptions}; use crate::spec::{cvs, LinkerFlavor, RelocModel, Target, TargetOptions};
/// A base target for Nintendo 3DS devices using the devkitARM toolchain. /// A base target for Nintendo 3DS devices using the devkitARM toolchain.
/// ///
/// Requires the devkitARM toolchain for 3DS targets on the host system. /// Requires the devkitARM toolchain for 3DS targets on the host system.
pub fn target() -> Target { pub fn target() -> Target {
let mut pre_link_args = LinkArgs::new(); let pre_link_args = TargetOptions::link_args(
pre_link_args.insert(
LinkerFlavor::Gcc, LinkerFlavor::Gcc,
vec![ &["-specs=3dsx.specs", "-mtune=mpcore", "-mfloat-abi=hard", "-mtp=soft"],
"-specs=3dsx.specs".into(),
"-mtune=mpcore".into(),
"-mfloat-abi=hard".into(),
"-mtp=soft".into(),
],
); );
Target { Target {

View file

@ -10,7 +10,7 @@ use crate::spec::{LinkerFlavor, SanitizerSet, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::android_base::opts(); let mut base = super::android_base::opts();
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-march=armv7-a".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-march=armv7-a"]);
Target { Target {
llvm_target: "armv7-none-linux-android".into(), llvm_target: "armv7-none-linux-android".into(),
pointer_width: 32, pointer_width: 32,

View file

@ -2,10 +2,6 @@ use super::{wasm32_unknown_emscripten, LinkerFlavor, Target};
pub fn target() -> Target { pub fn target() -> Target {
let mut target = wasm32_unknown_emscripten::target(); let mut target = wasm32_unknown_emscripten::target();
target.post_link_args.entry(LinkerFlavor::Em).or_default().extend(vec![ target.add_post_link_args(LinkerFlavor::Em, &["-sWASM=0", "--memory-init-file", "0"]);
"-sWASM=0".into(),
"--memory-init-file".into(),
"0".into(),
]);
target target
} }

View file

@ -3,7 +3,8 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
/// A base target for AVR devices using the GNU toolchain. /// A base target for AVR devices using the GNU toolchain.
/// ///
/// Requires GNU avr-gcc and avr-binutils on the host system. /// Requires GNU avr-gcc and avr-binutils on the host system.
pub fn target(target_cpu: &'static str) -> Target { /// FIXME: Remove the second parameter when const string concatenation is possible.
pub fn target(target_cpu: &'static str, mmcu: &'static str) -> Target {
Target { Target {
arch: "avr".into(), arch: "avr".into(),
data_layout: "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8".into(), data_layout: "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8".into(),
@ -17,10 +18,8 @@ pub fn target(target_cpu: &'static str) -> Target {
linker: Some("avr-gcc".into()), linker: Some("avr-gcc".into()),
executables: true, executables: true,
eh_frame_header: false, eh_frame_header: false,
pre_link_args: [(LinkerFlavor::Gcc, vec![format!("-mmcu={}", target_cpu).into()])] pre_link_args: TargetOptions::link_args(LinkerFlavor::Gcc, &[mmcu]),
.into_iter() late_link_args: TargetOptions::link_args(LinkerFlavor::Gcc, &["-lgcc"]),
.collect(),
late_link_args: [(LinkerFlavor::Gcc, vec!["-lgcc".into()])].into_iter().collect(),
max_atomic_width: Some(0), max_atomic_width: Some(0),
atomic_cas: false, atomic_cas: false,
..TargetOptions::default() ..TargetOptions::default()

View file

@ -1,5 +1,5 @@
use crate::spec::Target; use crate::spec::Target;
pub fn target() -> Target { pub fn target() -> Target {
super::avr_gnu_base::target("atmega328") super::avr_gnu_base::target("atmega328", "-mmcu=atmega328")
} }

View file

@ -1,23 +1,20 @@
use crate::spec::{ use crate::spec::{crt_objects, cvs, LinkOutputKind, LinkerFlavor, LldFlavor, TargetOptions};
crt_objects, cvs, LinkArgs, LinkOutputKind, LinkerFlavor, LldFlavor, TargetOptions,
};
pub fn opts() -> TargetOptions { pub fn opts() -> TargetOptions {
let mut pre_link_args = LinkArgs::new(); let pre_link_args = TargetOptions::link_args(
pre_link_args.insert( LinkerFlavor::Ld,
LinkerFlavor::Lld(LldFlavor::Ld), &[
vec![ "--build-id",
"--build-id".into(), "--hash-style=gnu",
"--hash-style=gnu".into(), "-z",
"-z".into(), "max-page-size=4096",
"max-page-size=4096".into(), "-z",
"-z".into(), "now",
"now".into(), "-z",
"-z".into(), "rodynamic",
"rodynamic".into(), "-z",
"-z".into(), "separate-loadable-segments",
"separate-loadable-segments".into(), "--pack-dyn-relocs=relr",
"--pack-dyn-relocs=relr".into(),
], ],
); );

View file

@ -1,10 +1,9 @@
use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions, TlsModel}; use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions, TlsModel};
pub fn opts() -> TargetOptions { pub fn opts() -> TargetOptions {
let mut pre_link_args = LinkArgs::new(); let pre_link_args = TargetOptions::link_args(
pre_link_args.insert( LinkerFlavor::Ld,
LinkerFlavor::Lld(LldFlavor::Ld), &["--build-id", "--hash-style=gnu", "--Bstatic"],
vec!["--build-id".into(), "--hash-style=gnu".into(), "--Bstatic".into()],
); );
TargetOptions { TargetOptions {

View file

@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::apple_base::opts("macos"); let mut base = super::apple_base::opts("macos");
base.cpu = "yonah".into(); base.cpu = "yonah".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".into()]); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
base.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove()); base.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove());
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call; base.stack_probes = StackProbeType::Call;

View file

@ -1,19 +1,16 @@
use crate::spec::{FramePointer, LinkerFlavor, LldFlavor, Target}; use crate::spec::{FramePointer, LinkerFlavor, Target};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::windows_gnu_base::opts(); let mut base = super::windows_gnu_base::opts();
base.cpu = "pentium4".into(); base.cpu = "pentium4".into();
base.pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), vec!["-m".into(), "i386pe".into()]); base.add_pre_link_args(LinkerFlavor::Ld, &["-m", "i386pe"]);
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.frame_pointer = FramePointer::Always; // Required for backtraces base.frame_pointer = FramePointer::Always; // Required for backtraces
base.linker = Some("i686-w64-mingw32-gcc".into()); base.linker = Some("i686-w64-mingw32-gcc".into());
// Mark all dynamic libraries and executables as compatible with the larger 4GiB address // Mark all dynamic libraries and executables as compatible with the larger 4GiB address
// space available to x86 Windows binaries on x86_64. // space available to x86 Windows binaries on x86_64.
base.pre_link_args base.add_pre_link_args(LinkerFlavor::Gcc, &["-Wl,--large-address-aware"]);
.entry(LinkerFlavor::Gcc)
.or_default()
.push("-Wl,--large-address-aware".into());
Target { Target {
llvm_target: "i686-pc-windows-gnu".into(), llvm_target: "i686-pc-windows-gnu".into(),

View file

@ -1,24 +1,22 @@
use crate::spec::{LinkerFlavor, LldFlavor, Target}; use crate::spec::{LinkerFlavor, Target};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::windows_msvc_base::opts(); let mut base = super::windows_msvc_base::opts();
base.cpu = "pentium4".into(); base.cpu = "pentium4".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
let pre_link_args_msvc = vec![ base.add_pre_link_args(
// Mark all dynamic libraries and executables as compatible with the larger 4GiB address LinkerFlavor::Msvc,
// space available to x86 Windows binaries on x86_64. &[
"/LARGEADDRESSAWARE".into(), // Mark all dynamic libraries and executables as compatible with the larger 4GiB address
// Ensure the linker will only produce an image if it can also produce a table of // space available to x86 Windows binaries on x86_64.
// the image's safe exception handlers. "/LARGEADDRESSAWARE",
// https://docs.microsoft.com/en-us/cpp/build/reference/safeseh-image-has-safe-exception-handlers // Ensure the linker will only produce an image if it can also produce a table of
"/SAFESEH".into(), // the image's safe exception handlers.
]; // https://docs.microsoft.com/en-us/cpp/build/reference/safeseh-image-has-safe-exception-handlers
base.pre_link_args.entry(LinkerFlavor::Msvc).or_default().extend(pre_link_args_msvc.clone()); "/SAFESEH",
base.pre_link_args ],
.entry(LinkerFlavor::Lld(LldFlavor::Link)) );
.or_default()
.extend(pre_link_args_msvc);
// Workaround for #95429 // Workaround for #95429
base.has_thread_local = false; base.has_thread_local = false;

View file

@ -4,9 +4,7 @@ pub fn target() -> Target {
let mut base = super::freebsd_base::opts(); let mut base = super::freebsd_base::opts();
base.cpu = "pentium4".into(); base.cpu = "pentium4".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
let pre_link_args = base.pre_link_args.entry(LinkerFlavor::Gcc).or_default(); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "-Wl,-znotext"]);
pre_link_args.push("-m32".into());
pre_link_args.push("-Wl,-znotext".into());
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call; base.stack_probes = StackProbeType::Call;

View file

@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::haiku_base::opts(); let mut base = super::haiku_base::opts();
base.cpu = "pentium4".into(); base.cpu = "pentium4".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".into()]); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call; base.stack_probes = StackProbeType::Call;

View file

@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts(); let mut base = super::linux_gnu_base::opts();
base.cpu = "pentium4".into(); base.cpu = "pentium4".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call; base.stack_probes = StackProbeType::Call;

View file

@ -4,8 +4,7 @@ pub fn target() -> Target {
let mut base = super::linux_musl_base::opts(); let mut base = super::linux_musl_base::opts();
base.cpu = "pentium4".into(); base.cpu = "pentium4".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "-Wl,-melf_i386"]);
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-Wl,-melf_i386".into());
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call; base.stack_probes = StackProbeType::Call;

View file

@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::netbsd_base::opts(); let mut base = super::netbsd_base::opts();
base.cpu = "pentium4".into(); base.cpu = "pentium4".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call; base.stack_probes = StackProbeType::Call;

View file

@ -4,8 +4,7 @@ pub fn target() -> Target {
let mut base = super::openbsd_base::opts(); let mut base = super::openbsd_base::opts();
base.cpu = "pentium4".into(); base.cpu = "pentium4".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "-fuse-ld=lld"]);
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-fuse-ld=lld".into());
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call; base.stack_probes = StackProbeType::Call;

View file

@ -1,18 +1,15 @@
use crate::spec::{FramePointer, LinkerFlavor, LldFlavor, Target}; use crate::spec::{FramePointer, LinkerFlavor, Target};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::windows_uwp_gnu_base::opts(); let mut base = super::windows_uwp_gnu_base::opts();
base.cpu = "pentium4".into(); base.cpu = "pentium4".into();
base.pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), vec!["-m".into(), "i386pe".into()]); base.add_pre_link_args(LinkerFlavor::Ld, &["-m", "i386pe"]);
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.frame_pointer = FramePointer::Always; // Required for backtraces base.frame_pointer = FramePointer::Always; // Required for backtraces
// Mark all dynamic libraries and executables as compatible with the larger 4GiB address // Mark all dynamic libraries and executables as compatible with the larger 4GiB address
// space available to x86 Windows binaries on x86_64. // space available to x86 Windows binaries on x86_64.
base.pre_link_args base.add_pre_link_args(LinkerFlavor::Gcc, &["-Wl,--large-address-aware"]);
.entry(LinkerFlavor::Gcc)
.or_default()
.push("-Wl,--large-address-aware".into());
Target { Target {
llvm_target: "i686-pc-windows-gnu".into(), llvm_target: "i686-pc-windows-gnu".into(),

View file

@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::vxworks_base::opts(); let mut base = super::vxworks_base::opts();
base.cpu = "pentium4".into(); base.cpu = "pentium4".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call; base.stack_probes = StackProbeType::Call;

View file

@ -1,10 +1,9 @@
use crate::spec::{cvs, FramePointer, LinkArgs, LinkerFlavor, TargetOptions}; use crate::spec::{cvs, FramePointer, LinkerFlavor, TargetOptions};
pub fn opts() -> TargetOptions { pub fn opts() -> TargetOptions {
let mut late_link_args = LinkArgs::new(); let late_link_args = TargetOptions::link_args(
late_link_args.insert(
LinkerFlavor::Gcc, LinkerFlavor::Gcc,
vec![ &[
// The illumos libc contains a stack unwinding implementation, as // The illumos libc contains a stack unwinding implementation, as
// does libgcc_s. The latter implementation includes several // does libgcc_s. The latter implementation includes several
// additional symbols that are not always in base libc. To force // additional symbols that are not always in base libc. To force
@ -15,13 +14,13 @@ pub fn opts() -> TargetOptions {
// FIXME: This should be replaced by a more complete and generic // FIXME: This should be replaced by a more complete and generic
// mechanism for controlling the order of library arguments passed // mechanism for controlling the order of library arguments passed
// to the linker. // to the linker.
"-lc".into(), "-lc",
// LLVM will insert calls to the stack protector functions // LLVM will insert calls to the stack protector functions
// "__stack_chk_fail" and "__stack_chk_guard" into code in native // "__stack_chk_fail" and "__stack_chk_guard" into code in native
// object files. Some platforms include these symbols directly in // object files. Some platforms include these symbols directly in
// libc, but at least historically these have been provided in // libc, but at least historically these have been provided in
// libssp.so on illumos and Solaris systems. // libssp.so on illumos and Solaris systems.
"-lssp".into(), "-lssp",
], ],
); );

View file

@ -1,13 +1,11 @@
use crate::spec::{cvs, Target, TargetOptions}; use crate::spec::{cvs, Target, TargetOptions};
use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, RelocModel}; use crate::spec::{LinkerFlavor, LldFlavor, RelocModel};
// The PSP has custom linker requirements. // The PSP has custom linker requirements.
const LINKER_SCRIPT: &str = include_str!("./mipsel_sony_psp_linker_script.ld"); const LINKER_SCRIPT: &str = include_str!("./mipsel_sony_psp_linker_script.ld");
pub fn target() -> Target { pub fn target() -> Target {
let mut pre_link_args = LinkArgs::new(); let pre_link_args = TargetOptions::link_args(LinkerFlavor::Ld, &["--emit-relocs", "--nmagic"]);
pre_link_args
.insert(LinkerFlavor::Lld(LldFlavor::Ld), vec!["--emit-relocs".into(), "--nmagic".into()]);
Target { Target {
llvm_target: "mipsel-sony-psp".into(), llvm_target: "mipsel-sony-psp".into(),

View file

@ -1459,6 +1459,44 @@ pub struct TargetOptions {
pub supports_stack_protector: bool, pub supports_stack_protector: bool,
} }
/// Add arguments for the given flavor and also for its "twin" flavors
/// that have a compatible command line interface.
fn add_link_args(link_args: &mut LinkArgs, flavor: LinkerFlavor, args: &[&'static str]) {
let mut insert = |flavor| {
link_args.entry(flavor).or_default().extend(args.iter().copied().map(Cow::Borrowed))
};
insert(flavor);
match flavor {
LinkerFlavor::Ld => insert(LinkerFlavor::Lld(LldFlavor::Ld)),
LinkerFlavor::Msvc => insert(LinkerFlavor::Lld(LldFlavor::Link)),
LinkerFlavor::Lld(LldFlavor::Wasm) => {}
LinkerFlavor::Lld(lld_flavor) => {
panic!("add_link_args: use non-LLD flavor for {:?}", lld_flavor)
}
LinkerFlavor::Gcc
| LinkerFlavor::Em
| LinkerFlavor::L4Bender
| LinkerFlavor::BpfLinker
| LinkerFlavor::PtxLinker => {}
}
}
impl TargetOptions {
fn link_args(flavor: LinkerFlavor, args: &[&'static str]) -> LinkArgs {
let mut link_args = LinkArgs::new();
add_link_args(&mut link_args, flavor, args);
link_args
}
fn add_pre_link_args(&mut self, flavor: LinkerFlavor, args: &[&'static str]) {
add_link_args(&mut self.pre_link_args, flavor, args);
}
fn add_post_link_args(&mut self, flavor: LinkerFlavor, args: &[&'static str]) {
add_link_args(&mut self.post_link_args, flavor, args);
}
}
impl Default for TargetOptions { impl Default for TargetOptions {
/// Creates a set of "sane defaults" for any target. This is still /// Creates a set of "sane defaults" for any target. This is still
/// incomplete, and if used for compilation, will certainly not work. /// incomplete, and if used for compilation, will certainly not work.

View file

@ -1,14 +1,9 @@
use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, SplitDebuginfo, TargetOptions}; use crate::spec::{LinkerFlavor, LldFlavor, SplitDebuginfo, TargetOptions};
pub fn opts() -> TargetOptions { pub fn opts() -> TargetOptions {
let pre_link_args_msvc = vec![ // Suppress the verbose logo and authorship debugging output, which would needlessly
// Suppress the verbose logo and authorship debugging output, which would needlessly // clog any log files.
// clog any log files. let pre_link_args = TargetOptions::link_args(LinkerFlavor::Msvc, &["/NOLOGO"]);
"/NOLOGO".into(),
];
let mut pre_link_args = LinkArgs::new();
pre_link_args.insert(LinkerFlavor::Msvc, pre_link_args_msvc.clone());
pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Link), pre_link_args_msvc);
TargetOptions { TargetOptions {
linker_flavor: LinkerFlavor::Msvc, linker_flavor: LinkerFlavor::Msvc,

View file

@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::freebsd_base::opts(); let mut base = super::freebsd_base::opts();
base.cpu = "ppc64".into(); base.cpu = "ppc64".into();
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
Target { Target {

View file

@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, RelroLevel, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts(); let mut base = super::linux_gnu_base::opts();
base.cpu = "ppc64".into(); base.cpu = "ppc64".into();
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
// ld.so in at least RHEL6 on ppc64 has a bug related to BIND_NOW, so only enable partial RELRO // ld.so in at least RHEL6 on ppc64 has a bug related to BIND_NOW, so only enable partial RELRO

View file

@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::linux_musl_base::opts(); let mut base = super::linux_musl_base::opts();
base.cpu = "ppc64".into(); base.cpu = "ppc64".into();
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
Target { Target {

View file

@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::vxworks_base::opts(); let mut base = super::vxworks_base::opts();
base.cpu = "ppc64".into(); base.cpu = "ppc64".into();
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
Target { Target {

View file

@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::freebsd_base::opts(); let mut base = super::freebsd_base::opts();
base.cpu = "ppc64le".into(); base.cpu = "ppc64le".into();
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
Target { Target {

View file

@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts(); let mut base = super::linux_gnu_base::opts();
base.cpu = "ppc64le".into(); base.cpu = "ppc64le".into();
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
Target { Target {

View file

@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::linux_musl_base::opts(); let mut base = super::linux_musl_base::opts();
base.cpu = "ppc64le".into(); base.cpu = "ppc64le".into();
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
Target { Target {

View file

@ -3,12 +3,8 @@ use crate::spec::{LinkerFlavor, RelocModel, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::freebsd_base::opts(); let mut base = super::freebsd_base::opts();
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into());
// Extra hint to linker that we are generating secure-PLT code. // Extra hint to linker that we are generating secure-PLT code.
base.pre_link_args base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "--target=powerpc-unknown-freebsd13.0"]);
.entry(LinkerFlavor::Gcc)
.or_default()
.push("--target=powerpc-unknown-freebsd13.0".into());
base.max_atomic_width = Some(32); base.max_atomic_width = Some(32);
Target { Target {

View file

@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts(); let mut base = super::linux_gnu_base::opts();
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
base.max_atomic_width = Some(32); base.max_atomic_width = Some(32);
Target { Target {

View file

@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts(); let mut base = super::linux_gnu_base::opts();
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-mspe".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-mspe"]);
base.max_atomic_width = Some(32); base.max_atomic_width = Some(32);
Target { Target {

View file

@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::linux_musl_base::opts(); let mut base = super::linux_musl_base::opts();
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
base.max_atomic_width = Some(32); base.max_atomic_width = Some(32);
Target { Target {

View file

@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::netbsd_base::opts(); let mut base = super::netbsd_base::opts();
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
base.max_atomic_width = Some(32); base.max_atomic_width = Some(32);
Target { Target {

View file

@ -3,8 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::vxworks_base::opts(); let mut base = super::vxworks_base::opts();
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "--secure-plt"]);
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("--secure-plt".into());
base.max_atomic_width = Some(32); base.max_atomic_width = Some(32);
Target { Target {

View file

@ -3,8 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::vxworks_base::opts(); let mut base = super::vxworks_base::opts();
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-mspe".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-mspe", "--secure-plt"]);
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("--secure-plt".into());
base.max_atomic_width = Some(32); base.max_atomic_width = Some(32);
Target { Target {

View file

@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::netbsd_base::opts(); let mut base = super::netbsd_base::opts();
base.cpu = "v9".into(); base.cpu = "v9".into();
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
Target { Target {

View file

@ -5,7 +5,7 @@ pub fn target() -> Target {
let mut base = super::openbsd_base::opts(); let mut base = super::openbsd_base::opts();
base.endian = Endian::Big; base.endian = Endian::Big;
base.cpu = "v9".into(); base.cpu = "v9".into();
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
Target { Target {

View file

@ -6,7 +6,7 @@ pub fn target() -> Target {
base.endian = Endian::Big; base.endian = Endian::Big;
base.cpu = "v9".into(); base.cpu = "v9".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-mv8plus".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-mv8plus"]);
Target { Target {
llvm_target: "sparc-unknown-linux-gnu".into(), llvm_target: "sparc-unknown-linux-gnu".into(),

View file

@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::solaris_base::opts(); let mut base = super::solaris_base::opts();
base.endian = Endian::Big; base.endian = Endian::Big;
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".into()]); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
// llvm calls this "v9" // llvm calls this "v9"
base.cpu = "v9".into(); base.cpu = "v9".into();
base.vendor = "sun".into(); base.vendor = "sun".into();

View file

@ -1,4 +1,4 @@
use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions}; use crate::spec::{LinkerFlavor, PanicStrategy, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::windows_msvc_base::opts(); let mut base = super::windows_msvc_base::opts();
@ -9,12 +9,7 @@ pub fn target() -> Target {
// should be smart enough to insert branch islands only // should be smart enough to insert branch islands only
// where necessary, but this is not the observed behavior. // where necessary, but this is not the observed behavior.
// Disabling the LBR optimization works around the issue. // Disabling the LBR optimization works around the issue.
let pre_link_args_msvc = "/OPT:NOLBR"; base.add_pre_link_args(LinkerFlavor::Msvc, &["/OPT:NOLBR"]);
base.pre_link_args.entry(LinkerFlavor::Msvc).or_default().push(pre_link_args_msvc.into());
base.pre_link_args
.entry(LinkerFlavor::Lld(LldFlavor::Link))
.or_default()
.push(pre_link_args_msvc.into());
Target { Target {
llvm_target: "thumbv7a-pc-windows-msvc".into(), llvm_target: "thumbv7a-pc-windows-msvc".into(),

View file

@ -10,7 +10,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::android_base::opts(); let mut base = super::android_base::opts();
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-march=armv7-a".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-march=armv7-a"]);
Target { Target {
llvm_target: "armv7-none-linux-android".into(), llvm_target: "armv7-none-linux-android".into(),
pointer_width: 32, pointer_width: 32,

View file

@ -14,27 +14,25 @@ use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, StackProbeType, Target
pub fn opts() -> TargetOptions { pub fn opts() -> TargetOptions {
let mut base = super::msvc_base::opts(); let mut base = super::msvc_base::opts();
let pre_link_args_msvc = vec![ base.add_pre_link_args(
// Non-standard subsystems have no default entry-point in PE+ files. We have to define LinkerFlavor::Msvc,
// one. "efi_main" seems to be a common choice amongst other implementations and the &[
// spec. // Non-standard subsystems have no default entry-point in PE+ files. We have to define
"/entry:efi_main".into(), // one. "efi_main" seems to be a common choice amongst other implementations and the
// COFF images have a "Subsystem" field in their header, which defines what kind of // spec.
// program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION, "/entry:efi_main",
// EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION, // COFF images have a "Subsystem" field in their header, which defines what kind of
// which is very likely the most common option. Individual projects can override this // program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION,
// with custom linker flags. // EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION,
// The subsystem-type only has minor effects on the application. It defines the memory // which is very likely the most common option. Individual projects can override this
// regions the application is loaded into (runtime-drivers need to be put into // with custom linker flags.
// reserved areas), as well as whether a return from the entry-point is treated as // The subsystem-type only has minor effects on the application. It defines the memory
// exit (default for applications). // regions the application is loaded into (runtime-drivers need to be put into
"/subsystem:efi_application".into(), // reserved areas), as well as whether a return from the entry-point is treated as
]; // exit (default for applications).
base.pre_link_args.entry(LinkerFlavor::Msvc).or_default().extend(pre_link_args_msvc.clone()); "/subsystem:efi_application",
base.pre_link_args ],
.entry(LinkerFlavor::Lld(LldFlavor::Link)) );
.or_default()
.extend(pre_link_args_msvc);
TargetOptions { TargetOptions {
os: "uefi".into(), os: "uefi".into(),

View file

@ -1,23 +1,16 @@
use super::{cvs, wasm_base}; use super::{cvs, wasm_base};
use super::{LinkArgs, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetOptions}; use super::{LinkerFlavor, PanicStrategy, RelocModel, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut options = wasm_base::options(); let mut options = wasm_base::options();
let clang_args = options.pre_link_args.entry(LinkerFlavor::Gcc).or_default();
// Rust really needs a way for users to specify exports and imports in // Rust really needs a way for users to specify exports and imports in
// the source code. --export-dynamic isn't the right tool for this job, // the source code. --export-dynamic isn't the right tool for this job,
// however it does have the side effect of automatically exporting a lot // however it does have the side effect of automatically exporting a lot
// of symbols, which approximates what people want when compiling for // of symbols, which approximates what people want when compiling for
// wasm32-unknown-unknown expect, so use it for now. // wasm32-unknown-unknown expect, so use it for now.
clang_args.push("--export-dynamic".into()); options.add_pre_link_args(LinkerFlavor::Gcc, &["--export-dynamic"]);
options.add_post_link_args(LinkerFlavor::Em, &["-sABORTING_MALLOC=0", "-Wl,--fatal-warnings"]);
let mut post_link_args = LinkArgs::new();
post_link_args.insert(
LinkerFlavor::Em,
vec!["-sABORTING_MALLOC=0".into(), "-Wl,--fatal-warnings".into()],
);
let opts = TargetOptions { let opts = TargetOptions {
os: "emscripten".into(), os: "emscripten".into(),
@ -29,7 +22,6 @@ pub fn target() -> Target {
relocation_model: RelocModel::Pic, relocation_model: RelocModel::Pic,
panic_strategy: PanicStrategy::Unwind, panic_strategy: PanicStrategy::Unwind,
no_default_libraries: false, no_default_libraries: false,
post_link_args,
families: cvs!["unix", "wasm"], families: cvs!["unix", "wasm"],
..options ..options
}; };

View file

@ -29,27 +29,27 @@ pub fn target() -> Target {
// code on this target due to this ABI mismatch. // code on this target due to this ABI mismatch.
options.default_adjusted_cabi = Some(Abi::Wasm); options.default_adjusted_cabi = Some(Abi::Wasm);
let clang_args = options.pre_link_args.entry(LinkerFlavor::Gcc).or_default(); options.add_pre_link_args(
LinkerFlavor::Gcc,
// Make sure clang uses LLD as its linker and is configured appropriately &[
// otherwise // Make sure clang uses LLD as its linker and is configured appropriately
clang_args.push("--target=wasm32-unknown-unknown".into()); // otherwise
"--target=wasm32-unknown-unknown",
// For now this target just never has an entry symbol no matter the output // For now this target just never has an entry symbol no matter the output
// type, so unconditionally pass this. // type, so unconditionally pass this.
clang_args.push("-Wl,--no-entry".into()); "-Wl,--no-entry",
// Rust really needs a way for users to specify exports and imports in
// Rust really needs a way for users to specify exports and imports in // the source code. --export-dynamic isn't the right tool for this job,
// the source code. --export-dynamic isn't the right tool for this job, // however it does have the side effect of automatically exporting a lot
// however it does have the side effect of automatically exporting a lot // of symbols, which approximates what people want when compiling for
// of symbols, which approximates what people want when compiling for // wasm32-unknown-unknown expect, so use it for now.
// wasm32-unknown-unknown expect, so use it for now. "-Wl,--export-dynamic",
clang_args.push("-Wl,--export-dynamic".into()); ],
);
// Add the flags to wasm-ld's args too. // Add the flags to wasm-ld's args too.
let lld_args = options.pre_link_args.entry(LinkerFlavor::Lld(LldFlavor::Wasm)).or_default(); options
lld_args.push("--no-entry".into()); .add_pre_link_args(LinkerFlavor::Lld(LldFlavor::Wasm), &["--no-entry", "--export-dynamic"]);
lld_args.push("--export-dynamic".into());
Target { Target {
llvm_target: "wasm32-unknown-unknown".into(), llvm_target: "wasm32-unknown-unknown".into(),

View file

@ -80,11 +80,7 @@ pub fn target() -> Target {
options.os = "wasi".into(); options.os = "wasi".into();
options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm); options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm);
options options.add_pre_link_args(LinkerFlavor::Gcc, &["--target=wasm32-wasi"]);
.pre_link_args
.entry(LinkerFlavor::Gcc)
.or_insert(Vec::new())
.push("--target=wasm32-wasi".into());
options.pre_link_objects_fallback = crt_objects::pre_wasi_fallback(); options.pre_link_objects_fallback = crt_objects::pre_wasi_fallback();
options.post_link_objects_fallback = crt_objects::post_wasi_fallback(); options.post_link_objects_fallback = crt_objects::post_wasi_fallback();

View file

@ -14,19 +14,20 @@ pub fn target() -> Target {
let mut options = wasm_base::options(); let mut options = wasm_base::options();
options.os = "unknown".into(); options.os = "unknown".into();
options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm); options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm);
let clang_args = options.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap();
// Make sure clang uses LLD as its linker and is configured appropriately options.add_pre_link_args(
// otherwise LinkerFlavor::Gcc,
clang_args.push("--target=wasm64-unknown-unknown".into()); &[
// Make sure clang uses LLD as its linker and is configured appropriately
// otherwise
"--target=wasm64-unknown-unknown",
// For now this target just never has an entry symbol no matter the output
// type, so unconditionally pass this.
"-Wl,--no-entry",
],
);
// For now this target just never has an entry symbol no matter the output options.add_pre_link_args(LinkerFlavor::Lld(LldFlavor::Wasm), &["--no-entry", "-mwasm64"]);
// type, so unconditionally pass this.
clang_args.push("-Wl,--no-entry".into());
let lld_args = options.pre_link_args.get_mut(&LinkerFlavor::Lld(LldFlavor::Wasm)).unwrap();
lld_args.push("--no-entry".into());
lld_args.push("-mwasm64".into());
// Any engine that implements wasm64 will surely implement the rest of these // Any engine that implements wasm64 will surely implement the rest of these
// features since they were all merged into the official spec by the time // features since they were all merged into the official spec by the time

View file

@ -1,63 +1,56 @@
use super::crt_objects::CrtObjectsFallback; use super::crt_objects::CrtObjectsFallback;
use super::{cvs, LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, TargetOptions, TlsModel}; use super::{cvs, LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, TargetOptions, TlsModel};
use std::collections::BTreeMap;
pub fn options() -> TargetOptions { pub fn options() -> TargetOptions {
let mut lld_args = Vec::new(); macro_rules! args {
let mut clang_args = Vec::new(); ($prefix:literal) => {
let mut arg = |arg: &'static str| { &[
lld_args.push(arg.into()); // By default LLD only gives us one page of stack (64k) which is a
clang_args.push(format!("-Wl,{}", arg).into()); // little small. Default to a larger stack closer to other PC platforms
}; // (1MB) and users can always inject their own link-args to override this.
concat!($prefix, "-z"),
concat!($prefix, "stack-size=1048576"),
// By default LLD's memory layout is:
//
// 1. First, a blank page
// 2. Next, all static data
// 3. Finally, the main stack (which grows down)
//
// This has the unfortunate consequence that on stack overflows you
// corrupt static data and can cause some exceedingly weird bugs. To
// help detect this a little sooner we instead request that the stack is
// placed before static data.
//
// This means that we'll generate slightly larger binaries as references
// to static data will take more bytes in the ULEB128 encoding, but
// stack overflow will be guaranteed to trap as it underflows instead of
// corrupting static data.
concat!($prefix, "--stack-first"),
// FIXME we probably shouldn't pass this but instead pass an explicit list
// of symbols we'll allow to be undefined. We don't currently have a
// mechanism of knowing, however, which symbols are intended to be imported
// from the environment and which are intended to be imported from other
// objects linked elsewhere. This is a coarse approximation but is sure to
// hide some bugs and frustrate someone at some point, so we should ideally
// work towards a world where we can explicitly list symbols that are
// supposed to be imported and have all other symbols generate errors if
// they remain undefined.
concat!($prefix, "--allow-undefined"),
// Rust code should never have warnings, and warnings are often
// indicative of bugs, let's prevent them.
concat!($prefix, "--fatal-warnings"),
// LLD only implements C++-like demangling, which doesn't match our own
// mangling scheme. Tell LLD to not demangle anything and leave it up to
// us to demangle these symbols later. Currently rustc does not perform
// further demangling, but tools like twiggy and wasm-bindgen are intended
// to do so.
concat!($prefix, "--no-demangle"),
]
};
}
// By default LLD only gives us one page of stack (64k) which is a let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::Lld(LldFlavor::Wasm), args!(""));
// little small. Default to a larger stack closer to other PC platforms super::add_link_args(&mut pre_link_args, LinkerFlavor::Gcc, args!("-Wl,"));
// (1MB) and users can always inject their own link-args to override this.
arg("-z");
arg("stack-size=1048576");
// By default LLD's memory layout is:
//
// 1. First, a blank page
// 2. Next, all static data
// 3. Finally, the main stack (which grows down)
//
// This has the unfortunate consequence that on stack overflows you
// corrupt static data and can cause some exceedingly weird bugs. To
// help detect this a little sooner we instead request that the stack is
// placed before static data.
//
// This means that we'll generate slightly larger binaries as references
// to static data will take more bytes in the ULEB128 encoding, but
// stack overflow will be guaranteed to trap as it underflows instead of
// corrupting static data.
arg("--stack-first");
// FIXME we probably shouldn't pass this but instead pass an explicit list
// of symbols we'll allow to be undefined. We don't currently have a
// mechanism of knowing, however, which symbols are intended to be imported
// from the environment and which are intended to be imported from other
// objects linked elsewhere. This is a coarse approximation but is sure to
// hide some bugs and frustrate someone at some point, so we should ideally
// work towards a world where we can explicitly list symbols that are
// supposed to be imported and have all other symbols generate errors if
// they remain undefined.
arg("--allow-undefined");
// Rust code should never have warnings, and warnings are often
// indicative of bugs, let's prevent them.
arg("--fatal-warnings");
// LLD only implements C++-like demangling, which doesn't match our own
// mangling scheme. Tell LLD to not demangle anything and leave it up to
// us to demangle these symbols later. Currently rustc does not perform
// further demangling, but tools like twiggy and wasm-bindgen are intended
// to do so.
arg("--no-demangle");
let mut pre_link_args = BTreeMap::new();
pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Wasm), lld_args);
pre_link_args.insert(LinkerFlavor::Gcc, clang_args);
TargetOptions { TargetOptions {
is_like_wasm: true, is_like_wasm: true,

View file

@ -1,31 +1,27 @@
use crate::spec::crt_objects::{self, CrtObjectsFallback}; use crate::spec::crt_objects::{self, CrtObjectsFallback};
use crate::spec::{cvs, LinkArgs, LinkerFlavor, LldFlavor, TargetOptions}; use crate::spec::{cvs, LinkerFlavor, TargetOptions};
pub fn opts() -> TargetOptions { pub fn opts() -> TargetOptions {
let mut pre_link_args = LinkArgs::new(); let pre_link_args = TargetOptions::link_args(
pre_link_args.insert(
LinkerFlavor::Gcc, LinkerFlavor::Gcc,
vec![ &[
// Tell GCC to avoid linker plugins, because we are not bundling // Tell GCC to avoid linker plugins, because we are not bundling
// them with Windows installer, and Rust does its own LTO anyways. // them with Windows installer, and Rust does its own LTO anyways.
"-fno-use-linker-plugin".into(), "-fno-use-linker-plugin",
// Enable ASLR // Enable ASLR
"-Wl,--dynamicbase".into(), "-Wl,--dynamicbase",
// ASLR will rebase it anyway so leaving that option enabled only leads to confusion // ASLR will rebase it anyway so leaving that option enabled only leads to confusion
"-Wl,--disable-auto-image-base".into(), "-Wl,--disable-auto-image-base",
], ],
); );
let mut late_link_args = LinkArgs::new();
let mut late_link_args_dynamic = LinkArgs::new();
let mut late_link_args_static = LinkArgs::new();
// Order of `late_link_args*` was found through trial and error to work with various // Order of `late_link_args*` was found through trial and error to work with various
// mingw-w64 versions (not tested on the CI). It's expected to change from time to time. // mingw-w64 versions (not tested on the CI). It's expected to change from time to time.
let mingw_libs = vec![ let mingw_libs = &[
"-lmsvcrt".into(), "-lmsvcrt",
"-lmingwex".into(), "-lmingwex",
"-lmingw32".into(), "-lmingw32",
"-lgcc".into(), // alas, mingw* libraries above depend on libgcc "-lgcc", // alas, mingw* libraries above depend on libgcc
// mingw's msvcrt is a weird hybrid import library and static library. // mingw's msvcrt is a weird hybrid import library and static library.
// And it seems that the linker fails to use import symbols from msvcrt // And it seems that the linker fails to use import symbols from msvcrt
// that are required from functions in msvcrt in certain cases. For example // that are required from functions in msvcrt in certain cases. For example
@ -33,31 +29,27 @@ pub fn opts() -> TargetOptions {
// The library is purposely listed twice to fix that. // The library is purposely listed twice to fix that.
// //
// See https://github.com/rust-lang/rust/pull/47483 for some more details. // See https://github.com/rust-lang/rust/pull/47483 for some more details.
"-lmsvcrt".into(), "-lmsvcrt",
"-luser32".into(), "-luser32",
"-lkernel32".into(), "-lkernel32",
]; ];
late_link_args.insert(LinkerFlavor::Gcc, mingw_libs.clone()); let mut late_link_args = TargetOptions::link_args(LinkerFlavor::Ld, mingw_libs);
late_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), mingw_libs); super::add_link_args(&mut late_link_args, LinkerFlavor::Gcc, mingw_libs);
let dynamic_unwind_libs = vec![ // If any of our crates are dynamically linked then we need to use
// If any of our crates are dynamically linked then we need to use // the shared libgcc_s-dw2-1.dll. This is required to support
// the shared libgcc_s-dw2-1.dll. This is required to support // unwinding across DLL boundaries.
// unwinding across DLL boundaries. let dynamic_unwind_libs = &["-lgcc_s"];
"-lgcc_s".into(), let mut late_link_args_dynamic =
]; TargetOptions::link_args(LinkerFlavor::Ld, dynamic_unwind_libs);
late_link_args_dynamic.insert(LinkerFlavor::Gcc, dynamic_unwind_libs.clone()); super::add_link_args(&mut late_link_args_dynamic, LinkerFlavor::Gcc, dynamic_unwind_libs);
late_link_args_dynamic.insert(LinkerFlavor::Lld(LldFlavor::Ld), dynamic_unwind_libs); // If all of our crates are statically linked then we can get away
let static_unwind_libs = vec![ // with statically linking the libgcc unwinding code. This allows
// If all of our crates are statically linked then we can get away // binaries to be redistributed without the libgcc_s-dw2-1.dll
// with statically linking the libgcc unwinding code. This allows // dependency, but unfortunately break unwinding across DLL
// binaries to be redistributed without the libgcc_s-dw2-1.dll // boundaries when unwinding across FFI boundaries.
// dependency, but unfortunately break unwinding across DLL let static_unwind_libs = &["-lgcc_eh", "-l:libpthread.a"];
// boundaries when unwinding across FFI boundaries. let mut late_link_args_static = TargetOptions::link_args(LinkerFlavor::Ld, static_unwind_libs);
"-lgcc_eh".into(), super::add_link_args(&mut late_link_args_static, LinkerFlavor::Gcc, static_unwind_libs);
"-l:libpthread.a".into(),
];
late_link_args_static.insert(LinkerFlavor::Gcc, static_unwind_libs.clone());
late_link_args_static.insert(LinkerFlavor::Lld(LldFlavor::Ld), static_unwind_libs);
TargetOptions { TargetOptions {
os: "windows".into(), os: "windows".into(),

View file

@ -1,28 +1,17 @@
use crate::spec::{cvs, LinkArgs, LinkerFlavor, TargetOptions}; use crate::spec::{cvs, LinkerFlavor, TargetOptions};
pub fn opts() -> TargetOptions { pub fn opts() -> TargetOptions {
let pre_link_args = LinkArgs::from([( // We cannot use `-nodefaultlibs` because compiler-rt has to be passed
// as a path since it's not added to linker search path by the default.
// There were attemts to make it behave like libgcc (so one can just use -l<name>)
// but LLVM maintainers rejected it: https://reviews.llvm.org/D51440
let pre_link_args =
TargetOptions::link_args(LinkerFlavor::Gcc, &["-nolibc", "--unwindlib=none"]);
// Order of `late_link_args*` does not matter with LLD.
let late_link_args = TargetOptions::link_args(
LinkerFlavor::Gcc, LinkerFlavor::Gcc,
vec![ &["-lmingw32", "-lmingwex", "-lmsvcrt", "-lkernel32", "-luser32"],
// We cannot use `-nodefaultlibs` because compiler-rt has to be passed );
// as a path since it's not added to linker search path by the default.
// There were attemts to make it behave like libgcc (so one can just use -l<name>)
// but LLVM maintainers rejected it: https://reviews.llvm.org/D51440
"-nolibc".into(),
"--unwindlib=none".into(),
],
)]);
let late_link_args = LinkArgs::from([(
LinkerFlavor::Gcc,
// Order of `late_link_args*` does not matter with LLD.
vec![
"-lmingw32".into(),
"-lmingwex".into(),
"-lmsvcrt".into(),
"-lkernel32".into(),
"-luser32".into(),
],
)]);
TargetOptions { TargetOptions {
os: "windows".into(), os: "windows".into(),

View file

@ -1,28 +1,24 @@
use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, TargetOptions}; use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
pub fn opts() -> TargetOptions { pub fn opts() -> TargetOptions {
let base = super::windows_gnu_base::opts(); let base = super::windows_gnu_base::opts();
// FIXME: This should be updated for the exception machinery changes from #67502 // FIXME: This should be updated for the exception machinery changes from #67502
// and inherit from `windows_gnu_base`, at least partially. // and inherit from `windows_gnu_base`, at least partially.
let mut late_link_args = LinkArgs::new(); let mingw_libs = &[
"-lwinstorecompat",
"-lruntimeobject",
"-lsynchronization",
"-lvcruntime140_app",
"-lucrt",
"-lwindowsapp",
"-lmingwex",
"-lmingw32",
];
let mut late_link_args = TargetOptions::link_args(LinkerFlavor::Ld, mingw_libs);
super::add_link_args(&mut late_link_args, LinkerFlavor::Gcc, mingw_libs);
let late_link_args_dynamic = LinkArgs::new(); let late_link_args_dynamic = LinkArgs::new();
let late_link_args_static = LinkArgs::new(); let late_link_args_static = LinkArgs::new();
let mingw_libs = vec![
//"-lwinstorecompat".into(),
//"-lmingwex".into(),
//"-lwinstorecompat".into(),
"-lwinstorecompat".into(),
"-lruntimeobject".into(),
"-lsynchronization".into(),
"-lvcruntime140_app".into(),
"-lucrt".into(),
"-lwindowsapp".into(),
"-lmingwex".into(),
"-lmingw32".into(),
];
late_link_args.insert(LinkerFlavor::Gcc, mingw_libs.clone());
late_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), mingw_libs);
TargetOptions { TargetOptions {
abi: "uwp".into(), abi: "uwp".into(),

View file

@ -1,16 +1,11 @@
use crate::spec::{LinkerFlavor, LldFlavor, TargetOptions}; use crate::spec::{LinkerFlavor, TargetOptions};
pub fn opts() -> TargetOptions { pub fn opts() -> TargetOptions {
let mut opts = super::windows_msvc_base::opts(); let mut opts = super::windows_msvc_base::opts();
opts.abi = "uwp".into(); opts.abi = "uwp".into();
opts.vendor = "uwp".into(); opts.vendor = "uwp".into();
let pre_link_args_msvc = vec!["/APPCONTAINER".into(), "mincore.lib".into()]; opts.add_pre_link_args(LinkerFlavor::Msvc, &["/APPCONTAINER", "mincore.lib"]);
opts.pre_link_args.entry(LinkerFlavor::Msvc).or_default().extend(pre_link_args_msvc.clone());
opts.pre_link_args
.entry(LinkerFlavor::Lld(LldFlavor::Link))
.or_default()
.extend(pre_link_args_msvc);
opts opts
} }

View file

@ -6,8 +6,7 @@ pub fn target() -> Target {
base.cpu = "core2".into(); base.cpu = "core2".into();
base.max_atomic_width = Some(128); // core2 support cmpxchg16b base.max_atomic_width = Some(128); // core2 support cmpxchg16b
base.frame_pointer = FramePointer::Always; base.frame_pointer = FramePointer::Always;
base.pre_link_args base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64", "-arch", "x86_64"]);
.insert(LinkerFlavor::Gcc, vec!["-m64".into(), "-arch".into(), "x86_64".into()]);
base.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove()); base.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove());
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call; base.stack_probes = StackProbeType::Call;

View file

@ -1,41 +1,44 @@
use std::{borrow::Cow, iter}; use std::borrow::Cow;
use crate::spec::cvs; use crate::spec::cvs;
use super::{LinkerFlavor, LldFlavor, Target, TargetOptions}; use super::{LinkerFlavor, LldFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
const PRE_LINK_ARGS: &[&str] = &[ let pre_link_args = TargetOptions::link_args(
"-e", LinkerFlavor::Ld,
"elf_entry", &[
"-Bstatic", "-e",
"--gc-sections", "elf_entry",
"-z", "-Bstatic",
"text", "--gc-sections",
"-z", "-z",
"norelro", "text",
"--no-undefined", "-z",
"--error-unresolved-symbols", "norelro",
"--no-undefined-version", "--no-undefined",
"-Bsymbolic", "--error-unresolved-symbols",
"--export-dynamic", "--no-undefined-version",
// The following symbols are needed by libunwind, which is linked after "-Bsymbolic",
// libstd. Make sure they're included in the link. "--export-dynamic",
"-u", // The following symbols are needed by libunwind, which is linked after
"__rust_abort", // libstd. Make sure they're included in the link.
"-u", "-u",
"__rust_c_alloc", "__rust_abort",
"-u", "-u",
"__rust_c_dealloc", "__rust_c_alloc",
"-u", "-u",
"__rust_print_err", "__rust_c_dealloc",
"-u", "-u",
"__rust_rwlock_rdlock", "__rust_print_err",
"-u", "-u",
"__rust_rwlock_unlock", "__rust_rwlock_rdlock",
"-u", "-u",
"__rust_rwlock_wrlock", "__rust_rwlock_unlock",
]; "-u",
"__rust_rwlock_wrlock",
],
);
const EXPORT_SYMBOLS: &[&str] = &[ const EXPORT_SYMBOLS: &[&str] = &[
"sgx_entry", "sgx_entry",
@ -66,11 +69,7 @@ pub fn target() -> Target {
features: "+rdrnd,+rdseed,+lvi-cfi,+lvi-load-hardening".into(), features: "+rdrnd,+rdseed,+lvi-cfi,+lvi-load-hardening".into(),
llvm_args: cvs!["--x86-experimental-lvi-inline-asm-hardening"], llvm_args: cvs!["--x86-experimental-lvi-inline-asm-hardening"],
position_independent_executables: true, position_independent_executables: true,
pre_link_args: iter::once(( pre_link_args,
LinkerFlavor::Lld(LldFlavor::Ld),
PRE_LINK_ARGS.iter().cloned().map(Cow::from).collect(),
))
.collect(),
override_export_symbols: Some(EXPORT_SYMBOLS.iter().cloned().map(Cow::from).collect()), override_export_symbols: Some(EXPORT_SYMBOLS.iter().cloned().map(Cow::from).collect()),
relax_elf_relocations: true, relax_elf_relocations: true,
..Default::default() ..Default::default()

View file

@ -6,7 +6,7 @@ pub fn target() -> Target {
// https://developer.android.com/ndk/guides/abis.html#86-64 // https://developer.android.com/ndk/guides/abis.html#86-64
base.features = "+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt".into(); base.features = "+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call; base.stack_probes = StackProbeType::Call;

View file

@ -2,7 +2,7 @@ use crate::spec::{LinkerFlavor, SanitizerSet, StackProbeType, Target};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::solaris_base::opts(); let mut base = super::solaris_base::opts();
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".into()]); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
base.vendor = "pc".into(); base.vendor = "pc".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);

View file

@ -1,14 +1,11 @@
use crate::spec::{LinkerFlavor, LldFlavor, Target}; use crate::spec::{LinkerFlavor, Target};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::windows_gnu_base::opts(); let mut base = super::windows_gnu_base::opts();
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
let gcc_pre_link_args = base.pre_link_args.entry(LinkerFlavor::Gcc).or_default();
gcc_pre_link_args.push("-m64".into());
// Use high-entropy 64 bit address space for ASLR // Use high-entropy 64 bit address space for ASLR
gcc_pre_link_args.push("-Wl,--high-entropy-va".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64", "-Wl,--high-entropy-va"]);
base.pre_link_args base.add_pre_link_args(LinkerFlavor::Ld, &["-m", "i386pep"]);
.insert(LinkerFlavor::Lld(LldFlavor::Ld), vec!["-m".into(), "i386pep".into()]);
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.linker = Some("x86_64-w64-mingw32-gcc".into()); base.linker = Some("x86_64-w64-mingw32-gcc".into());

View file

@ -3,8 +3,7 @@ use crate::spec::{LinkerFlavor, Target};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::windows_gnullvm_base::opts(); let mut base = super::windows_gnullvm_base::opts();
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
let gcc_pre_link_args = base.pre_link_args.entry(LinkerFlavor::Gcc).or_default(); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
gcc_pre_link_args.push("-m64".into());
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.linker = Some("x86_64-w64-mingw32-clang".into()); base.linker = Some("x86_64-w64-mingw32-clang".into());

View file

@ -2,7 +2,7 @@ use crate::spec::{LinkerFlavor, StackProbeType, Target};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::solaris_base::opts(); let mut base = super::solaris_base::opts();
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".into()]); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
base.vendor = "sun".into(); base.vendor = "sun".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);

View file

@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::dragonfly_base::opts(); let mut base = super::dragonfly_base::opts();
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call; base.stack_probes = StackProbeType::Call;

View file

@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::freebsd_base::opts(); let mut base = super::freebsd_base::opts();
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call; base.stack_probes = StackProbeType::Call;
base.supported_sanitizers = base.supported_sanitizers =

View file

@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::haiku_base::opts(); let mut base = super::haiku_base::opts();
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".into()]); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call; base.stack_probes = StackProbeType::Call;
// This option is required to build executables on Haiku x86_64 // This option is required to build executables on Haiku x86_64

View file

@ -2,7 +2,7 @@ use crate::spec::{LinkerFlavor, SanitizerSet, Target};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::illumos_base::opts(); let mut base = super::illumos_base::opts();
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".into(), "-std=c99".into()]); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64", "-std=c99"]);
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI; base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI;

View file

@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts(); let mut base = super::linux_gnu_base::opts();
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call; base.stack_probes = StackProbeType::Call;
base.static_position_independent_executables = true; base.static_position_independent_executables = true;

View file

@ -5,7 +5,7 @@ pub fn target() -> Target {
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
base.abi = "x32".into(); base.abi = "x32".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-mx32".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-mx32"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call; base.stack_probes = StackProbeType::Call;
base.has_thread_local = false; base.has_thread_local = false;

View file

@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::linux_musl_base::opts(); let mut base = super::linux_musl_base::opts();
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call; base.stack_probes = StackProbeType::Call;
base.static_position_independent_executables = true; base.static_position_independent_executables = true;

View file

@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::netbsd_base::opts(); let mut base = super::netbsd_base::opts();
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call; base.stack_probes = StackProbeType::Call;
base.supported_sanitizers = SanitizerSet::ADDRESS base.supported_sanitizers = SanitizerSet::ADDRESS

View file

@ -10,7 +10,7 @@ pub fn target() -> Target {
base.features = base.features =
"-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float".into(); "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float".into();
base.code_model = Some(CodeModel::Kernel); base.code_model = Some(CodeModel::Kernel);
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
Target { Target {
// FIXME: Some dispute, the linux-on-clang folks think this should use // FIXME: Some dispute, the linux-on-clang folks think this should use

View file

@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::openbsd_base::opts(); let mut base = super::openbsd_base::opts();
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call; base.stack_probes = StackProbeType::Call;

View file

@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::redox_base::opts(); let mut base = super::redox_base::opts();
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call; base.stack_probes = StackProbeType::Call;

View file

@ -1,14 +1,11 @@
use crate::spec::{LinkerFlavor, LldFlavor, Target}; use crate::spec::{LinkerFlavor, Target};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::windows_uwp_gnu_base::opts(); let mut base = super::windows_uwp_gnu_base::opts();
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
let gcc_pre_link_args = base.pre_link_args.entry(LinkerFlavor::Gcc).or_default();
gcc_pre_link_args.push("-m64".into());
// Use high-entropy 64 bit address space for ASLR // Use high-entropy 64 bit address space for ASLR
gcc_pre_link_args.push("-Wl,--high-entropy-va".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64", "-Wl,--high-entropy-va"]);
base.pre_link_args base.add_pre_link_args(LinkerFlavor::Ld, &["-m", "i386pep"]);
.insert(LinkerFlavor::Lld(LldFlavor::Ld), vec!["-m".into(), "i386pep".into()]);
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
Target { Target {

View file

@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::vxworks_base::opts(); let mut base = super::vxworks_base::opts();
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into()); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call; base.stack_probes = StackProbeType::Call;
base.disable_redzone = true; base.disable_redzone = true;