Ticket #118: No_FS_abuse_Odin.diff

File No_FS_abuse_Odin.diff, 31.9 KB (added by dmik, 13 years ago)
  • include/excpt.h

     
    4141
    4242#if defined(__GNUC__)
    4343
     44#if 1
     45
     46struct ___seh_REGISTRATIONRECORD;
     47typedef int (_System *__seh_PEXCEPTIONHANDLER)(void * /*PEXCEPTIONREPORTRECORD*/,
     48                                               struct ___seh_REGISTRATIONRECORD *,
     49                                               void * /*PCONTEXTRECORD*/,
     50                                               void * /*PDISPATCHERCONTEXT*/);
     51
     52#pragma pack(1)
     53
     54typedef struct ___seh_REGISTRATIONRECORD
     55{
     56    /* + 0 */ struct ___seh_REGISTRATIONRECORD *pPrev;
     57    /* + 4 */ __seh_PEXCEPTIONHANDLER pHandler;
     58    /* + 8 */ void *pFilterCallback;
     59    /* +12 */ void *pHandlerCallback;
     60    /* +16 */ void *pHandlerContext;
     61    /* +20 */ int filterResult;
     62    /* +24 */ DWORD EBX;
     63    /* +28 */ DWORD ESI;
     64    /* +32 */ DWORD EDI;
     65    /* +36 */ DWORD EBP;
     66    /* +40 */ DWORD ESP;
     67    /* +44 */ EXCEPTION_POINTERS Pointers;
     68    /* +52 */ int state;
     69}
     70__seh_REGISTRATIONRECORD;
     71
     72#pragma pack()
     73
     74extern int _System __seh_handler(void * /*PEXCEPTIONREPORTRECORD*/,
     75                                 struct ___seh_REGISTRATIONRECORD *,
     76                                 void * /*CONTEXTRECORD*/,
     77                                 void * /*DISPATCHERCONTEXT*/);
     78
     79#define _exception_code() (__seh_frame.Pointers.ExceptionRecord->ExceptionCode)
     80#define _exception_info() ((void *)&__seh_frame.Pointers)
     81
     82#define exception_code _exception_code
     83#define exception_info (PEXCEPTION_POINTERS)_exception_info
     84
     85#define GetExceptionCode _exception_code
     86#define GetExceptionInformation (PEXCEPTION_POINTERS)_exception_info
     87
     88#define __try \
     89    volatile __seh_REGISTRATIONRECORD __seh_frame;                             \
     90    __seh_frame.pHandler = __seh_handler;                                      \
     91    __seh_frame.Pointers.ExceptionRecord = NULL;                               \
     92    __seh_frame.Pointers.ContextRecord = NULL;                                 \
     93    __seh_frame.state = 0;                                                     \
     94    /* install OS/2 exception handler (note: EDX is in clobber too since it may\
     95     * carry any value when we jump back to pFilterCallback from the handler */\
     96    __asm__ ("leal %0, %%ecx; "                                                \
     97                                                                               \
     98             "movl %%fs:0, %%eax; "                                            \
     99             "movl %%eax, 0(%%ecx); "                                          \
     100             "movl $0f, 8(%%ecx); "                                            \
     101                                                                               \
     102             "movl %%ebx, 24(%%ecx); "                                         \
     103             "movl %%esi, 28(%%ecx); "                                         \
     104             "movl %%edi, 32(%%ecx); "                                         \
     105             "movl %%ebp, 36(%%ecx); "                                         \
     106             "movl %%esp, 40(%%ecx); "                                         \
     107                                                                               \
     108             "movl %%ecx, %%fs:0; "                                            \
     109                                                                               \
     110             "\n0: /* pFilterCallback */ \n"                                   \
     111                                                                               \
     112             : : "m" (__seh_frame)                                             \
     113             : "%eax", "%ecx", "%edx");                                        \
     114    for (; __seh_frame.state <= 3; ++__seh_frame.state)                        \
     115        if (__seh_frame.state == 0)                                            \
     116        {                                                                      \
     117            {
     118
     119#define __except(filter_expr) \
     120            }                                                                  \
     121            /* cause the next state to be 3 */                                 \
     122            __seh_frame.state = 2;                                             \
     123        }                                                                      \
     124        else if (__seh_frame.state == 1) {                                     \
     125            /* execption caught, call filter expression */                     \
     126            __seh_frame.filterResult = (filter_expr);                          \
     127            __asm__("leal %0, %%ebx; jmp *%1"                                  \
     128                    : : "m"(__seh_frame), "m"(__seh_frame.pHandlerCallback)    \
     129                    : "%ebx");                                                 \
     130        }                                                                      \
     131        else if (__seh_frame.state == 3)                                       \
     132            /* remove exception handler */                                     \
     133            __asm__ ("leal %0, %%ecx; "                                        \
     134                                                                               \
     135                     "movl 0(%%ecx), %%eax; "                                  \
     136                     "movl %%eax, %%fs:0; "                                    \
     137                                                                               \
     138                     : : "m"(__seh_frame)                                      \
     139                     : "%eax", "%ecx");                                        \
     140        else /* __seh_frame.state == 2 -> execute except block */
     141
     142#define __finally \
     143            }                                                                  \
     144            /* cause the next state to be 2 */                                 \
     145            __seh_frame.state = 1;                                             \
     146        }                                                                      \
     147        else if (__seh_frame.state == 1) {                                     \
     148            /* execption caught, handle and proceed to the filally block */    \
     149            __seh_frame.filterResult = EXCEPTION_EXECUTE_HANDLER;              \
     150            __asm__("leal %0, %%ebx; jmp *%1"                                  \
     151                    : : "m"(__seh_frame), "m"(__seh_frame.pHandlerCallback)    \
     152                    : "%ebx");                                                 \
     153        }                                                                      \
     154        else if (__seh_frame.state == 3)                                       \
     155            /* remove exception handler */                                     \
     156            __asm__ ("leal %0, %%ecx; "                                        \
     157                                                                               \
     158                     "movl 0(%%ecx), %%eax; "                                  \
     159                     "movl %%eax, %%fs:0; "                                    \
     160                                                                               \
     161                     : : "m"(__seh_frame)                                      \
     162                     : "%eax", "%ecx");                                        \
     163        else /* __seh_frame.state == 2 -> execute finally block */
     164
     165#define __leave \
     166            /* cause the next state to be 2 */                                 \
     167            __seh_frame.state = 1;                                             \
     168            continue;
     169
     170#else
     171
    44172struct ___seh_EXCEPTION_FRAME;
    45173typedef int (*__seh_PEXCEPTION_HANDLER)(PEXCEPTION_RECORD,
    46174                                        struct ___seh_EXCEPTION_FRAME *,
     
    200328            __seh_frame.state = 1;                                             \
    201329            continue;
    202330
     331#endif
     332
    203333#else /* defined(__GNUC__) */
    204334
    205335#warning "Structured exception handling is not supported for this compiler!"
  • src/kernel32/exceptions.cpp

     
    117117                             PEXCEPTIONREGISTRATIONRECORD pERegRec,
    118118                             PCONTEXTRECORD pCtxRec, PVOID p, PSZ szTrapDump);
    119119
     120#if 0
    120121extern "C"
    121122int __cdecl __seh_handler(PWINEXCEPTION_RECORD pRec,
    122123                          PWINEXCEPTION_FRAME pFrame,
     
    124125
    125126extern "C"
    126127PWINEXCEPTION_FRAME __cdecl __seh_get_prev_frame(PWINEXCEPTION_FRAME pFrame);
     128#endif
    127129
    128130#ifdef DEBUG
    129131static void PrintWin32ExceptionChain(PWINEXCEPTION_FRAME pframe);
     
    361363    // walk the exception chain
    362364    while( (pFrame != NULL) && ((ULONG)((ULONG)pFrame & 0xFFFFF000) != 0xFFFFF000) )
    363365    {
     366#if 0
    364367        pPrevFrame = __seh_get_prev_frame(pFrame);
     368#else
     369        pPrevFrame = pFrame->Prev;
     370#endif
    365371
    366372        dprintf(("KERNEL32: RtlDispatchException - pframe=%08X, pframe->Prev=%08X",
    367373                 pFrame, pPrevFrame));
     
    510516
    511517  while (((ULONG)((ULONG)frame & 0xFFFFF000) != 0xFFFFF000) && (frame != pEndFrame))
    512518  {
     519#if 0
    513520        prevFrame = __seh_get_prev_frame(frame);
     521#else
     522        prevFrame = frame->Prev;
     523#endif
    514524
    515525        /* Check frame address */
    516526        if (pEndFrame && (frame > pEndFrame))
     
    563573        dprintf(("KERNEL32: RtlUnwind (before)- frame=%08X, frame->Prev=%08X", frame, prevFrame));
    564574        SetExceptionChain((DWORD)prevFrame);
    565575        frame = prevFrame;
     576#if 0
    566577        dprintf(("KERNEL32: RtlUnwind (after) - frame=%08X, frame->Prev=%08X", frame,
    567578                 ((ULONG)((ULONG)frame & 0xFFFFF000) != 0xFFFFF000) ?
    568579                 __seh_get_prev_frame(frame) : (void*)0xFFFFFFFF));
     580#else
     581        dprintf(("KERNEL32: RtlUnwind (after) - frame=%08X, frame->Prev=%08X", frame,
     582                 ((ULONG)((ULONG)frame & 0xFFFFF000) != 0xFFFFF000) ?
     583                 frame->Prev : (void*)0xFFFFFFFF));
     584#endif
    569585  }
    570586
    571587  dprintf(("KERNEL32: RtlUnwind returning.\n"));
     
    13451361    }
    13461362continueFail:
    13471363
     1364#if 0
    13481365    /*
    13491366     * vladest: OK, try to implement write AUTOCOMMIT
    13501367     * last chance after MMAP commit is failed
     
    13821399        else
    13831400            goto CrashAndBurn;
    13841401    }
    1385 
     1402#endif
    13861403
    13871404////#define DEBUGSTACK
    13881405#ifdef DEBUGSTACK
     
    18401857    dprintf(("Win32 exception chain:"));
    18411858    while ((pFrame != NULL) && ((ULONG)pFrame != 0xFFFFFFFF))
    18421859    {
     1860#if 0
    18431861        PWINEXCEPTION_FRAME pPrevFrame = __seh_get_prev_frame(pFrame);
    18441862        dprintf(("  Record at %08X, Prev at %08X, handler at %08X%s",
    18451863                 pFrame, pPrevFrame, pFrame->Handler,
    18461864                 pFrame->Handler == (PEXCEPTION_HANDLER)__seh_handler ?
    18471865                 " (SEH)" : ""));
     1866#else
     1867        PWINEXCEPTION_FRAME pPrevFrame = pFrame->Prev;
     1868        dprintf(("  Record at %08X, Prev at %08X, handler at %08X",
     1869                 pFrame, pPrevFrame, pFrame->Handler));
     1870#endif
    18481871        if (pFrame == pPrevFrame)
    18491872        {
    18501873            dprintf(("Chain corrupted! Record at %08X pointing to itself!",
  • src/kernel32/KERNEL32.DEF

     
    13521352    EncodePointer              = _EncodePointer@4                 @3530 NONAME
    13531353    RtlUniform                 = _RtlUniform@4                    @3531 NONAME
    13541354   
    1355     ___seh_handler                                                @3600 NONAME
     1355;    ___seh_handler                                                @3600 NONAME
     1356;    _EnableSEH@0                                                  @3601 NONAME
     1357    __seh_handler                                                 @3600 NONAME
    13561358    _EnableSEH@0                                                  @3601 NONAME
    13571359   
     1360 No newline at end of file
  • src/kernel32/kernel32dbg.def

     
    13511351    EncodePointer              = _EncodePointer@4                 @3530 NONAME
    13521352    RtlUniform                 = _RtlUniform@4                    @3531 NONAME
    13531353   
    1354     ___seh_handler                                                @3600 NONAME
     1354;    ___seh_handler                                                @3600 NONAME
     1355;    _EnableSEH@0                                                  @3601 NONAME
     1356    __seh_handler                                                 @3600 NONAME
    13551357    _EnableSEH@0                                                  @3601 NONAME
  • src/kernel32/oslibexcept.cpp

     
    2222#define DBG_LOCALLOG    DBG_oslibexcept
    2323#include "dbglocal.h"
    2424
     25BOOL APIENTRY OSLibExeptionRecordsToWin32(PEXCEPTIONREPORTRECORD pReportRec,
     26                                          PCONTEXTRECORD pContextRec,
     27                                          WINEXCEPTION_RECORD *pWinReportRec,
     28                                          WINCONTEXT *pWinContextRec,
     29                                          ULONG FSReg)
     30{
     31    // Note: FSReg contains a FS value for Win32 apps and a non-zero value is
     32    // used as a flag to indicate Win32 app mode
     33
     34    memset(pWinReportRec, 0, sizeof(*pWinReportRec));
     35    memcpy(pWinReportRec, pReportRec, sizeof(*pReportRec));
     36
     37    switch(pReportRec->ExceptionNum) {
     38    case XCPT_FLOAT_DENORMAL_OPERAND:
     39          pWinReportRec->ExceptionCode = EXCEPTION_FLT_DENORMAL_OPERAND;
     40          break;
     41    case XCPT_FLOAT_DIVIDE_BY_ZERO:
     42          pWinReportRec->ExceptionCode = EXCEPTION_FLT_DIVIDE_BY_ZERO;
     43          break;
     44    case XCPT_FLOAT_INEXACT_RESULT:
     45          pWinReportRec->ExceptionCode = EXCEPTION_FLT_INEXACT_RESULT;
     46          break;
     47    case XCPT_FLOAT_INVALID_OPERATION:
     48          pWinReportRec->ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
     49          break;
     50    case XCPT_FLOAT_OVERFLOW:
     51          pWinReportRec->ExceptionCode = EXCEPTION_FLT_OVERFLOW;
     52          break;
     53    case XCPT_FLOAT_STACK_CHECK:
     54          pWinReportRec->ExceptionCode = EXCEPTION_FLT_STACK_CHECK;
     55          break;
     56    case XCPT_FLOAT_UNDERFLOW:
     57          pWinReportRec->ExceptionCode = EXCEPTION_FLT_UNDERFLOW;
     58          break;
     59    case XCPT_INTEGER_DIVIDE_BY_ZERO:
     60          pWinReportRec->ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
     61          break;
     62    case XCPT_INTEGER_OVERFLOW:
     63          pWinReportRec->ExceptionCode = EXCEPTION_INT_OVERFLOW;
     64          break;
     65    case XCPT_PRIVILEGED_INSTRUCTION:
     66          pWinReportRec->ExceptionCode = EXCEPTION_PRIV_INSTRUCTION;
     67          break;
     68    case XCPT_BREAKPOINT:
     69          pWinReportRec->ExceptionCode = EXCEPTION_BREAKPOINT;
     70          break;
     71    case XCPT_SINGLE_STEP:
     72          pWinReportRec->ExceptionCode = EXCEPTION_SINGLE_STEP;
     73          break;
     74    case XCPT_ARRAY_BOUNDS_EXCEEDED:
     75          pWinReportRec->ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
     76          break;
     77    case XCPT_DATATYPE_MISALIGNMENT:
     78          pWinReportRec->ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
     79          break;
     80    case XCPT_ILLEGAL_INSTRUCTION:
     81          pWinReportRec->ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
     82          break;
     83    case XCPT_INVALID_LOCK_SEQUENCE:
     84          pWinReportRec->ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
     85          break;
     86    case XCPT_GUARD_PAGE_VIOLATION:
     87          pWinReportRec->ExceptionCode = EXCEPTION_GUARD_PAGE;
     88          break;
     89    case XCPT_UNABLE_TO_GROW_STACK:
     90          pWinReportRec->ExceptionCode = EXCEPTION_STACK_OVERFLOW;
     91          break;
     92    case XCPT_IN_PAGE_ERROR:
     93          pWinReportRec->ExceptionCode = EXCEPTION_IN_PAGE_ERROR;
     94          break;
     95    case XCPT_ACCESS_VIOLATION:
     96          pWinReportRec->ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
     97          break;
     98    default:
     99          if (FSReg) {
     100              //no other exceptions should be dispatched to win32 apps
     101              return FALSE;
     102          }
     103          //TODO: convert other exception codes
     104          return FALSE;
     105    }
     106    //TODO:
     107    //According to the Wine folks the flags are the same in OS/2 and win32
     108    //Let's assume for now the rest is identical as well
     109
     110    //copy context record info
     111    memset(pWinContextRec, 0, sizeof(pWinContextRec));
     112    if(pContextRec->ContextFlags & CONTEXT_CONTROL) {
     113          pWinContextRec->ContextFlags |= WINCONTEXT_CONTROL;
     114          pWinContextRec->Ebp     = pContextRec->ctx_RegEbp;
     115          pWinContextRec->Eip     = pContextRec->ctx_RegEip;
     116          pWinContextRec->SegCs   = pContextRec->ctx_SegCs;
     117          pWinContextRec->EFlags  = pContextRec->ctx_EFlags;
     118          pWinContextRec->Esp     = pContextRec->ctx_RegEsp;
     119          pWinContextRec->SegSs   = pContextRec->ctx_SegSs;
     120    }
     121    if(pContextRec->ContextFlags & CONTEXT_INTEGER) {
     122          pWinContextRec->ContextFlags |= WINCONTEXT_INTEGER;
     123          pWinContextRec->Edi     = pContextRec->ctx_RegEdi;
     124          pWinContextRec->Esi     = pContextRec->ctx_RegEsi;
     125          pWinContextRec->Ebx     = pContextRec->ctx_RegEbx;
     126          pWinContextRec->Edx     = pContextRec->ctx_RegEdx;
     127          pWinContextRec->Ecx     = pContextRec->ctx_RegEcx;
     128          pWinContextRec->Eax     = pContextRec->ctx_RegEax;
     129    }
     130
     131    if(pContextRec->ContextFlags & CONTEXT_SEGMENTS) {
     132          pWinContextRec->ContextFlags |= WINCONTEXT_SEGMENTS;
     133          pWinContextRec->SegGs   = pContextRec->ctx_SegGs;
     134          // Use the overriden FS value (necessary for Win32 apps where FS
     135          // is not 0x150B)
     136          if (FSReg) {
     137            pWinContextRec->SegFs   = FSReg;
     138          } else {
     139            pWinContextRec->SegFs   = pContextRec->ctx_SegFs;
     140          }
     141          pWinContextRec->SegEs   = pContextRec->ctx_SegEs;
     142          pWinContextRec->SegDs   = pContextRec->ctx_SegDs;
     143    }
     144    if(pContextRec->ContextFlags & CONTEXT_FLOATING_POINT) {
     145          pWinContextRec->ContextFlags |= WINCONTEXT_FLOATING_POINT;
     146          //TODO: First 7 dwords the same?
     147          memcpy(&pWinContextRec->FloatSave, pContextRec->ctx_env,
     148                 sizeof(pContextRec->ctx_env));
     149          memcpy(&pWinContextRec->FloatSave.RegisterArea, pContextRec->ctx_stack,
     150                 sizeof(pContextRec->ctx_stack));
     151    }
     152
     153    return TRUE;
     154}
     155
    25156//******************************************************************************
    26157//Dispatches OS/2 exception to win32 handler
    27158//Returns: TRUE, win32 exception handler returned continue execution
     
    35166 WINCONTEXT          wincontextrec;
    36167 ULONG               rc;
    37168
    38   memset(&winreportrec, 0, sizeof(winreportrec));
    39   memcpy(&winreportrec, pReportRec, sizeof(*pReportRec));
    40 
    41   switch(pReportRec->ExceptionNum) {
    42   case XCPT_FLOAT_DENORMAL_OPERAND:
    43         winreportrec.ExceptionCode = EXCEPTION_FLT_DENORMAL_OPERAND;
    44         break;
    45   case XCPT_FLOAT_DIVIDE_BY_ZERO:
    46         winreportrec.ExceptionCode = EXCEPTION_FLT_DIVIDE_BY_ZERO;
    47         break;
    48   case XCPT_FLOAT_INEXACT_RESULT:
    49         winreportrec.ExceptionCode = EXCEPTION_FLT_INEXACT_RESULT;
    50         break;
    51   case XCPT_FLOAT_INVALID_OPERATION:
    52         winreportrec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
    53         break;
    54   case XCPT_FLOAT_OVERFLOW:
    55         winreportrec.ExceptionCode = EXCEPTION_FLT_OVERFLOW;
    56         break;
    57   case XCPT_FLOAT_STACK_CHECK:
    58         winreportrec.ExceptionCode = EXCEPTION_FLT_STACK_CHECK;
    59         break;
    60   case XCPT_FLOAT_UNDERFLOW:
    61         winreportrec.ExceptionCode = EXCEPTION_FLT_UNDERFLOW;
    62         break;
    63   case XCPT_INTEGER_DIVIDE_BY_ZERO:
    64         winreportrec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
    65         break;
    66   case XCPT_INTEGER_OVERFLOW:
    67         winreportrec.ExceptionCode = EXCEPTION_INT_OVERFLOW;
    68         break;
    69   case XCPT_PRIVILEGED_INSTRUCTION:
    70         winreportrec.ExceptionCode = EXCEPTION_PRIV_INSTRUCTION;
    71         break;
    72   case XCPT_BREAKPOINT:
    73         winreportrec.ExceptionCode = EXCEPTION_BREAKPOINT;
    74         break;
    75   case XCPT_SINGLE_STEP:
    76         winreportrec.ExceptionCode = EXCEPTION_SINGLE_STEP;
    77         break;
    78   case XCPT_ARRAY_BOUNDS_EXCEEDED:
    79         winreportrec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
    80         break;
    81   case XCPT_DATATYPE_MISALIGNMENT:
    82         winreportrec.ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
    83         break;
    84   case XCPT_ILLEGAL_INSTRUCTION:
    85         winreportrec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
    86         break;
    87   case XCPT_INVALID_LOCK_SEQUENCE:
    88         winreportrec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
    89         break;
    90   case XCPT_GUARD_PAGE_VIOLATION:
    91         winreportrec.ExceptionCode = EXCEPTION_GUARD_PAGE;
    92         break;
    93   case XCPT_UNABLE_TO_GROW_STACK:
    94         winreportrec.ExceptionCode = EXCEPTION_STACK_OVERFLOW;
    95         break;
    96   case XCPT_IN_PAGE_ERROR:
    97         winreportrec.ExceptionCode = EXCEPTION_IN_PAGE_ERROR;
    98         break;
    99   case XCPT_ACCESS_VIOLATION:
    100         winreportrec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
    101         break;
    102   default: //no other exceptions should be dispatched to win32 apps
    103         return FALSE;
    104   }
    105   //TODO:
    106   //According to the Wine folks the flags are the same in OS/2 and win32
    107   //Let's assume for now the rest is identical as well
    108 
    109   //copy context record info
    110   memset(&wincontextrec, 0, sizeof(wincontextrec));
    111   if(pContextRec->ContextFlags & CONTEXT_CONTROL) {
    112         wincontextrec.ContextFlags |= WINCONTEXT_CONTROL;
    113         wincontextrec.Ebp     = pContextRec->ctx_RegEbp;
    114         wincontextrec.Eip     = pContextRec->ctx_RegEip;
    115         wincontextrec.SegCs   = pContextRec->ctx_SegCs;
    116         wincontextrec.EFlags  = pContextRec->ctx_EFlags;
    117         wincontextrec.Esp     = pContextRec->ctx_RegEsp;
    118         wincontextrec.SegSs   = pContextRec->ctx_SegSs;
    119   }
    120   if(pContextRec->ContextFlags & CONTEXT_INTEGER) {
    121         wincontextrec.ContextFlags |= WINCONTEXT_INTEGER;
    122         wincontextrec.Edi     = pContextRec->ctx_RegEdi;
    123         wincontextrec.Esi     = pContextRec->ctx_RegEsi;
    124         wincontextrec.Ebx     = pContextRec->ctx_RegEbx;
    125         wincontextrec.Edx     = pContextRec->ctx_RegEdx;
    126         wincontextrec.Ecx     = pContextRec->ctx_RegEcx;
    127         wincontextrec.Eax     = pContextRec->ctx_RegEax;
    128   }
    129 
    130169  TEB *winteb = GetThreadTEB();
    131170
    132   if(pContextRec->ContextFlags & CONTEXT_SEGMENTS) {
    133         wincontextrec.ContextFlags |= WINCONTEXT_SEGMENTS;
    134         wincontextrec.SegGs   = pContextRec->ctx_SegGs;
    135 //   This resets FS to 0x150B - we DON'T want that!!
    136 //      wincontextrec.SegFs   = pContextRec->ctx_SegFs;
    137         wincontextrec.SegFs   = winteb->teb_sel;
    138         wincontextrec.SegEs   = pContextRec->ctx_SegEs;
    139         wincontextrec.SegDs   = pContextRec->ctx_SegDs;
    140   }
    141   if(pContextRec->ContextFlags & CONTEXT_FLOATING_POINT) {
    142         wincontextrec.ContextFlags |= WINCONTEXT_FLOATING_POINT;
    143         //TODO: First 7 dwords the same?
    144         memcpy(&wincontextrec.FloatSave, pContextRec->ctx_env, sizeof(pContextRec->ctx_env));
    145         memcpy(&wincontextrec.FloatSave.RegisterArea, pContextRec->ctx_stack, sizeof(pContextRec->ctx_stack));
    146   }
     171  if(!OSLibExeptionRecordsToWin32(pReportRec, pContextRec,
     172                                  &winreportrec, &wincontextrec,
     173                                  winteb->teb_sel))
     174    return FALSE;
     175
    147176  //It doesn't seem correct if we dispatch real exceptions to win32 apps
    148177  //Some just call RtlUnwind and continue as if they were processing an
    149178  //exception thrown by C++ code. (instead of real OS exception)
  • src/kernel32/seh/sehutil.s

     
    66 * Copyright 2010 Dmitriy Kuminov
    77 */
    88
     9#if 1
     10
     11.global __seh_handler
     12
     13/*
     14 * extern "C"
     15 * int _System __seh_handler(PEXCEPTIONREPORTRECORD pRec,
     16 *                           struct ___seh_REGISTRATIONRECORD *pFrame,
     17 *                           PCONTEXTRECORD pContext,
     18 *                           PDISPATCHERCONTEXT pVoid)
     19 *
     20 * OS/2 structured exception handler that implements the MSVC __try/__except
     21 * functionality for GCC.
     22 *
     23 * NOTE: This is a heavily platform specific stuff. The code depends on the
     24 * struct ___seh_EXCEPTION_FRAME and WINEXCEPTION_RECORD / WINCONTEXT layout so
     25 * be very careful and keep both in sync!
     26 *
     27 * _System is much like __cdecl: EAX/ECX/EDX are not preserved, result in
     28 * EAX/EDX, caller cleans up the stack.
     29 */
     30
     31__seh_handler:
     32
     33/*
     34    movl 4(%esp), %eax
     35    cmpl $0x80000001, 0(%eax)
     36    je 0f
     37    jmp 1f
     380:
     39    xorl %eax, %eax
     40    ret
     411:
     42*/
     43    jmp __seh_handler_Begin
     44
     45
     46    /* if we are the top exception handler, we need to call the Odin exception
     47     * handler first in order to let it handle some critical exceptions (e.g.
     48     * XCPT_GUARD_PAGE_VIOLATION used to commit new stack pages as it grows) */
     49
     50
     51    movl %fs:0, %eax
     520:
     53    cmpl $__seh_handler, 4(%eax)    /* Is it a SEH handler? */
     54    je 1f                           /* Yes */
     55    movl 0(%eax), %eax              /* pFrame = pFrame->pPrev */
     56    jmp 0b
     571:
     58    cmpl 8(%esp), %eax              /* Is it our frame? */
     59    jne __seh_handler_Begin         /* No */
     60
     61    /* We're the top SEH handler in the chain, call the Odin handler */
     620:
     63    movl 0(%eax), %eax              /* pFrame = pFrame->pPrev */
     64    cmpl $-1, %eax                  /* End of chain? */
     65    je __seh_handler_Begin
     66    cmpl $__seh_handler, 4(%eax)    /* Is it a SEH handler? */
     67    je 0b                           /* Yes, skip */
     68
     69    push 16(%esp)
     70    push 16(%esp)
     71    push %eax
     72    push 16(%esp)
     73    call *4(%eax)                   /* pFrame->Handler */
     74    movl %eax, %ecx
     75    movl 4(%esp), %eax              /* Get the current pFrame back */
     76    addl $16, %esp
     77    cmpl $0, %ecx                   /* XCPT_CONTINUE_SEARCH? */
     78    je 0b                           /* Yes, hand over to the prev handler */
     79    ret                             /* No (assume XCPT_CONTINUE_EXECUTION) */
     80
     81
     82
     83
     84__seh_handler_Begin:
     85
     86    pushl %ebp
     87    movl %esp, %ebp
     88
     89    /*
     90     * 8(%ebp)  - pRec
     91     * 12(%ebp) - pFrame
     92     * 16(%ebp) - pContext
     93     * 20(%ebp) - pVoid
     94     */
     95
     96    /* preserve used registers */
     97    pushl %ebx
     98    pushl %edi
     99    pushl %esi
     100
     101    /* skip EH_UNWINDING calls (for compatibility with MSVC) */
     102    movl 8(%ebp), %ebx
     103    movl 4(%ebx), %eax /* pRec->fHandlerFlags */
     104    testl $0x2, %eax /* EH_UNWINDING? */
     105    movl $0, %eax /* XCPT_CONTINUE_SEARCH */
     106    jne ___seh_handler_Return
     107
     108    /* save handler's context */
     109    pushl %ebp
     110    pushl $0   /* reserve space for length, must be saved right before ESP! */
     111    pushl %esp /* ESP must be saved last! */
     112
     113    movl 12(%ebp), %ebx
     114    movl $0f, 12(%ebx) /* pFrame->pHandlerCallback */
     115
     116    /* get the size of the handler's stack */
     117    movl 40(%ebx), %ecx /* pFrame->ESP */
     118    subl %esp, %ecx
     119    jle ___seh_handler_Error /* Invalid stack! */
     120    movl %ecx, 4(%esp) /* save length */
     121
     122    /* check that EXCEPTION_RECORD and CONTEXT are on our stack
     123     * and save their offsets in pFrame */
     124    movl 8(%ebp), %eax
     125    subl %esp, %eax
     126    jl ___seh_handler_Error /* Invalid stack! */
     127    cmpl %ecx, %eax
     128    jg ___seh_handler_Error /* Invalid stack! */
     129
     130    movl 16(%ebp), %eax
     131    subl %esp, %eax
     132    jl ___seh_handler_Error /* Invalid stack! */
     133    cmpl %ecx, %eax
     134    jg ___seh_handler_Error /* Invalid stack! */
     135
     136    /* allocate space on heap for the handler's stack and Win32 exception
     137     * records */
     138    movl %ecx, %eax /* stack length */
     139    addl $284, %eax /* WINEXCEPTION_RECORD (80 b) + WINCONTEXT (204 b) */
     140    subl $4, %esp
     141    movl %eax, 0(%esp)
     142    call odin_malloc /* _Optlink, rtl, EAX/EDX/ECX-in, caller cleans stack */
     143    addl $4, %esp
     144    testl %eax, %eax
     145    je ___seh_handler_Error /* No memory! */
     146
     147    /* save the handler's stack on heap */
     148    movl 4(%esp), %ecx
     149    movl %eax, %edi
     150    movl %edi, 16(%ebx) /* pFrame->pHandlerContext */
     151    movl %esp, %esi
     152    rep movsb
     153
     154    /* set Pointers to WINEXCEPTION_RECORD and WINCONTEXT */
     155    movl 16(%ebx), %eax /* pFrame->pHandlerContext */
     156    addl 4(%esp), %eax  /* stack length */
     157    movl %eax, 44(%ebx) /* pFrame->Pointers.ExceptionRecord */
     158    addl $80, %eax
     159    movl %eax, 48(%ebx) /* pFrame->Pointers.ContextRecord */
     160
     161    /* convert OS/2 exception records to Win32 exception records */
     162    pushl $0        /* FSReg, unused */
     163    pushl 48(%ebx)  /* WINCONTEXT */
     164    pushl 44(%ebx)  /* WINEXCEPTION_RECORD */
     165    pushl 16(%ebp)  /* PCONTEXTRECORD */
     166    pushl 8(%ebp)   /* PEXCEPTIONREPORTRECORD */
     167    call OSLibExeptionRecordsToWin32 /* _syscall, rtl, caller cleans stack */
     168    addl $20, %esp
     169    cmpl $0, %eax
     170    jne ___seh_handler_RestoreTryCatchContext
     171
     172    /* free heap block */
     173    movl 16(%ebx), %eax /* pFrame->pHandlerContext */
     174    subl $4, %esp
     175    movl %eax, 0(%esp)
     176    call odin_free /* _Optlink, rtl, EAX/EDX/ECX-in, caller cleans stack */
     177    addl $4, %esp
     178    jmp ___seh_handler_Error /* OSLibExeptionRecordsToWin32 failed */
     179
     180___seh_handler_RestoreTryCatchContext:
     181
     182    /* restore __try/__catch context */
     183    movl 12(%ebp), %eax
     184    movl 24(%eax), %ebx /* pFrame->EBX... */
     185    movl 28(%eax), %esi
     186    movl 32(%eax), %edi
     187    movl 36(%eax), %ebp
     188    movl 40(%eax), %esp
     189
     190    /* jump to the filter callback */
     191    movl $1, 52(%eax) /* pFrame->state */
     192    jmp *8(%eax) /* pFrame->pFilterCallback */
     193
     1940:
     195    /* restore handler's context (we assume that the callback puts the address
     196     * of pFrame back to EBX!) */
     197    movl 16(%ebx), %esi /* pFrame->pHandlerContext */
     198    movl 0(%esi), %esp  /* restore saved ESP */
     199    movl 4(%esi), %ecx  /* saved stack length */
     200    subl $4, %esp /* correct ESP to compensate for PUSH ESP logic */
     201    movl %esp, %edi
     202    rep movsb
     203
     204    popl %esp
     205    addl $4, %esp
     206    popl %ebp
     207
     208    /* free heap block */
     209    movl 16(%ebx), %eax /* pFrame->pHandlerContext */
     210    subl $4, %esp
     211    movl %eax, 0(%esp)
     212    call odin_free /* _Optlink, rtl, EAX/EDX/ECX-in, caller cleans stack */
     213    addl $4, %esp
     214
     215    /* analyze filter result */
     216    movl 20(%ebx), %eax /* pFrame->filterResult */
     217    cmpl $1, %eax /* EXCEPTION_EXECUTE_HANDLER? */
     218    je ___seh_handler_Unwind
     219    cmpl $-1, %eax /* EXCEPTION_CONTINUE_EXECUTION? */
     220    jne 1f
     221    movl $0, 52(%ebx) /* pFrame->state */
     222    movl $-1, %eax /* XCPT_CONTINUE_EXECUTION */
     223    jmp ___seh_handler_Return
     2241:
     225    /* assume EXCEPTION_CONTINUE_SEARCH (0) */
     226    movl $0, %eax /* XCPT_CONTINUE_SEARCH */
     227    jmp ___seh_handler_Return
     228
     229___seh_handler_Unwind:
     230
     231    /* unwind OS/2 exception chain up to ours */
     232    pushl $0        /* PEXCEPTIONREPORTRECORD */
     233    pushl $1f       /* PVOID pTargetIP */
     234    pushl 12(%ebp)  /* PEXCEPTIONREGISTRATIONRECORD */
     235    call _DosUnwindException /* _syscall, rtl, but stack is not restored! */
     2361:
     237
     238    /* restore __try/__except context */
     239    movl 12(%ebp), %eax
     240    movl 24(%eax), %ebx
     241    movl 28(%eax), %esi
     242    movl 32(%eax), %edi
     243    movl 36(%eax), %ebp
     244    movl 40(%eax), %esp
     245
     246    /* jump to __except */
     247    movl $2, 52(%eax) /* pFrame->state */
     248    jmp *8(%eax) /* pFrame->pFilterCallback */
     249
     250___seh_handler_Error:
     251
     252    addl $8, %esp
     253    popl %ebp
     254
     255    movl $0, %eax /* XCPT_CONTINUE_SEARCH */
     256
     257___seh_handler_Return:
     258
     259    popl %esi
     260    popl %edi
     261    popl %ebx
     262
     263    popl %ebp
     264    ret
     265
     266#else
     267
    9268.global ___seh_handler
    10269.global ___seh_get_prev_frame
    11270
     
    308567    movl 0(%eax), %eax /* pFrame->Prev */
    309568    ret
    310569
     570#endif