diff --git a/compiler/rustc_target/src/spec/avr_gnu_base.rs b/compiler/rustc_target/src/spec/avr_gnu_base.rs index 1d441e558dd..8cca33cc43b 100644 --- a/compiler/rustc_target/src/spec/avr_gnu_base.rs +++ b/compiler/rustc_target/src/spec/avr_gnu_base.rs @@ -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. /// @@ -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() }, } diff --git a/compiler/rustc_target/src/spec/l4re_base.rs b/compiler/rustc_target/src/spec/l4re_base.rs index a08756861e5..cab4dd333d4 100644 --- a/compiler/rustc_target/src/spec/l4re_base.rs +++ b/compiler/rustc_target/src/spec/l4re_base.rs @@ -1,4 +1,4 @@ -use crate::spec::{cvs, LinkerFlavor, PanicStrategy, TargetOptions}; +use crate::spec::{cvs, LinkerFlavor, PanicStrategy, RelocModel, TargetOptions}; pub fn opts() -> TargetOptions { TargetOptions { @@ -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() } } diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 8d00129b1b1..3ae5c9b5d65 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -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 { let mut t = match target { - $( $($triple)|+ => $module::target(), )+ + $( $triple => $module::target(), )+ _ => return None, }; t.is_builtin = true; @@ -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); } )+ } diff --git a/compiler/rustc_target/src/spec/tests/tests_impl.rs b/compiler/rustc_target/src/spec/tests/tests_impl.rs index 03e579aee0a..4a53b9c173d 100644 --- a/compiler/rustc_target/src/spec/tests/tests_impl.rs +++ b/compiler/rustc_target/src/spec/tests/tests_impl.rs @@ -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. @@ -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 => {} }, _ => {} } @@ -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 diff --git a/compiler/rustc_target/src/spec/uefi_msvc_base.rs b/compiler/rustc_target/src/spec/uefi_msvc_base.rs index aee8eb2e31c..250da03cbd2 100644 --- a/compiler/rustc_target/src/spec/uefi_msvc_base.rs +++ b/compiler/rustc_target/src/spec/uefi_msvc_base.rs @@ -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(); @@ -46,6 +47,7 @@ pub fn opts() -> TargetOptions { stack_probes: StackProbeType::Call, singlethread: true, linker: Some("rust-lld".into()), + relocation_model: RelocModel::Static, ..base } }