about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/middle/trans/context.rs2
-rw-r--r--src/librustdoc/lib.rs42
-rw-r--r--src/librustrt/stack.rs19
-rw-r--r--src/libstd/rand/os.rs40
-rw-r--r--src/test/run-pass/issue-13259-windows-tcb-trash.rs48
-rw-r--r--src/test/run-pass/out-of-stack.rs10
6 files changed, 63 insertions, 98 deletions
diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs
index 962f97ab74c..5c8c6a24b4f 100644
--- a/src/librustc/middle/trans/context.rs
+++ b/src/librustc/middle/trans/context.rs
@@ -546,7 +546,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
     // but it could be enabled (with patched LLVM)
     pub fn is_split_stack_supported(&self) -> bool {
         let ref cfg = self.sess().targ_cfg;
-        cfg.os != abi::OsiOS || cfg.arch != abi::Arm
+        (cfg.os != abi::OsiOS || cfg.arch != abi::Arm) && cfg.os != abi::OsWindows
     }
 
 
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 237a88ded71..71d00e50af8 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -89,47 +89,7 @@ local_data_key!(pub analysiskey: core::CrateAnalysis)
 type Output = (clean::Crate, Vec<plugins::PluginJson> );
 
 pub fn main() {
-    // Why run rustdoc in a separate task? That's a good question!
-    //
-    // We first begin our adventure at the ancient commit of e7c4fb69. In this
-    // commit it was discovered that the stack limit frobbing on windows ended
-    // up causing some syscalls to fail. This was worked around manually in the
-    // relevant location.
-    //
-    // Our journey now continues with #13259 where it was discovered that this
-    // stack limit frobbing has the ability to affect nearly any syscall. Note
-    // that the key idea here is that there is currently no knowledge as to why
-    // this is happening or how to preserve it, fun times!
-    //
-    // Now we continue along to #16275 where it was discovered that --test on
-    // windows didn't work at all! Yet curiously rustdoc worked without --test.
-    // The exact reason that #16275 cropped up is that during the expansion
-    // phase the compiler attempted to open libstd to read out its macros. This
-    // invoked the LLVMRustOpenArchive shim which in turned went to LLVM to go
-    // open a file and read it. Lo and behold this function returned an error!
-    // It was then discovered that when the same fix mentioned in #13259 was
-    // applied, the error went away. The plot thickens!
-    //
-    // Remember that rustdoc works without --test, which raises the question of
-    // how because the --test and non --test paths are almost identical. The
-    // first thing both paths do is parse and expand a crate! It turns out that
-    // the difference is that --test runs on the *main task* while the normal
-    // path runs in subtask. It turns out that running --test in a sub task also
-    // fixes the problem!
-    //
-    // So, in summary, it is unknown why this is necessary, what it is
-    // preventing, or what the actual bug is. In the meantime, this allows
-    // --test to work on windows, which seems good, right? Fun times.
-    let (tx, rx) = channel();
-    spawn(proc() {
-        std::os::set_exit_status(main_args(std::os::args().as_slice()));
-        tx.send(());
-    });
-
-    // If the task failed, set an error'd exit status
-    if rx.recv_opt().is_err() {
-        std::os::set_exit_status(std::rt::DEFAULT_ERROR_CODE);
-    }
+    std::os::set_exit_status(main_args(std::os::args().as_slice()));
 }
 
 pub fn opts() -> Vec<getopts::OptGroup> {
diff --git a/src/librustrt/stack.rs b/src/librustrt/stack.rs
index 3190e9f7841..a4cbbf24811 100644
--- a/src/librustrt/stack.rs
+++ b/src/librustrt/stack.rs
@@ -200,11 +200,7 @@ pub unsafe fn record_sp_limit(limit: uint) {
         asm!("movq $0, %fs:112" :: "r"(limit) :: "volatile")
     }
     #[cfg(target_arch = "x86_64", target_os = "windows")] #[inline(always)]
-    unsafe fn target_record_sp_limit(limit: uint) {
-        // see: http://en.wikipedia.org/wiki/Win32_Thread_Information_Block
-        // store this inside of the "arbitrary data slot", but double the size
-        // because this is 64 bit instead of 32 bit
-        asm!("movq $0, %gs:0x28" :: "r"(limit) :: "volatile")
+    unsafe fn target_record_sp_limit(_: uint) {
     }
     #[cfg(target_arch = "x86_64", target_os = "freebsd")] #[inline(always)]
     unsafe fn target_record_sp_limit(limit: uint) {
@@ -228,10 +224,7 @@ pub unsafe fn record_sp_limit(limit: uint) {
         asm!("movl $0, %gs:48" :: "r"(limit) :: "volatile")
     }
     #[cfg(target_arch = "x86", target_os = "windows")] #[inline(always)]
-    unsafe fn target_record_sp_limit(limit: uint) {
-        // see: http://en.wikipedia.org/wiki/Win32_Thread_Information_Block
-        // store this inside of the "arbitrary data slot"
-        asm!("movl $0, %fs:0x14" :: "r"(limit) :: "volatile")
+    unsafe fn target_record_sp_limit(_: uint) {
     }
 
     // mips, arm - Some brave soul can port these to inline asm, but it's over
@@ -282,9 +275,7 @@ pub unsafe fn get_sp_limit() -> uint {
     }
     #[cfg(target_arch = "x86_64", target_os = "windows")] #[inline(always)]
     unsafe fn target_get_sp_limit() -> uint {
-        let limit;
-        asm!("movq %gs:0x28, $0" : "=r"(limit) ::: "volatile");
-        return limit;
+        return 1024;
     }
     #[cfg(target_arch = "x86_64", target_os = "freebsd")] #[inline(always)]
     unsafe fn target_get_sp_limit() -> uint {
@@ -318,9 +309,7 @@ pub unsafe fn get_sp_limit() -> uint {
     }
     #[cfg(target_arch = "x86", target_os = "windows")] #[inline(always)]
     unsafe fn target_get_sp_limit() -> uint {
-        let limit;
-        asm!("movl %fs:0x14, $0" : "=r"(limit) ::: "volatile");
-        return limit;
+        return 1024;
     }
 
     // mips, arm - Some brave soul can port these to inline asm, but it's over
diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs
index 95be3191bab..120ace1c36a 100644
--- a/src/libstd/rand/os.rs
+++ b/src/libstd/rand/os.rs
@@ -136,7 +136,6 @@ mod imp {
     use os;
     use rand::Rng;
     use result::{Ok, Err};
-    use rt::stack;
     use self::libc::{DWORD, BYTE, LPCSTR, BOOL};
     use self::libc::types::os::arch::extra::{LONG_PTR};
     use slice::MutableSlice;
@@ -159,7 +158,6 @@ mod imp {
     static PROV_RSA_FULL: DWORD = 1;
     static CRYPT_SILENT: DWORD = 64;
     static CRYPT_VERIFYCONTEXT: DWORD = 0xF0000000;
-    static NTE_BAD_SIGNATURE: DWORD = 0x80090006;
 
     #[allow(non_snake_case)]
     extern "system" {
@@ -178,48 +176,12 @@ mod imp {
         /// Create a new `OsRng`.
         pub fn new() -> IoResult<OsRng> {
             let mut hcp = 0;
-            let mut ret = unsafe {
+            let ret = unsafe {
                 CryptAcquireContextA(&mut hcp, 0 as LPCSTR, 0 as LPCSTR,
                                      PROV_RSA_FULL,
                                      CRYPT_VERIFYCONTEXT | CRYPT_SILENT)
             };
 
-            // FIXME #13259:
-            // It turns out that if we can't acquire a context with the
-            // NTE_BAD_SIGNATURE error code, the documentation states:
-            //
-            //     The provider DLL signature could not be verified. Either the
-            //     DLL or the digital signature has been tampered with.
-            //
-            // Sounds fishy, no? As it turns out, our signature can be bad
-            // because our Thread Information Block (TIB) isn't exactly what it
-            // expects. As to why, I have no idea. The only data we store in the
-            // TIB is the stack limit for each thread, but apparently that's
-            // enough to make the signature valid.
-            //
-            // Furthermore, this error only happens the *first* time we call
-            // CryptAcquireContext, so we don't have to worry about future
-            // calls.
-            //
-            // Anyway, the fix employed here is that if we see this error, we
-            // pray that we're not close to the end of the stack, temporarily
-            // set the stack limit to 0 (what the TIB originally was), acquire a
-            // context, and then reset the stack limit.
-            //
-            // Again, I'm not sure why this is the fix, nor why we're getting
-            // this error. All I can say is that this seems to allow libnative
-            // to progress where it otherwise would be hindered. Who knew?
-            if ret == 0 && os::errno() as DWORD == NTE_BAD_SIGNATURE {
-                unsafe {
-                    let limit = stack::get_sp_limit();
-                    stack::record_sp_limit(0);
-                    ret = CryptAcquireContextA(&mut hcp, 0 as LPCSTR, 0 as LPCSTR,
-                                               PROV_RSA_FULL,
-                                               CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
-                    stack::record_sp_limit(limit);
-                }
-            }
-
             if ret == 0 {
                 Err(IoError::last_error())
             } else {
diff --git a/src/test/run-pass/issue-13259-windows-tcb-trash.rs b/src/test/run-pass/issue-13259-windows-tcb-trash.rs
new file mode 100644
index 00000000000..1a909db92e3
--- /dev/null
+++ b/src/test/run-pass/issue-13259-windows-tcb-trash.rs
@@ -0,0 +1,48 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern crate libc;
+
+#[cfg(windows)]
+mod imp {
+    use libc::{c_void, LPVOID, DWORD};
+    use libc::types::os::arch::extra::LPWSTR;
+
+    extern "system" {
+        fn FormatMessageW(flags: DWORD,
+                          lpSrc: LPVOID,
+                          msgId: DWORD,
+                          langId: DWORD,
+                          buf: LPWSTR,
+                          nsize: DWORD,
+                          args: *const c_void)
+                          -> DWORD;
+    }
+
+    pub fn test() {
+        let mut buf: [u16, ..50] = [0, ..50];
+        let ret = unsafe {
+            FormatMessageW(0x1000, 0 as *mut c_void, 1, 0x400,
+                           buf.as_mut_ptr(), buf.len() as u32, 0 as *const c_void)
+        };
+        // On some 32-bit Windowses (Win7-8 at least) this will fail with segmented
+        // stacks taking control of pvArbitrary
+        assert!(ret != 0);
+    }
+}
+
+#[cfg(not(windows))]
+mod imp {
+    pub fn test() { }
+}
+
+fn main() {
+    imp::test()
+}
diff --git a/src/test/run-pass/out-of-stack.rs b/src/test/run-pass/out-of-stack.rs
index 7f2f9f9ece8..bbaa09bfac3 100644
--- a/src/test/run-pass/out-of-stack.rs
+++ b/src/test/run-pass/out-of-stack.rs
@@ -42,11 +42,17 @@ fn main() {
         let silent = Command::new(args[0].as_slice()).arg("silent").output().unwrap();
         assert!(!silent.status.success());
         let error = String::from_utf8_lossy(silent.error.as_slice());
-        assert!(error.as_slice().contains("has overflowed its stack"));
+        // FIXME #17562: Windows is using stack probes and isn't wired up to print an error
+        if !cfg!(windows) {
+            assert!(error.as_slice().contains("has overflowed its stack"));
+        }
 
         let loud = Command::new(args[0].as_slice()).arg("loud").output().unwrap();
         assert!(!loud.status.success());
         let error = String::from_utf8_lossy(silent.error.as_slice());
-        assert!(error.as_slice().contains("has overflowed its stack"));
+        // FIXME #17562: Windows is using stack probes and isn't wired up to print an error
+        if !cfg!(windows) {
+            assert!(error.as_slice().contains("has overflowed its stack"));
+        }
     }
 }