Skip to content

Commit 2e83c22

Browse files
committed
rustc_target: Add some more target spec sanity checking
1 parent 4065b89 commit 2e83c22

File tree

5 files changed

+60
-17
lines changed

5 files changed

+60
-17
lines changed

compiler/rustc_target/src/spec/avr_gnu_base.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::spec::{LinkerFlavor, Target, TargetOptions};
1+
use crate::spec::{LinkerFlavor, RelocModel, Target, TargetOptions};
22

33
/// A base target for AVR devices using the GNU toolchain.
44
///
@@ -21,6 +21,7 @@ pub fn target(target_cpu: &'static str, mmcu: &'static str) -> Target {
2121
late_link_args: TargetOptions::link_args(LinkerFlavor::Gcc, &["-lgcc"]),
2222
max_atomic_width: Some(0),
2323
atomic_cas: false,
24+
relocation_model: RelocModel::Static,
2425
..TargetOptions::default()
2526
},
2627
}

compiler/rustc_target/src/spec/l4re_base.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::spec::{cvs, LinkerFlavor, PanicStrategy, TargetOptions};
1+
use crate::spec::{cvs, LinkerFlavor, PanicStrategy, RelocModel, TargetOptions};
22

33
pub fn opts() -> TargetOptions {
44
TargetOptions {
@@ -9,6 +9,7 @@ pub fn opts() -> TargetOptions {
99
linker: Some("l4-bender".into()),
1010
linker_is_gnu: false,
1111
families: cvs!["unix"],
12+
relocation_model: RelocModel::Static,
1213
..Default::default()
1314
}
1415
}

compiler/rustc_target/src/spec/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -837,15 +837,15 @@ impl fmt::Display for StackProtector {
837837
}
838838

839839
macro_rules! supported_targets {
840-
( $(($( $triple:literal, )+ $module:ident ),)+ ) => {
840+
( $(($triple:literal, $module:ident ),)+ ) => {
841841
$(mod $module;)+
842842

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

846846
fn load_builtin(target: &str) -> Option<Target> {
847847
let mut t = match target {
848-
$( $($triple)|+ => $module::target(), )+
848+
$( $triple => $module::target(), )+
849849
_ => return None,
850850
};
851851
t.is_builtin = true;
@@ -861,7 +861,7 @@ macro_rules! supported_targets {
861861
$(
862862
#[test] // `#[test]`
863863
fn $module() {
864-
tests_impl::test_target(super::$module::target());
864+
tests_impl::test_target(super::$module::target(), $triple);
865865
}
866866
)+
867867
}

compiler/rustc_target/src/spec/tests/tests_impl.rs

+49-10
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,20 @@ use super::super::*;
22
use std::assert_matches::assert_matches;
33

44
// Test target self-consistency and JSON encoding/decoding roundtrip.
5-
pub(super) fn test_target(target: Target) {
6-
target.check_consistency();
5+
pub(super) fn test_target(target: Target, triple: &str) {
6+
target.check_consistency(triple);
77
assert_eq!(Target::from_json(target.to_json()).map(|(j, _)| j), Ok(target));
88
}
99

1010
impl Target {
11-
fn check_consistency(&self) {
11+
fn check_consistency(&self, triple: &str) {
1212
assert_eq!(self.is_like_osx, self.vendor == "apple");
1313
assert_eq!(self.is_like_solaris, self.os == "solaris" || self.os == "illumos");
1414
assert_eq!(self.is_like_windows, self.os == "windows" || self.os == "uefi");
1515
assert_eq!(self.is_like_wasm, self.arch == "wasm32" || self.arch == "wasm64");
16-
assert!(self.is_like_windows || !self.is_like_msvc);
16+
if self.is_like_msvc {
17+
assert!(self.is_like_windows);
18+
}
1719

1820
// Check that default linker flavor and lld flavor are compatible
1921
// with some other key properties.
@@ -94,8 +96,9 @@ impl Target {
9496
check_noncc(LinkerFlavor::Ld);
9597
check_noncc(LinkerFlavor::Lld(LldFlavor::Ld));
9698
}
99+
LldFlavor::Ld64 => check_noncc(LinkerFlavor::Lld(LldFlavor::Ld64)),
97100
LldFlavor::Wasm => check_noncc(LinkerFlavor::Lld(LldFlavor::Wasm)),
98-
LldFlavor::Ld64 | LldFlavor::Link => {}
101+
LldFlavor::Link => {}
99102
},
100103
_ => {}
101104
}
@@ -109,20 +112,56 @@ impl Target {
109112
);
110113
}
111114

112-
assert!(
113-
(self.pre_link_objects_self_contained.is_empty()
114-
&& self.post_link_objects_self_contained.is_empty())
115-
|| self.link_self_contained != LinkSelfContainedDefault::False
116-
);
115+
if self.link_self_contained == LinkSelfContainedDefault::False {
116+
assert!(
117+
self.pre_link_objects_self_contained.is_empty()
118+
&& self.post_link_objects_self_contained.is_empty()
119+
);
120+
}
117121

118122
// If your target really needs to deviate from the rules below,
119123
// except it and document the reasons.
120124
// Keep the default "unknown" vendor instead.
121125
assert_ne!(self.vendor, "");
126+
assert_ne!(self.os, "");
122127
if !self.can_use_os_unknown() {
123128
// Keep the default "none" for bare metal targets instead.
124129
assert_ne!(self.os, "unknown");
125130
}
131+
132+
// Check dynamic linking stuff
133+
// BPF: when targeting user space vms (like rbpf), those can load dynamic libraries.
134+
if self.os == "none" && self.arch != "bpf" {
135+
assert!(!self.dynamic_linking);
136+
}
137+
if self.only_cdylib
138+
|| self.crt_static_allows_dylibs
139+
|| !self.late_link_args_dynamic.is_empty()
140+
{
141+
assert!(self.dynamic_linking);
142+
}
143+
// Apparently PIC was slow on wasm at some point, see comments in wasm_base.rs
144+
if self.dynamic_linking && !(self.is_like_wasm && self.os != "emscripten") {
145+
assert_eq!(self.relocation_model, RelocModel::Pic);
146+
}
147+
// PIEs are supported but not enabled by default with linuxkernel target.
148+
if self.position_independent_executables && !triple.ends_with("-linuxkernel") {
149+
assert_eq!(self.relocation_model, RelocModel::Pic);
150+
}
151+
if self.relocation_model == RelocModel::Pic {
152+
assert!(self.dynamic_linking || self.position_independent_executables);
153+
}
154+
if self.static_position_independent_executables {
155+
assert!(self.position_independent_executables);
156+
}
157+
if self.position_independent_executables {
158+
assert!(self.executables);
159+
}
160+
161+
// Check crt static stuff
162+
if self.crt_static_default || self.crt_static_allows_dylibs {
163+
assert!(self.crt_static_respected);
164+
}
126165
}
127166

128167
// Add your target to the whitelist if it has `std` library

compiler/rustc_target/src/spec/uefi_msvc_base.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
// the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all
1010
// code runs in the same environment, no process separation is supported.
1111

12-
use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, StackProbeType, TargetOptions};
12+
use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy};
13+
use crate::spec::{RelocModel, StackProbeType, TargetOptions};
1314

1415
pub fn opts() -> TargetOptions {
1516
let mut base = super::msvc_base::opts();
@@ -46,6 +47,7 @@ pub fn opts() -> TargetOptions {
4647
stack_probes: StackProbeType::Call,
4748
singlethread: true,
4849
linker: Some("rust-lld".into()),
50+
relocation_model: RelocModel::Static,
4951
..base
5052
}
5153
}

0 commit comments

Comments
 (0)