source: trunk/include/excpt.h@ 21427

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

SEH: Save EXCEPTION_RECORD and CONTEXT on heap when jumping back from the exception handler to execute the except() filter expression because they are stored on stack and may be overwritten during execution of the filter expression. This fixes garbage in structures pointed to by _exception_info()'s pointers.

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 <windows.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 _exception_code() (__seh_frame.Pointers.ExceptionRecord->ExceptionCode)
44#define _exception_info() (&__seh_frame.Pointers)
45
46#define GetExceptionCode _exception_code
47#define GetExceptionInformation _exception_info
48
49#define __try \
50 volatile __seh_PEXCEPTION_FRAME __seh_frame; \
51 __seh_frame.Pointers.ExceptionRecord = NULL; \
52 __seh_frame.Pointers.ContextRecord = NULL; \
53 __seh_frame.state = 0; \
54 __asm__("\n0:\n"); /* pFilterCallback */ \
55 for (; __seh_frame.state <= 3; ++__seh_frame.state) \
56 if (__seh_frame.state == 0) \
57 { \
58 /* install exception handler */ \
59 __asm__ ("\n.extern ___seh_handler\n" \
60 "" \
61 "leal %0, %%ecx; " \
62 "movl %%fs:0, %%eax; " \
63 "movl %%eax, 0(%%ecx); " \
64 "movl $___seh_handler, %%eax; " \
65 "movl %%eax, 4(%%ecx); " \
66 "movl $0b, 8(%%ecx); " \
67 "" \
68 "movl %%ebx, 24(%%ecx); " \
69 "movl %%esi, 28(%%ecx); " \
70 "movl %%edi, 32(%%ecx); " \
71 "movl %%ebp, 36(%%ecx); " \
72 "movl %%esp, 40(%%ecx); " \
73 "" \
74 "pushl %%fs; " \
75 "pushl $Dos32TIB; " \
76 "popl %%fs; " \
77 "movl %%fs:0, %%eax; " \
78 "movl %%eax, 44(%%ecx); " \
79 "popl %%fs; " \
80 "" \
81 "movl %%ecx, %%fs:0; " \
82 : : "m" (__seh_frame) \
83 : "%eax", "%ecx"); \
84 {
85
86#define __except(filter_expr) \
87 } \
88 __seh_frame.state = 2; \
89 } \
90 else if (__seh_frame.state == 1) { \
91 __seh_frame.filterResult = (filter_expr); \
92 __asm__("leal %0, %%ebx; jmp *%1" \
93 : : "m"(__seh_frame), "m"(__seh_frame.pHandlerCallback) \
94 : "%ebx"); \
95 } \
96 else if (__seh_frame.state == 3) \
97 /* remove exception handler */ \
98 __asm__ ("movl %%fs:0, %%eax; " \
99 "movl 0(%%eax), %%eax; " \
100 "movl %%eax, %%fs:0; " \
101 : : \
102 : "%eax"); \
103 else /* __seh_frame.state == 2 */
104
105#else /* defined(__GNUC__) */
106
107#warning "Structured exception handling is not supported for this compiler!"
108
109#endif /* defined(__GNUC__) */
110
111#ifdef __cplusplus
112}
113#endif
114
115#endif /* __EXCPT_H__ */
116
Note: See TracBrowser for help on using the repository browser.