Skip to content

Commit 8a497b7

Browse files
committed
Auto merge of #102328 - cuviper:ibm-stack-probes, r=nagisa
Enable inline stack probes on PowerPC and SystemZ The LLVM PowerPC and SystemZ targets have both supported `"probe-stack"="inline-asm"` for longer than our current minimum LLVM 13 requirement, so we can turn this on for all `powerpc`, `powerpc64`, `powerpc64le`, and `s390x` targets in Rust. These are all tier-2 or lower, so CI does not run their tests, but I have confirmed that their `linux-gnu` variants do pass on RHEL. cc #43241
2 parents 1536a53 + ad8f519 commit 8a497b7

23 files changed

+107
-48
lines changed

compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use crate::abi::Endian;
2-
use crate::spec::{LinkerFlavor, Target, TargetOptions};
2+
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
33

44
pub fn target() -> Target {
55
let mut base = super::freebsd_base::opts();
66
base.cpu = "ppc64".into();
77
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
88
base.max_atomic_width = Some(64);
9+
base.stack_probes = StackProbeType::Inline;
910

1011
Target {
1112
llvm_target: "powerpc64-unknown-freebsd".into(),

compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use crate::abi::Endian;
2-
use crate::spec::{LinkerFlavor, Target, TargetOptions};
2+
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
33

44
pub fn target() -> Target {
55
let mut base = super::linux_gnu_base::opts();
66
base.cpu = "ppc64".into();
77
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
88
base.max_atomic_width = Some(64);
9+
base.stack_probes = StackProbeType::Inline;
910

1011
Target {
1112
llvm_target: "powerpc64-unknown-linux-gnu".into(),

compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use crate::abi::Endian;
2-
use crate::spec::{LinkerFlavor, Target, TargetOptions};
2+
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
33

44
pub fn target() -> Target {
55
let mut base = super::linux_musl_base::opts();
66
base.cpu = "ppc64".into();
77
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
88
base.max_atomic_width = Some(64);
9+
base.stack_probes = StackProbeType::Inline;
910

1011
Target {
1112
llvm_target: "powerpc64-unknown-linux-musl".into(),

compiler/rustc_target/src/spec/powerpc64_unknown_openbsd.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use crate::abi::Endian;
2-
use crate::spec::{LinkerFlavor, Target, TargetOptions};
2+
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
33

44
pub fn target() -> Target {
55
let mut base = super::openbsd_base::opts();
66
base.cpu = "ppc64".into();
77
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
88
base.max_atomic_width = Some(64);
9+
base.stack_probes = StackProbeType::Inline;
910

1011
Target {
1112
llvm_target: "powerpc64-unknown-openbsd".into(),

compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use crate::abi::Endian;
2-
use crate::spec::{LinkerFlavor, Target, TargetOptions};
2+
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
33

44
pub fn target() -> Target {
55
let mut base = super::vxworks_base::opts();
66
base.cpu = "ppc64".into();
77
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
88
base.max_atomic_width = Some(64);
9+
base.stack_probes = StackProbeType::Inline;
910

1011
Target {
1112
llvm_target: "powerpc64-unknown-linux-gnu".into(),

compiler/rustc_target/src/spec/powerpc64le_unknown_freebsd.rs

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

33
pub fn target() -> Target {
44
let mut base = super::freebsd_base::opts();
55
base.cpu = "ppc64le".into();
66
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
77
base.max_atomic_width = Some(64);
8+
base.stack_probes = StackProbeType::Inline;
89

910
Target {
1011
llvm_target: "powerpc64le-unknown-freebsd".into(),

compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs

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

33
pub fn target() -> Target {
44
let mut base = super::linux_gnu_base::opts();
55
base.cpu = "ppc64le".into();
66
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
77
base.max_atomic_width = Some(64);
8+
base.stack_probes = StackProbeType::Inline;
89

910
Target {
1011
llvm_target: "powerpc64le-unknown-linux-gnu".into(),

compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs

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

33
pub fn target() -> Target {
44
let mut base = super::linux_musl_base::opts();
55
base.cpu = "ppc64le".into();
66
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
77
base.max_atomic_width = Some(64);
8+
base.stack_probes = StackProbeType::Inline;
89

910
Target {
1011
llvm_target: "powerpc64le-unknown-linux-musl".into(),

compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use crate::abi::Endian;
2-
use crate::spec::{LinkerFlavor, Target, TargetOptions};
2+
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
33

44
pub fn target() -> Target {
55
let mut base = super::freebsd_base::opts();
66
// Extra hint to linker that we are generating secure-PLT code.
77
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "--target=powerpc-unknown-freebsd13.0"]);
88
base.max_atomic_width = Some(32);
9+
base.stack_probes = StackProbeType::Inline;
910

1011
Target {
1112
llvm_target: "powerpc-unknown-freebsd13.0".into(),

compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use crate::abi::Endian;
2-
use crate::spec::{LinkerFlavor, Target, TargetOptions};
2+
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
33

44
pub fn target() -> Target {
55
let mut base = super::linux_gnu_base::opts();
66
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
77
base.max_atomic_width = Some(32);
8+
base.stack_probes = StackProbeType::Inline;
89

910
Target {
1011
llvm_target: "powerpc-unknown-linux-gnu".into(),

compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use crate::abi::Endian;
2-
use crate::spec::{LinkerFlavor, Target, TargetOptions};
2+
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
33

44
pub fn target() -> Target {
55
let mut base = super::linux_gnu_base::opts();
66
base.add_pre_link_args(LinkerFlavor::Gcc, &["-mspe"]);
77
base.max_atomic_width = Some(32);
8+
base.stack_probes = StackProbeType::Inline;
89

910
Target {
1011
llvm_target: "powerpc-unknown-linux-gnuspe".into(),

compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use crate::abi::Endian;
2-
use crate::spec::{LinkerFlavor, Target, TargetOptions};
2+
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
33

44
pub fn target() -> Target {
55
let mut base = super::linux_musl_base::opts();
66
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
77
base.max_atomic_width = Some(32);
8+
base.stack_probes = StackProbeType::Inline;
89

910
Target {
1011
llvm_target: "powerpc-unknown-linux-musl".into(),

compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use crate::abi::Endian;
2-
use crate::spec::{LinkerFlavor, Target, TargetOptions};
2+
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
33

44
pub fn target() -> Target {
55
let mut base = super::netbsd_base::opts();
66
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
77
base.max_atomic_width = Some(32);
8+
base.stack_probes = StackProbeType::Inline;
89

910
Target {
1011
llvm_target: "powerpc-unknown-netbsd".into(),

compiler/rustc_target/src/spec/powerpc_unknown_openbsd.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use crate::abi::Endian;
2-
use crate::spec::Target;
2+
use crate::spec::{StackProbeType, Target};
33

44
pub fn target() -> Target {
55
let mut base = super::openbsd_base::opts();
66
base.endian = Endian::Big;
77
base.max_atomic_width = Some(32);
8+
base.stack_probes = StackProbeType::Inline;
89

910
Target {
1011
llvm_target: "powerpc-unknown-openbsd".into(),

compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use crate::abi::Endian;
2-
use crate::spec::{LinkerFlavor, Target, TargetOptions};
2+
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
33

44
pub fn target() -> Target {
55
let mut base = super::vxworks_base::opts();
66
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "--secure-plt"]);
77
base.max_atomic_width = Some(32);
8+
base.stack_probes = StackProbeType::Inline;
89

910
Target {
1011
llvm_target: "powerpc-unknown-linux-gnu".into(),

compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use crate::abi::Endian;
2-
use crate::spec::{LinkerFlavor, Target, TargetOptions};
2+
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
33

44
pub fn target() -> Target {
55
let mut base = super::vxworks_base::opts();
66
base.add_pre_link_args(LinkerFlavor::Gcc, &["-mspe", "--secure-plt"]);
77
base.max_atomic_width = Some(32);
8+
base.stack_probes = StackProbeType::Inline;
89

910
Target {
1011
llvm_target: "powerpc-unknown-linux-gnuspe".into(),

compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::abi::Endian;
2-
use crate::spec::Target;
2+
use crate::spec::{StackProbeType, Target};
33

44
pub fn target() -> Target {
55
let mut base = super::linux_gnu_base::opts();
@@ -12,6 +12,7 @@ pub fn target() -> Target {
1212
base.features = "-vector".into();
1313
base.max_atomic_width = Some(64);
1414
base.min_global_align = Some(16);
15+
base.stack_probes = StackProbeType::Inline;
1516

1617
Target {
1718
llvm_target: "s390x-unknown-linux-gnu".into(),

compiler/rustc_target/src/spec/s390x_unknown_linux_musl.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::abi::Endian;
2-
use crate::spec::Target;
2+
use crate::spec::{StackProbeType, Target};
33

44
pub fn target() -> Target {
55
let mut base = super::linux_musl_base::opts();
@@ -13,6 +13,7 @@ pub fn target() -> Target {
1313
base.max_atomic_width = Some(64);
1414
base.min_global_align = Some(16);
1515
base.static_position_independent_executables = true;
16+
base.stack_probes = StackProbeType::Inline;
1617

1718
Target {
1819
llvm_target: "s390x-unknown-linux-musl".into(),

src/test/codegen/stack-probes-call.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Check the "probe-stack" attribute for targets with `StackProbeType::Call`,
2+
// or `StackProbeType::InlineOrCall` when running on older LLVM.
3+
4+
// compile-flags: -C no-prepopulate-passes
5+
// revisions: i686 x86_64
6+
//[i686] compile-flags: --target i686-unknown-linux-gnu
7+
//[i686] needs-llvm-components: x86
8+
//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
9+
//[x86_64] needs-llvm-components: x86
10+
11+
#![crate_type = "rlib"]
12+
#![feature(no_core, lang_items)]
13+
#![no_core]
14+
15+
#[lang = "sized"]
16+
trait Sized {}
17+
18+
#[no_mangle]
19+
pub fn foo() {
20+
// CHECK: @foo() unnamed_addr #0
21+
// CHECK: attributes #0 = { {{.*}}"probe-stack"="__rust_probestack"{{.*}} }
22+
}
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Check the "probe-stack" attribute for targets with `StackProbeType::Inline`,
2+
// or `StackProbeType::InlineOrCall` when running on newer LLVM.
3+
4+
// compile-flags: -C no-prepopulate-passes
5+
// revisions: powerpc powerpc64 powerpc64le s390x
6+
//[powerpc] compile-flags: --target powerpc-unknown-linux-gnu
7+
//[powerpc] needs-llvm-components: powerpc
8+
//[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu
9+
//[powerpc64] needs-llvm-components: powerpc
10+
//[powerpc64le] compile-flags: --target powerpc64le-unknown-linux-gnu
11+
//[powerpc64le] needs-llvm-components: powerpc
12+
//[s390x] compile-flags: --target s390x-unknown-linux-gnu
13+
//[s390x] needs-llvm-components: systemz
14+
15+
#![crate_type = "rlib"]
16+
#![feature(no_core, lang_items)]
17+
#![no_core]
18+
19+
#[lang = "sized"]
20+
trait Sized {}
21+
22+
#[no_mangle]
23+
pub fn foo() {
24+
// CHECK: @foo() unnamed_addr #0
25+
// CHECK: attributes #0 = { {{.*}}"probe-stack"="inline-asm"{{.*}} }
26+
}

src/test/codegen/stack-probes.rs

-22
This file was deleted.

src/test/ui/abi/stack-probes-lto.rs

-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
// ignore-aarch64
44
// ignore-mips
55
// ignore-mips64
6-
// ignore-powerpc
7-
// ignore-s390x
86
// ignore-sparc
97
// ignore-sparc64
108
// ignore-wasm

src/test/ui/abi/stack-probes.rs

+23-6
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
// ignore-aarch64
44
// ignore-mips
55
// ignore-mips64
6-
// ignore-powerpc
7-
// ignore-s390x
86
// ignore-sparc
97
// ignore-sparc64
108
// ignore-wasm
@@ -27,8 +25,9 @@ fn main() {
2725
let args = env::args().skip(1).collect::<Vec<_>>();
2826
if args.len() > 0 {
2927
match &args[0][..] {
30-
"main-thread" => recurse(&MaybeUninit::uninit()),
31-
"child-thread" => thread::spawn(|| recurse(&MaybeUninit::uninit())).join().unwrap(),
28+
"main-recurse" => overflow_recurse(),
29+
"child-recurse" => thread::spawn(overflow_recurse).join().unwrap(),
30+
"child-frame" => overflow_frame(),
3231
_ => panic!(),
3332
}
3433
return;
@@ -41,9 +40,10 @@ fn main() {
4140
// that we report stack overflow on the main thread, see #43052 for some
4241
// details
4342
if cfg!(not(target_os = "linux")) {
44-
assert_overflow(Command::new(&me).arg("main-thread"));
43+
assert_overflow(Command::new(&me).arg("main-recurse"));
4544
}
46-
assert_overflow(Command::new(&me).arg("child-thread"));
45+
assert_overflow(Command::new(&me).arg("child-recurse"));
46+
assert_overflow(Command::new(&me).arg("child-frame"));
4747
}
4848

4949
#[allow(unconditional_recursion)]
@@ -55,6 +55,23 @@ fn recurse(array: &MaybeUninit<[u64; 1024]>) {
5555
recurse(&local);
5656
}
5757

58+
#[inline(never)]
59+
fn overflow_recurse() {
60+
recurse(&MaybeUninit::uninit());
61+
}
62+
63+
fn overflow_frame() {
64+
// By using a 1MiB stack frame with only 512KiB stack, we'll jump over any
65+
// guard page, even with 64K pages -- but stack probes should catch it.
66+
const STACK_SIZE: usize = 512 * 1024;
67+
thread::Builder::new().stack_size(STACK_SIZE).spawn(|| {
68+
let local: MaybeUninit<[u8; 2 * STACK_SIZE]> = MaybeUninit::uninit();
69+
unsafe {
70+
black_box(local.as_ptr() as u64);
71+
}
72+
}).unwrap().join().unwrap();
73+
}
74+
5875
fn assert_overflow(cmd: &mut Command) {
5976
let output = cmd.output().unwrap();
6077
assert!(!output.status.success());

0 commit comments

Comments
 (0)