ReactOS 0.4.16-dev-1537-g4e425b5
pseh2.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2008 KJK::Hyperion
3
4 Permission is hereby granted, free of charge, to any person obtaining a
5 copy of this software and associated documentation files (the "Software"),
6 to deal in the Software without restriction, including without limitation
7 the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 and/or sell copies of the Software, and to permit persons to whom the
9 Software is furnished to do so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 DEALINGS IN THE SOFTWARE.
21*/
22
23#ifndef KJK_PSEH2_H_
24#define KJK_PSEH2_H_
25
26#define __USE_PSEH2__
27
28#if defined(_USE_NATIVE_SEH) || defined(_MSC_VER)
29
30#define _SEH2_TRY __try
31#define _SEH2_FINALLY __finally
32#define _SEH2_EXCEPT(...) __except(__VA_ARGS__)
33#define _SEH2_END
34#define _SEH2_GetExceptionInformation() (GetExceptionInformation())
35#define _SEH2_GetExceptionCode() (GetExceptionCode())
36#define _SEH2_AbnormalTermination() (AbnormalTermination())
37#define _SEH2_YIELD(STMT_) STMT_
38#define _SEH2_LEAVE __leave
39#define _SEH2_VOLATILE
40
41#define __endtry
42
43#elif defined(__GNUC__) && !defined(__clang__) && defined(_M_AMD64)
44
45#include "pseh2_64.h"
46
47#elif defined(_USE_DUMMY_PSEH) || defined (__arm__) || defined(_M_AMD64)
48
49#ifdef __cplusplus
50extern"C"
51{
52#endif
53extern int _SEH2_Volatile0;
55#ifdef __cplusplus
56} // extern "C"
57#endif
58
59#define _SEH2_TRY \
60_Pragma("GCC diagnostic push") \
61_Pragma("GCC diagnostic ignored \"-Wunused-label\"")\
62{ \
63 __label__ __seh2_scope_end__;
64
65#define _SEH2_FINALLY \
66 __seh2_scope_end__:; \
67 } \
68 if (1) \
69 { \
70 __label__ __seh2_scope_end__;
71
72#define _SEH2_EXCEPT(...) \
73 __seh2_scope_end__:; \
74 } \
75 if (_SEH2_Volatile0 || (0 && (__VA_ARGS__))) \
76 { \
77 __label__ __seh2_scope_end__;
78
79#define _SEH2_END \
80 __seh2_scope_end__:; \
81 } \
82_Pragma("GCC diagnostic pop")
83
84#define _SEH2_GetExceptionInformation() ((struct _EXCEPTION_POINTERS*)0)
85#define _SEH2_GetExceptionCode() _SEH2_VolatileExceptionCode
86#define _SEH2_AbnormalTermination() (0)
87#define _SEH2_YIELD(STMT_) STMT_
88#define _SEH2_LEAVE goto __seh2_scope_end__;
89#define _SEH2_VOLATILE volatile
90
91#ifndef __try // Conflict with GCC's x64 Linux STL, affects Clang on Linux x64 compilation as well
92#define __try _SEH2_TRY
93#define __except _SEH2_EXCEPT
94#define __finally _SEH2_FINALLY
95#define __endtry _SEH2_END
96#define __leave _SEH2_LEAVE
97#endif
98#define _exception_code() 0
99#define _exception_info() ((void*)0)
100
101#elif defined(_USE_PSEH3)
102
103#include "pseh3.h"
104
105/* Compatibility macros */
106#define _SEH2_TRY _SEH3_TRY
107#define _SEH2_EXCEPT _SEH3_EXCEPT
108#define _SEH2_FINALLY _SEH3_FINALLY
109#define _SEH2_END _SEH3_END
110#define _SEH2_GetExceptionInformation() ((struct _EXCEPTION_POINTERS*)_exception_info())
111#define _SEH2_GetExceptionCode _exception_code
112#define _SEH2_AbnormalTermination _abnormal_termination
113#define _SEH2_LEAVE _SEH3_LEAVE
114#define _SEH2_YIELD(x) x
115#define _SEH2_VOLATILE volatile
116
117#ifndef __try // Conflict with GCC's STL
118#define __try _SEH3_TRY
119#define __except _SEH3_EXCEPT
120#define __finally _SEH3_FINALLY
121#define __endtry _SEH3_END
122#define __leave _SEH3_LEAVE
123#endif
124
125#elif defined(__GNUC__)
126
127struct _EXCEPTION_RECORD;
129struct _CONTEXT;
130
131typedef int (__cdecl * _SEH2FrameHandler_t)
132(
133 struct _EXCEPTION_RECORD *,
134 void *,
135 struct _CONTEXT *,
136 void *
137);
138
139typedef struct __SEH2Registration
140{
141 struct __SEH2Registration * SER_Prev;
142 _SEH2FrameHandler_t SER_Handler;
143}
144_SEH2Registration_t;
145
146typedef struct __SEH2Frame
147{
148 _SEH2Registration_t SF_Registration;
149 volatile struct __SEH2TryLevel * volatile SF_TopTryLevel;
150 volatile unsigned long SF_Code;
151}
152_SEH2Frame_t;
153
154typedef struct __SEH2TryLevel
155{
156 volatile struct __SEH2TryLevel * ST_Next;
157 void * ST_Filter;
158 void * ST_Body;
159}
160_SEH2TryLevel_t;
161
162typedef struct __SEH2HandleTryLevel
163{
164 _SEH2TryLevel_t SHT_Common;
165 void * volatile SHT_Esp;
166 void * volatile SHT_Ebp;
167 void * volatile SHT_Ebx;
168 void * volatile SHT_Esi;
169 void * volatile SHT_Edi;
170}
171_SEH2HandleTryLevel_t;
172
173#ifdef __cplusplus
174extern "C" {
175#endif
176
177extern int __cdecl _SEH2EnterFrameAndTrylevel(_SEH2Frame_t *, volatile _SEH2TryLevel_t *);
178extern __attribute__((returns_twice)) int __cdecl _SEH2EnterFrameAndHandleTrylevel(_SEH2Frame_t *, volatile _SEH2HandleTryLevel_t *, void *);
179extern __attribute__((returns_twice)) int __cdecl _SEH2EnterHandleTrylevel(_SEH2Frame_t *, volatile _SEH2HandleTryLevel_t *, void *);
180extern void __cdecl _SEH2LeaveFrame(void);
181extern void __cdecl _SEH2Return(void);
182
183#ifdef __cplusplus
184}
185#endif
186
187/* Prevent gcc from inlining functions that use SEH. */
188#if ((__GNUC__ >= 4) && (__GNUC_MINOR__ >= 7))
189static inline __attribute__((always_inline)) __attribute__((returns_twice)) void _SEH_DontInline() {}
190#define __PREVENT_GCC_FROM_INLINING_SEH_FUNCTIONS() _SEH_DontInline();
191#else
192#define __PREVENT_GCC_FROM_INLINING_SEH_FUNCTIONS()
193#endif
194
195/* A no-op side effect that scares GCC */
196#define __SEH_SIDE_EFFECT __asm__ __volatile__("#")
197
198/* A no-op without any real side effects, but silences warnings */
199#define __SEH_PRETEND_SIDE_EFFECT (void)0
200
201/* Forces GCC to consider the specified label reachable */
202#define __SEH_USE_LABEL(L_) if(__SEH_VOLATILE_FALSE) goto L_;
203
204/* Makes GCC pretend the specified label is reachable, to silence warnings */
205#define __SEH_PRETEND_USE_LABEL(L_) (void)(&&L_)
206
207/* Soft memory barrier */
208#define __SEH_BARRIER __asm__ __volatile__("#":::"memory")
209
210/* GCC doesn't know that this equals zero */
211#define __SEH_VOLATILE_ZERO ({ int zero = 0; __asm__ __volatile__("#" : "+g" (zero)); zero; })
212
213#define __SEH_VOLATILE_FALSE __builtin_expect(__SEH_VOLATILE_ZERO, 0)
214#define __SEH_VOLATILE_TRUE __builtin_expect(!__SEH_VOLATILE_ZERO, 1)
215
216#define ___SEH_STRINGIFY(X_) # X_
217#define __SEH_STRINGIFY(X_) ___SEH_STRINGIFY(X_)
218
219#define __SEH_EXCEPT_RET long
220#define __SEH_EXCEPT_ARGS __attribute__((unused)) _SEH2Frame_t * _SEH2FrameP, __attribute__((unused)) struct _EXCEPTION_POINTERS * _SEHExceptionInformation
221#define __SEH_EXCEPT_ARGS_ , __SEH_EXCEPT_ARGS
222#define __SEH_EXCEPT_PFN __SEH_DECLARE_EXCEPT_PFN
223#define __SEH_DECLARE_EXCEPT_PFN(NAME_) __SEH_EXCEPT_RET (__cdecl * NAME_)(__SEH_EXCEPT_ARGS)
224#define __SEH_DECLARE_EXCEPT(NAME_) __SEH_EXCEPT_RET __cdecl NAME_(__SEH_EXCEPT_ARGS)
225#define __SEH_DEFINE_EXCEPT(NAME_) __SEH_EXCEPT_RET __cdecl NAME_(__SEH_EXCEPT_ARGS)
226
227#define __SEH_FINALLY_RET void
228#define __SEH_FINALLY_ARGS void
229#define __SEH_FINALLY_ARGS_
230#define __SEH_FINALLY_PFN __SEH_DECLARE_FINALLY_PFN
231#define __SEH_DECLARE_FINALLY_PFN(NAME_) __SEH_FINALLY_RET (__cdecl * NAME_)(__SEH_FINALLY_ARGS)
232#define __SEH_DECLARE_FINALLY(NAME_) __SEH_FINALLY_RET __cdecl NAME_(__SEH_FINALLY_ARGS)
233#define __SEH_DEFINE_FINALLY(NAME_) __SEH_FINALLY_RET __cdecl NAME_(__SEH_FINALLY_ARGS)
234
235#define __SEH_RETURN_EXCEPT(R_) return (long)(R_)
236#define __SEH_RETURN_FINALLY() return
237
238#define __SEH_BEGIN_TRY \
239 { \
240 __label__ _SEHEndTry; \
241 \
242 __SEH_PRETEND_USE_LABEL(_SEHEndTry); \
243 \
244 { \
245 __SEH_BARRIER;
246
247#define __SEH_END_TRY \
248 __SEH_BARRIER; \
249 } \
250 _SEHEndTry:; \
251 }
252
253#define __SEH_SET_TRYLEVEL(TRYLEVEL_) \
254 { \
255 __SEH_BARRIER; _SEH2FrameP->SF_TopTryLevel = (TRYLEVEL_); __SEH_BARRIER; \
256 }
257
258#define __SEH_ENTER_FRAME_AND_TRYLEVEL(TRYLEVEL_) (_SEH2EnterFrameAndTrylevel(_SEH2FrameP, (TRYLEVEL_)))
259#define __SEH_ENTER_TRYLEVEL(TRYLEVEL_) ((__SEH_SET_TRYLEVEL((TRYLEVEL_))), 0)
260
261#define __SEH_ENTER_FRAME_AND_HANDLE_TRYLEVEL(TRYLEVEL_, HANDLE_) _SEH2EnterFrameAndHandleTrylevel(_SEH2FrameP, (TRYLEVEL_), (HANDLE_))
262#define __SEH_ENTER_HANDLE_TRYLEVEL(TRYLEVEL_, HANDLE_) _SEH2EnterHandleTrylevel(_SEH2FrameP, (TRYLEVEL_), (HANDLE_))
263
264#define __SEH_ENTER_SCOPE(TRYLEVEL_) (_SEHTopTryLevel ? __SEH_ENTER_FRAME_AND_TRYLEVEL(TRYLEVEL_) : __SEH_ENTER_TRYLEVEL(TRYLEVEL_))
265#define __SEH_ENTER_HANDLE_SCOPE(TRYLEVEL_, HANDLE_) (({ __SEH_BARRIER; __asm__ __volatile__("mov %%esp, %0" : "=m" ((TRYLEVEL_)->SHT_Esp)); __SEH_BARRIER; }), (_SEHTopTryLevel ? __SEH_ENTER_FRAME_AND_HANDLE_TRYLEVEL((TRYLEVEL_), (HANDLE_)) : __SEH_ENTER_HANDLE_TRYLEVEL((TRYLEVEL_), (HANDLE_))))
266
267#define __SEH_LEAVE_TRYLEVEL() \
268 if(!_SEHTopTryLevel) \
269 { \
270 __SEH_SET_TRYLEVEL(_SEHPrevTryLevelP); \
271 } \
272
273#define __SEH_LEAVE_FRAME() \
274 if(_SEHTopTryLevel) \
275 { \
276 _SEH2LeaveFrame(); \
277 }
278
279#define __SEH_END_SCOPE_CHAIN \
280 static __attribute__((unused)) const int _SEH2ScopeKind = 1; \
281 static __attribute__((unused)) _SEH2Frame_t * const _SEH2FrameP = 0; \
282 static __attribute__((unused)) _SEH2TryLevel_t * const _SEH2TryLevelP = 0;
283
284#define __SEH_BEGIN_SCOPE \
285 for(;;) \
286 { \
287 const int _SEHTopTryLevel = (_SEH2ScopeKind != 0); \
288 _SEH2Frame_t * const _SEHCurFrameP = _SEH2FrameP; \
289 volatile _SEH2TryLevel_t * const _SEHPrevTryLevelP = _SEH2TryLevelP; \
290 __attribute__((unused)) int _SEHAbnormalTermination; \
291 \
292 (void)_SEHTopTryLevel; \
293 (void)_SEHCurFrameP; \
294 (void)_SEHPrevTryLevelP; \
295 \
296 { \
297 __label__ _SEHBeforeTry; \
298 __label__ _SEHDoTry; \
299 __label__ _SEHAfterTry; \
300 static const int _SEH2ScopeKind = 0; \
301 volatile _SEH2TryLevel_t _SEHTryLevel; \
302 volatile _SEH2HandleTryLevel_t _SEHHandleTryLevel; \
303 _SEH2Frame_t _SEH2Frame[_SEHTopTryLevel ? 1 : 0]; \
304 volatile _SEH2TryLevel_t * _SEH2TryLevelP; \
305 _SEH2Frame_t * const _SEH2FrameP = _SEHTopTryLevel ? \
306 _SEH2Frame : _SEHCurFrameP; \
307 \
308 (void)_SEH2ScopeKind; \
309 (void)_SEHTryLevel; \
310 (void)_SEHHandleTryLevel; \
311 (void)_SEH2FrameP; \
312 (void)_SEH2TryLevelP; \
313 \
314 goto _SEHBeforeTry; \
315 \
316 _SEHDoTry:;
317
318#define __SEH_END_SCOPE \
319 } \
320 \
321 break; \
322 }
323
324#define __SEH_SCOPE_LOCALS \
325 __label__ _SEHBeginExcept; \
326 __label__ _SEHEndExcept; \
327 \
328 auto __SEH_DECLARE_FINALLY(_SEHFinally);
329
330#define _SEH2_TRY \
331 __PREVENT_GCC_FROM_INLINING_SEH_FUNCTIONS() \
332 __SEH_BEGIN_SCOPE \
333 { \
334 __SEH_SCOPE_LOCALS; \
335 \
336 __SEH_BEGIN_TRY \
337 {
338
339#define _SEH2_FINALLY \
340 } \
341 __SEH_END_TRY; \
342 \
343 goto _SEHAfterTry; \
344 _SEHBeforeTry:; \
345 \
346 __SEH_PRETEND_USE_LABEL(_SEHBeginExcept); \
347 __SEH_PRETEND_USE_LABEL(_SEHEndExcept); \
348 \
349 _SEHTryLevel.ST_Filter = 0; \
350 _SEHTryLevel.ST_Body = &_SEHFinally; \
351 _SEHTryLevel.ST_Next = _SEHPrevTryLevelP; \
352 __SEH_ENTER_SCOPE(&_SEHTryLevel); \
353 _SEH2TryLevelP = &_SEHTryLevel; \
354 \
355 _SEHAbnormalTermination = 1; \
356 \
357 goto _SEHDoTry; \
358 _SEHAfterTry:; \
359 \
360 _SEHAbnormalTermination = 0; \
361 \
362 __SEH_LEAVE_TRYLEVEL(); \
363 \
364 _SEHFinally(); \
365 goto _SEHEndExcept; \
366 \
367 _SEHBeginExcept:; \
368 \
369 __attribute__((noinline)) __SEH_DEFINE_FINALLY(_SEHFinally) \
370 { \
371 __SEH_END_SCOPE_CHAIN; \
372 \
373 (void)_SEH2ScopeKind; \
374 (void)_SEH2FrameP; \
375 (void)_SEH2TryLevelP; \
376 \
377 for(;; ({ __SEH_RETURN_FINALLY(); })) \
378 {
379
380#define _SEH2_EXCEPT(...) \
381 } \
382 __SEH_END_TRY; \
383 \
384 goto _SEHAfterTry; \
385 \
386 _SEHBeforeTry:; \
387 \
388 { \
389 __attribute__((unused)) struct _EXCEPTION_POINTERS * volatile _SEHExceptionInformation; \
390 \
391 if(__builtin_constant_p((__VA_ARGS__)) && (__VA_ARGS__) <= 0) \
392 { \
393 if((__VA_ARGS__) < 0) \
394 { \
395 _SEHTryLevel.ST_Filter = (void *)-1; \
396 _SEHTryLevel.ST_Body = 0; \
397 } \
398 else \
399 { \
400 _SEHTryLevel.ST_Filter = (void *)0; \
401 _SEHTryLevel.ST_Body = 0; \
402 } \
403 \
404 _SEHTryLevel.ST_Next = _SEHPrevTryLevelP; \
405 __SEH_ENTER_SCOPE(&_SEHTryLevel); \
406 _SEH2TryLevelP = &_SEHTryLevel; \
407 } \
408 else \
409 { \
410 if(__builtin_constant_p((__VA_ARGS__)) && (__VA_ARGS__) > 0) \
411 _SEHHandleTryLevel.SHT_Common.ST_Filter = (void *)1; \
412 else \
413 { \
414 __SEH_DEFINE_EXCEPT(_SEHExcept) \
415 { \
416 __SEH_RETURN_EXCEPT((__VA_ARGS__)); \
417 } \
418 \
419 _SEHHandleTryLevel.SHT_Common.ST_Filter = &_SEHExcept; \
420 } \
421 \
422 _SEHHandleTryLevel.SHT_Common.ST_Next = _SEHPrevTryLevelP; \
423 _SEH2TryLevelP = &_SEHHandleTryLevel.SHT_Common; \
424 \
425 if(__builtin_expect(__SEH_ENTER_HANDLE_SCOPE(&_SEHHandleTryLevel, &&_SEHBeginExcept), 0)) \
426 goto _SEHBeginExcept; \
427 } \
428 } \
429 \
430 goto _SEHDoTry; \
431 \
432 __attribute__((unused)) __SEH_DEFINE_FINALLY(_SEHFinally) { __SEH_RETURN_FINALLY(); } \
433 \
434 _SEHAfterTry:; \
435 __SEH_LEAVE_TRYLEVEL(); \
436 \
437 goto _SEHEndExcept; \
438 \
439 _SEHBeginExcept:; \
440 { \
441 { \
442 __SEH_BARRIER;
443
444#define _SEH2_END \
445 __SEH_BARRIER; \
446 } \
447 } \
448 \
449 _SEHEndExcept:; \
450 \
451 __SEH_LEAVE_FRAME(); \
452 } \
453 __SEH_END_SCOPE;
454
455#define _SEH2_GetExceptionInformation() (_SEHExceptionInformation)
456#define _SEH2_GetExceptionCode() ((_SEH2FrameP)->SF_Code)
457#define _SEH2_AbnormalTermination() (_SEHAbnormalTermination)
458
459#define _SEH2_YIELD(STMT_) \
460 for(;;) \
461 { \
462 if(!_SEH2ScopeKind) \
463 _SEH2Return(); \
464 \
465 STMT_; \
466 }
467
468#define _SEH2_LEAVE goto _SEHEndTry
469
470__SEH_END_SCOPE_CHAIN;
471
472#define _SEH2_VOLATILE volatile
473
474#else
475#error no PSEH support
476#endif
477
478#endif /* !KJK_PSEH2_H_ */
479
480/* EOF */
#define __cdecl
Definition: accygwin.h:79
#define __attribute__(x)
Definition: wpp_private.h:207
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
int _SEH2_VolatileExceptionCode
Definition: dummy.c:4
int _SEH2_Volatile0
Definition: dummy.c:3
int __cdecl _SEH2EnterFrameAndTrylevel(_SEH2Frame_t *frame, volatile _SEH2TryLevel_t *trylevel)
void __cdecl _SEH2Return(void)
void __cdecl _SEH2LeaveFrame(void)