]> git.lizzy.rs Git - rust.git/blob - src/libstd/sys/windows/stack_overflow.rs
Add verbose option to rustdoc in order to fix problem with --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, thread_info};
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 // get_task_info is called from an exception / signal handler.
34 // It returns the guard page of the current task or 0 if that
35 // guard page doesn't exist. None is returned if there's currently
36 // no local task.
37 unsafe fn get_task_guard_page() -> uint {
38     thread_info::stack_guard()
39 }
40
41 // This is initialized in init() and only read from after
42 static mut PAGE_SIZE: uint = 0;
43
44 #[no_stack_check]
45 extern "system" fn vectored_handler(ExceptionInfo: *mut EXCEPTION_POINTERS) -> LONG {
46     unsafe {
47         let rec = &(*(*ExceptionInfo).ExceptionRecord);
48         let code = rec.ExceptionCode;
49
50         if code != EXCEPTION_STACK_OVERFLOW {
51             return EXCEPTION_CONTINUE_SEARCH;
52         }
53
54         // We're calling into functions with stack checks,
55         // however stack checks by limit should be disabled on Windows
56         stack::record_sp_limit(0);
57
58         report_overflow();
59
60         EXCEPTION_CONTINUE_SEARCH
61     }
62 }
63
64 pub unsafe fn init() {
65     let mut info = mem::zeroed();
66     libc::GetSystemInfo(&mut info);
67     PAGE_SIZE = info.dwPageSize as uint;
68
69     if AddVectoredExceptionHandler(0, vectored_handler) == ptr::null_mut() {
70         panic!("failed to install exception handler");
71     }
72
73     mem::forget(make_handler());
74 }
75
76 pub unsafe fn cleanup() {
77 }
78
79 pub unsafe fn make_handler() -> Handler {
80     if SetThreadStackGuarantee(&mut 0x5000) == 0 {
81         panic!("failed to reserve stack space for exception handling");
82     }
83
84     Handler { _data: 0i as *mut libc::c_void }
85 }
86
87 pub struct EXCEPTION_RECORD {
88     pub ExceptionCode: DWORD,
89     pub ExceptionFlags: DWORD,
90     pub ExceptionRecord: *mut EXCEPTION_RECORD,
91     pub ExceptionAddress: LPVOID,
92     pub NumberParameters: DWORD,
93     pub ExceptionInformation: [LPVOID, ..EXCEPTION_MAXIMUM_PARAMETERS]
94 }
95
96 pub struct EXCEPTION_POINTERS {
97     pub ExceptionRecord: *mut EXCEPTION_RECORD,
98     pub ContextRecord: LPVOID
99 }
100
101 pub type PVECTORED_EXCEPTION_HANDLER = extern "system"
102         fn(ExceptionInfo: *mut EXCEPTION_POINTERS) -> LONG;
103
104 pub type ULONG = libc::c_ulong;
105
106 const EXCEPTION_CONTINUE_SEARCH: LONG = 0;
107 const EXCEPTION_MAXIMUM_PARAMETERS: uint = 15;
108 const EXCEPTION_STACK_OVERFLOW: DWORD = 0xc00000fd;
109
110 extern "system" {
111     fn AddVectoredExceptionHandler(FirstHandler: ULONG,
112                                    VectoredHandler: PVECTORED_EXCEPTION_HANDLER)
113                                   -> LPVOID;
114     fn SetThreadStackGuarantee(StackSizeInBytes: *mut ULONG) -> BOOL;
115 }