]> git.lizzy.rs Git - rust.git/blob - src/libstd/sys/windows/stack_overflow.rs
rollup merge of #20350: fhahn/issue-20340-rustdoc-version
[rust.git] / src / libstd / sys / windows / stack_overflow.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use rt::util::report_overflow;
12 use core::prelude::*;
13 use ptr;
14 use mem;
15 use libc;
16 use libc::types::os::arch::extra::{LPVOID, DWORD, LONG, BOOL};
17 use sys_common::stack;
18
19 pub struct Handler {
20     _data: *mut libc::c_void
21 }
22
23 impl Handler {
24     pub unsafe fn new() -> Handler {
25         make_handler()
26     }
27 }
28
29 impl Drop for Handler {
30     fn drop(&mut self) {}
31 }
32
33 // This is initialized in init() and only read from after
34 static mut PAGE_SIZE: uint = 0;
35
36 #[no_stack_check]
37 extern "system" fn vectored_handler(ExceptionInfo: *mut EXCEPTION_POINTERS) -> LONG {
38     unsafe {
39         let rec = &(*(*ExceptionInfo).ExceptionRecord);
40         let code = rec.ExceptionCode;
41
42         if code != EXCEPTION_STACK_OVERFLOW {
43             return EXCEPTION_CONTINUE_SEARCH;
44         }
45
46         // We're calling into functions with stack checks,
47         // however stack checks by limit should be disabled on Windows
48         stack::record_sp_limit(0);
49
50         report_overflow();
51
52         EXCEPTION_CONTINUE_SEARCH
53     }
54 }
55
56 pub unsafe fn init() {
57     let mut info = mem::zeroed();
58     libc::GetSystemInfo(&mut info);
59     PAGE_SIZE = info.dwPageSize as uint;
60
61     if AddVectoredExceptionHandler(0, vectored_handler) == ptr::null_mut() {
62         panic!("failed to install exception handler");
63     }
64
65     mem::forget(make_handler());
66 }
67
68 pub unsafe fn cleanup() {
69 }
70
71 pub unsafe fn make_handler() -> Handler {
72     if SetThreadStackGuarantee(&mut 0x5000) == 0 {
73         panic!("failed to reserve stack space for exception handling");
74     }
75
76     Handler { _data: 0i as *mut libc::c_void }
77 }
78
79 pub struct EXCEPTION_RECORD {
80     pub ExceptionCode: DWORD,
81     pub ExceptionFlags: DWORD,
82     pub ExceptionRecord: *mut EXCEPTION_RECORD,
83     pub ExceptionAddress: LPVOID,
84     pub NumberParameters: DWORD,
85     pub ExceptionInformation: [LPVOID, ..EXCEPTION_MAXIMUM_PARAMETERS]
86 }
87
88 pub struct EXCEPTION_POINTERS {
89     pub ExceptionRecord: *mut EXCEPTION_RECORD,
90     pub ContextRecord: LPVOID
91 }
92
93 pub type PVECTORED_EXCEPTION_HANDLER = extern "system"
94         fn(ExceptionInfo: *mut EXCEPTION_POINTERS) -> LONG;
95
96 pub type ULONG = libc::c_ulong;
97
98 const EXCEPTION_CONTINUE_SEARCH: LONG = 0;
99 const EXCEPTION_MAXIMUM_PARAMETERS: uint = 15;
100 const EXCEPTION_STACK_OVERFLOW: DWORD = 0xc00000fd;
101
102 extern "system" {
103     fn AddVectoredExceptionHandler(FirstHandler: ULONG,
104                                    VectoredHandler: PVECTORED_EXCEPTION_HANDLER)
105                                   -> LPVOID;
106     fn SetThreadStackGuarantee(StackSizeInBytes: *mut ULONG) -> BOOL;
107 }