Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustc_target: Add some more target spec sanity checking #100537

Merged
merged 4 commits into from
Sep 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ pub fn target() -> Target {
panic_strategy: PanicStrategy::Abort,
position_independent_executables: true,
dynamic_linking: true,
executables: true,
relro_level: RelroLevel::Off,
..Default::default()
},
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_target/src/spec/android_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ pub fn opts() -> TargetOptions {
let mut base = super::linux_base::opts();
base.os = "android".into();
base.default_dwarf_version = 2;
base.position_independent_executables = true;
base.has_thread_local = false;
// This is for backward compatibility, see https://github.com/rust-lang/rust/issues/49867
// for context. (At that time, there was no `-C force-unwind-tables`, so the only solution
Expand Down
41 changes: 19 additions & 22 deletions compiler/rustc_target/src/spec/apple_base.rs
Original file line number Diff line number Diff line change
@@ -1,40 +1,37 @@
use std::{borrow::Cow, env};

use crate::spec::{cvs, DebuginfoKind, FramePointer, SplitDebuginfo, TargetOptions};
use crate::spec::{cvs, DebuginfoKind, FramePointer, SplitDebuginfo, StaticCow, TargetOptions};
use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor};

fn pre_link_args(os: &'static str, arch: &'static str, abi: &'static str) -> LinkArgs {
let mut args = LinkArgs::new();

let platform_name = match abi {
"sim" => format!("{}-simulator", os),
"macabi" => "mac-catalyst".to_string(),
_ => os.to_string(),
let platform_name: StaticCow<str> = match abi {
"sim" => format!("{}-simulator", os).into(),
"macabi" => "mac-catalyst".into(),
_ => os.into(),
};

let platform_version = match os.as_ref() {
let platform_version: StaticCow<str> = match os.as_ref() {
"ios" => ios_lld_platform_version(),
"tvos" => tvos_lld_platform_version(),
"watchos" => watchos_lld_platform_version(),
"macos" => macos_lld_platform_version(arch),
_ => unreachable!(),
};

if abi != "macabi" {
args.insert(LinkerFlavor::Gcc, vec!["-arch".into(), arch.into()]);
}
.into();

args.insert(
let mut args = TargetOptions::link_args(
LinkerFlavor::Lld(LldFlavor::Ld64),
vec![
"-arch".into(),
arch.into(),
"-platform_version".into(),
platform_name.into(),
platform_version.clone().into(),
platform_version.into(),
],
&["-arch", arch, "-platform_version"],
);
// Manually add owned args unsupported by link arg building helpers.
args.entry(LinkerFlavor::Lld(LldFlavor::Ld64)).or_default().extend([
platform_name,
platform_version.clone(),
platform_version,
]);
if abi != "macabi" {
super::add_link_args(&mut args, LinkerFlavor::Gcc, &["-arch", arch]);
}

args
}
Expand Down Expand Up @@ -127,7 +124,7 @@ pub fn macos_llvm_target(arch: &str) -> String {
format!("{}-apple-macosx{}.{}.0", arch, major, minor)
}

pub fn macos_link_env_remove() -> Vec<Cow<'static, str>> {
pub fn macos_link_env_remove() -> Vec<StaticCow<str>> {
let mut env_remove = Vec::with_capacity(2);
// Remove the `SDKROOT` environment variable if it's clearly set for the wrong platform, which
// may occur when we're linking a custom build script while targeting iOS for example.
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_target/src/spec/avr_gnu_base.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::spec::{LinkerFlavor, Target, TargetOptions};
use crate::spec::{LinkerFlavor, RelocModel, Target, TargetOptions};

/// A base target for AVR devices using the GNU toolchain.
///
Expand All @@ -21,6 +21,7 @@ pub fn target(target_cpu: &'static str, mmcu: &'static str) -> Target {
late_link_args: TargetOptions::link_args(LinkerFlavor::Gcc, &["-lgcc"]),
max_atomic_width: Some(0),
atomic_cas: false,
relocation_model: RelocModel::Static,
..TargetOptions::default()
},
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ pub fn target() -> Target {
base.crt_static_default = false;
base.has_rpath = true;
base.linker_is_gnu = false;
base.dynamic_linking = true;

base.c_enum_min_bits = 8;

Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_target/src/spec/l4re_base.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::spec::{cvs, LinkerFlavor, PanicStrategy, TargetOptions};
use crate::spec::{cvs, LinkerFlavor, PanicStrategy, RelocModel, TargetOptions};

pub fn opts() -> TargetOptions {
TargetOptions {
Expand All @@ -9,6 +9,7 @@ pub fn opts() -> TargetOptions {
linker: Some("l4-bender".into()),
linker_is_gnu: false,
families: cvs!["unix"],
relocation_model: RelocModel::Static,
..Default::default()
}
}
10 changes: 5 additions & 5 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -837,15 +837,15 @@ impl fmt::Display for StackProtector {
}

macro_rules! supported_targets {
( $(($( $triple:literal, )+ $module:ident ),)+ ) => {
( $(($triple:literal, $module:ident ),)+ ) => {
$(mod $module;)+

/// List of supported targets
pub const TARGETS: &[&str] = &[$($($triple),+),+];
pub const TARGETS: &[&str] = &[$($triple),+];

fn load_builtin(target: &str) -> Option<Target> {
let mut t = match target {
$( $($triple)|+ => $module::target(), )+
$( $triple => $module::target(), )+
_ => return None,
};
t.is_builtin = true;
Expand All @@ -861,7 +861,7 @@ macro_rules! supported_targets {
$(
#[test] // `#[test]`
fn $module() {
tests_impl::test_target(super::$module::target());
tests_impl::test_target(super::$module::target(), $triple);
}
)+
}
Expand Down Expand Up @@ -1526,7 +1526,7 @@ fn add_link_args(link_args: &mut LinkArgs, flavor: LinkerFlavor, args: &[&'stati
match flavor {
LinkerFlavor::Ld => insert(LinkerFlavor::Lld(LldFlavor::Ld)),
LinkerFlavor::Msvc => insert(LinkerFlavor::Lld(LldFlavor::Link)),
LinkerFlavor::Lld(LldFlavor::Wasm) => {}
LinkerFlavor::Lld(LldFlavor::Ld64) | LinkerFlavor::Lld(LldFlavor::Wasm) => {}
LinkerFlavor::Lld(lld_flavor) => {
panic!("add_link_args: use non-LLD flavor for {:?}", lld_flavor)
}
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::abi::Endian;
use crate::spec::{LinkerFlavor, RelocModel, Target, TargetOptions};
use crate::spec::{LinkerFlavor, Target, TargetOptions};

pub fn target() -> Target {
let mut base = super::freebsd_base::opts();
Expand All @@ -15,7 +15,6 @@ pub fn target() -> Target {
options: TargetOptions {
endian: Endian::Big,
features: "+secure-plt".into(),
relocation_model: RelocModel::Pic,
mcount: "_mcount".into(),
..base
},
Expand Down
59 changes: 49 additions & 10 deletions compiler/rustc_target/src/spec/tests/tests_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@ 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) {
target.check_consistency();
pub(super) fn test_target(target: Target, triple: &str) {
target.check_consistency(triple);
assert_eq!(Target::from_json(target.to_json()).map(|(j, _)| j), Ok(target));
}

impl Target {
fn check_consistency(&self) {
fn check_consistency(&self, triple: &str) {
assert_eq!(self.is_like_osx, self.vendor == "apple");
assert_eq!(self.is_like_solaris, self.os == "solaris" || self.os == "illumos");
assert_eq!(self.is_like_windows, self.os == "windows" || self.os == "uefi");
assert_eq!(self.is_like_wasm, self.arch == "wasm32" || self.arch == "wasm64");
assert!(self.is_like_windows || !self.is_like_msvc);
if self.is_like_msvc {
assert!(self.is_like_windows);
}

// Check that default linker flavor and lld flavor are compatible
// with some other key properties.
Expand Down Expand Up @@ -94,8 +96,9 @@ impl Target {
check_noncc(LinkerFlavor::Ld);
check_noncc(LinkerFlavor::Lld(LldFlavor::Ld));
}
LldFlavor::Ld64 => check_noncc(LinkerFlavor::Lld(LldFlavor::Ld64)),
LldFlavor::Wasm => check_noncc(LinkerFlavor::Lld(LldFlavor::Wasm)),
LldFlavor::Ld64 | LldFlavor::Link => {}
LldFlavor::Link => {}
},
_ => {}
}
Expand All @@ -109,20 +112,56 @@ impl Target {
);
}

assert!(
(self.pre_link_objects_self_contained.is_empty()
&& self.post_link_objects_self_contained.is_empty())
|| self.link_self_contained != LinkSelfContainedDefault::False
);
if self.link_self_contained == LinkSelfContainedDefault::False {
assert!(
self.pre_link_objects_self_contained.is_empty()
&& self.post_link_objects_self_contained.is_empty()
);
}

// 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, "");
assert_ne!(self.os, "");
if !self.can_use_os_unknown() {
// Keep the default "none" for bare metal targets instead.
assert_ne!(self.os, "unknown");
}

// Check dynamic linking stuff
// BPF: when targeting user space vms (like rbpf), those can load dynamic libraries.
if self.os == "none" && self.arch != "bpf" {
assert!(!self.dynamic_linking);
petrochenkov marked this conversation as resolved.
Show resolved Hide resolved
}
if self.only_cdylib
|| self.crt_static_allows_dylibs
|| !self.late_link_args_dynamic.is_empty()
{
assert!(self.dynamic_linking);
}
// Apparently PIC was slow on wasm at some point, see comments in wasm_base.rs
if self.dynamic_linking && !(self.is_like_wasm && self.os != "emscripten") {
assert_eq!(self.relocation_model, RelocModel::Pic);
}
// PIEs are supported but not enabled by default with linuxkernel target.
if self.position_independent_executables && !triple.ends_with("-linuxkernel") {
assert_eq!(self.relocation_model, RelocModel::Pic);
}
if self.relocation_model == RelocModel::Pic {
assert!(self.dynamic_linking || self.position_independent_executables);
}
if self.static_position_independent_executables {
assert!(self.position_independent_executables);
}
if self.position_independent_executables {
assert!(self.executables);
}

// Check crt static stuff
if self.crt_static_default || self.crt_static_allows_dylibs {
assert!(self.crt_static_respected);
}
}

// Add your target to the whitelist if it has `std` library
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_target/src/spec/uefi_msvc_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
// the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all
// code runs in the same environment, no process separation is supported.

use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, StackProbeType, TargetOptions};
use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy};
use crate::spec::{RelocModel, StackProbeType, TargetOptions};

pub fn opts() -> TargetOptions {
let mut base = super::msvc_base::opts();
Expand Down Expand Up @@ -46,6 +47,7 @@ pub fn opts() -> TargetOptions {
stack_probes: StackProbeType::Call,
singlethread: true,
linker: Some("rust-lld".into()),
relocation_model: RelocModel::Static,
..base
}
}
2 changes: 0 additions & 2 deletions compiler/rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ pub fn target() -> Target {
let mut base = super::l4re_base::opts();
base.cpu = "x86-64".into();
base.max_atomic_width = Some(64);
base.crt_static_allows_dylibs = false;
base.dynamic_linking = false;
base.panic_strategy = PanicStrategy::Abort;

Target {
Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_target/src/spec/x86_64_unknown_none.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@
// `target-cpu` compiler flags to opt-in more hardware-specific
// features.

use super::{
CodeModel, LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, RelroLevel, StackProbeType,
Target, TargetOptions,
};
use super::{CodeModel, LinkerFlavor, LldFlavor, PanicStrategy};
use super::{RelroLevel, StackProbeType, Target, TargetOptions};

pub fn target() -> Target {
let opts = TargetOptions {
Expand All @@ -18,7 +16,6 @@ pub fn target() -> Target {
position_independent_executables: true,
static_position_independent_executables: true,
relro_level: RelroLevel::Full,
relocation_model: RelocModel::Pic,
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
linker: Some("rust-lld".into()),
features:
Expand Down
2 changes: 1 addition & 1 deletion src/test/codegen/abi-efiapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ trait Freeze { }
#[lang="copy"]
trait Copy { }

//x86_64: define win64cc void @has_efiapi
//x86_64: define dso_local win64cc void @has_efiapi
//i686: define void @has_efiapi
//aarch64: define dso_local void @has_efiapi
//arm: define dso_local void @has_efiapi
Expand Down
2 changes: 1 addition & 1 deletion src/test/codegen/avr/avr-func-addrspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ fn update_bar_value() {
}
}

// CHECK: define void @test(){{.+}}addrspace(1)
// CHECK: define dso_local void @test(){{.+}}addrspace(1)
#[no_mangle]
pub extern "C" fn test() {
let mut buf = 7;
Expand Down