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.
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.
11 use rt::util::report_overflow;
16 use libc::types::os::arch::extra::{LPVOID, DWORD, LONG, BOOL};
17 use sys_common::{stack, thread_info};
20 _data: *mut libc::c_void
24 pub unsafe fn new() -> Handler {
29 impl Drop for Handler {
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
37 unsafe fn get_task_guard_page() -> uint {
38 thread_info::stack_guard()
41 // This is initialized in init() and only read from after
42 static mut PAGE_SIZE: uint = 0;
45 extern "system" fn vectored_handler(ExceptionInfo: *mut EXCEPTION_POINTERS) -> LONG {
47 let rec = &(*(*ExceptionInfo).ExceptionRecord);
48 let code = rec.ExceptionCode;
50 if code != EXCEPTION_STACK_OVERFLOW {
51 return EXCEPTION_CONTINUE_SEARCH;
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);
60 EXCEPTION_CONTINUE_SEARCH
64 pub unsafe fn init() {
65 let mut info = mem::zeroed();
66 libc::GetSystemInfo(&mut info);
67 PAGE_SIZE = info.dwPageSize as uint;
69 if AddVectoredExceptionHandler(0, vectored_handler) == ptr::null_mut() {
70 panic!("failed to install exception handler");
73 mem::forget(make_handler());
76 pub unsafe fn cleanup() {
79 pub unsafe fn make_handler() -> Handler {
80 if SetThreadStackGuarantee(&mut 0x5000) == 0 {
81 panic!("failed to reserve stack space for exception handling");
84 Handler { _data: 0i as *mut libc::c_void }
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]
96 pub struct EXCEPTION_POINTERS {
97 pub ExceptionRecord: *mut EXCEPTION_RECORD,
98 pub ContextRecord: LPVOID
101 pub type PVECTORED_EXCEPTION_HANDLER = extern "system"
102 fn(ExceptionInfo: *mut EXCEPTION_POINTERS) -> LONG;
104 pub type ULONG = libc::c_ulong;
106 const EXCEPTION_CONTINUE_SEARCH: LONG = 0;
107 const EXCEPTION_MAXIMUM_PARAMETERS: uint = 15;
108 const EXCEPTION_STACK_OVERFLOW: DWORD = 0xc00000fd;
111 fn AddVectoredExceptionHandler(FirstHandler: ULONG,
112 VectoredHandler: PVECTORED_EXCEPTION_HANDLER)
114 fn SetThreadStackGuarantee(StackSizeInBytes: *mut ULONG) -> BOOL;