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