Skip to content

Commit ed8981f

Browse files
committed
Turn off segmented stack support and use stack probes instead
Fixes rust-lang#10781, rust-lang#11359, rust-lang#13259, rust-lang#14742 and rust-lang#16012.
1 parent f5ac411 commit ed8981f

File tree

9 files changed

+16
-183
lines changed

9 files changed

+16
-183
lines changed

src/librustc/middle/lang_items.rs

-2
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,4 @@ lets_do_this! {
300300
ManagedItem, "managed_bound", managed_bound;
301301

302302
IteratorItem, "iterator", iterator;
303-
304-
StackExhaustedLangItem, "stack_exhausted", stack_exhausted;
305303
}

src/librustc/middle/trans/base.rs

+9-24
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ fn decl_fn(ccx: &CrateContext, name: &str, cc: llvm::CallConv,
204204
// Function addresses in Rust are never significant, allowing functions to be merged.
205205
llvm::SetUnnamedAddr(llfn, true);
206206

207-
if ccx.is_split_stack_supported() {
208-
set_split_stack(llfn);
207+
if ccx.is_probe_stack_supported() {
208+
set_probe_stack(llfn);
209209
}
210210

211211
llfn
@@ -429,11 +429,6 @@ pub fn set_llvm_fn_attrs(attrs: &[ast::Attribute], llfn: ValueRef) {
429429
InlineNone => { /* fallthrough */ }
430430
}
431431

432-
// Add the no-split-stack attribute if requested
433-
if contains_name(attrs, "no_split_stack") {
434-
unset_split_stack(llfn);
435-
}
436-
437432
if contains_name(attrs, "cold") {
438433
unsafe {
439434
llvm::LLVMAddFunctionAttribute(llfn,
@@ -447,14 +442,14 @@ pub fn set_always_inline(f: ValueRef) {
447442
llvm::SetFunctionAttribute(f, llvm::AlwaysInlineAttribute)
448443
}
449444

450-
pub fn set_split_stack(f: ValueRef) {
451-
"split-stack".with_c_str(|buf| {
445+
pub fn set_probe_stack(f: ValueRef) {
446+
"probe-stack".with_c_str(|buf| {
452447
unsafe { llvm::LLVMAddFunctionAttrString(f, llvm::FunctionIndex as c_uint, buf); }
453448
})
454449
}
455450

456-
pub fn unset_split_stack(f: ValueRef) {
457-
"split-stack".with_c_str(|buf| {
451+
pub fn unset_probe_stack(f: ValueRef) {
452+
"probe-stack".with_c_str(|buf| {
458453
unsafe { llvm::LLVMRemoveFunctionAttrString(f, llvm::FunctionIndex as c_uint, buf); }
459454
})
460455
}
@@ -2009,14 +2004,8 @@ fn finish_register_fn(ccx: &CrateContext, sp: Span, sym: String, node_id: ast::N
20092004
llvm::SetLinkage(llfn, llvm::InternalLinkage);
20102005
}
20112006

2012-
// The stack exhaustion lang item shouldn't have a split stack because
2013-
// otherwise it would continue to be exhausted (bad), and both it and the
2014-
// eh_personality functions need to be externally linkable.
2007+
// The eh_personality function need to be externally linkable.
20152008
let def = ast_util::local_def(node_id);
2016-
if ccx.tcx.lang_items.stack_exhausted() == Some(def) {
2017-
unset_split_stack(llfn);
2018-
llvm::SetLinkage(llfn, llvm::ExternalLinkage);
2019-
}
20202009
if ccx.tcx.lang_items.eh_personality() == Some(def) {
20212010
llvm::SetLinkage(llfn, llvm::ExternalLinkage);
20222011
}
@@ -2729,13 +2718,9 @@ pub fn trans_crate(krate: ast::Crate,
27292718
});
27302719

27312720
// Make sure that some other crucial symbols are not eliminated from the
2732-
// module. This includes the main function, the crate map (used for debug
2733-
// log settings and I/O), and finally the curious rust_stack_exhausted
2734-
// symbol. This symbol is required for use by the libmorestack library that
2735-
// we link in, so we must ensure that this symbol is not internalized (if
2736-
// defined in the crate).
2721+
// module. This includes the main function and the crate map (used for debug
2722+
// log settings and I/O)
27372723
reachable.push("main".to_string());
2738-
reachable.push("rust_stack_exhausted".to_string());
27392724

27402725
// referenced from .eh_frame section on some platforms
27412726
reachable.push("rust_eh_personality".to_string());

src/librustc/middle/trans/context.rs

+2-11
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ use std::c_str::ToCStr;
3232
use std::ptr;
3333
use std::rc::Rc;
3434
use std::collections::{HashMap, HashSet};
35-
use syntax::abi;
3635
use syntax::ast;
3736
use syntax::parse::token::InternedString;
3837

@@ -275,16 +274,8 @@ impl CrateContext {
275274
}
276275
}
277276

278-
// Although there is an experimental implementation of LLVM which
279-
// supports SS on armv7 it wasn't approved by Apple, see:
280-
// http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140505/216350.html
281-
// It looks like it might be never accepted to upstream LLVM.
282-
//
283-
// So far the decision was to disable them in default builds
284-
// but it could be enabled (with patched LLVM)
285-
pub fn is_split_stack_supported(&self) -> bool {
286-
let ref cfg = self.sess().targ_cfg;
287-
cfg.os != abi::OsiOS || cfg.arch != abi::Arm
277+
pub fn is_probe_stack_supported(&self) -> bool {
278+
true
288279
}
289280
}
290281

src/librustc/middle/weak_lang_items.rs

-4
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,6 @@ pub fn check_crate(krate: &ast::Crate,
3838
// These are never called by user code, they're generated by the compiler.
3939
// They will never implicitly be added to the `missing` array unless we do
4040
// so here.
41-
if items.stack_exhausted().is_none() {
42-
items.missing.push(lang_items::StackExhaustedLangItem);
43-
}
4441
if items.eh_personality().is_none() {
4542
items.missing.push(lang_items::EhPersonalityLangItem);
4643
}
@@ -119,6 +116,5 @@ impl<'a> Visitor<()> for Context<'a> {
119116

120117
weak_lang_items!(
121118
begin_unwind, BeginUnwindLangItem, rust_begin_unwind;
122-
stack_exhausted, StackExhaustedLangItem, rust_stack_exhausted;
123119
eh_personality, EhPersonalityLangItem, rust_eh_personality;
124120
)

src/rt/arch/arm/morestack.S

+1-22
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,10 @@
1616

1717
#if defined(__APPLE__)
1818
#define MORESTACK ___morestack
19-
#define STACK_EXHAUSTED _rust_stack_exhausted
2019
#else
2120
#define MORESTACK __morestack
22-
#define STACK_EXHAUSTED rust_stack_exhausted
2321
#endif
2422

25-
.global STACK_EXHAUSTED
2623
.global MORESTACK
2724

2825
// Unfortunately LLVM yet doesn't support emitting correct debug
@@ -48,23 +45,5 @@
4845
// ARMFrameLowering::adjustForSegmentedStacks() implementation.
4946
MORESTACK:
5047
UNWIND .fnstart
51-
52-
// Save frame pointer and return address
53-
UNWIND .save {r4, r5}
54-
UNWIND .save {lr}
55-
UNWIND .save {r6, fp, lr}
56-
push {r6, fp, lr}
57-
58-
UNWIND .movsp r6
59-
mov r6, sp
60-
UNWIND .setfp fp, sp, #4
61-
add fp, sp, #4
62-
63-
// Save argument registers of the original function
64-
push {r0, r1, r2, r3, lr}
65-
66-
// Create new stack
67-
bl STACK_EXHAUSTED@plt
68-
69-
// the above function ensures that it never returns
48+
b MORESTACK
7049
UNWIND .fnend

src/rt/arch/i386/morestack.S

+1-44
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,11 @@
7171

7272
#if defined(__APPLE__)
7373
#define MORESTACK ___morestack
74-
#define EXHAUSTED _rust_stack_exhausted
7574
#else
7675
#if defined(__linux__) || defined(__FreeBSD__)
7776
#define MORESTACK __morestack
78-
#define EXHAUSTED rust_stack_exhausted
7977
#else
8078
#define MORESTACK ___morestack
81-
#define EXHAUSTED _rust_stack_exhausted
8279
#endif
8380
#endif
8481

@@ -100,45 +97,5 @@
10097

10198
MORESTACK:
10299
.cfi_startproc
103-
104-
// This base pointer setup differs from most in that we are
105-
// telling the unwinder to consider the Canonical Frame
106-
// Address (CFA) for this frame to be the value of the stack
107-
// pointer prior to entry to the original function, whereas
108-
// the CFA would typically be the value of the stack
109-
// pointer prior to entry to this function. This will allow
110-
// the unwinder to understand how to skip the tiny partial
111-
// frame that the original function created by calling
112-
// __morestack.
113-
114-
// In practical terms, our CFA is 12 bytes greater than it
115-
// would normally be, accounting for the two arguments to
116-
// __morestack, and an extra return address.
117-
118-
// FIXME(#9854) these cfi directives don't work on windows.
119-
120-
pushl %ebp
121-
122-
#if defined(__APPLE__)
123-
// The pattern of the return address being saved twice to the same location
124-
// tells the OS X linker that it should not attempt to convert the DWARF
125-
// unwind information to the compact format.
126-
.cfi_offset %eip, -4
127-
.cfi_offset %eip, -4
128-
#endif
129-
130-
// The CFA is 20 bytes above the register that it is
131-
// associated with for this frame (which will be %ebp)
132-
.cfi_def_cfa_offset 20
133-
// %ebp is -20 bytes from the CFA
134-
.cfi_offset %ebp, -20
135-
movl %esp, %ebp
136-
// Calculate the CFA as an offset from %ebp
137-
.cfi_def_cfa_register %ebp
138-
139-
// re-align the stack
140-
subl $12,%esp
141-
calll EXHAUSTED
142-
// the exhaustion function guarantees that it can't return
143-
100+
jmp MORESTACK
144101
.cfi_endproc

src/rt/arch/mips/morestack.S

+1-19
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
.text
99

10-
.globl rust_stack_exhausted
1110
.globl __morestack
1211

1312
.hidden __morestack
@@ -19,25 +18,8 @@ __morestack:
1918
.set noreorder
2019
.set nomacro
2120

22-
addiu $29, $29, -4
23-
sw $30, 0($29)
24-
25-
// 16 = 4 (current) + 12 (previous)
26-
.cfi_def_cfa_offset 16
27-
.cfi_offset 31, -4
28-
.cfi_offset 30, -16
29-
30-
move $30, $29
31-
.cfi_def_cfa_register 30
32-
33-
// O32 ABI always reserves 16 bytes for arguments
34-
addiu $29, $29, -16
35-
36-
lw $25, %call16(rust_stack_exhausted)($28)
37-
jalr $25
21+
b __morestack
3822
nop
3923

40-
// the above function make sure that we never get here
41-
4224
.end __morestack
4325
.cfi_endproc

src/rt/arch/mipsel/morestack.S

+1-19
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
.text
99

10-
.globl rust_stack_exhausted
1110
.globl __morestack
1211

1312
.hidden __morestack
@@ -19,25 +18,8 @@ __morestack:
1918
.set noreorder
2019
.set nomacro
2120

22-
addiu $29, $29, -4
23-
sw $30, 0($29)
24-
25-
// 16 = 4 (current) + 12 (previous)
26-
.cfi_def_cfa_offset 16
27-
.cfi_offset 31, -4
28-
.cfi_offset 30, -16
29-
30-
move $30, $29
31-
.cfi_def_cfa_register 30
32-
33-
// O32 ABI always reserves 16 bytes for arguments
34-
addiu $29, $29, -16
35-
36-
lw $25, %call16(rust_stack_exhausted)($28)
37-
jalr $25
21+
b __morestack
3822
nop
3923

40-
// the above function make sure that we never get here
41-
4224
.end __morestack
4325
.cfi_endproc

src/rt/arch/x86_64/morestack.S

+1-38
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,6 @@
1313
#define MORESTACK __morestack
1414
#endif
1515

16-
#if defined(__APPLE__)
17-
#define EXHAUSTED _rust_stack_exhausted
18-
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
19-
#define EXHAUSTED rust_stack_exhausted@PLT
20-
#else
21-
#define EXHAUSTED rust_stack_exhausted
22-
#endif
23-
2416
#if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
2517
.hidden MORESTACK
2618
#else
@@ -36,34 +28,5 @@
3628
.globl MORESTACK
3729
MORESTACK:
3830
.cfi_startproc
39-
40-
pushq %rbp
41-
// The CFA is 24 bytes above the register that it will
42-
// be associated with for this frame (%rbp). That is 8
43-
// bytes greater than a normal frame, to allow the unwinder
44-
// to skip the partial frame of the original function.
45-
.cfi_def_cfa_offset 24
46-
47-
#if defined(__APPLE__)
48-
// The pattern of the return address being saved twice to the same location
49-
// tells the OS X linker that it should not attempt to convert the DWARF
50-
// unwind information to the compact format.
51-
.cfi_offset %rip, -8
52-
.cfi_offset %rip, -8
53-
#endif
54-
55-
// %rbp is -24 bytes from the CFA
56-
.cfi_offset %rbp, -24
57-
movq %rsp, %rbp
58-
// Calculate the CFA as on offset from %ebp
59-
.cfi_def_cfa_register %rbp
60-
61-
// re-align the stack
62-
subq $8, %rsp
63-
64-
// kill this program
65-
call EXHAUSTED
66-
67-
// the exhaustion function guarantees that it can't return
68-
31+
jmp MORESTACK
6932
.cfi_endproc

0 commit comments

Comments
 (0)