1 |
/* |
2 |
* excpt.h |
3 |
* |
4 |
* Experimental support for operating system level structured handling |
5 |
* of exceptions. |
6 |
* |
7 |
* $Id: excpt.h,v 14fc79433294 2016/06/28 13:50:38 keithmarshall $ |
8 |
* |
9 |
* Written by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> |
10 |
* Revised by Keith Marshall <keithmarshall@users.sourceforge.net> |
11 |
* Copyright (C) 1997, 1999, 2001-2002, 2004, 2007, 2012, 2016, |
12 |
* MinGW.org Project. |
13 |
* |
14 |
* |
15 |
* Permission is hereby granted, free of charge, to any person obtaining a |
16 |
* copy of this software and associated documentation files (the "Software"), |
17 |
* to deal in the Software without restriction, including without limitation |
18 |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
19 |
* and/or sell copies of the Software, and to permit persons to whom the |
20 |
* Software is furnished to do so, subject to the following conditions: |
21 |
* |
22 |
* The above copyright notice, this permission notice, and the following |
23 |
* disclaimer shall be included in all copies or substantial portions of |
24 |
* the Software. |
25 |
* |
26 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
27 |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
28 |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
29 |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
30 |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
31 |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER |
32 |
* DEALINGS IN THE SOFTWARE. |
33 |
* |
34 |
*/ |
35 |
#ifndef _EXCPT_H |
36 |
#pragma GCC system_header |
37 |
#define _EXCPT_H |
38 |
|
39 |
/* FIXME: this utility macro, to allocate stack space for any aggregate |
40 |
* data type, with an explicit type cast of a pointer to that data type, |
41 |
* deserves a place in a more universally accessible header file. The |
42 |
* type cast is not strictly necessary for C, (but is permitted); it is |
43 |
* essential for C++. |
44 |
*/ |
45 |
#define __typecast_alloca(type) (type *)(__builtin_alloca( sizeof(type) )) |
46 |
|
47 |
/* All MinGW CRT headers are required to include <_mingw.h> |
48 |
*/ |
49 |
#include <_mingw.h> |
50 |
|
51 |
/* Exception handler functions require definitions of _CONTEXT, and |
52 |
* _EXCEPTION_RECORD structures, which are provided in <windef.h> |
53 |
*/ |
54 |
#include <windef.h> |
55 |
|
56 |
#ifndef _EXCPT_W32API_H |
57 |
/* FIXME: These constants, structs, and typedefs should be defined |
58 |
* in the Win32 API headers; (we need to establish where -- perhaps |
59 |
* this header itself should be redesignated as a W32API header). |
60 |
*/ |
61 |
#define EH_NONCONTINUABLE 0x01 |
62 |
#define EH_UNWINDING 0x02 |
63 |
#define EH_EXIT_UNWIND 0x04 |
64 |
#define EH_STACK_INVALID 0x08 |
65 |
#define EH_NESTED_CALL 0x10 |
66 |
|
67 |
#ifndef RC_INVOKED |
68 |
|
69 |
typedef enum |
70 |
{ ExceptionContinueExecution, |
71 |
ExceptionContinueSearch, |
72 |
ExceptionNestedException, |
73 |
ExceptionCollidedUnwind |
74 |
} EXCEPTION_DISPOSITION; |
75 |
|
76 |
#endif /* ! RC_INVOKED */ |
77 |
#endif /* !_EXCPT_W2API_H */ |
78 |
|
79 |
#ifndef RC_INVOKED |
80 |
|
81 |
_BEGIN_C_DECLS |
82 |
|
83 |
/* The type of function that is expected as an exception handler, |
84 |
* to be installed by the __try1(__handler) primitive. |
85 |
*/ |
86 |
typedef EXCEPTION_DISPOSITION (*PEXCEPTION_HANDLER) |
87 |
(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *); |
88 |
|
89 |
typedef struct _EXCEPTION_REGISTRATION |
90 |
{ /* Maps the structure of the exception handler registration |
91 |
* block, as installed by the __try1(__handler) primitive. |
92 |
*/ |
93 |
struct _EXCEPTION_REGISTRATION *prev; |
94 |
PEXCEPTION_HANDLER handler; |
95 |
} EXCEPTION_REGISTRATION, *PEXCEPTION_REGISTRATION; |
96 |
|
97 |
/* Aliases which may be preferred, when referring to the |
98 |
* EXCEPTION_REGISTRATION structure. |
99 |
*/ |
100 |
typedef EXCEPTION_REGISTRATION EXCEPTION_REGISTRATION_RECORD; |
101 |
typedef PEXCEPTION_REGISTRATION PEXCEPTION_REGISTRATION_RECORD; |
102 |
|
103 |
/* Deployment of exception handlers is facilitated by the pair |
104 |
* of macros, __try1(_handler) and __except1. |
105 |
* |
106 |
* CAUTION: __try1(__handler) and __except1 must be deployed as |
107 |
* a complementary pair, within the scope of the stack frame of |
108 |
* a single function, with __try1(__handler) preceding the use |
109 |
* of __except1. Failure to invoke __except1 before release of |
110 |
* any stack frame, in which __try1(__handler) has been invoked, |
111 |
* will invalidate the EXCEPTION_REGISTRATION_RECORD, which has |
112 |
* been installed by __try1(_handler), at the head of the active |
113 |
* exception handler chain; this will cause undefined behaviour, |
114 |
* which is sure to go badly. |
115 |
* |
116 |
* To accommodate implementation differences between _WIN32 and |
117 |
* _WIN64 hosts, the actual implementations of __try1(__handler) |
118 |
* and __except1 are expressed in terms of a pair of lower level |
119 |
* internal macros, namely: |
120 |
* |
121 |
* Macro: __try1_setup(__handler,__wsize,__ts) |
122 |
* |
123 |
* Helper for implementation of macro __try1(__handler); allocate |
124 |
* a block of memory, within the stack frame of the calling function, |
125 |
* which is then initialized as an EXCEPTION_REGISTRATION_RECORD, and |
126 |
* linked to the head of the installed exception handler chain. |
127 |
* |
128 |
* Inputs: |
129 |
* __handler pointer to an EXCEPTION_HANDLER function. |
130 |
* __wsize the Intel host word size pointer description. |
131 |
* __ts thread information segment register name. |
132 |
*/ |
133 |
#define __try1_setup(__handler,__wsize,__ts) \ |
134 |
{ EXCEPTION_REGISTRATION *__hook; \ |
135 |
__hook = __typecast_alloca( EXCEPTION_REGISTRATION ); \ |
136 |
__hook->handler = __handler; \ |
137 |
__asm__ __volatile__ \ |
138 |
( "mov{%z0}\t{%%|%0, "__wsize" }"__ts":{|[}0x0{, %0|]}\n\t" \ |
139 |
"mov{%z1}\t{%1, %%|"__wsize" }"__ts":{|[}0x0{|], %1}" \ |
140 |
:"=r"(__hook->prev):"r"(__hook):"memory" \ |
141 |
); \ |
142 |
} |
143 |
|
144 |
/* Macro: __except1_teardown(__wsize,__ts) |
145 |
* |
146 |
* Helper which provides the implementation for the __except1 |
147 |
* complement to __try1(__handler) macro; it unlinks the first |
148 |
* EXCEPTION_REGISTRATION_RECORD from the head of the exception |
149 |
* handler chain. Arguments are as described for those of the |
150 |
* same name, in the __try1_setup macro argument list. |
151 |
*/ |
152 |
#define __except1_teardown(__wsize,__ts) \ |
153 |
{ register EXCEPTION_REGISTRATION *__hook; \ |
154 |
__asm__ __volatile__ \ |
155 |
( "mov{%z0}\t{%%|%0, "__wsize" }"__ts":{|[}0x0{, %0|]}\n\t" \ |
156 |
"mov{%z0}\t{(}%0{)}, {|"__wsize" [}%0{|]}\n\t" \ |
157 |
"mov{%z0}\t{%0, %%|"__wsize" }"__ts":{|[}0x0{|], %0}" \ |
158 |
:"+r"(__hook)::"memory" \ |
159 |
); \ |
160 |
} |
161 |
|
162 |
/* Specialization of the above primitives, creating __try1(__handler), |
163 |
* and its complementary __except1 implementation, with the appropriate |
164 |
* assignments of word size and TIB segment register, for each of... |
165 |
*/ |
166 |
#ifdef _WIN64 |
167 |
/* ...64-bit windows, for which the word size for representation of |
168 |
* pointers, in Intel-syntax code, is "QWORD PTR", and the gs segment |
169 |
* is used for access to the thread information block... |
170 |
*/ |
171 |
# define __try1(__handler) __try1_setup(__handler,"QWORD PTR","gs") |
172 |
# define __except1 __except1_teardown("QWORD PTR","gs") |
173 |
|
174 |
#else /* _WIN32 */ |
175 |
/* ...while in 32-bit windows, the corresponding pointer word size |
176 |
* is "DWORD PTR", and the the thread information block is located |
177 |
* in the fs segment. |
178 |
*/ |
179 |
# define __try1(__handler) __try1_setup(__handler,"DWORD PTR","fs") |
180 |
# define __except1 __except1_teardown("DWORD PTR","fs") |
181 |
#endif |
182 |
|
183 |
_END_C_DECLS |
184 |
|
185 |
#endif /* ! RC_INVOKED */ |
186 |
#endif /* !_EXCPT_H: $RCSfile: excpt.h,v $: end of file */ |