]> git.proxmox.com Git - rustc.git/blame - src/libstd/sys/windows/stack_overflow.rs
Imported Upstream version 1.0.0~0alpha
[rustc.git] / src / libstd / sys / windows / stack_overflow.rs
CommitLineData
1a4d82fc
JJ
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
11use rt::util::report_overflow;
12use core::prelude::*;
13use ptr;
14use mem;
15use libc;
16use libc::types::os::arch::extra::{LPVOID, DWORD, LONG, BOOL};
17use sys_common::{stack, thread_info};
18
19pub struct Handler {
20 _data: *mut libc::c_void
21}
22
23impl Handler {
24 pub unsafe fn new() -> Handler {
25 make_handler()
26 }
27}
28
29impl 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.
37unsafe fn get_task_guard_page() -> uint {
38 thread_info::stack_guard()
39}
40
41// This is initialized in init() and only read from after
42static mut PAGE_SIZE: uint = 0;
43
44#[no_stack_check]
45extern "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
64pub 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
76pub unsafe fn cleanup() {
77}
78
79pub 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
87pub 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
96pub struct EXCEPTION_POINTERS {
97 pub ExceptionRecord: *mut EXCEPTION_RECORD,
98 pub ContextRecord: LPVOID
99}
100
101pub type PVECTORED_EXCEPTION_HANDLER = extern "system"
102 fn(ExceptionInfo: *mut EXCEPTION_POINTERS) -> LONG;
103
104pub type ULONG = libc::c_ulong;
105
106const EXCEPTION_CONTINUE_SEARCH: LONG = 0;
107const EXCEPTION_MAXIMUM_PARAMETERS: uint = 15;
108const EXCEPTION_STACK_OVERFLOW: DWORD = 0xc00000fd;
109
110extern "system" {
111 fn AddVectoredExceptionHandler(FirstHandler: ULONG,
112 VectoredHandler: PVECTORED_EXCEPTION_HANDLER)
113 -> LPVOID;
114 fn SetThreadStackGuarantee(StackSizeInBytes: *mut ULONG) -> BOOL;
115}