OSDN Git Service

Work around another C++11 compliance issue; fix bug [#2321].
[mingw/mingw-org-wsl.git] / mingwrt / include / excpt.h
1 /*
2  * excpt.h
3  *
4  * Experimental support for operating system level structured handling
5  * of exceptions.
6  *
7  * $Id$
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$: end of file */