Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 007080b

Browse files
committed
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.
1 parent efdb859 commit 007080b

35 files changed

+203
-87
lines changed

compiler/rustc_codegen_llvm/src/attributes.rs

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_middle::ty::query::Providers;
1313
use rustc_middle::ty::{self, TyCtxt};
1414
use rustc_session::config::{OptLevel, SanitizerSet};
1515
use rustc_session::Session;
16+
use rustc_target::spec::StackProbeType;
1617

1718
use crate::attributes;
1819
use crate::llvm::AttributePlace::Function;
@@ -98,12 +99,6 @@ fn set_instrument_function(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
9899
}
99100

100101
fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
101-
// Only use stack probes if the target specification indicates that we
102-
// should be using stack probes
103-
if !cx.sess().target.stack_probes {
104-
return;
105-
}
106-
107102
// Currently stack probes seem somewhat incompatible with the address
108103
// sanitizer and thread sanitizer. With asan we're already protected from
109104
// 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) {
127122
return;
128123
}
129124

130-
llvm::AddFunctionAttrStringValue(
131-
llfn,
132-
llvm::AttributePlace::Function,
133-
const_cstr!("probe-stack"),
134-
if llvm_util::get_version() < (11, 0, 1) {
135-
// Flag our internal `__rust_probestack` function as the stack probe symbol.
136-
// This is defined in the `compiler-builtins` crate for each architecture.
137-
const_cstr!("__rust_probestack")
138-
} else {
139-
// On LLVM 11+, emit inline asm for stack probes instead of a function call.
140-
const_cstr!("inline-asm")
141-
},
142-
);
125+
let attr_value = match cx.sess().target.stack_probes {
126+
StackProbeType::None => None,
127+
// Request LLVM to generate the probes inline. If the given LLVM version does not support
128+
// this, no probe is generated at all (even if the attribute is specified).
129+
StackProbeType::Inline => Some(const_cstr!("inline-asm")),
130+
// Flag our internal `__rust_probestack` function as the stack probe symbol.
131+
// This is defined in the `compiler-builtins` crate for each architecture.
132+
StackProbeType::Call => Some(const_cstr!("__rust_probestack")),
133+
// Pick from the two above based on the LLVM version.
134+
StackProbeType::InlineOrCall { min_llvm_version_for_inline } => {
135+
if llvm_util::get_version() < min_llvm_version_for_inline {
136+
Some(const_cstr!("__rust_probestack"))
137+
} else {
138+
Some(const_cstr!("inline-asm"))
139+
}
140+
}
141+
};
142+
if let Some(attr_value) = attr_value {
143+
llvm::AddFunctionAttrStringValue(
144+
llfn,
145+
llvm::AttributePlace::Function,
146+
const_cstr!("probe-stack"),
147+
attr_value,
148+
);
149+
}
143150
}
144151

145152
pub fn llvm_target_features(sess: &Session) -> impl Iterator<Item = &str> {

compiler/rustc_target/src/spec/i386_apple_ios.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::apple_sdk_base::{opts, Arch};
2-
use crate::spec::{Target, TargetOptions};
2+
use crate::spec::{StackProbeType, Target, TargetOptions};
33

44
pub fn target() -> Target {
55
let base = opts("ios", Arch::I386);
@@ -10,6 +10,10 @@ pub fn target() -> Target {
1010
f64:32:64-f80:128-n8:16:32-S128"
1111
.to_string(),
1212
arch: "x86".to_string(),
13-
options: TargetOptions { max_atomic_width: Some(64), stack_probes: true, ..base },
13+
options: TargetOptions {
14+
max_atomic_width: Some(64),
15+
stack_probes: StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) },
16+
..base
17+
},
1418
}
1519
}

compiler/rustc_target/src/spec/i686_apple_darwin.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
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::apple_base::opts("macos");
55
base.cpu = "yonah".to_string();
66
base.max_atomic_width = Some(64);
77
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]);
88
base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
9-
base.stack_probes = true;
9+
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
1010
base.eliminate_frame_pointer = false;
1111

1212
// Clang automatically chooses a more specific target based on

compiler/rustc_target/src/spec/i686_linux_android.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::spec::Target;
1+
use crate::spec::{StackProbeType, Target};
22

33
// See https://developer.android.com/ndk/guides/abis.html#x86
44
// for target ABI requirements.
@@ -11,7 +11,7 @@ pub fn target() -> Target {
1111
// http://developer.android.com/ndk/guides/abis.html#x86
1212
base.cpu = "pentiumpro".to_string();
1313
base.features = "+mmx,+sse,+sse2,+sse3,+ssse3".to_string();
14-
base.stack_probes = true;
14+
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
1515

1616
Target {
1717
llvm_target: "i686-linux-android".to_string(),

compiler/rustc_target/src/spec/i686_unknown_freebsd.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::spec::{LinkerFlavor, Target};
1+
use crate::spec::{LinkerFlavor, StackProbeType, Target};
22

33
pub fn target() -> Target {
44
let mut base = super::freebsd_base::opts();
@@ -7,7 +7,7 @@ pub fn target() -> Target {
77
let pre_link_args = base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap();
88
pre_link_args.push("-m32".to_string());
99
pre_link_args.push("-Wl,-znotext".to_string());
10-
base.stack_probes = true;
10+
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
1111

1212
Target {
1313
llvm_target: "i686-unknown-freebsd".to_string(),

compiler/rustc_target/src/spec/i686_unknown_haiku.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
use crate::spec::{LinkerFlavor, Target};
1+
use crate::spec::{LinkerFlavor, StackProbeType, Target};
22

33
pub fn target() -> Target {
44
let mut base = super::haiku_base::opts();
55
base.cpu = "pentium4".to_string();
66
base.max_atomic_width = Some(64);
77
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]);
8-
base.stack_probes = true;
8+
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
99

1010
Target {
1111
llvm_target: "i686-unknown-haiku".to_string(),

compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
use crate::spec::{LinkerFlavor, Target};
1+
use crate::spec::{LinkerFlavor, StackProbeType, Target};
22

33
pub fn target() -> Target {
44
let mut base = super::linux_gnu_base::opts();
55
base.cpu = "pentium4".to_string();
66
base.max_atomic_width = Some(64);
77
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string());
8-
base.stack_probes = true;
8+
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
99

1010
Target {
1111
llvm_target: "i686-unknown-linux-gnu".to_string(),

compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
use crate::spec::{LinkerFlavor, Target};
1+
use crate::spec::{LinkerFlavor, StackProbeType, Target};
22

33
pub fn target() -> Target {
44
let mut base = super::linux_musl_base::opts();
55
base.cpu = "pentium4".to_string();
66
base.max_atomic_width = Some(64);
77
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string());
88
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-Wl,-melf_i386".to_string());
9-
base.stack_probes = true;
9+
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
1010

1111
// The unwinder used by i686-unknown-linux-musl, the LLVM libunwind
1212
// implementation, apparently relies on frame pointers existing... somehow.

compiler/rustc_target/src/spec/i686_unknown_netbsd.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +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::netbsd_base::opts();
55
base.cpu = "pentium4".to_string();
66
base.max_atomic_width = Some(64);
77
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string());
8-
base.stack_probes = true;
8+
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
99

1010
Target {
1111
llvm_target: "i686-unknown-netbsdelf".to_string(),

compiler/rustc_target/src/spec/i686_unknown_openbsd.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
use crate::spec::{LinkerFlavor, Target};
1+
use crate::spec::{LinkerFlavor, StackProbeType, Target};
22

33
pub fn target() -> Target {
44
let mut base = super::openbsd_base::opts();
55
base.cpu = "pentium4".to_string();
66
base.max_atomic_width = Some(64);
77
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string());
88
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-fuse-ld=lld".to_string());
9-
base.stack_probes = true;
9+
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
1010

1111
Target {
1212
llvm_target: "i686-unknown-openbsd".to_string(),

0 commit comments

Comments
 (0)