From 007080b60791d9751fd298b49879fe2fe5bc4c10 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Sat, 9 Jan 2021 16:54:20 +0200 Subject: [PATCH 1/2] Target stack-probe support configurable finely This adds capability to configure the target's stack probe support in a more precise manner than just on/off. In particular now we allow choosing between always inline-asm, always call or either one of those depending on the LLVM version on a per-target basis. --- compiler/rustc_codegen_llvm/src/attributes.rs | 45 +++++---- .../rustc_target/src/spec/i386_apple_ios.rs | 8 +- .../src/spec/i686_apple_darwin.rs | 4 +- .../src/spec/i686_linux_android.rs | 4 +- .../src/spec/i686_unknown_freebsd.rs | 4 +- .../src/spec/i686_unknown_haiku.rs | 4 +- .../src/spec/i686_unknown_linux_gnu.rs | 4 +- .../src/spec/i686_unknown_linux_musl.rs | 4 +- .../src/spec/i686_unknown_netbsd.rs | 4 +- .../src/spec/i686_unknown_openbsd.rs | 4 +- .../rustc_target/src/spec/i686_wrs_vxworks.rs | 4 +- .../src/spec/linux_kernel_base.rs | 6 +- compiler/rustc_target/src/spec/mod.rs | 98 ++++++++++++++++++- .../rustc_target/src/spec/uefi_msvc_base.rs | 4 +- .../src/spec/x86_64_apple_darwin.rs | 4 +- .../rustc_target/src/spec/x86_64_apple_ios.rs | 8 +- .../src/spec/x86_64_apple_ios_macabi.rs | 8 +- .../src/spec/x86_64_apple_tvos.rs | 8 +- .../rustc_target/src/spec/x86_64_fuchsia.rs | 4 +- .../src/spec/x86_64_linux_android.rs | 4 +- .../src/spec/x86_64_rumprun_netbsd.rs | 4 +- .../src/spec/x86_64_sun_solaris.rs | 4 +- .../src/spec/x86_64_unknown_dragonfly.rs | 4 +- .../src/spec/x86_64_unknown_freebsd.rs | 4 +- .../src/spec/x86_64_unknown_haiku.rs | 4 +- .../src/spec/x86_64_unknown_hermit.rs | 4 +- .../src/spec/x86_64_unknown_hermit_kernel.rs | 4 +- .../src/spec/x86_64_unknown_linux_gnu.rs | 4 +- .../src/spec/x86_64_unknown_linux_gnux32.rs | 4 +- .../src/spec/x86_64_unknown_linux_musl.rs | 4 +- .../src/spec/x86_64_unknown_netbsd.rs | 4 +- .../src/spec/x86_64_unknown_openbsd.rs | 4 +- .../src/spec/x86_64_unknown_redox.rs | 4 +- .../src/spec/x86_64_wrs_vxworks.rs | 4 +- .../extern/extern-compare-with-return-type.rs | 1 + 35 files changed, 203 insertions(+), 87 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 700f32e15b952..a78d692aaa7fb 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -13,6 +13,7 @@ use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::config::{OptLevel, SanitizerSet}; use rustc_session::Session; +use rustc_target::spec::StackProbeType; use crate::attributes; use crate::llvm::AttributePlace::Function; @@ -98,12 +99,6 @@ fn set_instrument_function(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { } fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { - // Only use stack probes if the target specification indicates that we - // should be using stack probes - if !cx.sess().target.stack_probes { - return; - } - // Currently stack probes seem somewhat incompatible with the address // sanitizer and thread sanitizer. With asan we're already protected from // stack overflow anyway so we don't really need stack probes regardless. @@ -127,19 +122,31 @@ fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { return; } - llvm::AddFunctionAttrStringValue( - llfn, - llvm::AttributePlace::Function, - const_cstr!("probe-stack"), - if llvm_util::get_version() < (11, 0, 1) { - // Flag our internal `__rust_probestack` function as the stack probe symbol. - // This is defined in the `compiler-builtins` crate for each architecture. - const_cstr!("__rust_probestack") - } else { - // On LLVM 11+, emit inline asm for stack probes instead of a function call. - const_cstr!("inline-asm") - }, - ); + let attr_value = match cx.sess().target.stack_probes { + StackProbeType::None => None, + // Request LLVM to generate the probes inline. If the given LLVM version does not support + // this, no probe is generated at all (even if the attribute is specified). + StackProbeType::Inline => Some(const_cstr!("inline-asm")), + // Flag our internal `__rust_probestack` function as the stack probe symbol. + // This is defined in the `compiler-builtins` crate for each architecture. + StackProbeType::Call => Some(const_cstr!("__rust_probestack")), + // Pick from the two above based on the LLVM version. + StackProbeType::InlineOrCall { min_llvm_version_for_inline } => { + if llvm_util::get_version() < min_llvm_version_for_inline { + Some(const_cstr!("__rust_probestack")) + } else { + Some(const_cstr!("inline-asm")) + } + } + }; + if let Some(attr_value) = attr_value { + llvm::AddFunctionAttrStringValue( + llfn, + llvm::AttributePlace::Function, + const_cstr!("probe-stack"), + attr_value, + ); + } } pub fn llvm_target_features(sess: &Session) -> impl Iterator { diff --git a/compiler/rustc_target/src/spec/i386_apple_ios.rs b/compiler/rustc_target/src/spec/i386_apple_ios.rs index 302306ee57990..cfaf020175b7f 100644 --- a/compiler/rustc_target/src/spec/i386_apple_ios.rs +++ b/compiler/rustc_target/src/spec/i386_apple_ios.rs @@ -1,5 +1,5 @@ use super::apple_sdk_base::{opts, Arch}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let base = opts("ios", Arch::I386); @@ -10,6 +10,10 @@ pub fn target() -> Target { f64:32:64-f80:128-n8:16:32-S128" .to_string(), arch: "x86".to_string(), - options: TargetOptions { max_atomic_width: Some(64), stack_probes: true, ..base }, + options: TargetOptions { + max_atomic_width: Some(64), + stack_probes: StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }, + ..base + }, } } diff --git a/compiler/rustc_target/src/spec/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/i686_apple_darwin.rs index 0ab40340928cc..2d3310c7582ef 100644 --- a/compiler/rustc_target/src/spec/i686_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/i686_apple_darwin.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::apple_base::opts("macos"); @@ -6,7 +6,7 @@ pub fn target() -> Target { base.max_atomic_width = Some(64); base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]); base.link_env_remove.extend(super::apple_base::macos_link_env_remove()); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; base.eliminate_frame_pointer = false; // Clang automatically chooses a more specific target based on diff --git a/compiler/rustc_target/src/spec/i686_linux_android.rs b/compiler/rustc_target/src/spec/i686_linux_android.rs index 52059b930d134..18cd8847abd39 100644 --- a/compiler/rustc_target/src/spec/i686_linux_android.rs +++ b/compiler/rustc_target/src/spec/i686_linux_android.rs @@ -1,4 +1,4 @@ -use crate::spec::Target; +use crate::spec::{StackProbeType, Target}; // See https://developer.android.com/ndk/guides/abis.html#x86 // for target ABI requirements. @@ -11,7 +11,7 @@ pub fn target() -> Target { // http://developer.android.com/ndk/guides/abis.html#x86 base.cpu = "pentiumpro".to_string(); base.features = "+mmx,+sse,+sse2,+sse3,+ssse3".to_string(); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { llvm_target: "i686-linux-android".to_string(), diff --git a/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs b/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs index fc1c8607d654c..fc425babb6948 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{LinkerFlavor, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::freebsd_base::opts(); @@ -7,7 +7,7 @@ pub fn target() -> Target { let pre_link_args = base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap(); pre_link_args.push("-m32".to_string()); pre_link_args.push("-Wl,-znotext".to_string()); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { llvm_target: "i686-unknown-freebsd".to_string(), diff --git a/compiler/rustc_target/src/spec/i686_unknown_haiku.rs b/compiler/rustc_target/src/spec/i686_unknown_haiku.rs index 22c8ba5475315..5fba4e3f14a25 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_haiku.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_haiku.rs @@ -1,11 +1,11 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{LinkerFlavor, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::haiku_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { llvm_target: "i686-unknown-haiku".to_string(), diff --git a/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs index 083c115d084b4..fe1e6a4299dab 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs @@ -1,11 +1,11 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{LinkerFlavor, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { llvm_target: "i686-unknown-linux-gnu".to_string(), diff --git a/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs index 1673b2a180245..623fd1b9ae801 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{LinkerFlavor, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); @@ -6,7 +6,7 @@ pub fn target() -> Target { base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-Wl,-melf_i386".to_string()); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; // The unwinder used by i686-unknown-linux-musl, the LLVM libunwind // implementation, apparently relies on frame pointers existing... somehow. diff --git a/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs index c22139b5875d6..c4d11bfb13ece 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs @@ -1,11 +1,11 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::netbsd_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { llvm_target: "i686-unknown-netbsdelf".to_string(), diff --git a/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs b/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs index 87642efdee8f7..fdaaf6c741e89 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{LinkerFlavor, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::openbsd_base::opts(); @@ -6,7 +6,7 @@ pub fn target() -> Target { base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-fuse-ld=lld".to_string()); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { llvm_target: "i686-unknown-openbsd".to_string(), diff --git a/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs index c0825358cabbc..ec8a2493b4e42 100644 --- a/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs @@ -1,11 +1,11 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{LinkerFlavor, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::vxworks_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { llvm_target: "i686-unknown-linux-gnu".to_string(), diff --git a/compiler/rustc_target/src/spec/linux_kernel_base.rs b/compiler/rustc_target/src/spec/linux_kernel_base.rs index a5fc1649e7ffd..5220156895367 100644 --- a/compiler/rustc_target/src/spec/linux_kernel_base.rs +++ b/compiler/rustc_target/src/spec/linux_kernel_base.rs @@ -1,4 +1,6 @@ -use crate::spec::{LinkArgs, LinkerFlavor, PanicStrategy, RelocModel, RelroLevel, TargetOptions}; +use crate::spec::{ + LinkArgs, LinkerFlavor, PanicStrategy, RelocModel, RelroLevel, StackProbeType, TargetOptions, +}; pub fn opts() -> TargetOptions { let mut pre_link_args = LinkArgs::new(); @@ -11,7 +13,7 @@ pub fn opts() -> TargetOptions { env: "gnu".to_string(), disable_redzone: true, panic_strategy: PanicStrategy::Abort, - stack_probes: true, + stack_probes: StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }, eliminate_frame_pointer: false, linker_is_gnu: true, position_independent_executables: true, diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index d283c2548864f..90d35efaa25bd 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -40,6 +40,7 @@ use crate::spec::crt_objects::{CrtObjects, CrtObjectsFallback}; use rustc_serialize::json::{Json, ToJson}; use rustc_span::symbol::{sym, Symbol}; use std::collections::BTreeMap; +use std::convert::TryFrom; use std::ops::{Deref, DerefMut}; use std::path::{Path, PathBuf}; use std::str::FromStr; @@ -479,6 +480,83 @@ macro_rules! supported_targets { }; } +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum StackProbeType { + /// Don't emit any stack probes. + None, + /// It is harmless to use this option even on targets that do not have backend support for + /// stack probes as the failure mode is the same as if no stack-probe option was specified in + /// the first place. + Inline, + /// Call `__rust_probestack` whenever stack needs to be probed. + Call, + /// Use inline option for LLVM versions later than specified in `min_llvm_version_for_inline` + /// and call `__rust_probestack` otherwise. + InlineOrCall { min_llvm_version_for_inline: (u32, u32, u32) }, +} + +impl StackProbeType { + fn from_json(json: &Json) -> Result { + let object = json.as_object().ok_or_else(|| "expected a JSON object")?; + let kind = object + .get("kind") + .and_then(|o| o.as_string()) + .ok_or_else(|| "expected `kind` to be a string")?; + match kind { + "none" => Ok(StackProbeType::None), + "inline" => Ok(StackProbeType::Inline), + "call" => Ok(StackProbeType::Call), + "inline-or-call" => { + let min_version = object + .get("min-llvm-version-for-inline") + .and_then(|o| o.as_array()) + .ok_or_else(|| "expected `min-llvm-version-for-inline` to be an array")?; + let mut iter = min_version.into_iter().map(|v| { + let int = v.as_u64().ok_or_else( + || "expected `min-llvm-version-for-inline` values to be integers", + )?; + u32::try_from(int) + .map_err(|_| "`min-llvm-version-for-inline` values don't convert to u32") + }); + let min_llvm_version_for_inline = ( + iter.next().unwrap_or(Ok(11))?, + iter.next().unwrap_or(Ok(0))?, + iter.next().unwrap_or(Ok(0))?, + ); + Ok(StackProbeType::InlineOrCall { min_llvm_version_for_inline }) + } + _ => Err(String::from( + "`kind` expected to be one of `inline-or-none`, `call` or `inline-or-call`", + )), + } + } +} + +impl ToJson for StackProbeType { + fn to_json(&self) -> Json { + Json::Object(match self { + StackProbeType::None => { + vec![(String::from("kind"), "none".to_json())].into_iter().collect() + } + StackProbeType::Inline => { + vec![(String::from("kind"), "inline".to_json())].into_iter().collect() + } + StackProbeType::Call => { + vec![(String::from("kind"), "call".to_json())].into_iter().collect() + } + StackProbeType::InlineOrCall { min_llvm_version_for_inline } => vec![ + (String::from("kind"), "inline-or-call".to_json()), + ( + String::from("min-llvm-version-for-inline"), + min_llvm_version_for_inline.to_json(), + ), + ] + .into_iter() + .collect(), + }) + } +} + supported_targets! { ("x86_64-unknown-linux-gnu", x86_64_unknown_linux_gnu), ("x86_64-unknown-linux-gnux32", x86_64_unknown_linux_gnux32), @@ -926,8 +1004,8 @@ pub struct TargetOptions { /// Whether or not crt-static is respected by the compiler (or is a no-op). pub crt_static_respected: bool, - /// Whether or not stack probes (__rust_probestack) are enabled - pub stack_probes: bool, + /// The implementation of stack probes to use. + pub stack_probes: StackProbeType, /// The minimum alignment for global symbols. pub min_global_align: Option, @@ -1085,7 +1163,7 @@ impl Default for TargetOptions { crt_static_allows_dylibs: false, crt_static_default: false, crt_static_respected: false, - stack_probes: false, + stack_probes: StackProbeType::None, min_global_align: None, default_codegen_units: None, trap_unreachable: true, @@ -1361,6 +1439,18 @@ impl Target { Some(Ok(())) })).unwrap_or(Ok(())) } ); + ($key_name:ident, StackProbeType) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.find(&name[..]).and_then(|o| match StackProbeType::from_json(o) { + Ok(v) => { + base.$key_name = v; + Some(Ok(())) + }, + Err(s) => Some(Err( + format!("`{:?}` is not a valid value for `{}`: {}", o, name, s) + )), + }).unwrap_or(Ok(())) + } ); ($key_name:ident, crt_objects_fallback) => ( { let name = (stringify!($key_name)).replace("_", "-"); obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| { @@ -1516,7 +1606,7 @@ impl Target { key!(crt_static_allows_dylibs, bool); key!(crt_static_default, bool); key!(crt_static_respected, bool); - key!(stack_probes, bool); + key!(stack_probes, StackProbeType)?; key!(min_global_align, Option); key!(default_codegen_units, Option); key!(trap_unreachable, bool); diff --git a/compiler/rustc_target/src/spec/uefi_msvc_base.rs b/compiler/rustc_target/src/spec/uefi_msvc_base.rs index 322b6f530e9fd..c17b0fa07abba 100644 --- a/compiler/rustc_target/src/spec/uefi_msvc_base.rs +++ b/compiler/rustc_target/src/spec/uefi_msvc_base.rs @@ -9,7 +9,7 @@ // 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, TargetOptions}; +use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, StackProbeType, TargetOptions}; pub fn opts() -> TargetOptions { let mut base = super::msvc_base::opts(); @@ -43,7 +43,7 @@ pub fn opts() -> TargetOptions { exe_suffix: ".efi".to_string(), allows_weak_linkage: false, panic_strategy: PanicStrategy::Abort, - stack_probes: true, + stack_probes: StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }, singlethread: true, linker: Some("rust-lld".to_string()), ..base diff --git a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs index edb33fe6e2b13..8c40baccda84a 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::apple_base::opts("macos"); @@ -10,7 +10,7 @@ pub fn target() -> Target { vec!["-m64".to_string(), "-arch".to_string(), "x86_64".to_string()], ); base.link_env_remove.extend(super::apple_base::macos_link_env_remove()); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; // Clang automatically chooses a more specific target based on // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs index c9c7eeb723198..6feeeac451b27 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs @@ -1,5 +1,5 @@ use super::apple_sdk_base::{opts, Arch}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let base = opts("ios", Arch::X86_64); @@ -9,6 +9,10 @@ pub fn target() -> Target { data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - options: TargetOptions { max_atomic_width: Some(64), stack_probes: true, ..base }, + options: TargetOptions { + max_atomic_width: Some(64), + stack_probes: StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }, + ..base + }, } } diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs index 6b360e5495be7..a6e066213e7f9 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs @@ -1,5 +1,5 @@ use super::apple_sdk_base::{opts, Arch}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let base = opts("ios", Arch::X86_64_macabi); @@ -9,6 +9,10 @@ pub fn target() -> Target { data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - options: TargetOptions { max_atomic_width: Some(64), stack_probes: true, ..base }, + options: TargetOptions { + max_atomic_width: Some(64), + stack_probes: StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }, + ..base + }, } } diff --git a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs index 5b2a62a23fd8c..f8c47168da87f 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs @@ -1,5 +1,5 @@ use super::apple_sdk_base::{opts, Arch}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let base = opts("tvos", Arch::X86_64); @@ -8,6 +8,10 @@ pub fn target() -> Target { pointer_width: 64, data_layout: "e-m:o-i64:64-f80:128-n8:16:32:64-S128".to_string(), arch: "x86_64".to_string(), - options: TargetOptions { max_atomic_width: Some(64), stack_probes: true, ..base }, + options: TargetOptions { + max_atomic_width: Some(64), + stack_probes: StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }, + ..base + }, } } diff --git a/compiler/rustc_target/src/spec/x86_64_fuchsia.rs b/compiler/rustc_target/src/spec/x86_64_fuchsia.rs index 6c049c2635c79..a39e7f8c34105 100644 --- a/compiler/rustc_target/src/spec/x86_64_fuchsia.rs +++ b/compiler/rustc_target/src/spec/x86_64_fuchsia.rs @@ -1,10 +1,10 @@ -use crate::spec::Target; +use crate::spec::{StackProbeType, Target}; pub fn target() -> Target { let mut base = super::fuchsia_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { llvm_target: "x86_64-fuchsia".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_linux_android.rs b/compiler/rustc_target/src/spec/x86_64_linux_android.rs index 27327160178a0..d436242e62b30 100644 --- a/compiler/rustc_target/src/spec/x86_64_linux_android.rs +++ b/compiler/rustc_target/src/spec/x86_64_linux_android.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{LinkerFlavor, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::android_base::opts(); @@ -7,7 +7,7 @@ pub fn target() -> Target { base.features = "+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { llvm_target: "x86_64-linux-android".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_rumprun_netbsd.rs b/compiler/rustc_target/src/spec/x86_64_rumprun_netbsd.rs index 095c6f15c77ad..d84a63562c70a 100644 --- a/compiler/rustc_target/src/spec/x86_64_rumprun_netbsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_rumprun_netbsd.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::netbsd_base::opts(); @@ -12,7 +12,7 @@ pub fn target() -> Target { base.has_rpath = false; base.position_independent_executables = false; base.disable_redzone = true; - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { llvm_target: "x86_64-rumprun-netbsd".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs b/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs index 6ccf78402e149..0fe462ec83cbc 100644 --- a/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs +++ b/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs @@ -1,11 +1,11 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{LinkerFlavor, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::solaris_base::opts(); base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { llvm_target: "x86_64-pc-solaris".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs b/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs index 30aa2909873a3..d86b0d67acd15 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs @@ -1,11 +1,11 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{LinkerFlavor, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::dragonfly_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { llvm_target: "x86_64-unknown-dragonfly".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs index ee904d762421f..c7d3b3feed50e 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs @@ -1,11 +1,11 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{LinkerFlavor, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::freebsd_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { llvm_target: "x86_64-unknown-freebsd".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs b/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs index ea7e068e516a9..963d4fdb12f2d 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs @@ -1,11 +1,11 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{LinkerFlavor, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::haiku_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; // This option is required to build executables on Haiku x86_64 base.position_independent_executables = true; diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs b/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs index 4005aaf58b133..31164f8408dcb 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs @@ -1,11 +1,11 @@ -use crate::spec::Target; +use crate::spec::{StackProbeType, Target}; pub fn target() -> Target { let mut base = super::hermit_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.features = "+rdrnd,+rdseed".to_string(); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { llvm_target: "x86_64-unknown-hermit".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_hermit_kernel.rs b/compiler/rustc_target/src/spec/x86_64_unknown_hermit_kernel.rs index b72d529363afb..9fcfe4e6c14bf 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_hermit_kernel.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_hermit_kernel.rs @@ -1,4 +1,4 @@ -use crate::spec::Target; +use crate::spec::{StackProbeType, Target}; pub fn target() -> Target { let mut base = super::hermit_kernel_base::opts(); @@ -7,7 +7,7 @@ pub fn target() -> Target { base.features = "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float" .to_string(); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { llvm_target: "x86_64-unknown-hermit".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs index f127dd49bc4b7..99906764dfc6e 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs @@ -1,11 +1,11 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{LinkerFlavor, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { llvm_target: "x86_64-unknown-linux-gnu".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs index 0cae57528483f..4b2bce37470cc 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs @@ -1,11 +1,11 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{LinkerFlavor, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-mx32".to_string()); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; base.has_elf_tls = false; // BUG(GabrielMajeri): disabling the PLT on x86_64 Linux with x32 ABI // breaks code gen. See LLVM bug 36743 diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs index 3669c10981e19..fa9fdf5aa0992 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs @@ -1,11 +1,11 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{LinkerFlavor, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; base.static_position_independent_executables = true; Target { diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs index 7e91a6ddbe296..6d19dec00b411 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs @@ -1,11 +1,11 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::netbsd_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { llvm_target: "x86_64-unknown-netbsd".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs index 0fe01f09c2e85..ac5939bcb3c43 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs @@ -1,11 +1,11 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{LinkerFlavor, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::openbsd_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { llvm_target: "x86_64-unknown-openbsd".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs b/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs index cdd445b2614b2..ddabe95ab8394 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs @@ -1,11 +1,11 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{LinkerFlavor, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::redox_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; Target { llvm_target: "x86_64-unknown-redox".to_string(), diff --git a/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs index 163af6fd8e175..1b35e813fcd8f 100644 --- a/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs @@ -1,11 +1,11 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{LinkerFlavor, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::vxworks_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); - base.stack_probes = true; + base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }; base.disable_redzone = true; Target { diff --git a/src/test/ui/extern/extern-compare-with-return-type.rs b/src/test/ui/extern/extern-compare-with-return-type.rs index 1ddfc77a4c43a..42693d3a061c8 100644 --- a/src/test/ui/extern/extern-compare-with-return-type.rs +++ b/src/test/ui/extern/extern-compare-with-return-type.rs @@ -1,4 +1,5 @@ // run-pass + // Tests that we can compare various kinds of extern fn signatures. #![allow(non_camel_case_types)] From 1b15ec656b992fd991abad35b14c9e8ecb089132 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Wed, 20 Jan 2021 01:26:06 +0200 Subject: [PATCH 2/2] Use a call probe on the x86_64-uefi target Fixes #81196 --- compiler/rustc_target/src/spec/uefi_msvc_base.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/uefi_msvc_base.rs b/compiler/rustc_target/src/spec/uefi_msvc_base.rs index c17b0fa07abba..b9ff16bd19ff4 100644 --- a/compiler/rustc_target/src/spec/uefi_msvc_base.rs +++ b/compiler/rustc_target/src/spec/uefi_msvc_base.rs @@ -43,7 +43,9 @@ pub fn opts() -> TargetOptions { exe_suffix: ".efi".to_string(), allows_weak_linkage: false, panic_strategy: PanicStrategy::Abort, - stack_probes: StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) }, + // LLVM does not emit inline assembly because the LLVM target does not get considered as… + // "Windows". + stack_probes: StackProbeType::Call, singlethread: true, linker: Some("rust-lld".to_string()), ..base