Ticket #118: No_FS_abuse_Odin.diff
File No_FS_abuse_Odin.diff, 31.9 KB (added by , 13 years ago) |
---|
-
include/excpt.h
41 41 42 42 #if defined(__GNUC__) 43 43 44 #if 1 45 46 struct ___seh_REGISTRATIONRECORD; 47 typedef int (_System *__seh_PEXCEPTIONHANDLER)(void * /*PEXCEPTIONREPORTRECORD*/, 48 struct ___seh_REGISTRATIONRECORD *, 49 void * /*PCONTEXTRECORD*/, 50 void * /*PDISPATCHERCONTEXT*/); 51 52 #pragma pack(1) 53 54 typedef 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 74 extern 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 44 172 struct ___seh_EXCEPTION_FRAME; 45 173 typedef int (*__seh_PEXCEPTION_HANDLER)(PEXCEPTION_RECORD, 46 174 struct ___seh_EXCEPTION_FRAME *, … … 200 328 __seh_frame.state = 1; \ 201 329 continue; 202 330 331 #endif 332 203 333 #else /* defined(__GNUC__) */ 204 334 205 335 #warning "Structured exception handling is not supported for this compiler!" -
src/kernel32/exceptions.cpp
117 117 PEXCEPTIONREGISTRATIONRECORD pERegRec, 118 118 PCONTEXTRECORD pCtxRec, PVOID p, PSZ szTrapDump); 119 119 120 #if 0 120 121 extern "C" 121 122 int __cdecl __seh_handler(PWINEXCEPTION_RECORD pRec, 122 123 PWINEXCEPTION_FRAME pFrame, … … 124 125 125 126 extern "C" 126 127 PWINEXCEPTION_FRAME __cdecl __seh_get_prev_frame(PWINEXCEPTION_FRAME pFrame); 128 #endif 127 129 128 130 #ifdef DEBUG 129 131 static void PrintWin32ExceptionChain(PWINEXCEPTION_FRAME pframe); … … 361 363 // walk the exception chain 362 364 while( (pFrame != NULL) && ((ULONG)((ULONG)pFrame & 0xFFFFF000) != 0xFFFFF000) ) 363 365 { 366 #if 0 364 367 pPrevFrame = __seh_get_prev_frame(pFrame); 368 #else 369 pPrevFrame = pFrame->Prev; 370 #endif 365 371 366 372 dprintf(("KERNEL32: RtlDispatchException - pframe=%08X, pframe->Prev=%08X", 367 373 pFrame, pPrevFrame)); … … 510 516 511 517 while (((ULONG)((ULONG)frame & 0xFFFFF000) != 0xFFFFF000) && (frame != pEndFrame)) 512 518 { 519 #if 0 513 520 prevFrame = __seh_get_prev_frame(frame); 521 #else 522 prevFrame = frame->Prev; 523 #endif 514 524 515 525 /* Check frame address */ 516 526 if (pEndFrame && (frame > pEndFrame)) … … 563 573 dprintf(("KERNEL32: RtlUnwind (before)- frame=%08X, frame->Prev=%08X", frame, prevFrame)); 564 574 SetExceptionChain((DWORD)prevFrame); 565 575 frame = prevFrame; 576 #if 0 566 577 dprintf(("KERNEL32: RtlUnwind (after) - frame=%08X, frame->Prev=%08X", frame, 567 578 ((ULONG)((ULONG)frame & 0xFFFFF000) != 0xFFFFF000) ? 568 579 __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 569 585 } 570 586 571 587 dprintf(("KERNEL32: RtlUnwind returning.\n")); … … 1345 1361 } 1346 1362 continueFail: 1347 1363 1364 #if 0 1348 1365 /* 1349 1366 * vladest: OK, try to implement write AUTOCOMMIT 1350 1367 * last chance after MMAP commit is failed … … 1382 1399 else 1383 1400 goto CrashAndBurn; 1384 1401 } 1385 1402 #endif 1386 1403 1387 1404 ////#define DEBUGSTACK 1388 1405 #ifdef DEBUGSTACK … … 1840 1857 dprintf(("Win32 exception chain:")); 1841 1858 while ((pFrame != NULL) && ((ULONG)pFrame != 0xFFFFFFFF)) 1842 1859 { 1860 #if 0 1843 1861 PWINEXCEPTION_FRAME pPrevFrame = __seh_get_prev_frame(pFrame); 1844 1862 dprintf((" Record at %08X, Prev at %08X, handler at %08X%s", 1845 1863 pFrame, pPrevFrame, pFrame->Handler, 1846 1864 pFrame->Handler == (PEXCEPTION_HANDLER)__seh_handler ? 1847 1865 " (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 1848 1871 if (pFrame == pPrevFrame) 1849 1872 { 1850 1873 dprintf(("Chain corrupted! Record at %08X pointing to itself!", -
src/kernel32/KERNEL32.DEF
1352 1352 EncodePointer = _EncodePointer@4 @3530 NONAME 1353 1353 RtlUniform = _RtlUniform@4 @3531 NONAME 1354 1354 1355 ___seh_handler @3600 NONAME 1355 ; ___seh_handler @3600 NONAME 1356 ; _EnableSEH@0 @3601 NONAME 1357 __seh_handler @3600 NONAME 1356 1358 _EnableSEH@0 @3601 NONAME 1357 1359 1360 No newline at end of file -
src/kernel32/kernel32dbg.def
1351 1351 EncodePointer = _EncodePointer@4 @3530 NONAME 1352 1352 RtlUniform = _RtlUniform@4 @3531 NONAME 1353 1353 1354 ___seh_handler @3600 NONAME 1354 ; ___seh_handler @3600 NONAME 1355 ; _EnableSEH@0 @3601 NONAME 1356 __seh_handler @3600 NONAME 1355 1357 _EnableSEH@0 @3601 NONAME -
src/kernel32/oslibexcept.cpp
22 22 #define DBG_LOCALLOG DBG_oslibexcept 23 23 #include "dbglocal.h" 24 24 25 BOOL 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 25 156 //****************************************************************************** 26 157 //Dispatches OS/2 exception to win32 handler 27 158 //Returns: TRUE, win32 exception handler returned continue execution … … 35 166 WINCONTEXT wincontextrec; 36 167 ULONG rc; 37 168 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 apps103 return FALSE;104 }105 //TODO:106 //According to the Wine folks the flags are the same in OS/2 and win32107 //Let's assume for now the rest is identical as well108 109 //copy context record info110 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 130 169 TEB *winteb = GetThreadTEB(); 131 170 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 147 176 //It doesn't seem correct if we dispatch real exceptions to win32 apps 148 177 //Some just call RtlUnwind and continue as if they were processing an 149 178 //exception thrown by C++ code. (instead of real OS exception) -
src/kernel32/seh/sehutil.s
6 6 * Copyright 2010 Dmitriy Kuminov 7 7 */ 8 8 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 38 0: 39 xorl %eax, %eax 40 ret 41 1: 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 52 0: 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 57 1: 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 */ 62 0: 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 194 0: 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 224 1: 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! */ 236 1: 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 9 268 .global ___seh_handler 10 269 .global ___seh_get_prev_frame 11 270 … … 308 567 movl 0(%eax), %eax /* pFrame->Prev */ 309 568 ret 310 569 570 #endif