source: trunk/include/excpt.h@ 21381

Last change on this file since 21381 was 21381, checked in by dmik, 15 years ago

Implemented compiler-level SEH (try/catch) support for GCC.

File size: 5.5 KB
Line 
1/*
2 * Project Odin Software License can be found in LICENSE.TXT
3 *
4 * Compiler-level Win32 SEH support for OS/2
5 *
6 * Copyright 2010 Dmitry A. Kuminov
7 */
8
9#ifndef __EXCPT_H__
10#define __EXCPT_H__
11
12#include "winnt.h"
13
14#ifdef __cplusplus
15extern "C" {
16#endif
17
18#if defined(__GNUC__)
19
20struct ___seh_PEXCEPTION_FRAME;
21typedef int (*__seh_PEXCEPTION_HANDLER)(PEXCEPTION_RECORD,
22 struct ___seh_PEXCEPTION_FRAME *,
23 PCONTEXT, PVOID);
24
25typedef struct ___seh_PEXCEPTION_FRAME
26{
27 struct ___seh_PEXCEPTION_FRAME *pPrev;
28 __seh_PEXCEPTION_HANDLER pHandler;
29 void *pFilterCallback;
30 void *pHandlerCallback;
31 void *pHandlerContext;
32 int filterResult;
33 DWORD pTryRegs[6]; /* EBX/ESI/EDI/EBP/ESP/ExceptionHandler */
34 EXCEPTION_POINTERS Pointers;
35 int state;
36}
37__seh_PEXCEPTION_FRAME;
38
39int __seh_handler(PEXCEPTION_RECORD pRec,
40 struct ___seh_PEXCEPTION_FRAME *pFrame,
41 PCONTEXT pContext, PVOID pVoid);
42
43#define GetExceptionCode() (__seh_frame.Pointers.ExceptionRecord->ExceptionCode)
44#define GetExceptionInformation() (&__seh_frame.Pointers)
45
46#define __try \
47 volatile __seh_PEXCEPTION_FRAME __seh_frame; \
48 for (__seh_frame.state = 0; __seh_frame.state <= 3; ++__seh_frame.state) \
49 if (__seh_frame.state == 0) \
50 { \
51 __label__ __seh_label_filter; \
52 __label__ __seh_label_except; \
53 \
54 /* install exception handler */ \
55 __asm__ ("\n.extern ___seh_handler\n" \
56 "" \
57 "leal %0, %%ecx; " \
58 "movl %%fs:0, %%eax; " \
59 "movl %%eax, 0(%%ecx); " \
60 "movl $___seh_handler, %%eax; " \
61 "movl %%eax, 4(%%ecx); " \
62 "movl $0f, %%eax; " \
63 "movl %%eax, 8(%%ecx); " \
64 "" \
65 "movl %%ebx, 24(%%ecx); " \
66 "movl %%esi, 28(%%ecx); " \
67 "movl %%edi, 32(%%ecx); " \
68 "movl %%ebp, 36(%%ecx); " \
69 "movl %%esp, 40(%%ecx); " \
70 "" \
71 "pushl %%fs; " \
72 "pushl $Dos32TIB; " \
73 "popl %%fs; " \
74 "movl %%fs:0, %%eax; " \
75 "movl %%eax, 44(%%ecx); " \
76 "popl %%fs; " \
77 "" \
78 "movl %%ecx, %%fs:0; " \
79 : : "m" (__seh_frame) \
80 : "%eax", "%ecx"); \
81 {
82
83#define __except(filter_expr) \
84 } \
85 __seh_frame.state = 2; \
86 __asm__("\n0:\n"); /* pFilterCallback */ \
87 continue; \
88 } \
89 else if (__seh_frame.state == 1) { \
90 __seh_frame.filterResult = (filter_expr); \
91 __asm__("leal %0, %%ebx; jmp *%1" \
92 : : "m"(__seh_frame), "m"(__seh_frame.pHandlerCallback) \
93 : "%ebx"); \
94 } \
95 else if (__seh_frame.state == 3) \
96 /* remove exception handler */ \
97 __asm__ ("movl %%fs:0, %%eax; " \
98 "movl 0(%%eax), %%eax; " \
99 "movl %%eax, %%fs:0; " \
100 : : \
101 : "%eax"); \
102 else /* __seh_frame.state == 2 */
103
104#else /* defined(__GNUC__) */
105
106#warning "Structured exception handling is not supported for this compiler!"
107
108#endif /* defined(__GNUC__) */
109
110#ifdef __cplusplus
111}
112#endif
113
114#endif /* __EXCPT_H__ */
Note: See TracBrowser for help on using the repository browser.