Auto merge of #100537 - petrochenkov:piccheck, r=oli-obk
rustc_target: Add some more target spec sanity checking
This commit is contained in:
commit
aa857eb953
14 changed files with 85 additions and 54 deletions
|
@ -18,7 +18,6 @@ pub fn target() -> Target {
|
||||||
panic_strategy: PanicStrategy::Abort,
|
panic_strategy: PanicStrategy::Abort,
|
||||||
position_independent_executables: true,
|
position_independent_executables: true,
|
||||||
dynamic_linking: true,
|
dynamic_linking: true,
|
||||||
executables: true,
|
|
||||||
relro_level: RelroLevel::Off,
|
relro_level: RelroLevel::Off,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
|
|
@ -4,7 +4,6 @@ pub fn opts() -> TargetOptions {
|
||||||
let mut base = super::linux_base::opts();
|
let mut base = super::linux_base::opts();
|
||||||
base.os = "android".into();
|
base.os = "android".into();
|
||||||
base.default_dwarf_version = 2;
|
base.default_dwarf_version = 2;
|
||||||
base.position_independent_executables = true;
|
|
||||||
base.has_thread_local = false;
|
base.has_thread_local = false;
|
||||||
// This is for backward compatibility, see https://github.com/rust-lang/rust/issues/49867
|
// 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
|
// for context. (At that time, there was no `-C force-unwind-tables`, so the only solution
|
||||||
|
|
|
@ -1,40 +1,37 @@
|
||||||
use std::{borrow::Cow, env};
|
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};
|
use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor};
|
||||||
|
|
||||||
fn pre_link_args(os: &'static str, arch: &'static str, abi: &'static str) -> LinkArgs {
|
fn pre_link_args(os: &'static str, arch: &'static str, abi: &'static str) -> LinkArgs {
|
||||||
let mut args = LinkArgs::new();
|
let platform_name: StaticCow<str> = match abi {
|
||||||
|
"sim" => format!("{}-simulator", os).into(),
|
||||||
let platform_name = match abi {
|
"macabi" => "mac-catalyst".into(),
|
||||||
"sim" => format!("{}-simulator", os),
|
_ => os.into(),
|
||||||
"macabi" => "mac-catalyst".to_string(),
|
|
||||||
_ => os.to_string(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let platform_version = match os.as_ref() {
|
let platform_version: StaticCow<str> = match os.as_ref() {
|
||||||
"ios" => ios_lld_platform_version(),
|
"ios" => ios_lld_platform_version(),
|
||||||
"tvos" => tvos_lld_platform_version(),
|
"tvos" => tvos_lld_platform_version(),
|
||||||
"watchos" => watchos_lld_platform_version(),
|
"watchos" => watchos_lld_platform_version(),
|
||||||
"macos" => macos_lld_platform_version(arch),
|
"macos" => macos_lld_platform_version(arch),
|
||||||
_ => unreachable!(),
|
_ => 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),
|
LinkerFlavor::Lld(LldFlavor::Ld64),
|
||||||
vec![
|
&["-arch", arch, "-platform_version"],
|
||||||
"-arch".into(),
|
|
||||||
arch.into(),
|
|
||||||
"-platform_version".into(),
|
|
||||||
platform_name.into(),
|
|
||||||
platform_version.clone().into(),
|
|
||||||
platform_version.into(),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
// 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
|
args
|
||||||
}
|
}
|
||||||
|
@ -127,7 +124,7 @@ pub fn macos_llvm_target(arch: &str) -> String {
|
||||||
format!("{}-apple-macosx{}.{}.0", arch, major, minor)
|
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);
|
let mut env_remove = Vec::with_capacity(2);
|
||||||
// Remove the `SDKROOT` environment variable if it's clearly set for the wrong platform, which
|
// 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.
|
// may occur when we're linking a custom build script while targeting iOS for example.
|
||||||
|
|
|
@ -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.
|
/// A base target for AVR devices using the GNU toolchain.
|
||||||
///
|
///
|
||||||
|
@ -21,6 +21,7 @@ pub fn target(target_cpu: &'static str, mmcu: &'static str) -> Target {
|
||||||
late_link_args: TargetOptions::link_args(LinkerFlavor::Gcc, &["-lgcc"]),
|
late_link_args: TargetOptions::link_args(LinkerFlavor::Gcc, &["-lgcc"]),
|
||||||
max_atomic_width: Some(0),
|
max_atomic_width: Some(0),
|
||||||
atomic_cas: false,
|
atomic_cas: false,
|
||||||
|
relocation_model: RelocModel::Static,
|
||||||
..TargetOptions::default()
|
..TargetOptions::default()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ pub fn target() -> Target {
|
||||||
base.crt_static_default = false;
|
base.crt_static_default = false;
|
||||||
base.has_rpath = true;
|
base.has_rpath = true;
|
||||||
base.linker_is_gnu = false;
|
base.linker_is_gnu = false;
|
||||||
base.dynamic_linking = true;
|
|
||||||
|
|
||||||
base.c_enum_min_bits = 8;
|
base.c_enum_min_bits = 8;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::spec::{cvs, LinkerFlavor, PanicStrategy, TargetOptions};
|
use crate::spec::{cvs, LinkerFlavor, PanicStrategy, RelocModel, TargetOptions};
|
||||||
|
|
||||||
pub fn opts() -> TargetOptions {
|
pub fn opts() -> TargetOptions {
|
||||||
TargetOptions {
|
TargetOptions {
|
||||||
|
@ -9,6 +9,7 @@ pub fn opts() -> TargetOptions {
|
||||||
linker: Some("l4-bender".into()),
|
linker: Some("l4-bender".into()),
|
||||||
linker_is_gnu: false,
|
linker_is_gnu: false,
|
||||||
families: cvs!["unix"],
|
families: cvs!["unix"],
|
||||||
|
relocation_model: RelocModel::Static,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -837,15 +837,15 @@ impl fmt::Display for StackProtector {
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! supported_targets {
|
macro_rules! supported_targets {
|
||||||
( $(($( $triple:literal, )+ $module:ident ),)+ ) => {
|
( $(($triple:literal, $module:ident ),)+ ) => {
|
||||||
$(mod $module;)+
|
$(mod $module;)+
|
||||||
|
|
||||||
/// List of supported targets
|
/// List of supported targets
|
||||||
pub const TARGETS: &[&str] = &[$($($triple),+),+];
|
pub const TARGETS: &[&str] = &[$($triple),+];
|
||||||
|
|
||||||
fn load_builtin(target: &str) -> Option<Target> {
|
fn load_builtin(target: &str) -> Option<Target> {
|
||||||
let mut t = match target {
|
let mut t = match target {
|
||||||
$( $($triple)|+ => $module::target(), )+
|
$( $triple => $module::target(), )+
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
t.is_builtin = true;
|
t.is_builtin = true;
|
||||||
|
@ -861,7 +861,7 @@ macro_rules! supported_targets {
|
||||||
$(
|
$(
|
||||||
#[test] // `#[test]`
|
#[test] // `#[test]`
|
||||||
fn $module() {
|
fn $module() {
|
||||||
tests_impl::test_target(super::$module::target());
|
tests_impl::test_target(super::$module::target(), $triple);
|
||||||
}
|
}
|
||||||
)+
|
)+
|
||||||
}
|
}
|
||||||
|
@ -1528,7 +1528,7 @@ fn add_link_args(link_args: &mut LinkArgs, flavor: LinkerFlavor, args: &[&'stati
|
||||||
match flavor {
|
match flavor {
|
||||||
LinkerFlavor::Ld => insert(LinkerFlavor::Lld(LldFlavor::Ld)),
|
LinkerFlavor::Ld => insert(LinkerFlavor::Lld(LldFlavor::Ld)),
|
||||||
LinkerFlavor::Msvc => insert(LinkerFlavor::Lld(LldFlavor::Link)),
|
LinkerFlavor::Msvc => insert(LinkerFlavor::Lld(LldFlavor::Link)),
|
||||||
LinkerFlavor::Lld(LldFlavor::Wasm) => {}
|
LinkerFlavor::Lld(LldFlavor::Ld64) | LinkerFlavor::Lld(LldFlavor::Wasm) => {}
|
||||||
LinkerFlavor::Lld(lld_flavor) => {
|
LinkerFlavor::Lld(lld_flavor) => {
|
||||||
panic!("add_link_args: use non-LLD flavor for {:?}", lld_flavor)
|
panic!("add_link_args: use non-LLD flavor for {:?}", lld_flavor)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::abi::Endian;
|
use crate::abi::Endian;
|
||||||
use crate::spec::{LinkerFlavor, RelocModel, Target, TargetOptions};
|
use crate::spec::{LinkerFlavor, Target, TargetOptions};
|
||||||
|
|
||||||
pub fn target() -> Target {
|
pub fn target() -> Target {
|
||||||
let mut base = super::freebsd_base::opts();
|
let mut base = super::freebsd_base::opts();
|
||||||
|
@ -15,7 +15,6 @@ pub fn target() -> Target {
|
||||||
options: TargetOptions {
|
options: TargetOptions {
|
||||||
endian: Endian::Big,
|
endian: Endian::Big,
|
||||||
features: "+secure-plt".into(),
|
features: "+secure-plt".into(),
|
||||||
relocation_model: RelocModel::Pic,
|
|
||||||
mcount: "_mcount".into(),
|
mcount: "_mcount".into(),
|
||||||
..base
|
..base
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,18 +2,20 @@ use super::super::*;
|
||||||
use std::assert_matches::assert_matches;
|
use std::assert_matches::assert_matches;
|
||||||
|
|
||||||
// Test target self-consistency and JSON encoding/decoding roundtrip.
|
// Test target self-consistency and JSON encoding/decoding roundtrip.
|
||||||
pub(super) fn test_target(target: Target) {
|
pub(super) fn test_target(target: Target, triple: &str) {
|
||||||
target.check_consistency();
|
target.check_consistency(triple);
|
||||||
assert_eq!(Target::from_json(target.to_json()).map(|(j, _)| j), Ok(target));
|
assert_eq!(Target::from_json(target.to_json()).map(|(j, _)| j), Ok(target));
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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_osx, self.vendor == "apple");
|
||||||
assert_eq!(self.is_like_solaris, self.os == "solaris" || self.os == "illumos");
|
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_windows, self.os == "windows" || self.os == "uefi");
|
||||||
assert_eq!(self.is_like_wasm, self.arch == "wasm32" || self.arch == "wasm64");
|
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
|
// Check that default linker flavor and lld flavor are compatible
|
||||||
// with some other key properties.
|
// with some other key properties.
|
||||||
|
@ -94,8 +96,9 @@ impl Target {
|
||||||
check_noncc(LinkerFlavor::Ld);
|
check_noncc(LinkerFlavor::Ld);
|
||||||
check_noncc(LinkerFlavor::Lld(LldFlavor::Ld));
|
check_noncc(LinkerFlavor::Lld(LldFlavor::Ld));
|
||||||
}
|
}
|
||||||
|
LldFlavor::Ld64 => check_noncc(LinkerFlavor::Lld(LldFlavor::Ld64)),
|
||||||
LldFlavor::Wasm => check_noncc(LinkerFlavor::Lld(LldFlavor::Wasm)),
|
LldFlavor::Wasm => check_noncc(LinkerFlavor::Lld(LldFlavor::Wasm)),
|
||||||
LldFlavor::Ld64 | LldFlavor::Link => {}
|
LldFlavor::Link => {}
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -109,20 +112,56 @@ impl Target {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert!(
|
if self.link_self_contained == LinkSelfContainedDefault::False {
|
||||||
(self.pre_link_objects_self_contained.is_empty()
|
assert!(
|
||||||
&& self.post_link_objects_self_contained.is_empty())
|
self.pre_link_objects_self_contained.is_empty()
|
||||||
|| self.link_self_contained != LinkSelfContainedDefault::False
|
&& self.post_link_objects_self_contained.is_empty()
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// If your target really needs to deviate from the rules below,
|
// If your target really needs to deviate from the rules below,
|
||||||
// except it and document the reasons.
|
// except it and document the reasons.
|
||||||
// Keep the default "unknown" vendor instead.
|
// Keep the default "unknown" vendor instead.
|
||||||
assert_ne!(self.vendor, "");
|
assert_ne!(self.vendor, "");
|
||||||
|
assert_ne!(self.os, "");
|
||||||
if !self.can_use_os_unknown() {
|
if !self.can_use_os_unknown() {
|
||||||
// Keep the default "none" for bare metal targets instead.
|
// Keep the default "none" for bare metal targets instead.
|
||||||
assert_ne!(self.os, "unknown");
|
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
|
// Add your target to the whitelist if it has `std` library
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
// the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all
|
// 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.
|
// 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 {
|
pub fn opts() -> TargetOptions {
|
||||||
let mut base = super::msvc_base::opts();
|
let mut base = super::msvc_base::opts();
|
||||||
|
@ -46,6 +47,7 @@ pub fn opts() -> TargetOptions {
|
||||||
stack_probes: StackProbeType::Call,
|
stack_probes: StackProbeType::Call,
|
||||||
singlethread: true,
|
singlethread: true,
|
||||||
linker: Some("rust-lld".into()),
|
linker: Some("rust-lld".into()),
|
||||||
|
relocation_model: RelocModel::Static,
|
||||||
..base
|
..base
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,6 @@ pub fn target() -> Target {
|
||||||
let mut base = super::l4re_base::opts();
|
let mut base = super::l4re_base::opts();
|
||||||
base.cpu = "x86-64".into();
|
base.cpu = "x86-64".into();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.crt_static_allows_dylibs = false;
|
|
||||||
base.dynamic_linking = false;
|
|
||||||
base.panic_strategy = PanicStrategy::Abort;
|
base.panic_strategy = PanicStrategy::Abort;
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
|
|
|
@ -4,10 +4,8 @@
|
||||||
// `target-cpu` compiler flags to opt-in more hardware-specific
|
// `target-cpu` compiler flags to opt-in more hardware-specific
|
||||||
// features.
|
// features.
|
||||||
|
|
||||||
use super::{
|
use super::{CodeModel, LinkerFlavor, LldFlavor, PanicStrategy};
|
||||||
CodeModel, LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, RelroLevel, StackProbeType,
|
use super::{RelroLevel, StackProbeType, Target, TargetOptions};
|
||||||
Target, TargetOptions,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn target() -> Target {
|
pub fn target() -> Target {
|
||||||
let opts = TargetOptions {
|
let opts = TargetOptions {
|
||||||
|
@ -18,7 +16,6 @@ pub fn target() -> Target {
|
||||||
position_independent_executables: true,
|
position_independent_executables: true,
|
||||||
static_position_independent_executables: true,
|
static_position_independent_executables: true,
|
||||||
relro_level: RelroLevel::Full,
|
relro_level: RelroLevel::Full,
|
||||||
relocation_model: RelocModel::Pic,
|
|
||||||
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
|
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
|
||||||
linker: Some("rust-lld".into()),
|
linker: Some("rust-lld".into()),
|
||||||
features:
|
features:
|
||||||
|
|
|
@ -24,7 +24,7 @@ trait Freeze { }
|
||||||
#[lang="copy"]
|
#[lang="copy"]
|
||||||
trait Copy { }
|
trait Copy { }
|
||||||
|
|
||||||
//x86_64: define win64cc void @has_efiapi
|
//x86_64: define dso_local win64cc void @has_efiapi
|
||||||
//i686: define void @has_efiapi
|
//i686: define void @has_efiapi
|
||||||
//aarch64: define dso_local void @has_efiapi
|
//aarch64: define dso_local void @has_efiapi
|
||||||
//arm: define dso_local void @has_efiapi
|
//arm: define dso_local void @has_efiapi
|
||||||
|
|
|
@ -77,7 +77,7 @@ fn update_bar_value() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK: define void @test(){{.+}}addrspace(1)
|
// CHECK: define dso_local void @test(){{.+}}addrspace(1)
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn test() {
|
pub extern "C" fn test() {
|
||||||
let mut buf = 7;
|
let mut buf = 7;
|
||||||
|
|
Loading…
Add table
Reference in a new issue