Ignore:
Timestamp:
Nov 14, 2010, 12:41:50 AM (15 years ago)
Author:
dmik
Message:

kernel32/SEH: Added support for setjmp()/longjmp() within the try block. See #26.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/excpt.h

    r21448 r21474  
    1313 * crash the application):
    1414 *
    15  * 1. You cannot use return, goto and longjmp statements within __try or
    16  *    __except or __finally blocks.
     15 * 1. You cannot use the return statement within __try or __except or __finally
     16 *    blocks.
     17 *
     18 * 2. You cannot use the goto statement or the longjmp() function within __try
     19 *    or __except or __finally blocks if it passes control outside these blocks.
    1720 *
    1821 * 2. If you use __try and friends inside a do/while/for/switch block, you will
     
    3942#if defined(__GNUC__)
    4043
    41 struct ___seh_PEXCEPTION_FRAME;
     44struct ___seh_EXCEPTION_FRAME;
    4245typedef int (*__seh_PEXCEPTION_HANDLER)(PEXCEPTION_RECORD,
    43                                         struct ___seh_PEXCEPTION_FRAME *,
     46                                        struct ___seh_EXCEPTION_FRAME *,
    4447                                        PCONTEXT, PVOID);
    4548
    46 typedef struct ___seh_PEXCEPTION_FRAME
     49#pragma pack(1)
     50
     51typedef struct ___seh_EXCEPTION_FRAME
    4752{
    48     struct ___seh_PEXCEPTION_FRAME *pPrev;
    49     __seh_PEXCEPTION_HANDLER pHandler;
    50     void *pFilterCallback;
    51     void *pHandlerCallback;
    52     void *pHandlerContext;
    53     int filterResult;
    54     DWORD pTryRegs[6]; /* EBX/ESI/EDI/EBP/ESP/ExceptionHandler */
    55     EXCEPTION_POINTERS Pointers;
    56     int state;
     53    /* + 0 */ struct ___seh_EXCEPTION_FRAME *pPrev;
     54    /* + 4 */ __seh_PEXCEPTION_HANDLER pHandler;
     55    /* + 8 */ void *pFilterCallback;
     56    /* +12 */ void *pHandlerCallback;
     57    /* +16 */ void *pHandlerContext;
     58    /* +20 */ int filterResult;
     59    /* +24 */ DWORD EBX;
     60    /* +28 */ DWORD ESI;
     61    /* +32 */ DWORD EDI;
     62    /* +36 */ DWORD EBP;
     63    /* +40 */ DWORD ESP;
     64    /* +44 */ DWORD pPrevFrameOS2;
     65    /* +48 */ EXCEPTION_POINTERS Pointers;
     66    /* +56 */ int state;
     67    /* +60 */ DWORD pPrevFrameWin32;
    5768}
    58 __seh_PEXCEPTION_FRAME;
     69__seh_EXCEPTION_FRAME;
    5970
    60 int __seh_handler(PEXCEPTION_RECORD pRec,
    61                   struct ___seh_PEXCEPTION_FRAME *pFrame,
    62                   PCONTEXT pContext, PVOID pVoid);
     71#pragma pack()
     72
     73extern int __seh_handler(PEXCEPTION_RECORD pRec,
     74                         struct ___seh_EXCEPTION_FRAME *pFrame,
     75                         PCONTEXT pContext, PVOID pVoid);
    6376
    6477#define _exception_code() (__seh_frame.Pointers.ExceptionRecord->ExceptionCode)
    65 #define _exception_info() (&__seh_frame.Pointers)
     78#define _exception_info() ((void *)&__seh_frame.Pointers)
     79
     80#define exception_code _exception_code
     81#define exception_info (PEXCEPTION_POINTERS)_exception_info
    6682
    6783#define GetExceptionCode _exception_code
    68 #define GetExceptionInformation _exception_info
     84#define GetExceptionInformation (PEXCEPTION_POINTERS)_exception_info
    6985
    7086#define __try \
    71     volatile __seh_PEXCEPTION_FRAME __seh_frame;                               \
     87    volatile __seh_EXCEPTION_FRAME __seh_frame;                                \
     88    __seh_frame.pHandler = __seh_handler;                                      \
    7289    __seh_frame.Pointers.ExceptionRecord = NULL;                               \
    7390    __seh_frame.Pointers.ContextRecord = NULL;                                 \
     
    7794        if (__seh_frame.state == 0)                                            \
    7895        {                                                                      \
    79             /* install exception handler */                                    \
    80             __asm__ ("\n.extern ___seh_handler\n"                              \
    81                      ""                                                        \
    82                      "leal %0, %%ecx; "                                        \
     96            /* install exception handler (both Win32 and OS/2 chains) */       \
     97            __asm__ ("leal %0, %%ecx; "                                        \
    8398                     "movl %%fs:0, %%eax; "                                    \
    8499                     "movl %%eax, 0(%%ecx); "                                  \
    85                      "movl $___seh_handler, %%eax; "                           \
    86                      "movl %%eax, 4(%%ecx); "                                  \
     100                     "movl %%eax, 60(%%ecx); "                                 \
    87101                     "movl $0b, 8(%%ecx); "                                    \
    88102                     ""                                                        \
     
    98112                     "movl %%fs:0, %%eax; "                                    \
    99113                     "movl %%eax, 44(%%ecx); "                                 \
     114                     "movl %%ecx, %%fs:0; "                                    \
    100115                     "popl %%fs; "                                             \
    101116                     ""                                                        \
     
    119134        else if (__seh_frame.state == 3)                                       \
    120135            /* remove exception handler */                                     \
    121             __asm__ ("movl %%fs:0, %%eax; "                                    \
    122                      "movl 0(%%eax), %%eax; "                                  \
     136            __asm__ ("movl %%fs:0, %%ecx; "                                    \
     137                     "movl 60(%%ecx), %%eax; "                                 \
    123138                     "movl %%eax, %%fs:0; "                                    \
     139                     ""                                                        \
     140                     "pushl %%fs; "                                            \
     141                     "pushl $Dos32TIB; "                                       \
     142                     "popl %%fs; "                                             \
     143                     "movl 44(%%ecx), %%eax; "                                 \
     144                     "movl %%eax, %%fs:0; "                                    \
     145                     "popl %%fs; "                                             \
    124146                     : :                                                       \
    125                      : "%eax");                                                \
     147                     : "%eax", "%ecx");                                        \
    126148        else /* __seh_frame.state == 2 -> execute except block */
    127149
     
    140162        else if (__seh_frame.state == 3)                                       \
    141163            /* remove exception handler */                                     \
    142             __asm__ ("movl %%fs:0, %%eax; "                                    \
    143                      "movl 0(%%eax), %%eax; "                                  \
     164            __asm__ ("movl %%fs:0, %%ecx; "                                    \
     165                     "movl 60(%%ecx), %%eax; "                                 \
    144166                     "movl %%eax, %%fs:0; "                                    \
     167                     ""                                                        \
     168                     "pushl %%fs; "                                            \
     169                     "pushl $Dos32TIB; "                                       \
     170                     "popl %%fs; "                                             \
     171                     "movl 44(%%ecx), %%eax; "                                 \
     172                     "movl %%eax, %%fs:0; "                                    \
     173                     "popl %%fs; "                                             \
    145174                     : :                                                       \
    146                      : "%eax");                                                \
     175                     : "%eax", "%ecx");                                        \
    147176        else /* __seh_frame.state == 2 -> execute finally block */
    148177
Note: See TracChangeset for help on using the changeset viewer.