Auto merge of #98212 - petrochenkov:addlinkargs, r=lqd
rustc_target: Add convenience functions for adding linker arguments They ensure that lld and non-lld linker flavors get the same set of arguments. The second commit also adds some tests checking for linker argument inconsistencies, and tweaks some arguments to fix those inconsistencies.
This commit is contained in:
commit
221bdb62a2
76 changed files with 458 additions and 442 deletions
|
@ -8,6 +8,7 @@
|
|||
//! LLVM.
|
||||
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(associated_type_bounds)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
#![feature(let_else)]
|
||||
|
|
|
@ -8,7 +8,7 @@ pub fn target() -> Target {
|
|||
// FIXME: The leak sanitizer currently fails the tests, see #88132.
|
||||
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());
|
||||
|
||||
// Clang automatically chooses a more specific target based on
|
||||
|
|
|
@ -2,20 +2,13 @@
|
|||
// uefi-base module for generic UEFI options.
|
||||
|
||||
use super::uefi_msvc_base;
|
||||
use crate::spec::{LinkerFlavor, LldFlavor, Target};
|
||||
use crate::spec::{LinkerFlavor, Target};
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut base = uefi_msvc_base::opts();
|
||||
|
||||
base.max_atomic_width = Some(64);
|
||||
|
||||
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);
|
||||
base.add_pre_link_args(LinkerFlavor::Msvc, &["/machine:arm64"]);
|
||||
|
||||
Target {
|
||||
llvm_target: "aarch64-unknown-windows".into(),
|
||||
|
|
|
@ -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.
|
||||
///
|
||||
/// Requires the devkitARM toolchain for 3DS targets on the host system.
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut pre_link_args = LinkArgs::new();
|
||||
pre_link_args.insert(
|
||||
let pre_link_args = TargetOptions::link_args(
|
||||
LinkerFlavor::Gcc,
|
||||
vec![
|
||||
"-specs=3dsx.specs".into(),
|
||||
"-mtune=mpcore".into(),
|
||||
"-mfloat-abi=hard".into(),
|
||||
"-mtp=soft".into(),
|
||||
],
|
||||
&["-specs=3dsx.specs", "-mtune=mpcore", "-mfloat-abi=hard", "-mtp=soft"],
|
||||
);
|
||||
|
||||
Target {
|
||||
|
|
|
@ -10,7 +10,7 @@ use crate::spec::{LinkerFlavor, SanitizerSet, Target, TargetOptions};
|
|||
|
||||
pub fn target() -> Target {
|
||||
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 {
|
||||
llvm_target: "armv7-none-linux-android".into(),
|
||||
pointer_width: 32,
|
||||
|
|
|
@ -2,10 +2,6 @@ use super::{wasm32_unknown_emscripten, LinkerFlavor, Target};
|
|||
|
||||
pub fn target() -> Target {
|
||||
let mut target = wasm32_unknown_emscripten::target();
|
||||
target.post_link_args.entry(LinkerFlavor::Em).or_default().extend(vec![
|
||||
"-sWASM=0".into(),
|
||||
"--memory-init-file".into(),
|
||||
"0".into(),
|
||||
]);
|
||||
target.add_post_link_args(LinkerFlavor::Em, &["-sWASM=0", "--memory-init-file", "0"]);
|
||||
target
|
||||
}
|
||||
|
|
|
@ -3,7 +3,8 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
|
|||
/// A base target for AVR devices using the GNU toolchain.
|
||||
///
|
||||
/// 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 {
|
||||
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(),
|
||||
|
@ -17,10 +18,8 @@ pub fn target(target_cpu: &'static str) -> Target {
|
|||
linker: Some("avr-gcc".into()),
|
||||
executables: true,
|
||||
eh_frame_header: false,
|
||||
pre_link_args: [(LinkerFlavor::Gcc, vec![format!("-mmcu={}", target_cpu).into()])]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
late_link_args: [(LinkerFlavor::Gcc, vec!["-lgcc".into()])].into_iter().collect(),
|
||||
pre_link_args: TargetOptions::link_args(LinkerFlavor::Gcc, &[mmcu]),
|
||||
late_link_args: TargetOptions::link_args(LinkerFlavor::Gcc, &["-lgcc"]),
|
||||
max_atomic_width: Some(0),
|
||||
atomic_cas: false,
|
||||
..TargetOptions::default()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::spec::Target;
|
||||
|
||||
pub fn target() -> Target {
|
||||
super::avr_gnu_base::target("atmega328")
|
||||
super::avr_gnu_base::target("atmega328", "-mmcu=atmega328")
|
||||
}
|
||||
|
|
|
@ -1,23 +1,20 @@
|
|||
use crate::spec::{
|
||||
crt_objects, cvs, LinkArgs, LinkOutputKind, LinkerFlavor, LldFlavor, TargetOptions,
|
||||
};
|
||||
use crate::spec::{crt_objects, cvs, LinkOutputKind, LinkerFlavor, LldFlavor, TargetOptions};
|
||||
|
||||
pub fn opts() -> TargetOptions {
|
||||
let mut pre_link_args = LinkArgs::new();
|
||||
pre_link_args.insert(
|
||||
LinkerFlavor::Lld(LldFlavor::Ld),
|
||||
vec![
|
||||
"--build-id".into(),
|
||||
"--hash-style=gnu".into(),
|
||||
"-z".into(),
|
||||
"max-page-size=4096".into(),
|
||||
"-z".into(),
|
||||
"now".into(),
|
||||
"-z".into(),
|
||||
"rodynamic".into(),
|
||||
"-z".into(),
|
||||
"separate-loadable-segments".into(),
|
||||
"--pack-dyn-relocs=relr".into(),
|
||||
let pre_link_args = TargetOptions::link_args(
|
||||
LinkerFlavor::Ld,
|
||||
&[
|
||||
"--build-id",
|
||||
"--hash-style=gnu",
|
||||
"-z",
|
||||
"max-page-size=4096",
|
||||
"-z",
|
||||
"now",
|
||||
"-z",
|
||||
"rodynamic",
|
||||
"-z",
|
||||
"separate-loadable-segments",
|
||||
"--pack-dyn-relocs=relr",
|
||||
],
|
||||
);
|
||||
|
||||
|
|
|
@ -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 {
|
||||
let mut pre_link_args = LinkArgs::new();
|
||||
pre_link_args.insert(
|
||||
LinkerFlavor::Lld(LldFlavor::Ld),
|
||||
vec!["--build-id".into(), "--hash-style=gnu".into(), "--Bstatic".into()],
|
||||
let pre_link_args = TargetOptions::link_args(
|
||||
LinkerFlavor::Ld,
|
||||
&["--build-id", "--hash-style=gnu", "--Bstatic"],
|
||||
);
|
||||
|
||||
TargetOptions {
|
||||
|
|
|
@ -4,7 +4,7 @@ pub fn target() -> Target {
|
|||
let mut base = super::apple_base::opts("macos");
|
||||
base.cpu = "yonah".into();
|
||||
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());
|
||||
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
|
|
|
@ -1,19 +1,16 @@
|
|||
use crate::spec::{FramePointer, LinkerFlavor, LldFlavor, Target};
|
||||
use crate::spec::{FramePointer, LinkerFlavor, Target};
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut base = super::windows_gnu_base::opts();
|
||||
base.cpu = "pentium4".into();
|
||||
base.pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), vec!["-m".into(), "i386pe".into()]);
|
||||
base.max_atomic_width = Some(64);
|
||||
base.frame_pointer = FramePointer::Always; // Required for backtraces
|
||||
base.linker = Some("i686-w64-mingw32-gcc".into());
|
||||
|
||||
// Mark all dynamic libraries and executables as compatible with the larger 4GiB address
|
||||
// space available to x86 Windows binaries on x86_64.
|
||||
base.pre_link_args
|
||||
.entry(LinkerFlavor::Gcc)
|
||||
.or_default()
|
||||
.push("-Wl,--large-address-aware".into());
|
||||
base.add_pre_link_args(LinkerFlavor::Ld, &["-m", "i386pe", "--large-address-aware"]);
|
||||
base.add_pre_link_args(LinkerFlavor::Gcc, &["-Wl,--large-address-aware"]);
|
||||
|
||||
Target {
|
||||
llvm_target: "i686-pc-windows-gnu".into(),
|
||||
|
|
|
@ -1,24 +1,22 @@
|
|||
use crate::spec::{LinkerFlavor, LldFlavor, Target};
|
||||
use crate::spec::{LinkerFlavor, Target};
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut base = super::windows_msvc_base::opts();
|
||||
base.cpu = "pentium4".into();
|
||||
base.max_atomic_width = Some(64);
|
||||
|
||||
let pre_link_args_msvc = vec![
|
||||
// Mark all dynamic libraries and executables as compatible with the larger 4GiB address
|
||||
// space available to x86 Windows binaries on x86_64.
|
||||
"/LARGEADDRESSAWARE".into(),
|
||||
// Ensure the linker will only produce an image if it can also produce a table of
|
||||
// the image's safe exception handlers.
|
||||
// https://docs.microsoft.com/en-us/cpp/build/reference/safeseh-image-has-safe-exception-handlers
|
||||
"/SAFESEH".into(),
|
||||
];
|
||||
base.pre_link_args.entry(LinkerFlavor::Msvc).or_default().extend(pre_link_args_msvc.clone());
|
||||
base.pre_link_args
|
||||
.entry(LinkerFlavor::Lld(LldFlavor::Link))
|
||||
.or_default()
|
||||
.extend(pre_link_args_msvc);
|
||||
base.add_pre_link_args(
|
||||
LinkerFlavor::Msvc,
|
||||
&[
|
||||
// Mark all dynamic libraries and executables as compatible with the larger 4GiB address
|
||||
// space available to x86 Windows binaries on x86_64.
|
||||
"/LARGEADDRESSAWARE",
|
||||
// Ensure the linker will only produce an image if it can also produce a table of
|
||||
// the image's safe exception handlers.
|
||||
// https://docs.microsoft.com/en-us/cpp/build/reference/safeseh-image-has-safe-exception-handlers
|
||||
"/SAFESEH",
|
||||
],
|
||||
);
|
||||
// Workaround for #95429
|
||||
base.has_thread_local = false;
|
||||
|
||||
|
|
|
@ -4,9 +4,7 @@ pub fn target() -> Target {
|
|||
let mut base = super::freebsd_base::opts();
|
||||
base.cpu = "pentium4".into();
|
||||
base.max_atomic_width = Some(64);
|
||||
let pre_link_args = base.pre_link_args.entry(LinkerFlavor::Gcc).or_default();
|
||||
pre_link_args.push("-m32".into());
|
||||
pre_link_args.push("-Wl,-znotext".into());
|
||||
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "-Wl,-znotext"]);
|
||||
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ pub fn target() -> Target {
|
|||
let mut base = super::haiku_base::opts();
|
||||
base.cpu = "pentium4".into();
|
||||
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
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ pub fn target() -> Target {
|
|||
let mut base = super::linux_gnu_base::opts();
|
||||
base.cpu = "pentium4".into();
|
||||
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
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
|
||||
|
|
|
@ -4,8 +4,7 @@ pub fn target() -> Target {
|
|||
let mut base = super::linux_musl_base::opts();
|
||||
base.cpu = "pentium4".into();
|
||||
base.max_atomic_width = Some(64);
|
||||
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into());
|
||||
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-Wl,-melf_i386".into());
|
||||
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "-Wl,-melf_i386"]);
|
||||
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ pub fn target() -> Target {
|
|||
let mut base = super::netbsd_base::opts();
|
||||
base.cpu = "pentium4".into();
|
||||
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
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
|
||||
|
|
|
@ -4,8 +4,7 @@ pub fn target() -> Target {
|
|||
let mut base = super::openbsd_base::opts();
|
||||
base.cpu = "pentium4".into();
|
||||
base.max_atomic_width = Some(64);
|
||||
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into());
|
||||
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-fuse-ld=lld".into());
|
||||
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "-fuse-ld=lld"]);
|
||||
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
|
||||
|
|
|
@ -1,18 +1,15 @@
|
|||
use crate::spec::{FramePointer, LinkerFlavor, LldFlavor, Target};
|
||||
use crate::spec::{FramePointer, LinkerFlavor, Target};
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut base = super::windows_uwp_gnu_base::opts();
|
||||
base.cpu = "pentium4".into();
|
||||
base.pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), vec!["-m".into(), "i386pe".into()]);
|
||||
base.max_atomic_width = Some(64);
|
||||
base.frame_pointer = FramePointer::Always; // Required for backtraces
|
||||
|
||||
// Mark all dynamic libraries and executables as compatible with the larger 4GiB address
|
||||
// space available to x86 Windows binaries on x86_64.
|
||||
base.pre_link_args
|
||||
.entry(LinkerFlavor::Gcc)
|
||||
.or_default()
|
||||
.push("-Wl,--large-address-aware".into());
|
||||
base.add_pre_link_args(LinkerFlavor::Ld, &["-m", "i386pe", "--large-address-aware"]);
|
||||
base.add_pre_link_args(LinkerFlavor::Gcc, &["-Wl,--large-address-aware"]);
|
||||
|
||||
Target {
|
||||
llvm_target: "i686-pc-windows-gnu".into(),
|
||||
|
|
|
@ -4,7 +4,7 @@ pub fn target() -> Target {
|
|||
let mut base = super::vxworks_base::opts();
|
||||
base.cpu = "pentium4".into();
|
||||
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
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
use crate::spec::{cvs, FramePointer, LinkArgs, LinkerFlavor, TargetOptions};
|
||||
use crate::spec::{cvs, FramePointer, LinkerFlavor, TargetOptions};
|
||||
|
||||
pub fn opts() -> TargetOptions {
|
||||
let mut late_link_args = LinkArgs::new();
|
||||
late_link_args.insert(
|
||||
let late_link_args = TargetOptions::link_args(
|
||||
LinkerFlavor::Gcc,
|
||||
vec![
|
||||
&[
|
||||
// The illumos libc contains a stack unwinding implementation, as
|
||||
// does libgcc_s. The latter implementation includes several
|
||||
// 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
|
||||
// mechanism for controlling the order of library arguments passed
|
||||
// to the linker.
|
||||
"-lc".into(),
|
||||
"-lc",
|
||||
// LLVM will insert calls to the stack protector functions
|
||||
// "__stack_chk_fail" and "__stack_chk_guard" into code in native
|
||||
// object files. Some platforms include these symbols directly in
|
||||
// libc, but at least historically these have been provided in
|
||||
// libssp.so on illumos and Solaris systems.
|
||||
"-lssp".into(),
|
||||
"-lssp",
|
||||
],
|
||||
);
|
||||
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
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.
|
||||
const LINKER_SCRIPT: &str = include_str!("./mipsel_sony_psp_linker_script.ld");
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut pre_link_args = LinkArgs::new();
|
||||
pre_link_args
|
||||
.insert(LinkerFlavor::Lld(LldFlavor::Ld), vec!["--emit-relocs".into(), "--nmagic".into()]);
|
||||
let pre_link_args = TargetOptions::link_args(LinkerFlavor::Ld, &["--emit-relocs", "--nmagic"]);
|
||||
|
||||
Target {
|
||||
llvm_target: "mipsel-sony-psp".into(),
|
||||
|
|
|
@ -1459,6 +1459,44 @@ pub struct TargetOptions {
|
|||
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 {
|
||||
/// Creates a set of "sane defaults" for any target. This is still
|
||||
/// incomplete, and if used for compilation, will certainly not work.
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, SplitDebuginfo, TargetOptions};
|
||||
use crate::spec::{LinkerFlavor, LldFlavor, SplitDebuginfo, TargetOptions};
|
||||
|
||||
pub fn opts() -> TargetOptions {
|
||||
let pre_link_args_msvc = vec![
|
||||
// Suppress the verbose logo and authorship debugging output, which would needlessly
|
||||
// clog any log files.
|
||||
"/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);
|
||||
// Suppress the verbose logo and authorship debugging output, which would needlessly
|
||||
// clog any log files.
|
||||
let pre_link_args = TargetOptions::link_args(LinkerFlavor::Msvc, &["/NOLOGO"]);
|
||||
|
||||
TargetOptions {
|
||||
linker_flavor: LinkerFlavor::Msvc,
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
|
|||
pub fn target() -> Target {
|
||||
let mut base = super::freebsd_base::opts();
|
||||
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);
|
||||
|
||||
Target {
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, RelroLevel, Target, TargetOptions};
|
|||
pub fn target() -> Target {
|
||||
let mut base = super::linux_gnu_base::opts();
|
||||
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);
|
||||
|
||||
// ld.so in at least RHEL6 on ppc64 has a bug related to BIND_NOW, so only enable partial RELRO
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
|
|||
pub fn target() -> Target {
|
||||
let mut base = super::linux_musl_base::opts();
|
||||
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);
|
||||
|
||||
Target {
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
|
|||
pub fn target() -> Target {
|
||||
let mut base = super::vxworks_base::opts();
|
||||
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);
|
||||
|
||||
Target {
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
|
|||
pub fn target() -> Target {
|
||||
let mut base = super::freebsd_base::opts();
|
||||
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);
|
||||
|
||||
Target {
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
|
|||
pub fn target() -> Target {
|
||||
let mut base = super::linux_gnu_base::opts();
|
||||
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);
|
||||
|
||||
Target {
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
|
|||
pub fn target() -> Target {
|
||||
let mut base = super::linux_musl_base::opts();
|
||||
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);
|
||||
|
||||
Target {
|
||||
|
|
|
@ -3,12 +3,8 @@ use crate::spec::{LinkerFlavor, RelocModel, Target, TargetOptions};
|
|||
|
||||
pub fn target() -> Target {
|
||||
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.
|
||||
base.pre_link_args
|
||||
.entry(LinkerFlavor::Gcc)
|
||||
.or_default()
|
||||
.push("--target=powerpc-unknown-freebsd13.0".into());
|
||||
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "--target=powerpc-unknown-freebsd13.0"]);
|
||||
base.max_atomic_width = Some(32);
|
||||
|
||||
Target {
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
|
|||
|
||||
pub fn target() -> Target {
|
||||
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);
|
||||
|
||||
Target {
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
|
|||
|
||||
pub fn target() -> Target {
|
||||
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);
|
||||
|
||||
Target {
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
|
|||
|
||||
pub fn target() -> Target {
|
||||
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);
|
||||
|
||||
Target {
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
|
|||
|
||||
pub fn target() -> Target {
|
||||
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);
|
||||
|
||||
Target {
|
||||
|
|
|
@ -3,8 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
|
|||
|
||||
pub fn target() -> Target {
|
||||
let mut base = super::vxworks_base::opts();
|
||||
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into());
|
||||
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("--secure-plt".into());
|
||||
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "--secure-plt"]);
|
||||
base.max_atomic_width = Some(32);
|
||||
|
||||
Target {
|
||||
|
|
|
@ -3,8 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
|
|||
|
||||
pub fn target() -> Target {
|
||||
let mut base = super::vxworks_base::opts();
|
||||
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-mspe".into());
|
||||
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("--secure-plt".into());
|
||||
base.add_pre_link_args(LinkerFlavor::Gcc, &["-mspe", "--secure-plt"]);
|
||||
base.max_atomic_width = Some(32);
|
||||
|
||||
Target {
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
|
|||
pub fn target() -> Target {
|
||||
let mut base = super::netbsd_base::opts();
|
||||
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);
|
||||
|
||||
Target {
|
||||
|
|
|
@ -5,7 +5,7 @@ pub fn target() -> Target {
|
|||
let mut base = super::openbsd_base::opts();
|
||||
base.endian = Endian::Big;
|
||||
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);
|
||||
|
||||
Target {
|
||||
|
|
|
@ -6,7 +6,7 @@ pub fn target() -> Target {
|
|||
base.endian = Endian::Big;
|
||||
base.cpu = "v9".into();
|
||||
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 {
|
||||
llvm_target: "sparc-unknown-linux-gnu".into(),
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target};
|
|||
pub fn target() -> Target {
|
||||
let mut base = super::solaris_base::opts();
|
||||
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"
|
||||
base.cpu = "v9".into();
|
||||
base.vendor = "sun".into();
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use super::super::*;
|
||||
use std::assert_matches::assert_matches;
|
||||
|
||||
// Test target self-consistency and JSON encoding/decoding roundtrip.
|
||||
pub(super) fn test_target(target: Target) {
|
||||
|
@ -14,35 +15,105 @@ impl Target {
|
|||
assert_eq!(self.is_like_wasm, self.arch == "wasm32" || self.arch == "wasm64");
|
||||
assert!(self.is_like_windows || !self.is_like_msvc);
|
||||
|
||||
// Check that LLD with the given flavor is treated identically to the linker it emulates.
|
||||
// If your target really needs to deviate from the rules below, except it and document the
|
||||
// reasons.
|
||||
assert_eq!(
|
||||
self.linker_flavor == LinkerFlavor::Msvc
|
||||
|| self.linker_flavor == LinkerFlavor::Lld(LldFlavor::Link),
|
||||
self.lld_flavor == LldFlavor::Link,
|
||||
);
|
||||
assert_eq!(self.is_like_msvc, self.lld_flavor == LldFlavor::Link);
|
||||
for args in &[
|
||||
// Check that default linker flavor and lld flavor are compatible
|
||||
// with some other key properties.
|
||||
assert_eq!(self.is_like_osx, matches!(self.lld_flavor, LldFlavor::Ld64));
|
||||
assert_eq!(self.is_like_msvc, matches!(self.lld_flavor, LldFlavor::Link));
|
||||
assert_eq!(self.is_like_wasm, matches!(self.lld_flavor, LldFlavor::Wasm));
|
||||
assert_eq!(self.os == "l4re", matches!(self.linker_flavor, LinkerFlavor::L4Bender));
|
||||
assert_eq!(self.os == "emscripten", matches!(self.linker_flavor, LinkerFlavor::Em));
|
||||
assert_eq!(self.arch == "bpf", matches!(self.linker_flavor, LinkerFlavor::BpfLinker));
|
||||
assert_eq!(self.arch == "nvptx64", matches!(self.linker_flavor, LinkerFlavor::PtxLinker));
|
||||
|
||||
for args in [
|
||||
&self.pre_link_args,
|
||||
&self.late_link_args,
|
||||
&self.late_link_args_dynamic,
|
||||
&self.late_link_args_static,
|
||||
&self.post_link_args,
|
||||
] {
|
||||
for (&flavor, flavor_args) in args {
|
||||
assert!(!flavor_args.is_empty());
|
||||
// Check that flavors mentioned in link args are compatible with the default flavor.
|
||||
match (self.linker_flavor, self.lld_flavor) {
|
||||
(
|
||||
LinkerFlavor::Ld | LinkerFlavor::Lld(LldFlavor::Ld) | LinkerFlavor::Gcc,
|
||||
LldFlavor::Ld,
|
||||
) => {
|
||||
assert_matches!(
|
||||
flavor,
|
||||
LinkerFlavor::Ld | LinkerFlavor::Lld(LldFlavor::Ld) | LinkerFlavor::Gcc
|
||||
)
|
||||
}
|
||||
(LinkerFlavor::Gcc, LldFlavor::Ld64) => {
|
||||
assert_matches!(flavor, LinkerFlavor::Gcc)
|
||||
}
|
||||
(LinkerFlavor::Msvc | LinkerFlavor::Lld(LldFlavor::Link), LldFlavor::Link) => {
|
||||
assert_matches!(
|
||||
flavor,
|
||||
LinkerFlavor::Msvc | LinkerFlavor::Lld(LldFlavor::Link)
|
||||
)
|
||||
}
|
||||
(LinkerFlavor::Lld(LldFlavor::Wasm) | LinkerFlavor::Gcc, LldFlavor::Wasm) => {
|
||||
assert_matches!(
|
||||
flavor,
|
||||
LinkerFlavor::Lld(LldFlavor::Wasm) | LinkerFlavor::Gcc
|
||||
)
|
||||
}
|
||||
(LinkerFlavor::L4Bender, LldFlavor::Ld) => {
|
||||
assert_matches!(flavor, LinkerFlavor::L4Bender)
|
||||
}
|
||||
(LinkerFlavor::Em, LldFlavor::Wasm) => {
|
||||
assert_matches!(flavor, LinkerFlavor::Em)
|
||||
}
|
||||
(LinkerFlavor::BpfLinker, LldFlavor::Ld) => {
|
||||
assert_matches!(flavor, LinkerFlavor::BpfLinker)
|
||||
}
|
||||
(LinkerFlavor::PtxLinker, LldFlavor::Ld) => {
|
||||
assert_matches!(flavor, LinkerFlavor::PtxLinker)
|
||||
}
|
||||
flavors => unreachable!("unexpected flavor combination: {:?}", flavors),
|
||||
}
|
||||
|
||||
// Check that link args for cc and non-cc versions of flavors are consistent.
|
||||
let check_noncc = |noncc_flavor| {
|
||||
if let Some(noncc_args) = args.get(&noncc_flavor) {
|
||||
for arg in flavor_args {
|
||||
if let Some(suffix) = arg.strip_prefix("-Wl,") {
|
||||
assert!(noncc_args.iter().any(|a| a == suffix));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
match self.linker_flavor {
|
||||
LinkerFlavor::Gcc => match self.lld_flavor {
|
||||
LldFlavor::Ld => {
|
||||
check_noncc(LinkerFlavor::Ld);
|
||||
check_noncc(LinkerFlavor::Lld(LldFlavor::Ld));
|
||||
}
|
||||
LldFlavor::Wasm => check_noncc(LinkerFlavor::Lld(LldFlavor::Wasm)),
|
||||
LldFlavor::Ld64 | LldFlavor::Link => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Check that link args for lld and non-lld versions of flavors are consistent.
|
||||
assert_eq!(args.get(&LinkerFlavor::Ld), args.get(&LinkerFlavor::Lld(LldFlavor::Ld)));
|
||||
assert_eq!(
|
||||
args.get(&LinkerFlavor::Msvc),
|
||||
args.get(&LinkerFlavor::Lld(LldFlavor::Link)),
|
||||
);
|
||||
if args.contains_key(&LinkerFlavor::Msvc) {
|
||||
assert_eq!(self.lld_flavor, LldFlavor::Link);
|
||||
}
|
||||
}
|
||||
|
||||
assert!(
|
||||
(self.pre_link_objects_fallback.is_empty()
|
||||
&& self.post_link_objects_fallback.is_empty())
|
||||
|| self.crt_objects_fallback.is_some()
|
||||
);
|
||||
|
||||
// If your target really needs to deviate from the rules below,
|
||||
// except it and document the reasons.
|
||||
// Keep the default "unknown" vendor instead.
|
||||
assert_ne!(self.vendor, "");
|
||||
if !self.can_use_os_unknown() {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions};
|
||||
use crate::spec::{LinkerFlavor, PanicStrategy, Target, TargetOptions};
|
||||
|
||||
pub fn target() -> Target {
|
||||
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
|
||||
// where necessary, but this is not the observed behavior.
|
||||
// Disabling the LBR optimization works around the issue.
|
||||
let pre_link_args_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());
|
||||
base.add_pre_link_args(LinkerFlavor::Msvc, &["/OPT:NOLBR"]);
|
||||
|
||||
Target {
|
||||
llvm_target: "thumbv7a-pc-windows-msvc".into(),
|
||||
|
|
|
@ -10,7 +10,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
|
|||
|
||||
pub fn target() -> Target {
|
||||
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 {
|
||||
llvm_target: "armv7-none-linux-android".into(),
|
||||
pointer_width: 32,
|
||||
|
|
|
@ -14,27 +14,25 @@ use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, StackProbeType, Target
|
|||
pub fn opts() -> TargetOptions {
|
||||
let mut base = super::msvc_base::opts();
|
||||
|
||||
let pre_link_args_msvc = vec![
|
||||
// Non-standard subsystems have no default entry-point in PE+ files. We have to define
|
||||
// one. "efi_main" seems to be a common choice amongst other implementations and the
|
||||
// spec.
|
||||
"/entry:efi_main".into(),
|
||||
// COFF images have a "Subsystem" field in their header, which defines what kind of
|
||||
// program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION,
|
||||
// EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION,
|
||||
// which is very likely the most common option. Individual projects can override this
|
||||
// with custom linker flags.
|
||||
// The subsystem-type only has minor effects on the application. It defines the memory
|
||||
// regions the application is loaded into (runtime-drivers need to be put into
|
||||
// reserved areas), as well as whether a return from the entry-point is treated as
|
||||
// exit (default for applications).
|
||||
"/subsystem:efi_application".into(),
|
||||
];
|
||||
base.pre_link_args.entry(LinkerFlavor::Msvc).or_default().extend(pre_link_args_msvc.clone());
|
||||
base.pre_link_args
|
||||
.entry(LinkerFlavor::Lld(LldFlavor::Link))
|
||||
.or_default()
|
||||
.extend(pre_link_args_msvc);
|
||||
base.add_pre_link_args(
|
||||
LinkerFlavor::Msvc,
|
||||
&[
|
||||
// Non-standard subsystems have no default entry-point in PE+ files. We have to define
|
||||
// one. "efi_main" seems to be a common choice amongst other implementations and the
|
||||
// spec.
|
||||
"/entry:efi_main",
|
||||
// COFF images have a "Subsystem" field in their header, which defines what kind of
|
||||
// program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION,
|
||||
// EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION,
|
||||
// which is very likely the most common option. Individual projects can override this
|
||||
// with custom linker flags.
|
||||
// The subsystem-type only has minor effects on the application. It defines the memory
|
||||
// regions the application is loaded into (runtime-drivers need to be put into
|
||||
// reserved areas), as well as whether a return from the entry-point is treated as
|
||||
// exit (default for applications).
|
||||
"/subsystem:efi_application",
|
||||
],
|
||||
);
|
||||
|
||||
TargetOptions {
|
||||
os: "uefi".into(),
|
||||
|
|
|
@ -2,21 +2,11 @@ use super::{cvs, wasm_base};
|
|||
use super::{LinkArgs, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetOptions};
|
||||
|
||||
pub fn target() -> Target {
|
||||
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
|
||||
// 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
|
||||
// of symbols, which approximates what people want when compiling for
|
||||
// wasm32-unknown-unknown expect, so use it for now.
|
||||
clang_args.push("--export-dynamic".into());
|
||||
|
||||
let mut post_link_args = LinkArgs::new();
|
||||
post_link_args.insert(
|
||||
// Reset flags for non-Em flavors back to empty to satisfy sanity checking tests.
|
||||
let pre_link_args = LinkArgs::new();
|
||||
let post_link_args = TargetOptions::link_args(
|
||||
LinkerFlavor::Em,
|
||||
vec!["-sABORTING_MALLOC=0".into(), "-Wl,--fatal-warnings".into()],
|
||||
&["-sABORTING_MALLOC=0", "-Wl,--fatal-warnings"],
|
||||
);
|
||||
|
||||
let opts = TargetOptions {
|
||||
|
@ -26,12 +16,13 @@ pub fn target() -> Target {
|
|||
// functionality, and a .wasm file.
|
||||
exe_suffix: ".js".into(),
|
||||
linker: None,
|
||||
pre_link_args,
|
||||
post_link_args,
|
||||
relocation_model: RelocModel::Pic,
|
||||
panic_strategy: PanicStrategy::Unwind,
|
||||
no_default_libraries: false,
|
||||
post_link_args,
|
||||
families: cvs!["unix", "wasm"],
|
||||
..options
|
||||
..wasm_base::options()
|
||||
};
|
||||
Target {
|
||||
llvm_target: "wasm32-unknown-emscripten".into(),
|
||||
|
|
|
@ -29,27 +29,30 @@ pub fn target() -> Target {
|
|||
// code on this target due to this ABI mismatch.
|
||||
options.default_adjusted_cabi = Some(Abi::Wasm);
|
||||
|
||||
let clang_args = options.pre_link_args.entry(LinkerFlavor::Gcc).or_default();
|
||||
|
||||
// Make sure clang uses LLD as its linker and is configured appropriately
|
||||
// otherwise
|
||||
clang_args.push("--target=wasm32-unknown-unknown".into());
|
||||
|
||||
// For now this target just never has an entry symbol no matter the output
|
||||
// type, so unconditionally pass this.
|
||||
clang_args.push("-Wl,--no-entry".into());
|
||||
|
||||
// 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,
|
||||
// however it does have the side effect of automatically exporting a lot
|
||||
// of symbols, which approximates what people want when compiling for
|
||||
// wasm32-unknown-unknown expect, so use it for now.
|
||||
clang_args.push("-Wl,--export-dynamic".into());
|
||||
|
||||
// Add the flags to wasm-ld's args too.
|
||||
let lld_args = options.pre_link_args.entry(LinkerFlavor::Lld(LldFlavor::Wasm)).or_default();
|
||||
lld_args.push("--no-entry".into());
|
||||
lld_args.push("--export-dynamic".into());
|
||||
options.add_pre_link_args(
|
||||
LinkerFlavor::Lld(LldFlavor::Wasm),
|
||||
&[
|
||||
// For now this target just never has an entry symbol no matter the output
|
||||
// type, so unconditionally pass this.
|
||||
"--no-entry",
|
||||
// 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,
|
||||
// however it does have the side effect of automatically exporting a lot
|
||||
// of symbols, which approximates what people want when compiling for
|
||||
// wasm32-unknown-unknown expect, so use it for now.
|
||||
"--export-dynamic",
|
||||
],
|
||||
);
|
||||
options.add_pre_link_args(
|
||||
LinkerFlavor::Gcc,
|
||||
&[
|
||||
// Make sure clang uses LLD as its linker and is configured appropriately
|
||||
// otherwise
|
||||
"--target=wasm32-unknown-unknown",
|
||||
"-Wl,--no-entry",
|
||||
"-Wl,--export-dynamic",
|
||||
],
|
||||
);
|
||||
|
||||
Target {
|
||||
llvm_target: "wasm32-unknown-unknown".into(),
|
||||
|
|
|
@ -80,11 +80,7 @@ pub fn target() -> Target {
|
|||
|
||||
options.os = "wasi".into();
|
||||
options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm);
|
||||
options
|
||||
.pre_link_args
|
||||
.entry(LinkerFlavor::Gcc)
|
||||
.or_insert(Vec::new())
|
||||
.push("--target=wasm32-wasi".into());
|
||||
options.add_pre_link_args(LinkerFlavor::Gcc, &["--target=wasm32-wasi"]);
|
||||
|
||||
options.pre_link_objects_fallback = crt_objects::pre_wasi_fallback();
|
||||
options.post_link_objects_fallback = crt_objects::post_wasi_fallback();
|
||||
|
|
|
@ -14,19 +14,25 @@ pub fn target() -> Target {
|
|||
let mut options = wasm_base::options();
|
||||
options.os = "unknown".into();
|
||||
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
|
||||
// otherwise
|
||||
clang_args.push("--target=wasm64-unknown-unknown".into());
|
||||
|
||||
// For now this target just never has an entry symbol no matter the output
|
||||
// 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());
|
||||
options.add_pre_link_args(
|
||||
LinkerFlavor::Lld(LldFlavor::Wasm),
|
||||
&[
|
||||
// For now this target just never has an entry symbol no matter the output
|
||||
// type, so unconditionally pass this.
|
||||
"--no-entry",
|
||||
"-mwasm64",
|
||||
],
|
||||
);
|
||||
options.add_pre_link_args(
|
||||
LinkerFlavor::Gcc,
|
||||
&[
|
||||
// Make sure clang uses LLD as its linker and is configured appropriately
|
||||
// otherwise
|
||||
"--target=wasm64-unknown-unknown",
|
||||
"-Wl,--no-entry",
|
||||
],
|
||||
);
|
||||
|
||||
// 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
|
||||
|
|
|
@ -1,63 +1,56 @@
|
|||
use super::crt_objects::CrtObjectsFallback;
|
||||
use super::{cvs, LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, TargetOptions, TlsModel};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
pub fn options() -> TargetOptions {
|
||||
let mut lld_args = Vec::new();
|
||||
let mut clang_args = Vec::new();
|
||||
let mut arg = |arg: &'static str| {
|
||||
lld_args.push(arg.into());
|
||||
clang_args.push(format!("-Wl,{}", arg).into());
|
||||
};
|
||||
macro_rules! args {
|
||||
($prefix:literal) => {
|
||||
&[
|
||||
// By default LLD only gives us one page of stack (64k) which is a
|
||||
// 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
|
||||
// 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.
|
||||
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);
|
||||
let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::Lld(LldFlavor::Wasm), args!(""));
|
||||
super::add_link_args(&mut pre_link_args, LinkerFlavor::Gcc, args!("-Wl,"));
|
||||
|
||||
TargetOptions {
|
||||
is_like_wasm: true,
|
||||
|
|
|
@ -1,31 +1,35 @@
|
|||
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 {
|
||||
let mut pre_link_args = LinkArgs::new();
|
||||
pre_link_args.insert(
|
||||
let mut pre_link_args = TargetOptions::link_args(
|
||||
LinkerFlavor::Ld,
|
||||
&[
|
||||
// Enable ASLR
|
||||
"--dynamicbase",
|
||||
// ASLR will rebase it anyway so leaving that option enabled only leads to confusion
|
||||
"--disable-auto-image-base",
|
||||
],
|
||||
);
|
||||
super::add_link_args(
|
||||
&mut pre_link_args,
|
||||
LinkerFlavor::Gcc,
|
||||
vec![
|
||||
&[
|
||||
// Tell GCC to avoid linker plugins, because we are not bundling
|
||||
// them with Windows installer, and Rust does its own LTO anyways.
|
||||
"-fno-use-linker-plugin".into(),
|
||||
// Enable ASLR
|
||||
"-Wl,--dynamicbase".into(),
|
||||
// ASLR will rebase it anyway so leaving that option enabled only leads to confusion
|
||||
"-Wl,--disable-auto-image-base".into(),
|
||||
"-fno-use-linker-plugin",
|
||||
"-Wl,--dynamicbase",
|
||||
"-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
|
||||
// mingw-w64 versions (not tested on the CI). It's expected to change from time to time.
|
||||
let mingw_libs = vec![
|
||||
"-lmsvcrt".into(),
|
||||
"-lmingwex".into(),
|
||||
"-lmingw32".into(),
|
||||
"-lgcc".into(), // alas, mingw* libraries above depend on libgcc
|
||||
let mingw_libs = &[
|
||||
"-lmsvcrt",
|
||||
"-lmingwex",
|
||||
"-lmingw32",
|
||||
"-lgcc", // alas, mingw* libraries above depend on libgcc
|
||||
// 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
|
||||
// that are required from functions in msvcrt in certain cases. For example
|
||||
|
@ -33,31 +37,27 @@ pub fn opts() -> TargetOptions {
|
|||
// The library is purposely listed twice to fix that.
|
||||
//
|
||||
// See https://github.com/rust-lang/rust/pull/47483 for some more details.
|
||||
"-lmsvcrt".into(),
|
||||
"-luser32".into(),
|
||||
"-lkernel32".into(),
|
||||
"-lmsvcrt",
|
||||
"-luser32",
|
||||
"-lkernel32",
|
||||
];
|
||||
late_link_args.insert(LinkerFlavor::Gcc, mingw_libs.clone());
|
||||
late_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), mingw_libs);
|
||||
let dynamic_unwind_libs = vec![
|
||||
// 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
|
||||
// unwinding across DLL boundaries.
|
||||
"-lgcc_s".into(),
|
||||
];
|
||||
late_link_args_dynamic.insert(LinkerFlavor::Gcc, dynamic_unwind_libs.clone());
|
||||
late_link_args_dynamic.insert(LinkerFlavor::Lld(LldFlavor::Ld), dynamic_unwind_libs);
|
||||
let static_unwind_libs = vec![
|
||||
// If all of our crates are statically linked then we can get away
|
||||
// with statically linking the libgcc unwinding code. This allows
|
||||
// binaries to be redistributed without the libgcc_s-dw2-1.dll
|
||||
// dependency, but unfortunately break unwinding across DLL
|
||||
// boundaries when unwinding across FFI boundaries.
|
||||
"-lgcc_eh".into(),
|
||||
"-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);
|
||||
let mut late_link_args = TargetOptions::link_args(LinkerFlavor::Ld, mingw_libs);
|
||||
super::add_link_args(&mut late_link_args, LinkerFlavor::Gcc, mingw_libs);
|
||||
// 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
|
||||
// unwinding across DLL boundaries.
|
||||
let dynamic_unwind_libs = &["-lgcc_s"];
|
||||
let mut late_link_args_dynamic =
|
||||
TargetOptions::link_args(LinkerFlavor::Ld, dynamic_unwind_libs);
|
||||
super::add_link_args(&mut late_link_args_dynamic, LinkerFlavor::Gcc, dynamic_unwind_libs);
|
||||
// If all of our crates are statically linked then we can get away
|
||||
// with statically linking the libgcc unwinding code. This allows
|
||||
// binaries to be redistributed without the libgcc_s-dw2-1.dll
|
||||
// dependency, but unfortunately break unwinding across DLL
|
||||
// boundaries when unwinding across FFI boundaries.
|
||||
let static_unwind_libs = &["-lgcc_eh", "-l:libpthread.a"];
|
||||
let mut late_link_args_static = TargetOptions::link_args(LinkerFlavor::Ld, static_unwind_libs);
|
||||
super::add_link_args(&mut late_link_args_static, LinkerFlavor::Gcc, static_unwind_libs);
|
||||
|
||||
TargetOptions {
|
||||
os: "windows".into(),
|
||||
|
|
|
@ -1,28 +1,17 @@
|
|||
use crate::spec::{cvs, LinkArgs, LinkerFlavor, TargetOptions};
|
||||
use crate::spec::{cvs, LinkerFlavor, 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,
|
||||
vec![
|
||||
// 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(),
|
||||
],
|
||||
)]);
|
||||
&["-lmingw32", "-lmingwex", "-lmsvcrt", "-lkernel32", "-luser32"],
|
||||
);
|
||||
|
||||
TargetOptions {
|
||||
os: "windows".into(),
|
||||
|
|
|
@ -1,28 +1,25 @@
|
|||
use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, TargetOptions};
|
||||
use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
|
||||
|
||||
pub fn opts() -> TargetOptions {
|
||||
let base = super::windows_gnu_base::opts();
|
||||
|
||||
// FIXME: This should be updated for the exception machinery changes from #67502
|
||||
// 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);
|
||||
// Reset the flags back to empty until the FIXME above is addressed.
|
||||
let late_link_args_dynamic = 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 {
|
||||
abi: "uwp".into(),
|
||||
|
|
|
@ -1,16 +1,11 @@
|
|||
use crate::spec::{LinkerFlavor, LldFlavor, TargetOptions};
|
||||
use crate::spec::{LinkerFlavor, TargetOptions};
|
||||
|
||||
pub fn opts() -> TargetOptions {
|
||||
let mut opts = super::windows_msvc_base::opts();
|
||||
|
||||
opts.abi = "uwp".into();
|
||||
opts.vendor = "uwp".into();
|
||||
let pre_link_args_msvc = vec!["/APPCONTAINER".into(), "mincore.lib".into()];
|
||||
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.add_pre_link_args(LinkerFlavor::Msvc, &["/APPCONTAINER", "mincore.lib"]);
|
||||
|
||||
opts
|
||||
}
|
||||
|
|
|
@ -6,8 +6,7 @@ pub fn target() -> Target {
|
|||
base.cpu = "core2".into();
|
||||
base.max_atomic_width = Some(128); // core2 support cmpxchg16b
|
||||
base.frame_pointer = FramePointer::Always;
|
||||
base.pre_link_args
|
||||
.insert(LinkerFlavor::Gcc, vec!["-m64".into(), "-arch".into(), "x86_64".into()]);
|
||||
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64", "-arch", "x86_64"]);
|
||||
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
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
|
|
|
@ -1,41 +1,44 @@
|
|||
use std::{borrow::Cow, iter};
|
||||
use std::borrow::Cow;
|
||||
|
||||
use crate::spec::cvs;
|
||||
|
||||
use super::{LinkerFlavor, LldFlavor, Target, TargetOptions};
|
||||
|
||||
pub fn target() -> Target {
|
||||
const PRE_LINK_ARGS: &[&str] = &[
|
||||
"-e",
|
||||
"elf_entry",
|
||||
"-Bstatic",
|
||||
"--gc-sections",
|
||||
"-z",
|
||||
"text",
|
||||
"-z",
|
||||
"norelro",
|
||||
"--no-undefined",
|
||||
"--error-unresolved-symbols",
|
||||
"--no-undefined-version",
|
||||
"-Bsymbolic",
|
||||
"--export-dynamic",
|
||||
// The following symbols are needed by libunwind, which is linked after
|
||||
// libstd. Make sure they're included in the link.
|
||||
"-u",
|
||||
"__rust_abort",
|
||||
"-u",
|
||||
"__rust_c_alloc",
|
||||
"-u",
|
||||
"__rust_c_dealloc",
|
||||
"-u",
|
||||
"__rust_print_err",
|
||||
"-u",
|
||||
"__rust_rwlock_rdlock",
|
||||
"-u",
|
||||
"__rust_rwlock_unlock",
|
||||
"-u",
|
||||
"__rust_rwlock_wrlock",
|
||||
];
|
||||
let pre_link_args = TargetOptions::link_args(
|
||||
LinkerFlavor::Ld,
|
||||
&[
|
||||
"-e",
|
||||
"elf_entry",
|
||||
"-Bstatic",
|
||||
"--gc-sections",
|
||||
"-z",
|
||||
"text",
|
||||
"-z",
|
||||
"norelro",
|
||||
"--no-undefined",
|
||||
"--error-unresolved-symbols",
|
||||
"--no-undefined-version",
|
||||
"-Bsymbolic",
|
||||
"--export-dynamic",
|
||||
// The following symbols are needed by libunwind, which is linked after
|
||||
// libstd. Make sure they're included in the link.
|
||||
"-u",
|
||||
"__rust_abort",
|
||||
"-u",
|
||||
"__rust_c_alloc",
|
||||
"-u",
|
||||
"__rust_c_dealloc",
|
||||
"-u",
|
||||
"__rust_print_err",
|
||||
"-u",
|
||||
"__rust_rwlock_rdlock",
|
||||
"-u",
|
||||
"__rust_rwlock_unlock",
|
||||
"-u",
|
||||
"__rust_rwlock_wrlock",
|
||||
],
|
||||
);
|
||||
|
||||
const EXPORT_SYMBOLS: &[&str] = &[
|
||||
"sgx_entry",
|
||||
|
@ -66,11 +69,7 @@ pub fn target() -> Target {
|
|||
features: "+rdrnd,+rdseed,+lvi-cfi,+lvi-load-hardening".into(),
|
||||
llvm_args: cvs!["--x86-experimental-lvi-inline-asm-hardening"],
|
||||
position_independent_executables: true,
|
||||
pre_link_args: iter::once((
|
||||
LinkerFlavor::Lld(LldFlavor::Ld),
|
||||
PRE_LINK_ARGS.iter().cloned().map(Cow::from).collect(),
|
||||
))
|
||||
.collect(),
|
||||
pre_link_args,
|
||||
override_export_symbols: Some(EXPORT_SYMBOLS.iter().cloned().map(Cow::from).collect()),
|
||||
relax_elf_relocations: true,
|
||||
..Default::default()
|
||||
|
|
|
@ -6,7 +6,7 @@ pub fn target() -> Target {
|
|||
// https://developer.android.com/ndk/guides/abis.html#86-64
|
||||
base.features = "+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt".into();
|
||||
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
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::spec::{LinkerFlavor, SanitizerSet, StackProbeType, Target};
|
|||
|
||||
pub fn target() -> Target {
|
||||
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.vendor = "pc".into();
|
||||
base.max_atomic_width = Some(64);
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
use crate::spec::{LinkerFlavor, LldFlavor, Target};
|
||||
use crate::spec::{LinkerFlavor, Target};
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut base = super::windows_gnu_base::opts();
|
||||
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
|
||||
gcc_pre_link_args.push("-Wl,--high-entropy-va".into());
|
||||
base.pre_link_args
|
||||
.insert(LinkerFlavor::Lld(LldFlavor::Ld), vec!["-m".into(), "i386pep".into()]);
|
||||
base.add_pre_link_args(LinkerFlavor::Ld, &["-m", "i386pep", "--high-entropy-va"]);
|
||||
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64", "-Wl,--high-entropy-va"]);
|
||||
base.max_atomic_width = Some(64);
|
||||
base.linker = Some("x86_64-w64-mingw32-gcc".into());
|
||||
|
||||
|
|
|
@ -3,8 +3,7 @@ use crate::spec::{LinkerFlavor, Target};
|
|||
pub fn target() -> Target {
|
||||
let mut base = super::windows_gnullvm_base::opts();
|
||||
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());
|
||||
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
|
||||
base.max_atomic_width = Some(64);
|
||||
base.linker = Some("x86_64-w64-mingw32-clang".into());
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::spec::{LinkerFlavor, StackProbeType, Target};
|
|||
|
||||
pub fn target() -> Target {
|
||||
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.vendor = "sun".into();
|
||||
base.max_atomic_width = Some(64);
|
||||
|
|
|
@ -4,7 +4,7 @@ pub fn target() -> Target {
|
|||
let mut base = super::dragonfly_base::opts();
|
||||
base.cpu = "x86-64".into();
|
||||
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
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ pub fn target() -> Target {
|
|||
let mut base = super::freebsd_base::opts();
|
||||
base.cpu = "x86-64".into();
|
||||
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
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
base.supported_sanitizers =
|
||||
|
|
|
@ -4,7 +4,7 @@ pub fn target() -> Target {
|
|||
let mut base = super::haiku_base::opts();
|
||||
base.cpu = "x86-64".into();
|
||||
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
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
// This option is required to build executables on Haiku x86_64
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::spec::{LinkerFlavor, SanitizerSet, Target};
|
|||
|
||||
pub fn target() -> Target {
|
||||
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.max_atomic_width = Some(64);
|
||||
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI;
|
||||
|
|
|
@ -4,7 +4,7 @@ pub fn target() -> Target {
|
|||
let mut base = super::linux_gnu_base::opts();
|
||||
base.cpu = "x86-64".into();
|
||||
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
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
base.static_position_independent_executables = true;
|
||||
|
|
|
@ -5,7 +5,7 @@ pub fn target() -> Target {
|
|||
base.cpu = "x86-64".into();
|
||||
base.abi = "x32".into();
|
||||
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
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
base.has_thread_local = false;
|
||||
|
|
|
@ -4,7 +4,7 @@ pub fn target() -> Target {
|
|||
let mut base = super::linux_musl_base::opts();
|
||||
base.cpu = "x86-64".into();
|
||||
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
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
base.static_position_independent_executables = true;
|
||||
|
|
|
@ -4,7 +4,7 @@ pub fn target() -> Target {
|
|||
let mut base = super::netbsd_base::opts();
|
||||
base.cpu = "x86-64".into();
|
||||
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
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
base.supported_sanitizers = SanitizerSet::ADDRESS
|
||||
|
|
|
@ -10,7 +10,7 @@ pub fn target() -> Target {
|
|||
base.features =
|
||||
"-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float".into();
|
||||
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 {
|
||||
// FIXME: Some dispute, the linux-on-clang folks think this should use
|
||||
|
|
|
@ -4,7 +4,7 @@ pub fn target() -> Target {
|
|||
let mut base = super::openbsd_base::opts();
|
||||
base.cpu = "x86-64".into();
|
||||
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
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ pub fn target() -> Target {
|
|||
let mut base = super::redox_base::opts();
|
||||
base.cpu = "x86-64".into();
|
||||
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
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
use crate::spec::{LinkerFlavor, LldFlavor, Target};
|
||||
use crate::spec::{LinkerFlavor, Target};
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut base = super::windows_uwp_gnu_base::opts();
|
||||
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
|
||||
gcc_pre_link_args.push("-Wl,--high-entropy-va".into());
|
||||
base.pre_link_args
|
||||
.insert(LinkerFlavor::Lld(LldFlavor::Ld), vec!["-m".into(), "i386pep".into()]);
|
||||
base.add_pre_link_args(LinkerFlavor::Ld, &["-m", "i386pep", "--high-entropy-va"]);
|
||||
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64", "-Wl,--high-entropy-va"]);
|
||||
base.max_atomic_width = Some(64);
|
||||
|
||||
Target {
|
||||
|
|
|
@ -4,7 +4,7 @@ pub fn target() -> Target {
|
|||
let mut base = super::vxworks_base::opts();
|
||||
base.cpu = "x86-64".into();
|
||||
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
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
base.disable_redzone = true;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue