Skip to content

Commit 720746a

Browse files
committed
Merge commit '881bfb1a180a1b545daa9da1539ec4c8ebda7ed1' into rollup
2 parents e5df5f5 + 881bfb1 commit 720746a

File tree

17 files changed

+271
-101
lines changed

17 files changed

+271
-101
lines changed

mk/platform.mk

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ RUSTC_CROSS_FLAGS_arm-unknown-linux-gnueabi :=
377377
# mipsel-linux configuration
378378
CC_mipsel-linux=mipsel-linux-gcc
379379
CXX_mipsel-linux=mipsel-linux-g++
380-
CPP_mipsel-linux=mipsel-linux-gcc
380+
CPP_mipsel-linux=mipsel-linux-gcc
381381
AR_mipsel-linux=mipsel-linux-ar
382382
CFG_LIB_NAME_mipsel-linux=lib$(1).so
383383
CFG_STATIC_LIB_NAME_mipsel-linux=lib$(1).a
@@ -641,7 +641,7 @@ define CFG_MAKE_TOOLCHAIN
641641
CXX_$(1)=$(CROSS_PREFIX_$(1))$(CXX_$(1))
642642
CPP_$(1)=$(CROSS_PREFIX_$(1))$(CPP_$(1))
643643
AR_$(1)=$(CROSS_PREFIX_$(1))$(AR_$(1))
644-
RUSTC_CROSS_FLAGS_$(1)=-C linker=$$(call FIND_COMPILER,$$(CXX_$(1))) \
644+
RUSTC_CROSS_FLAGS_$(1)=-C linker=$$(call FIND_COMPILER,$$(CC_$(1))) \
645645
-C ar=$$(call FIND_COMPILER,$$(AR_$(1))) $(RUSTC_CROSS_FLAGS_$(1))
646646

647647
RUSTC_FLAGS_$(1)=$$(RUSTC_CROSS_FLAGS_$(1)) $(RUSTC_FLAGS_$(1))

src/etc/get-snapshot.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def unpack_snapshot(triple, dl_path):
5353
dl_path = sys.argv[2]
5454
else:
5555
# There are no 64-bit Windows snapshots yet, so we'll use 32-bit ones instead, for now
56-
snap_triple = triple if triple != "x86_64-w64-mingw32" else "i686-pc-mingw32"
56+
snap_triple = triple if triple != "x86_64-w64-mingw32" else "i686-w64-mingw32"
5757
snap = determine_curr_snapshot(snap_triple)
5858
dl = os.path.join(download_dir_base, snap)
5959
url = download_url_base + "/" + snap

src/libgreen/context.rs

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ use std::uint;
1313
use std::mem::transmute;
1414
use std::rt::stack;
1515
use std::raw;
16+
#[cfg(target_arch = "x86_64")]
17+
use std::simd;
1618

1719
// FIXME #7761: Registers is boxed so that it is 16-byte aligned, for storing
1820
// SSE regs. It would be marginally better not to do this. In C++ we
@@ -103,11 +105,11 @@ impl Context {
103105
// invalid for the current task. Lucky for us `rust_swap_registers`
104106
// is a C function so we don't have to worry about that!
105107
match in_context.stack_bounds {
106-
Some((lo, hi)) => stack::record_stack_bounds(lo, hi),
108+
Some((lo, hi)) => stack::record_rust_managed_stack_bounds(lo, hi),
107109
// If we're going back to one of the original contexts or
108110
// something that's possibly not a "normal task", then reset
109111
// the stack limit to 0 to make morestack never fail
110-
None => stack::record_stack_bounds(0, uint::MAX),
112+
None => stack::record_rust_managed_stack_bounds(0, uint::MAX),
111113
}
112114
rust_swap_registers(out_regs, in_regs)
113115
}
@@ -186,14 +188,30 @@ fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
186188
// windows requires saving more registers (both general and XMM), so the windows
187189
// register context must be larger.
188190
#[cfg(windows, target_arch = "x86_64")]
189-
type Registers = [uint, ..34];
191+
struct Registers {
192+
gpr:[uint, ..14],
193+
_xmm:[simd::u32x4, ..10]
194+
}
190195
#[cfg(not(windows), target_arch = "x86_64")]
191-
type Registers = [uint, ..22];
196+
struct Registers {
197+
gpr:[uint, ..10],
198+
_xmm:[simd::u32x4, ..6]
199+
}
192200

193201
#[cfg(windows, target_arch = "x86_64")]
194-
fn new_regs() -> Box<Registers> { box() ([0, .. 34]) }
202+
fn new_regs() -> Box<Registers> {
203+
box() Registers {
204+
gpr:[0,..14],
205+
_xmm:[simd::u32x4(0,0,0,0),..10]
206+
}
207+
}
195208
#[cfg(not(windows), target_arch = "x86_64")]
196-
fn new_regs() -> Box<Registers> { box() ([0, .. 22]) }
209+
fn new_regs() -> Box<Registers> {
210+
box() Registers {
211+
gpr:[0,..10],
212+
_xmm:[simd::u32x4(0,0,0,0),..6]
213+
}
214+
}
197215

198216
#[cfg(target_arch = "x86_64")]
199217
fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
@@ -222,20 +240,20 @@ fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
222240

223241
// These registers are frobbed by rust_bootstrap_green_task into the right
224242
// location so we can invoke the "real init function", `fptr`.
225-
regs[RUSTRT_R12] = arg as uint;
226-
regs[RUSTRT_R13] = procedure.code as uint;
227-
regs[RUSTRT_R14] = procedure.env as uint;
228-
regs[RUSTRT_R15] = fptr as uint;
243+
regs.gpr[RUSTRT_R12] = arg as uint;
244+
regs.gpr[RUSTRT_R13] = procedure.code as uint;
245+
regs.gpr[RUSTRT_R14] = procedure.env as uint;
246+
regs.gpr[RUSTRT_R15] = fptr as uint;
229247

230248
// These registers are picked up by the regular context switch paths. These
231249
// will put us in "mostly the right context" except for frobbing all the
232250
// arguments to the right place. We have the small trampoline code inside of
233251
// rust_bootstrap_green_task to do that.
234-
regs[RUSTRT_RSP] = sp as uint;
235-
regs[RUSTRT_IP] = rust_bootstrap_green_task as uint;
252+
regs.gpr[RUSTRT_RSP] = sp as uint;
253+
regs.gpr[RUSTRT_IP] = rust_bootstrap_green_task as uint;
236254

237255
// Last base pointer on the stack should be 0
238-
regs[RUSTRT_RBP] = 0;
256+
regs.gpr[RUSTRT_RBP] = 0;
239257
}
240258

241259
#[cfg(target_arch = "arm")]

src/libnative/lib.rs

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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/libunwind.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub type _Unwind_Word = libc::uintptr_t;
6060
pub static unwinder_private_data_size: uint = 5;
6161

6262
#[cfg(target_arch = "x86_64")]
63-
pub static unwinder_private_data_size: uint = 2;
63+
pub static unwinder_private_data_size: uint = 6;
6464

6565
#[cfg(target_arch = "arm", not(target_os = "ios"))]
6666
pub static unwinder_private_data_size: uint = 20;

src/librustrt/stack.rs

Lines changed: 24 additions & 8 deletions
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+
127137
#[inline(always)]
128-
pub unsafe fn record_stack_bounds(stack_lo: uint, stack_hi: uint) {
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+
142+
#[inline(always)]
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,16 +153,17 @@ pub unsafe fn record_stack_bounds(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");

src/librustrt/thread.rs

Lines changed: 1 addition & 1 deletion
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)