]> git.proxmox.com Git - rustc.git/blob - src/libstd/sys/windows/stack_overflow.rs
79b7de4f341ac07280d7d69a5c28faa44266f75d
[rustc.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: usize = 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 usize;
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: 0 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: usize = 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 }