From 2e83c22154afb6dd9fe32a17e9eaa0332c073707 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 28 Jun 2022 12:40:39 +0300 Subject: [PATCH 1/4] rustc_target: Add some more target spec sanity checking --- .../rustc_target/src/spec/avr_gnu_base.rs | 3 +- compiler/rustc_target/src/spec/l4re_base.rs | 3 +- compiler/rustc_target/src/spec/mod.rs | 8 +-- .../rustc_target/src/spec/tests/tests_impl.rs | 59 +++++++++++++++---- .../rustc_target/src/spec/uefi_msvc_base.rs | 4 +- 5 files changed, 60 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_target/src/spec/avr_gnu_base.rs b/compiler/rustc_target/src/spec/avr_gnu_base.rs index 1d441e558ddcc..8cca33cc43b35 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 a08756861e5b2..cab4dd333d43d 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 8d00129b1b1dc..3ae5c9b5d65dd 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 03e579aee0a96..4a53b9c173d1f 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 aee8eb2e31c7a..250da03cbd2b6 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 } } From f0d0573db1a791958938789b35309aab7323c284 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 14 Aug 2022 19:11:31 +0300 Subject: [PATCH 2/4] rustc_target: Do not specify some target options redundantly These values are already inherited --- .../src/spec/aarch64_nintendo_switch_freestanding.rs | 1 - compiler/rustc_target/src/spec/android_base.rs | 1 - .../rustc_target/src/spec/hexagon_unknown_linux_musl.rs | 1 - compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs | 3 +-- .../rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs | 2 -- compiler/rustc_target/src/spec/x86_64_unknown_none.rs | 7 ++----- 6 files changed, 3 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding.rs b/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding.rs index 1b7161fbb85c5..b301ce68a1ce1 100644 --- a/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding.rs +++ b/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding.rs @@ -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() }, diff --git a/compiler/rustc_target/src/spec/android_base.rs b/compiler/rustc_target/src/spec/android_base.rs index 2bf83a8782a12..9f3e0bd5ef0e3 100644 --- a/compiler/rustc_target/src/spec/android_base.rs +++ b/compiler/rustc_target/src/spec/android_base.rs @@ -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 diff --git a/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs index cc2c78c69fe15..2a24e4459c553 100644 --- a/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs @@ -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; diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs b/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs index 516b2de37eaa7..75ac66c276d57 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs @@ -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(); @@ -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 }, diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs b/compiler/rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs index 78189a0c0969a..26da7e800114a 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs @@ -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 { diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_none.rs b/compiler/rustc_target/src/spec/x86_64_unknown_none.rs index 809fd642d4114..b9a345127e372 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_none.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_none.rs @@ -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 { @@ -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: From f4b5954764f68b2487f2603dc3e0eed39bcf74e5 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 14 Aug 2022 19:13:15 +0300 Subject: [PATCH 3/4] rustc_target: Use `Cow` and link args helpers in `apple_base` --- compiler/rustc_target/src/spec/apple_base.rs | 41 +++++++++----------- compiler/rustc_target/src/spec/mod.rs | 2 +- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs index 9bbee88a894ca..2c72bf88a41e8 100644 --- a/compiler/rustc_target/src/spec/apple_base.rs +++ b/compiler/rustc_target/src/spec/apple_base.rs @@ -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 = match abi { + "sim" => format!("{}-simulator", os).into(), + "macabi" => "mac-catalyst".into(), + _ => os.into(), }; - let platform_version = match os.as_ref() { + let platform_version: StaticCow = 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 } @@ -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> { +pub fn macos_link_env_remove() -> Vec> { 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. diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 3ae5c9b5d65dd..b4ca1ddcf63c0 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -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) } From f7eb7ef2caa3236487980d0127998ab03bafb42d Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 27 Aug 2022 16:19:56 +0300 Subject: [PATCH 4/4] Update tests for UEFI and AVR --- src/test/codegen/abi-efiapi.rs | 2 +- src/test/codegen/avr/avr-func-addrspace.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/codegen/abi-efiapi.rs b/src/test/codegen/abi-efiapi.rs index b4fda5f8c8428..4dc9d183b0b20 100644 --- a/src/test/codegen/abi-efiapi.rs +++ b/src/test/codegen/abi-efiapi.rs @@ -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 diff --git a/src/test/codegen/avr/avr-func-addrspace.rs b/src/test/codegen/avr/avr-func-addrspace.rs index 530164edd4682..a038dfe76f707 100644 --- a/src/test/codegen/avr/avr-func-addrspace.rs +++ b/src/test/codegen/avr/avr-func-addrspace.rs @@ -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;