Skip to content

Commit 881bfb1

Browse files
committed
Renamed record_stack_bounds for clarity.
For a good measure, implemented target_record_stack_bounds for 32-bit Windows as well.
1 parent cd2003f commit 881bfb1

File tree

5 files changed

+29
-18
lines changed

5 files changed

+29
-18
lines changed

src/libgreen/context.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,11 @@ impl Context {
105105
// invalid for the current task. Lucky for us `rust_swap_registers`
106106
// is a C function so we don't have to worry about that!
107107
match in_context.stack_bounds {
108-
Some((lo, hi)) => stack::record_stack_bounds_green(lo, hi),
108+
Some((lo, hi)) => stack::record_rust_managed_stack_bounds(lo, hi),
109109
// If we're going back to one of the original contexts or
110110
// something that's possibly not a "normal task", then reset
111111
// the stack limit to 0 to make morestack never fail
112-
None => stack::record_stack_bounds_green(0, uint::MAX),
112+
None => stack::record_rust_managed_stack_bounds(0, uint::MAX),
113113
}
114114
rust_swap_registers(out_regs, in_regs)
115115
}

src/libnative/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ pub fn start(argc: int, argv: *const *const u8, main: proc()) -> int {
137137
task.name = Some(str::Slice("<main>"));
138138
drop(task.run(|| {
139139
unsafe {
140-
rt::stack::record_stack_bounds(my_stack_bottom, my_stack_top);
140+
rt::stack::record_os_managed_stack_bounds(my_stack_bottom, my_stack_top);
141141
}
142142
exit_code = Some(run(main.take_unwrap()));
143143
}).destroy());

src/libnative/task.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ pub fn spawn_opts(opts: TaskOpts, f: proc():Send) {
8484
let addr = &something_around_the_top_of_the_stack as *const int;
8585
let my_stack = addr as uint;
8686
unsafe {
87-
stack::record_stack_bounds(my_stack - stack + 1024, my_stack);
87+
stack::record_os_managed_stack_bounds(my_stack - stack + 1024, my_stack);
8888
}
8989
let mut ops = ops;
9090
ops.stack_bounds = (my_stack - stack + 1024, my_stack);

src/librustrt/stack.rs

+24-13
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,23 @@ extern fn stack_exhausted() {
124124
}
125125
}
126126

127+
// Windows maintains a record of upper and lower stack bounds in the Thread Information
128+
// Block (TIB), and some syscalls do check that addresses which are supposed to be in
129+
// the stack, indeed lie between these two values.
130+
// (See https://github.com/rust-lang/rust/issues/3445#issuecomment-26114839)
131+
//
132+
// When using Rust-managed stacks (libgreen), we must maintain these values accordingly.
133+
// For OS-managed stacks (libnative), we let the OS manage them for us.
134+
//
135+
// On all other platforms both variants behave identically.
136+
137+
#[inline(always)]
138+
pub unsafe fn record_os_managed_stack_bounds(stack_lo: uint, _stack_hi: uint) {
139+
record_sp_limit(stack_lo + RED_ZONE);
140+
}
141+
127142
#[inline(always)]
128-
pub unsafe fn record_stack_bounds_green(stack_lo: uint, stack_hi: uint) {
143+
pub unsafe fn record_rust_managed_stack_bounds(stack_lo: uint, stack_hi: uint) {
129144
// When the old runtime had segmented stacks, it used a calculation that was
130145
// "limit + RED_ZONE + FUDGE". The red zone was for things like dynamic
131146
// symbol resolution, llvm function calls, etc. In theory this red zone
@@ -138,27 +153,23 @@ pub unsafe fn record_stack_bounds_green(stack_lo: uint, stack_hi: uint) {
138153

139154
return target_record_stack_bounds(stack_lo, stack_hi);
140155

141-
#[cfg(not(windows))] #[cfg(not(target_arch = "x86_64"))] #[inline(always)]
156+
#[cfg(not(windows))] #[inline(always)]
142157
unsafe fn target_record_stack_bounds(_stack_lo: uint, _stack_hi: uint) {}
158+
159+
#[cfg(windows, target_arch = "x86")] #[inline(always)]
160+
unsafe fn target_record_stack_bounds(stack_lo: uint, stack_hi: uint) {
161+
// stack range is at TIB: %fs:0x04 (top) and %fs:0x08 (bottom)
162+
asm!("mov $0, %fs:0x04" :: "r"(stack_hi) :: "volatile");
163+
asm!("mov $0, %fs:0x08" :: "r"(stack_lo) :: "volatile");
164+
}
143165
#[cfg(windows, target_arch = "x86_64")] #[inline(always)]
144166
unsafe fn target_record_stack_bounds(stack_lo: uint, stack_hi: uint) {
145-
// Windows compiles C functions which may check the stack bounds. This
146-
// means that if we want to perform valid FFI on windows, then we need
147-
// to ensure that the stack bounds are what they truly are for this
148-
// task. More info can be found at:
149-
// https://github.com/rust-lang/rust/issues/3445#issuecomment-26114839
150-
//
151167
// stack range is at TIB: %gs:0x08 (top) and %gs:0x10 (bottom)
152168
asm!("mov $0, %gs:0x08" :: "r"(stack_hi) :: "volatile");
153169
asm!("mov $0, %gs:0x10" :: "r"(stack_lo) :: "volatile");
154170
}
155171
}
156172

157-
#[inline(always)]
158-
pub unsafe fn record_stack_bounds(stack_lo: uint, _stack_hi: uint) {
159-
record_sp_limit(stack_lo + RED_ZONE);
160-
}
161-
162173
/// Records the current limit of the stack as specified by `end`.
163174
///
164175
/// This is stored in an OS-dependent location, likely inside of the thread

src/librustrt/thread.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ static DEFAULT_STACK_SIZE: uint = 1024 * 1024;
4444
#[no_split_stack]
4545
extern fn thread_start(main: *mut libc::c_void) -> imp::rust_thread_return {
4646
unsafe {
47-
stack::record_stack_bounds(0, uint::MAX);
47+
stack::record_os_managed_stack_bounds(0, uint::MAX);
4848
let f: Box<proc()> = mem::transmute(main);
4949
(*f)();
5050
mem::transmute(0 as imp::rust_thread_return)

0 commit comments

Comments
 (0)