Ignore:
Timestamp:
Apr 18, 2012, 10:46:37 PM (13 years ago)
Author:
dmik
Message:

kernel32: Make SEH work in OS/2 context.

See #82 for details.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/excpt.h

    r21636 r21999  
    4343
    4444struct ___seh_EXCEPTION_FRAME;
    45 typedef int (*__seh_PEXCEPTION_HANDLER)(PEXCEPTION_RECORD,
    46                                         struct ___seh_EXCEPTION_FRAME *,
    47                                         PCONTEXT, PVOID);
     45
     46#ifdef ODIN_FORCE_WIN32_TIB
     47
     48typedef int (*__seh_PEXCEPTION_HANDLER_WIN32)(PEXCEPTION_RECORD,
     49                                              struct ___seh_EXCEPTION_FRAME *,
     50                                              PCONTEXT, PVOID);
    4851
    4952#pragma pack(1)
     
    5255{
    5356    /* + 0 */ struct ___seh_EXCEPTION_FRAME *pPrev;
    54     /* + 4 */ __seh_PEXCEPTION_HANDLER pHandler;
     57    /* + 4 */ __seh_PEXCEPTION_HANDLER_WIN32 pHandler;
    5558    /* + 8 */ void *pFilterCallback;
    5659    /* +12 */ void *pHandlerCallback;
     
    7275#pragma pack()
    7376
    74 extern int __seh_handler(PEXCEPTION_RECORD pRec,
     77extern int __seh_handler_win32(PEXCEPTION_RECORD pRec,
     78                               struct ___seh_EXCEPTION_FRAME *pFrame,
     79                               PCONTEXT pContext, PVOID pVoid);
     80
     81#else /* ODIN_FORCE_WIN32_TIB */
     82
     83typedef int (*__seh_PEXCEPTION_HANDLER)(PVOID,
     84                                        struct ___seh_EXCEPTION_FRAME *,
     85                                        PVOID, PVOID);
     86
     87#pragma pack(1)
     88
     89typedef struct ___seh_EXCEPTION_FRAME
     90{
     91    /* + 0 */ struct ___seh_EXCEPTION_FRAME *pPrev;
     92    /* + 4 */ __seh_PEXCEPTION_HANDLER pHandler;
     93    /* + 8 */ void *pFilterCallback;
     94    /* +12 */ void *pHandlerCallback;
     95    /* +16 */ void *pHandlerContext;
     96    /* +20 */ int filterResult;
     97    /* +24 */ DWORD EBX;
     98    /* +28 */ DWORD ESI;
     99    /* +32 */ DWORD EDI;
     100    /* +36 */ DWORD EBP;
     101    /* +40 */ DWORD ESP;
     102    /* +44 */ EXCEPTION_POINTERS Pointers;
     103    /* +52 */ int state;
     104}
     105__seh_EXCEPTION_FRAME;
     106
     107#pragma pack()
     108
     109extern int __seh_handler(PVOID pRec,
    75110                         struct ___seh_EXCEPTION_FRAME *pFrame,
    76                          PCONTEXT pContext, PVOID pVoid);
     111                         PVOID pContext, PVOID pVoid);
     112
     113#endif /* ODIN_FORCE_WIN32_TIB */
    77114
    78115#define _exception_code() (__seh_frame.Pointers.ExceptionRecord->ExceptionCode)
     
    85122#define GetExceptionInformation (PEXCEPTION_POINTERS)_exception_info
    86123
     124#ifdef ODIN_FORCE_WIN32_TIB
     125
    87126#define __try \
    88127    volatile __seh_EXCEPTION_FRAME __seh_frame;                                \
    89     __seh_frame.pHandler = __seh_handler;                                      \
     128    __seh_frame.pHandler = __seh_handler_win32;                                \
    90129    __seh_frame.Pointers.ExceptionRecord = NULL;                               \
    91130    __seh_frame.Pointers.ContextRecord = NULL;                                 \
     
    201240            continue;
    202241
     242#else /* ODIN_FORCE_WIN32_TIB */
     243
     244#define __try \
     245    volatile __seh_EXCEPTION_FRAME __seh_frame;                                \
     246    __seh_frame.pHandler = __seh_handler;                                      \
     247    __seh_frame.Pointers.ExceptionRecord = NULL;                               \
     248    __seh_frame.Pointers.ContextRecord = NULL;                                 \
     249    __seh_frame.state = 0;                                                     \
     250    /* install OS/2 exception handler (note: EDX is in clobber too since it    \
     251     * may carry any value when we jump back to pFilterCallback from the       \
     252     * handler */                                                              \
     253    __asm__ ("leal %0, %%ecx; "                                                \
     254             "pushl %%fs; "                                                    \
     255             "pushl $Dos32TIB; "                                               \
     256             "popl %%fs; "                                                     \
     257             "movl %%fs:0, %%eax; "                                            \
     258             "movl %%eax, 0(%%ecx); "                                          \
     259             "movl $0f, 8(%%ecx); "                                            \
     260             "movl %%ebx, 24(%%ecx); "                                         \
     261             "movl %%esi, 28(%%ecx); "                                         \
     262             "movl %%edi, 32(%%ecx); "                                         \
     263             "movl %%ebp, 36(%%ecx); "                                         \
     264             "movl %%esp, 40(%%ecx); "                                         \
     265             "movl %%ecx, %%fs:0; "                                            \
     266             "popl %%fs; "                                                     \
     267                                                                               \
     268             "\n0: /* pFilterCallback */ \n"                                   \
     269                                                                               \
     270             : : "m" (__seh_frame)                                             \
     271             : "%eax", "%ecx", "%edx");                                        \
     272    for (; __seh_frame.state <= 3; ++__seh_frame.state)                        \
     273        if (__seh_frame.state == 0)                                            \
     274        {                                                                      \
     275            {
     276
     277#define __except(filter_expr) \
     278            }                                                                  \
     279            /* cause the next state to be 3 */                                 \
     280            __seh_frame.state = 2;                                             \
     281        }                                                                      \
     282        else if (__seh_frame.state == 1) {                                     \
     283            /* execption caught, call filter expression */                     \
     284            __seh_frame.filterResult = (filter_expr);                          \
     285            __asm__("leal %0, %%ebx; jmp *%1"                                  \
     286                    : : "m"(__seh_frame), "m"(__seh_frame.pHandlerCallback)    \
     287                    : "%ebx");                                                 \
     288        }                                                                      \
     289        else if (__seh_frame.state == 3)                                       \
     290            /* remove exception handler */                                     \
     291            __asm__ ("leal %0, %%ecx; "                                        \
     292                     "pushl %%fs; "                                            \
     293                     "pushl $Dos32TIB; "                                       \
     294                     "popl %%fs; "                                             \
     295                     "movl 0(%%ecx), %%eax; "                                  \
     296                     "movl %%eax, %%fs:0; "                                    \
     297                     "popl %%fs; "                                             \
     298                     : : "m"(__seh_frame)                                      \
     299                     : "%eax", "%ecx");                                        \
     300        else /* __seh_frame.state == 2 -> execute except block */
     301
     302#define __finally \
     303            }                                                                  \
     304            /* cause the next state to be 2 */                                 \
     305            __seh_frame.state = 1;                                             \
     306        }                                                                      \
     307        else if (__seh_frame.state == 1) {                                     \
     308            /* execption caught, handle and proceed to the filally block */    \
     309            __seh_frame.filterResult = EXCEPTION_EXECUTE_HANDLER;              \
     310            __asm__("leal %0, %%ebx; jmp *%1"                                  \
     311                    : : "m"(__seh_frame), "m"(__seh_frame.pHandlerCallback)    \
     312                    : "%ebx");                                                 \
     313        }                                                                      \
     314        else if (__seh_frame.state == 3)                                       \
     315            /* remove exception handler */                                     \
     316            __asm__ ("leal %0, %%ecx; "                                        \
     317                     "pushl %%fs; "                                            \
     318                     "pushl $Dos32TIB; "                                       \
     319                     "popl %%fs; "                                             \
     320                     "movl 0(%%ecx), %%eax; "                                  \
     321                     "movl %%eax, %%fs:0; "                                    \
     322                     "popl %%fs; "                                             \
     323                     : : "m"(__seh_frame)                                      \
     324                     : "%eax", "%ecx");                                        \
     325        else /* __seh_frame.state == 2 -> execute finally block */
     326
     327#define __leave \
     328            /* cause the next state to be 2 */                                 \
     329            __seh_frame.state = 1;                                             \
     330            continue;
     331
     332#endif /* ODIN_FORCE_WIN32_TIB */
     333
    203334#else /* defined(__GNUC__) */
    204335
Note: See TracChangeset for help on using the changeset viewer.