Skip to content

Commit

Permalink
Auto merge of #100537 - petrochenkov:piccheck, r=oli-obk
Browse files Browse the repository at this point in the history
rustc_target: Add some more target spec sanity checking
  • Loading branch information
bors committed Sep 1, 2022
2 parents 3892b70 + f7eb7ef commit aa857eb
Show file tree
Hide file tree
Showing 14 changed files with 85 additions and 54 deletions.
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 @@ -1528,7 +1528,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);
}
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

0 comments on commit aa857eb

Please sign in to comment.