mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Rollup merge of #152432 - fneddy:s390x_packed_stack_attribute, r=nikic
add rustc option -Zpacked-stack this enables `-Zpacked-stack` just as `-mpacked-stack` in clang and gcc. packed-stack is needed on s390x for kernel development. For reference: rust-lang/rust#151154 and rust-lang/rust#150766 look at @uweigand s post for full explanation of what this does. Here a wrap-up: https://github.com/rust-lang/rust/pull/150766#issuecomment-3729074303 > [...] > packed-stack [...] modifies how the compiler-generated function prolog/epilog code makes use of the 160 byte register save area provided by a caller to the callee [...] this variant is not actually incompatible with the ABI - packed-stack and regular functions can freely call each other without ABI issues. > [...] > combination of -mpacked-stack and -mbackchain [...] the location in the stack frame where the backchain link ought to be stored is not available. [...] is not supported at all with the default ABI > [...] > However, in the special case of also using soft-float, our (implied) soft-float ABI provides a different location for the backchain that is compatible with -mpacked-stack, so that combination should be supported > [...]
This commit is contained in:
@@ -3,16 +3,17 @@
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::find_attr;
|
||||
use rustc_middle::middle::codegen_fn_attrs::{
|
||||
CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, SanitizerFnAttrs,
|
||||
CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, SanitizerFnAttrs, TargetFeature,
|
||||
};
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_session::config::{BranchProtection, FunctionReturn, OptLevel, PAuthKey, PacRet};
|
||||
use rustc_span::sym;
|
||||
use rustc_symbol_mangling::mangle_internal_symbol;
|
||||
use rustc_target::spec::{Arch, FramePointer, SanitizerSet, StackProbeType, StackProtector};
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::context::SimpleCx;
|
||||
use crate::errors::SanitizerMemtagRequiresMte;
|
||||
use crate::errors::{PackedStackBackchainNeedsSoftfloat, SanitizerMemtagRequiresMte};
|
||||
use crate::llvm::AttributePlace::Function;
|
||||
use crate::llvm::{
|
||||
self, AllocKindFlags, Attribute, AttributeKind, AttributePlace, MemoryEffects, Value,
|
||||
@@ -302,6 +303,36 @@ fn stackprotector_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> Option<&'ll A
|
||||
Some(sspattr.create_attr(cx.llcx))
|
||||
}
|
||||
|
||||
fn packed_stack_attr<'ll>(
|
||||
cx: &SimpleCx<'ll>,
|
||||
sess: &Session,
|
||||
function_attributes: &Vec<TargetFeature>,
|
||||
) -> Option<&'ll Attribute> {
|
||||
if sess.target.arch != Arch::S390x {
|
||||
return None;
|
||||
}
|
||||
if !sess.opts.unstable_opts.packed_stack {
|
||||
return None;
|
||||
}
|
||||
|
||||
// The backchain and softfloat flags can be set via -Ctarget-features=...
|
||||
// or via #[target_features(enable = ...)] so we have to check both possibilities
|
||||
let have_backchain = sess.unstable_target_features.contains(&sym::backchain)
|
||||
|| function_attributes.iter().any(|feature| feature.name == sym::backchain);
|
||||
let have_softfloat = sess.unstable_target_features.contains(&sym::soft_float)
|
||||
|| function_attributes.iter().any(|feature| feature.name == sym::soft_float);
|
||||
|
||||
// If both, backchain and packedstack, are enabled LLVM cannot generate valid function entry points
|
||||
// with the default ABI. However if the softfloat flag is set LLVM will switch to the softfloat
|
||||
// ABI, where this works.
|
||||
if have_backchain && !have_softfloat {
|
||||
sess.dcx().emit_err(PackedStackBackchainNeedsSoftfloat);
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(llvm::CreateAttrString(cx.llcx, "packed-stack"))
|
||||
}
|
||||
|
||||
pub(crate) fn target_cpu_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> &'ll Attribute {
|
||||
let target_cpu = llvm_util::target_cpu(sess);
|
||||
llvm::CreateAttrStringValue(cx.llcx, "target-cpu", target_cpu)
|
||||
@@ -517,6 +548,9 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
|
||||
if let Some(align) = codegen_fn_attrs.alignment {
|
||||
llvm::set_alignment(llfn, align);
|
||||
}
|
||||
if let Some(packed_stack) = packed_stack_attr(cx, sess, &codegen_fn_attrs.target_features) {
|
||||
to_add.push(packed_stack);
|
||||
}
|
||||
to_add.extend(patchable_function_entry_attrs(
|
||||
cx,
|
||||
sess,
|
||||
|
||||
@@ -204,3 +204,10 @@ pub(crate) struct MismatchedDataLayout<'a> {
|
||||
pub(crate) struct FixedX18InvalidArch<'a> {
|
||||
pub arch: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("`-Zpacked-stack` is incompatible with `backchain` target feature")]
|
||||
#[note(
|
||||
"enabling both `-Zpacked-stack` and the `backchain` target feature is incompatible with the default s390x ABI. Switch to s390x-unknown-none-softfloat if you need both attributes"
|
||||
)]
|
||||
pub(crate) struct PackedStackBackchainNeedsSoftfloat;
|
||||
|
||||
@@ -530,3 +530,7 @@ pub(crate) struct UnexpectedBuiltinCfg {
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("ThinLTO is not supported by the codegen backend, using fat LTO instead")]
|
||||
pub(crate) struct ThinLtoNotSupportedByBackend;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("`-Zpacked-stack` is only supported on s390x")]
|
||||
pub(crate) struct UnsupportedPackedStack;
|
||||
|
||||
@@ -2557,6 +2557,8 @@ pub(crate) fn parse_assert_incr_state(
|
||||
"pass `-install_name @rpath/...` to the macOS linker (default: no)"),
|
||||
packed_bundled_libs: bool = (false, parse_bool, [TRACKED],
|
||||
"change rlib format to store native libraries as archives"),
|
||||
packed_stack: bool = (false, parse_bool, [TRACKED],
|
||||
"use packed stack frames (s390x only) (default: no)"),
|
||||
panic_abort_tests: bool = (false, parse_bool, [TRACKED],
|
||||
"support compiling tests with panic=abort (default: no)"),
|
||||
panic_in_drop: PanicStrategy = (PanicStrategy::Unwind, parse_panic_strategy, [TRACKED],
|
||||
|
||||
@@ -1363,6 +1363,12 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if sess.opts.unstable_opts.packed_stack {
|
||||
if sess.target.arch != Arch::S390x {
|
||||
sess.dcx().emit_err(errors::UnsupportedPackedStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Holds data on the current incremental compilation session, if there is one.
|
||||
|
||||
@@ -505,6 +505,7 @@
|
||||
avx512bw,
|
||||
avx512f,
|
||||
await_macro,
|
||||
backchain,
|
||||
bang,
|
||||
begin_panic,
|
||||
bench,
|
||||
@@ -1919,6 +1920,7 @@
|
||||
slice_len_fn,
|
||||
slice_patterns,
|
||||
slicing_syntax,
|
||||
soft_float: "soft-float",
|
||||
sparc,
|
||||
sparc64,
|
||||
sparc_target_feature,
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
//@ add-minicore
|
||||
//@ revisions: enable-packedstack default-packedstack
|
||||
//@ assembly-output: emit-asm
|
||||
//@ compile-flags: -Copt-level=3 --crate-type=lib --target=s390x-unknown-linux-gnu -Cforce-unwind-tables=no
|
||||
//@ needs-llvm-components: systemz
|
||||
//@[enable-packedstack] compile-flags: -Zpacked-stack
|
||||
#![feature(no_core, lang_items)]
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
|
||||
extern crate minicore;
|
||||
use minicore::*;
|
||||
|
||||
extern "C" {
|
||||
fn extern_func() -> i32;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test_packedstack
|
||||
#[no_mangle]
|
||||
extern "C" fn test_packedstack() -> i32 {
|
||||
// test the creation of call stack with and without packed-stack
|
||||
|
||||
// without packed-stack we always reserve a least the maximal space of 160 bytes
|
||||
// default-packedstack: stmg %r14, %r15, 112(%r15)
|
||||
// default-packedstack-NEXT: aghi %r15, -160
|
||||
// default-packedstack-NEXT: brasl %r14, extern_func
|
||||
|
||||
// with packed-stack only the actually needed registers are reserved on the stack
|
||||
// enable-packedstack: stmg %r14, %r15, 144(%r15)
|
||||
// enable-packedstack-NEXT: aghi %r15, -16
|
||||
// enable-packedstack-NEXT: brasl %r14, extern_func
|
||||
unsafe {
|
||||
extern_func();
|
||||
}
|
||||
1
|
||||
// CHECK: br %r{{.*}}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
//@ add-minicore
|
||||
//@ compile-flags: -Copt-level=3 --crate-type=lib --target=s390x-unknown-none-softfloat -Zpacked-stack
|
||||
//@ needs-llvm-components: systemz
|
||||
#![feature(s390x_target_feature)]
|
||||
#![crate_type = "lib"]
|
||||
#![feature(no_core, lang_items)]
|
||||
#![no_core]
|
||||
|
||||
extern crate minicore;
|
||||
use minicore::*;
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
pub fn test_packedstack() {
|
||||
// CHECK: @test_packedstack() unnamed_addr #0
|
||||
}
|
||||
|
||||
// CHECK: attributes #0 = { {{.*}}"packed-stack"{{.*}} }
|
||||
@@ -0,0 +1,6 @@
|
||||
error: `-Zpacked-stack` is incompatible with `backchain` target feature
|
||||
|
|
||||
= note: enabling both `-Zpacked-stack` and the `backchain` target feature is incompatible with the default s390x ABI. Switch to s390x-unknown-none-softfloat if you need both attributes
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
warning: unstable feature specified for `-Ctarget-feature`: `backchain`
|
||||
|
|
||||
= note: this feature is not stably supported; its behavior can change in the future
|
||||
|
||||
error: packedstack with backchain needs softfloat
|
||||
|
|
||||
= note: enabling both `-Zpacked-stack` and the `backchain` target feature is incompatible with the default s390x ABI. Switch to s390x-unknown-none-softfloat if you need both attributes
|
||||
|
||||
error: aborting due to 1 previous error; 1 warning emitted
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
//@ add-minicore
|
||||
//@ revisions: wrong_arch only_packedstack backchain_attr backchain_cli with_softfloat
|
||||
//@ compile-flags: -Zpacked-stack --crate-type=rlib
|
||||
//@ ignore-backends: gcc
|
||||
|
||||
//@ [wrong_arch] compile-flags: --target=x86_64-unknown-linux-gnu
|
||||
//@ [wrong_arch] should-fail
|
||||
//@ [wrong_arch] needs-llvm-components: x86
|
||||
|
||||
//@ [only_packedstack] compile-flags: --target=s390x-unknown-linux-gnu
|
||||
//@ [only_packedstack] build-pass
|
||||
//@ [only_packedstack] needs-llvm-components: systemz
|
||||
|
||||
//@ [backchain_attr] compile-flags: --target=s390x-unknown-linux-gnu
|
||||
//@ [backchain_attr] build-fail
|
||||
//@ [backchain_attr] needs-llvm-components: systemz
|
||||
|
||||
//@ [backchain_cli] compile-flags: -Ctarget-feature=+backchain --target=s390x-unknown-linux-gnu
|
||||
//@ [backchain_cli] should-fail
|
||||
//@ [backchain_cli] needs-llvm-components: systemz
|
||||
|
||||
//@ [with_softfloat] compile-flags: -Ctarget-feature=+backchain
|
||||
//@ [with_softfloat] compile-flags: --target=s390x-unknown-none-softfloat
|
||||
//@ [with_softfloat] build-pass
|
||||
//@ [with_softfloat] needs-llvm-components: systemz
|
||||
|
||||
#![feature(s390x_target_feature)]
|
||||
#![crate_type = "rlib"]
|
||||
#![feature(no_core,lang_items)]
|
||||
#![no_core]
|
||||
|
||||
extern crate minicore;
|
||||
use minicore::*;
|
||||
|
||||
#[no_mangle]
|
||||
#[cfg_attr(backchain_attr,target_feature(enable = "backchain"))]
|
||||
pub fn test() {
|
||||
}
|
||||
|
||||
//[wrong_arch]~? ERROR `-Zpacked-stack` is only supported on s390x
|
||||
//[backchain_cli]~? WARN unstable feature specified for `-Ctarget-feature`: `backchain`
|
||||
//[backchain_cli]~? ERROR `-Zpacked-stack` is incompatible with `backchain` target feature
|
||||
//[backchain_attr]~? ERROR `-Zpacked-stack` is incompatible with `backchain` target feature
|
||||
//[with_softfloat]~? WARN unstable feature specified for `-Ctarget-feature`: `backchain`
|
||||
@@ -0,0 +1,6 @@
|
||||
warning: unstable feature specified for `-Ctarget-feature`: `backchain`
|
||||
|
|
||||
= note: this feature is not stably supported; its behavior can change in the future
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
error: `-Zpacked-stack` is only supported on s390x
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
Reference in New Issue
Block a user