Changeset 21999
- Timestamp:
- Apr 18, 2012, 10:46:37 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 26 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/excpt.h
r21636 r21999 43 43 44 44 struct ___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 48 typedef int (*__seh_PEXCEPTION_HANDLER_WIN32)(PEXCEPTION_RECORD, 49 struct ___seh_EXCEPTION_FRAME *, 50 PCONTEXT, PVOID); 48 51 49 52 #pragma pack(1) … … 52 55 { 53 56 /* + 0 */ struct ___seh_EXCEPTION_FRAME *pPrev; 54 /* + 4 */ __seh_PEXCEPTION_HANDLER pHandler;57 /* + 4 */ __seh_PEXCEPTION_HANDLER_WIN32 pHandler; 55 58 /* + 8 */ void *pFilterCallback; 56 59 /* +12 */ void *pHandlerCallback; … … 72 75 #pragma pack() 73 76 74 extern int __seh_handler(PEXCEPTION_RECORD pRec, 77 extern 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 83 typedef int (*__seh_PEXCEPTION_HANDLER)(PVOID, 84 struct ___seh_EXCEPTION_FRAME *, 85 PVOID, PVOID); 86 87 #pragma pack(1) 88 89 typedef 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 109 extern int __seh_handler(PVOID pRec, 75 110 struct ___seh_EXCEPTION_FRAME *pFrame, 76 PCONTEXT pContext, PVOID pVoid); 111 PVOID pContext, PVOID pVoid); 112 113 #endif /* ODIN_FORCE_WIN32_TIB */ 77 114 78 115 #define _exception_code() (__seh_frame.Pointers.ExceptionRecord->ExceptionCode) … … 85 122 #define GetExceptionInformation (PEXCEPTION_POINTERS)_exception_info 86 123 124 #ifdef ODIN_FORCE_WIN32_TIB 125 87 126 #define __try \ 88 127 volatile __seh_EXCEPTION_FRAME __seh_frame; \ 89 __seh_frame.pHandler = __seh_handler ;\128 __seh_frame.pHandler = __seh_handler_win32; \ 90 129 __seh_frame.Pointers.ExceptionRecord = NULL; \ 91 130 __seh_frame.Pointers.ContextRecord = NULL; \ … … 201 240 continue; 202 241 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 203 334 #else /* defined(__GNUC__) */ 204 335 -
trunk/include/odinlx.h
r21941 r21999 67 67 68 68 //****************************************************************************** 69 //Enable SEH (structured exception handling) support. This call is necessary 70 //for the __try/__except statement to work correctly. Must be called before 71 // RegisterLxDll()/RegisterLxExe(). 69 //Makes FS register point to the Win32 thread information block. For Win32 70 //binaries, this is set automatically but for OS/2 binaries it must be set by 71 //hand when ODIN_FORCE_WIN32_TIB is defined in order for SEH (structured 72 //exception handling) to work properly. Must be called before RegisterLxDll()/ 73 //RegisterLxExe(). 72 74 //****************************************************************************** 73 VOID WIN32API EnableSEH();75 VOID WIN32API ForceWin32TIB(); 74 76 75 77 #ifdef __cplusplus -
trunk/include/wprocess.h
r21941 r21999 62 62 extern BOOL fSwitchTIBSel; // TRUE -> switch TIB selectors 63 63 // FALSE -> don't 64 extern BOOL f SEHEnabled;// TRUE -> SEH support enabled64 extern BOOL fForceWin32TIB;// TRUE -> SEH support enabled 65 65 // FALSE -> not enabled 66 66 extern BOOL fExitProcess; -
trunk/src/Odin32API/odindll.cpp
r21384 r21999 87 87 88 88 // Uncomment this to enable proper __try/__except support: 89 //EnableSEH(); 89 #ifdef ODIN_FORCE_WIN32_TIB 90 ForceWin32TIB(); 91 #endif 90 92 dllHandle = RegisterLxDll(hModule, LibMain, (PVOID)&_Resource_PEResTab); 91 93 if(dllHandle == 0) -
trunk/src/Odin32API/odinexe.cpp
r21384 r21999 27 27 int main(int argc, char *argv[]) 28 28 { 29 // Uncomment this to enable proper __try/__except support: 30 //EnableSEH(); 29 #ifdef ODIN_FORCE_WIN32_TIB 30 // Needed for proper __try/__except support: 31 ForceWin32TIB(); 32 #endif 31 33 RegisterLxExe(WinMain, (PVOID)&_Resource_PEResTab); 32 34 } -
trunk/src/kernel32/exceptions.cpp
r21980 r21999 120 120 PCONTEXTRECORD pCtxRec, PVOID p, PSZ szTrapDump); 121 121 122 int __cdecl __seh_handler(PWINEXCEPTION_RECORD pRec, 123 PWINEXCEPTION_FRAME pFrame, 124 PCONTEXTRECORD pContext, PVOID pVoid); 125 126 PWINEXCEPTION_FRAME __cdecl __seh_get_prev_frame(PWINEXCEPTION_FRAME pFrame); 122 int __cdecl __seh_handler(PVOID pRec, PVOID pFrame, 123 PVOID pContext, PVOID pVoid); 124 125 int __cdecl __seh_handler_win32(PWINEXCEPTION_RECORD pRec, 126 PWINEXCEPTION_FRAME pFrame, 127 PCONTEXTRECORD pContext, PVOID pVoid); 128 129 PWINEXCEPTION_FRAME __cdecl __seh_get_prev_frame_win32(PWINEXCEPTION_FRAME pFrame); 127 130 128 131 #ifdef DEBUG … … 363 366 while( (pFrame != NULL) && ((ULONG)((ULONG)pFrame & 0xFFFFF000) != 0xFFFFF000) ) 364 367 { 365 pPrevFrame = __seh_get_prev_frame (pFrame);368 pPrevFrame = __seh_get_prev_frame_win32(pFrame); 366 369 367 370 dprintf(("KERNEL32: RtlDispatchException - pframe=%08X, pframe->Prev=%08X", … … 518 521 while (((ULONG)((ULONG)frame & 0xFFFFF000) != 0xFFFFF000) && (frame != pEndFrame)) 519 522 { 520 prevFrame = __seh_get_prev_frame (frame);523 prevFrame = __seh_get_prev_frame_win32(frame); 521 524 522 525 /* Check frame address */ … … 590 593 dprintf(("KERNEL32: RtlUnwind (after) - frame=%08X, frame->Prev=%08X", frame, 591 594 ((ULONG)((ULONG)frame & 0xFFFFF000) != 0xFFFFF000) ? 592 __seh_get_prev_frame (frame) : (void*)0xFFFFFFFF));595 __seh_get_prev_frame_win32(frame) : (void*)0xFFFFFFFF)); 593 596 } 594 597 … … 1242 1245 PVOID p) 1243 1246 { 1247 // we need special processing when reused from ___seh_handler 1248 BOOL fSEH = pERegRec->ExceptionHandler == (_ERR *)__seh_handler; 1249 1244 1250 #ifdef DEBUG 1245 1251 //SvL: Check if exception inside debug fprintf -> if so, clear lock so … … 1279 1285 if (pERepRec->fHandlerFlags & EH_EXIT_UNWIND) 1280 1286 { 1281 dprintf(("KERNEL32: OS2ExceptionHandler : EH_EXIT_UNWIND, "1282 "unwinding all the Win32 exception chain" ));1287 dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): EH_EXIT_UNWIND, " 1288 "unwinding all the Win32 exception chain", fSEH)); 1283 1289 RtlUnwind(NULL, 0, 0, 0); 1284 1290 } 1285 1291 else 1286 1292 { 1287 dprintf(("KERNEL32: OS2ExceptionHandler : EH_UNWINDING, "1288 "unwinding the Win32 exception chain up to 0x%p", pERegRec));1293 dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): EH_UNWINDING, " 1294 "unwinding the Win32 exception chain up to 0x%p", fSEH, pERegRec)); 1289 1295 1290 1296 // find a Win32 exception frame closest to the OS/2 one (pERegRec) … … 1295 1301 while (frame != NULL && ((ULONG)frame)!= 0xFFFFFFFF && 1296 1302 ((ULONG)frame) <= ((ULONG)pERegRec)) 1297 frame = __seh_get_prev_frame (frame);1303 frame = __seh_get_prev_frame_win32(frame); 1298 1304 if (((ULONG)frame) == 0xFFFFFFFF) 1299 1305 frame = NULL; … … 1316 1322 case XCPT_FLOAT_UNDERFLOW: 1317 1323 dprintfException(pERepRec, pERegRec, pCtxRec, p); 1318 dprintf(("KERNEL32: OS2ExceptionHandler : FPU exception\n"));1319 if((!fIsOS2Image || f SEHEnabled) && !fExitProcess) //Only for real win32 apps or if SEH enabled1320 { 1321 if(OSLibDispatchException(pERepRec, pERegRec, pCtxRec, p ) == FALSE)1324 dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): FPU exception\n", fSEH)); 1325 if((!fIsOS2Image || fForceWin32TIB || fSEH) && !fExitProcess) //Only for real win32 apps or when forced 1326 { 1327 if(OSLibDispatchException(pERepRec, pERegRec, pCtxRec, p, fSEH) == FALSE) 1322 1328 { 1323 1329 pCtxRec->ctx_env[0] |= 0x1F; … … 1328 1334 else 1329 1335 { 1330 dprintf(("KERNEL32: OS2ExceptionHandler : fix and continue\n"));1336 dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): fix and continue\n", fSEH)); 1331 1337 goto continueexecution; 1332 1338 } 1333 1339 } 1334 dprintf(("KERNEL32: OS2ExceptionHandler : continue search\n"));1340 dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): continue search\n", fSEH)); 1335 1341 goto continuesearch; 1336 1342 … … 1439 1445 DosQueryMem((PVOID) pERepRec->ExceptionInfo[1], 1440 1446 &offset, &accessflag); 1441 dprintf(("KERNEL32: OS2ExceptionHandler : failed address info 0x%X size 0x%X. flag %X\n",1442 pERepRec->ExceptionInfo[1], offset, accessflag));1447 dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): failed address info 0x%X size 0x%X. flag %X\n", 1448 fSEH, pERepRec->ExceptionInfo[1], offset, accessflag)); 1443 1449 /* check for valid address */ 1444 1450 if (!pERepRec->ExceptionInfo[1] || … … 1454 1460 offset + (pERepRec->ExceptionInfo[1] - (pERepRec->ExceptionInfo[1] & 0xFFFFF000)), 1455 1461 accessflag | PAG_WRITE | PAG_COMMIT); 1456 dprintf(("KERNEL32: OS2ExceptionHandler : commiting 0x%X size 0x%X. RC: %i\n",1457 pERepRec->ExceptionInfo[1] & 0xFFFFF000,1462 dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): commiting 0x%X size 0x%X. RC: %i\n", 1463 fSEH, pERepRec->ExceptionInfo[1] & 0xFFFFF000, 1458 1464 offset + (pERepRec->ExceptionInfo[1] - (pERepRec->ExceptionInfo[1] & 0xFFFFF000)), 1459 1465 rc)); … … 1508 1514 1509 1515 //NOTE: This will not work properly in case multiple threads execute this code 1510 dprintf((" Changing thread registers (SetThreadContext)!!"));1516 dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): Changing thread registers (SetThreadContext)!!", fSEH)); 1511 1517 1512 1518 if(teb->o.odin.context.ContextFlags & WINCONTEXT_CONTROL) { … … 1583 1589 #endif 1584 1590 1585 if((!fIsOS2Image || f SEHEnabled) && !fExitProcess) //Only for real win32 apps or if SEH enabled1586 { 1587 if(OSLibDispatchException(pERepRec, pERegRec, pCtxRec, p ) == TRUE)1591 if((!fIsOS2Image || fForceWin32TIB || fSEH) && !fExitProcess) //Only for real win32 apps or when forced 1592 { 1593 if(OSLibDispatchException(pERepRec, pERegRec, pCtxRec, p, fSEH) == TRUE) 1588 1594 { 1589 dprintf(("KERNEL32: OS2ExceptionHandler : fix and continue\n"));1595 dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): fix and continue\n", fSEH)); 1590 1596 goto continueexecution; 1591 1597 } 1592 1598 else 1593 1599 { 1594 dprintf(("KERNEL32: OS2ExceptionHandler : continue search\n"));1600 dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): continue search\n", fSEH)); 1595 1601 goto continuesearch; 1596 1602 } … … 1605 1611 if(rc == NO_ERROR) 1606 1612 { 1607 dprintf(("KERNEL32: OS2ExceptionHandler : Continue and kill thread"));1613 dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): Continue and kill thread", fSEH)); 1608 1614 1609 1615 pCtxRec->ctx_RegEip = (pTIB->tib_ptib2->tib2_ultid != 1) ? (ULONG)KillWin32Thread : (ULONG)KillWin32Process; … … 1620 1626 logException(pERepRec, pERegRec, pCtxRec, p); 1621 1627 1622 dprintf(("KERNEL32: OS2ExceptionHandler : Continue and kill\n"));1628 dprintf(("KERNEL32: OS2ExceptionHandler (fSEH=%d): Continue and kill\n", fSEH)); 1623 1629 1624 1630 pCtxRec->ctx_RegEip = (ULONG)KillWin32Process; … … 1648 1654 1649 1655 // Make sure we detect a stack overflow condition before the system does 1650 if ((!fIsOS2Image || f SEHEnabled) && //Only for real win32 apps or if SEH enabled1656 if ((!fIsOS2Image || fForceWin32TIB || fSEH) && //Only for real win32 apps or when forced 1651 1657 pERepRec->ExceptionInfo[1] >= stackbottom && 1652 1658 pERepRec->ExceptionInfo[1] < stacktop … … 1704 1710 recoutofstack.cParameters = 0; 1705 1711 1706 if(OSLibDispatchException(&recoutofstack, pERegRec, pCtxRec, p ) == TRUE)1712 if(OSLibDispatchException(&recoutofstack, pERegRec, pCtxRec, p, fSEH) == TRUE) 1707 1713 { 1708 1714 goto continueexecution; … … 1714 1720 { 1715 1721 // Throw EXCEPTION_GUARD_PAGE_VIOLATION in the Win32 context 1716 if((!fIsOS2Image || f SEHEnabled) && !fExitProcess) //Only for real win32 apps or if SEH enabled1722 if((!fIsOS2Image || fForceWin32TIB || fSEH) && !fExitProcess) //Only for real win32 apps or when forced 1717 1723 { 1718 if(OSLibDispatchException(pERepRec, pERegRec, pCtxRec, p ) == TRUE)1724 if(OSLibDispatchException(pERepRec, pERegRec, pCtxRec, p, fSEH) == TRUE) 1719 1725 { 1720 1726 goto continueexecution; … … 1961 1967 while ((pFrame != NULL) && ((ULONG)pFrame != 0xFFFFFFFF)) 1962 1968 { 1963 PWINEXCEPTION_FRAME pPrevFrame = __seh_get_prev_frame (pFrame);1969 PWINEXCEPTION_FRAME pPrevFrame = __seh_get_prev_frame_win32(pFrame); 1964 1970 dprintf((" Record at %08X, Prev at %08X, handler at %08X%s", 1965 1971 pFrame, pPrevFrame, pFrame->Handler, 1966 pFrame->Handler == (PEXCEPTION_HANDLER)__seh_handler ? 1967 " (SEH)" : ""));1972 pFrame->Handler == (PEXCEPTION_HANDLER)__seh_handler ? " (SEH)" : 1973 pFrame->Handler == (PEXCEPTION_HANDLER)__seh_handler_win32 ? " (SEH Win32)" : "")); 1968 1974 if (pFrame == pPrevFrame) 1969 1975 { -
trunk/src/kernel32/exceptutil.asm
r21916 r21999 151 151 OS2ExceptionHandler endp 152 152 153 154 PUBLIC OSLibDispatchException 155 EXTRN OSLibDispatchExceptionWin32:NEAR 156 EXTRN ___seh_handler_filter:NEAR 157 158 ; BOOL APIENTRY OSLibDispatchException(PEXCEPTIONREPORTRECORD pReportRec, 159 ; PEXCEPTIONREGISTRATIONRECORD pRegistrationRec, 160 ; PCONTEXTRECORD pContextRec, PVOID p, 161 ; BOOL fSEH); 162 OSLibDispatchException proc near 163 cmp dword ptr [esp + 20], 0 ; fSEH == FALSE? 164 jz OSLibDispatchExceptionWin32 165 jmp ___seh_handler_filter 166 OSLibDispatchException endp 167 168 153 169 PUBLIC _QueryExceptionChain 154 170 -
trunk/src/kernel32/kernel32.def
r21996 r21999 1358 1358 RtlUniform = "_RtlUniform@4" @3531 NONAME 1359 1359 1360 ___seh_handler @3600 NONAME 1361 "_EnableSEH@0" @3601 NONAME 1360 ___seh_handler_win32 @3600 NONAME 1361 "_ForceWin32TIB@0" @3601 NONAME 1362 ___seh_handler @3602 NONAME -
trunk/src/kernel32/kernel32dbg.def
r21996 r21999 1357 1357 RtlUniform = "_RtlUniform@4" @3531 NONAME 1358 1358 1359 ___seh_handler @3600 NONAME 1360 "_EnableSEH@0" @3601 NONAME 1359 ___seh_handler_win32 @3600 NONAME 1360 "_ForceWin32TIB@0" @3601 NONAME 1361 ___seh_handler @3602 NONAME -
trunk/src/kernel32/oslibexcept.cpp
r21980 r21999 16 16 #include <win32type.h> 17 17 #include <misc.h> 18 #include "oslibexcept.h"19 18 #include <exceptions.h> 20 19 #include <wprocess.h> 21 20 21 #include "oslibexcept.h" 22 22 23 #define DBG_LOCALLOG DBG_oslibexcept 23 24 #include "dbglocal.h" 24 25 25 //****************************************************************************** 26 //Dispatches OS/2 exception to win32 handler 27 //Returns: TRUE, win32 exception handler returned continue execution 28 // FALSE, otherwise 29 //****************************************************************************** 30 BOOL APIENTRY OSLibDispatchException(PEXCEPTIONREPORTRECORD pReportRec, 31 PEXCEPTIONREGISTRATIONRECORD pRegistrationRec, 32 PCONTEXTRECORD pContextRec, PVOID p) 26 /** 27 * Converts the OS/2 exception information to the Win32 exception information. 28 * 29 * Returns TRUE on succes and FALSE otherwise. 30 */ 31 BOOL APIENTRY OSLibConvertExceptionInfo(PEXCEPTIONREPORTRECORD pReportRec, 32 PCONTEXTRECORD pContextRec, 33 PWINEXCEPTION_RECORD pWinReportRec, 34 PWINCONTEXT pWinContextRec, 35 TEB *pWinTEB) 33 36 { 34 WINEXCEPTION_RECORD winreportrec; 35 WINCONTEXT wincontextrec; 36 ULONG rc; 37 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 37 memset(pWinReportRec, 0, sizeof(*pWinReportRec)); 38 memcpy(pWinReportRec, pReportRec, sizeof(*pReportRec)); 39 40 switch (pReportRec->ExceptionNum) 41 { 42 case XCPT_FLOAT_DENORMAL_OPERAND: 43 pWinReportRec->ExceptionCode = EXCEPTION_FLT_DENORMAL_OPERAND; 44 break; 45 case XCPT_FLOAT_DIVIDE_BY_ZERO: 46 pWinReportRec->ExceptionCode = EXCEPTION_FLT_DIVIDE_BY_ZERO; 47 break; 48 case XCPT_FLOAT_INEXACT_RESULT: 49 pWinReportRec->ExceptionCode = EXCEPTION_FLT_INEXACT_RESULT; 50 break; 51 case XCPT_FLOAT_INVALID_OPERATION: 52 pWinReportRec->ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION; 53 break; 54 case XCPT_FLOAT_OVERFLOW: 55 pWinReportRec->ExceptionCode = EXCEPTION_FLT_OVERFLOW; 56 break; 57 case XCPT_FLOAT_STACK_CHECK: 58 pWinReportRec->ExceptionCode = EXCEPTION_FLT_STACK_CHECK; 59 break; 60 case XCPT_FLOAT_UNDERFLOW: 61 pWinReportRec->ExceptionCode = EXCEPTION_FLT_UNDERFLOW; 62 break; 63 case XCPT_INTEGER_DIVIDE_BY_ZERO: 64 pWinReportRec->ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO; 65 break; 66 case XCPT_INTEGER_OVERFLOW: 67 pWinReportRec->ExceptionCode = EXCEPTION_INT_OVERFLOW; 68 break; 69 case XCPT_PRIVILEGED_INSTRUCTION: 70 pWinReportRec->ExceptionCode = EXCEPTION_PRIV_INSTRUCTION; 71 break; 72 case XCPT_BREAKPOINT: 73 pWinReportRec->ExceptionCode = EXCEPTION_BREAKPOINT; 74 break; 75 case XCPT_SINGLE_STEP: 76 pWinReportRec->ExceptionCode = EXCEPTION_SINGLE_STEP; 77 break; 78 case XCPT_ARRAY_BOUNDS_EXCEEDED: 79 pWinReportRec->ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED; 80 break; 81 case XCPT_DATATYPE_MISALIGNMENT: 82 pWinReportRec->ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT; 83 break; 84 case XCPT_ILLEGAL_INSTRUCTION: 85 pWinReportRec->ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION; 86 break; 87 case XCPT_INVALID_LOCK_SEQUENCE: 88 pWinReportRec->ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION; 89 break; 90 case XCPT_GUARD_PAGE_VIOLATION: 91 pWinReportRec->ExceptionCode = EXCEPTION_GUARD_PAGE; 92 break; 93 case XCPT_UNABLE_TO_GROW_STACK: 94 pWinReportRec->ExceptionCode = EXCEPTION_STACK_OVERFLOW; 95 break; 96 case XCPT_IN_PAGE_ERROR: 97 pWinReportRec->ExceptionCode = EXCEPTION_IN_PAGE_ERROR; 98 break; 99 case XCPT_ACCESS_VIOLATION: 100 pWinReportRec->ExceptionCode = EXCEPTION_ACCESS_VIOLATION; 101 break; 102 default: // no other exceptions should be dispatched to win32 apps 103 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 130 TEB *winteb = GetThreadTEB(); 131 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; 104 } 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 { 114 pWinContextRec->ContextFlags |= WINCONTEXT_CONTROL; 115 pWinContextRec->Ebp = pContextRec->ctx_RegEbp; 116 pWinContextRec->Eip = pContextRec->ctx_RegEip; 117 pWinContextRec->SegCs = pContextRec->ctx_SegCs; 118 pWinContextRec->EFlags = pContextRec->ctx_EFlags; 119 pWinContextRec->Esp = pContextRec->ctx_RegEsp; 120 pWinContextRec->SegSs = pContextRec->ctx_SegSs; 121 } 122 if (pContextRec->ContextFlags & CONTEXT_INTEGER) 123 { 124 pWinContextRec->ContextFlags |= WINCONTEXT_INTEGER; 125 pWinContextRec->Edi = pContextRec->ctx_RegEdi; 126 pWinContextRec->Esi = pContextRec->ctx_RegEsi; 127 pWinContextRec->Ebx = pContextRec->ctx_RegEbx; 128 pWinContextRec->Edx = pContextRec->ctx_RegEdx; 129 pWinContextRec->Ecx = pContextRec->ctx_RegEcx; 130 pWinContextRec->Eax = pContextRec->ctx_RegEax; 131 } 132 133 if (pContextRec->ContextFlags & CONTEXT_SEGMENTS) 134 { 135 pWinContextRec->ContextFlags |= WINCONTEXT_SEGMENTS; 136 pWinContextRec->SegGs = pContextRec->ctx_SegGs; 137 // set Wn32 TEB if we run in switch FS mode 138 if (pWinTEB) 139 pWinContextRec->SegFs = pWinTEB->teb_sel; 140 else 141 pWinContextRec->SegFs = pContextRec->ctx_SegFs; 142 pWinContextRec->SegEs = pContextRec->ctx_SegEs; 143 pWinContextRec->SegDs = pContextRec->ctx_SegDs; 144 } 145 146 if (pContextRec->ContextFlags & CONTEXT_FLOATING_POINT) 147 { 148 pWinContextRec->ContextFlags |= WINCONTEXT_FLOATING_POINT; 143 149 //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 } 147 //It doesn't seem correct if we dispatch real exceptions to win32 apps 148 //Some just call RtlUnwind and continue as if they were processing an 149 //exception thrown by C++ code. (instead of real OS exception) 150 #if 1 151 // We need to reset FS to its original (Win32) value, otherwise we'll likely 152 // fuck up the Win32 exception handlers. They could end up using the wrong 153 // exception chain if they access FS:[0] directly. 154 DWORD oldsel = SetReturnFS(winteb->teb_sel); 155 156 switch(pReportRec->ExceptionNum) { 157 case XCPT_FLOAT_DENORMAL_OPERAND: 158 case XCPT_FLOAT_DIVIDE_BY_ZERO: 159 case XCPT_FLOAT_INEXACT_RESULT: 160 case XCPT_FLOAT_INVALID_OPERATION: 161 case XCPT_FLOAT_OVERFLOW: 162 case XCPT_FLOAT_STACK_CHECK: 163 case XCPT_FLOAT_UNDERFLOW: 164 rc = RtlDispatchException(&winreportrec, &wincontextrec); 165 break; 166 167 case XCPT_ACCESS_VIOLATION: 168 rc = RtlDispatchException(&winreportrec, &wincontextrec); 169 break; 170 171 case XCPT_ILLEGAL_INSTRUCTION: 172 case XCPT_PRIVILEGED_INSTRUCTION: 173 case XCPT_INTEGER_DIVIDE_BY_ZERO: 174 case XCPT_UNABLE_TO_GROW_STACK: 175 case XCPT_GUARD_PAGE_VIOLATION: 150 memcpy(&pWinContextRec->FloatSave, 151 pContextRec->ctx_env, sizeof(pContextRec->ctx_env)); 152 memcpy(&pWinContextRec->FloatSave.RegisterArea, 153 pContextRec->ctx_stack, sizeof(pContextRec->ctx_stack)); 154 } 155 156 return TRUE; 157 } 158 159 /** 160 * Converts the Win32 exception handler result to the OS/2 exception handler 161 * result. 162 * 163 * Returns TRUE if the OS/2 exception handler result should be 164 * XCPT_CONTINUE_EXECUTION and FALSE otherwise. 165 */ 166 BOOL APIENTRY OSLibConvertExceptionResult(ULONG rc, 167 PWINCONTEXT pWinContextRec, 168 PCONTEXTRECORD pContextRec) 169 { 170 if (rc != ExceptionContinueExecution) 171 { 172 dprintf(("Win32 exception handler returned %x", rc)); 173 return FALSE; 174 } 175 176 dprintf(("Win32 exception handler returned ExceptionContinueExecution")); 177 178 if (pWinContextRec->ContextFlags & WINCONTEXT_CONTROL) 179 { 180 pContextRec->ctx_RegEbp = pWinContextRec->Ebp; 181 pContextRec->ctx_RegEip = pWinContextRec->Eip; 182 pContextRec->ctx_SegCs = pWinContextRec->SegCs; 183 pContextRec->ctx_EFlags = pWinContextRec->EFlags; 184 pContextRec->ctx_RegEsp = pWinContextRec->Esp; 185 pContextRec->ctx_SegSs = pWinContextRec->SegSs; 186 } 187 188 if (pWinContextRec->ContextFlags & WINCONTEXT_INTEGER) 189 { 190 pContextRec->ctx_RegEdi = pWinContextRec->Edi; 191 pContextRec->ctx_RegEsi = pWinContextRec->Esi; 192 pContextRec->ctx_RegEbx = pWinContextRec->Ebx; 193 pContextRec->ctx_RegEdx = pWinContextRec->Edx; 194 pContextRec->ctx_RegEcx = pWinContextRec->Ecx; 195 pContextRec->ctx_RegEax = pWinContextRec->Eax; 196 } 197 198 #if 0 199 // This is not a good idea 200 if (pWinContextRec->ContextFlags & WINCONTEXT_SEGMENTS) 201 { 202 pContextRec->ctx_SegGs = pWinContextRec->SegGs; 203 pContextRec->ctx_SegFs = pWinContextRec->SegFs; 204 pContextRec->ctx_SegEs = pWinContextRec->SegEs; 205 pContextRec->ctx_SegDs = pWinContextRec->SegDs; 206 } 207 #endif 208 209 if (pWinContextRec->ContextFlags & WINCONTEXT_FLOATING_POINT) 210 { 211 //TODO: First 7 dwords the same? 212 memcpy(pContextRec->ctx_env, &pWinContextRec->FloatSave, 213 sizeof(pContextRec->ctx_env)); 214 memcpy(pContextRec->ctx_stack, &pWinContextRec->FloatSave.RegisterArea, 215 sizeof(pContextRec->ctx_stack)); 216 } 217 218 if (pContextRec->ContextFlags & CONTEXT_CONTROL) /* check flags */ 219 dprintf((" SS:ESP=%04x:%08x EFLAGS=%08x\n", 220 pContextRec->ctx_SegSs, 221 pContextRec->ctx_RegEsp, 222 pContextRec->ctx_EFlags)); 223 dprintf((" CS:EIP=%04x:%08x EBP =%08x\n", 224 pContextRec->ctx_SegCs, 225 pContextRec->ctx_RegEip, 226 pContextRec->ctx_RegEbp)); 227 228 if (pContextRec->ContextFlags & CONTEXT_INTEGER) /* check flags */ 229 dprintf((" EAX=%08x EBX=%08x ESI=%08x\n", 230 pContextRec->ctx_RegEax, 231 pContextRec->ctx_RegEbx, 232 pContextRec->ctx_RegEsi)); 233 dprintf((" ECX=%08x EDX=%08x EDI=%08x\n", 234 pContextRec->ctx_RegEcx, 235 pContextRec->ctx_RegEdx, 236 pContextRec->ctx_RegEdi)); 237 238 if (pContextRec->ContextFlags & CONTEXT_SEGMENTS) /* check flags */ 239 dprintf((" DS=%04x ES=%08x" 240 " FS=%04x GS=%04x\n", 241 pContextRec->ctx_SegDs, 242 pContextRec->ctx_SegEs, 243 pContextRec->ctx_SegFs, 244 pContextRec->ctx_SegGs)); 245 246 if (pContextRec->ContextFlags & CONTEXT_FLOATING_POINT) /* check flags */ 247 { 248 ULONG ulCounter; /* temporary local counter for fp stack */ 249 250 dprintf((" Env[0]=%08x Env[1]=%08x Env[2]=%08x Env[3]=%08x\n", 251 pContextRec->ctx_env[0], 252 pContextRec->ctx_env[1], 253 pContextRec->ctx_env[2], 254 pContextRec->ctx_env[3])); 255 256 dprintf((" Env[4]=%08x Env[5]=%08x Env[6]=%08x\n", 257 pContextRec->ctx_env[4], 258 pContextRec->ctx_env[5], 259 pContextRec->ctx_env[6])); 260 261 for (ulCounter = 0; 262 ulCounter < 8; /* see TOOLKIT\INCLUDE\BSEEXPT.H, _CONTEXT structure */ 263 ulCounter ++) 264 dprintf((" FP-Stack[%u] losig=%08x hisig=%08x signexp=%04x\n", 265 ulCounter, 266 pContextRec->ctx_stack[0].losig, 267 pContextRec->ctx_stack[0].hisig, 268 pContextRec->ctx_stack[0].signexp)); 269 } 270 271 return TRUE; 272 } 273 274 /** 275 * Dispatches OS/2 exception to win32 handler. 276 * 277 * Returns TRUE if the Win32 exception handler returned 278 * ExceptionContinueExecution and FALSE otherwise. 279 */ 280 BOOL APIENTRY OSLibDispatchExceptionWin32(PEXCEPTIONREPORTRECORD pReportRec, 281 PEXCEPTIONREGISTRATIONRECORD pRegistrationRec, 282 PCONTEXTRECORD pContextRec, PVOID p) 283 { 284 WINEXCEPTION_RECORD winReportRec; 285 WINCONTEXT winContextRec; 286 287 ULONG rc; 288 289 TEB *pWinTEB = GetThreadTEB(); 290 291 OSLibConvertExceptionInfo(pReportRec, pContextRec, 292 &winReportRec, &winContextRec, pWinTEB); 293 294 // It doesn't seem correct if we dispatch real exceptions to win32 apps 295 // Some just call RtlUnwind and continue as if they were processing an 296 // exception thrown by C++ code. (instead of real OS exception) 297 298 // We need to reset FS to its original (Win32) value, otherwise we'll likely 299 // fuck up the Win32 exception handlers. They could end up using the wrong 300 // exception chain if they access FS:[0] directly. 301 DWORD oldsel = SetReturnFS(pWinTEB->teb_sel); 302 303 switch(pReportRec->ExceptionNum) 304 { 305 case XCPT_FLOAT_DENORMAL_OPERAND: 306 case XCPT_FLOAT_DIVIDE_BY_ZERO: 307 case XCPT_FLOAT_INEXACT_RESULT: 308 case XCPT_FLOAT_INVALID_OPERATION: 309 case XCPT_FLOAT_OVERFLOW: 310 case XCPT_FLOAT_STACK_CHECK: 311 case XCPT_FLOAT_UNDERFLOW: 312 rc = RtlDispatchException(&winReportRec, &winContextRec); 313 break; 314 315 case XCPT_ACCESS_VIOLATION: 316 rc = RtlDispatchException(&winReportRec, &winContextRec); 317 break; 318 319 case XCPT_ILLEGAL_INSTRUCTION: 320 case XCPT_PRIVILEGED_INSTRUCTION: 321 case XCPT_INTEGER_DIVIDE_BY_ZERO: 322 case XCPT_UNABLE_TO_GROW_STACK: 323 case XCPT_GUARD_PAGE_VIOLATION: 176 324 #ifndef DEBUG 177 case XCPT_BREAKPOINT:325 case XCPT_BREAKPOINT: 178 326 #endif 179 rc = RtlDispatchException(&win reportrec, &wincontextrec);327 rc = RtlDispatchException(&winReportRec, &winContextRec); 180 328 break; 181 329 182 330 #ifdef DEBUG 183 case XCPT_BREAKPOINT:331 case XCPT_BREAKPOINT: 184 332 #endif 185 case XCPT_INTEGER_OVERFLOW:186 case XCPT_SINGLE_STEP:187 case XCPT_ARRAY_BOUNDS_EXCEEDED:188 case XCPT_DATATYPE_MISALIGNMENT:189 case XCPT_INVALID_LOCK_SEQUENCE:190 case XCPT_IN_PAGE_ERROR:191 default:192 333 case XCPT_INTEGER_OVERFLOW: 334 case XCPT_SINGLE_STEP: 335 case XCPT_ARRAY_BOUNDS_EXCEEDED: 336 case XCPT_DATATYPE_MISALIGNMENT: 337 case XCPT_INVALID_LOCK_SEQUENCE: 338 case XCPT_IN_PAGE_ERROR: 339 default: 340 SetFS(oldsel); //restore FS 193 341 return FALSE; //let's not dispatch those for now 194 } 195 SetFS(oldsel); //restore FS 196 197 if(rc == ExceptionContinueExecution) { 198 dprintf(("Win32 exception handler returned ExceptionContinueExecution")); 199 if(wincontextrec.ContextFlags & WINCONTEXT_CONTROL) { 200 pContextRec->ctx_RegEbp = wincontextrec.Ebp; 201 pContextRec->ctx_RegEip = wincontextrec.Eip; 202 pContextRec->ctx_SegCs = wincontextrec.SegCs; 203 pContextRec->ctx_EFlags = wincontextrec.EFlags; 204 pContextRec->ctx_RegEsp = wincontextrec.Esp; 205 pContextRec->ctx_SegSs = wincontextrec.SegSs; 206 } 207 if(wincontextrec.ContextFlags & WINCONTEXT_INTEGER) { 208 pContextRec->ctx_RegEdi = wincontextrec.Edi; 209 pContextRec->ctx_RegEsi = wincontextrec.Esi; 210 pContextRec->ctx_RegEbx = wincontextrec.Ebx; 211 pContextRec->ctx_RegEdx = wincontextrec.Edx; 212 pContextRec->ctx_RegEcx = wincontextrec.Ecx; 213 pContextRec->ctx_RegEax = wincontextrec.Eax; 214 } 215 #if 0 216 //This is not a good idea 217 if(wincontextrec.ContextFlags & WINCONTEXT_SEGMENTS) { 218 pContextRec->ctx_SegGs = wincontextrec.SegGs; 219 pContextRec->ctx_SegFs = wincontextrec.SegFs; 220 pContextRec->ctx_SegEs = wincontextrec.SegEs; 221 pContextRec->ctx_SegDs = wincontextrec.SegDs; 222 } 223 #endif 224 if(wincontextrec.ContextFlags & WINCONTEXT_FLOATING_POINT) { 225 //TODO: First 7 dwords the same? 226 memcpy(pContextRec->ctx_env, &wincontextrec.FloatSave, sizeof(pContextRec->ctx_env)); 227 memcpy(pContextRec->ctx_stack, &wincontextrec.FloatSave.RegisterArea, sizeof(pContextRec->ctx_stack)); 228 } 229 if (pContextRec->ContextFlags & CONTEXT_CONTROL) /* check flags */ 230 dprintf((" SS:ESP=%04x:%08x EFLAGS=%08x\n", 231 pContextRec->ctx_SegSs, 232 pContextRec->ctx_RegEsp, 233 pContextRec->ctx_EFlags)); 234 dprintf((" CS:EIP=%04x:%08x EBP =%08x\n", 235 pContextRec->ctx_SegCs, 236 pContextRec->ctx_RegEip, 237 pContextRec->ctx_RegEbp)); 238 239 if (pContextRec->ContextFlags & CONTEXT_INTEGER) /* check flags */ 240 dprintf((" EAX=%08x EBX=%08x ESI=%08x\n", 241 pContextRec->ctx_RegEax, 242 pContextRec->ctx_RegEbx, 243 pContextRec->ctx_RegEsi)); 244 dprintf((" ECX=%08x EDX=%08x EDI=%08x\n", 245 pContextRec->ctx_RegEcx, 246 pContextRec->ctx_RegEdx, 247 pContextRec->ctx_RegEdi)); 248 249 if (pContextRec->ContextFlags & CONTEXT_SEGMENTS) /* check flags */ 250 dprintf((" DS=%04x ES=%08x" 251 " FS=%04x GS=%04x\n", 252 pContextRec->ctx_SegDs, 253 pContextRec->ctx_SegEs, 254 pContextRec->ctx_SegFs, 255 pContextRec->ctx_SegGs)); 256 257 if (pContextRec->ContextFlags & CONTEXT_FLOATING_POINT) /* check flags */ 258 { 259 ULONG ulCounter; /* temporary local counter for fp stack */ 260 261 dprintf((" Env[0]=%08x Env[1]=%08x Env[2]=%08x Env[3]=%08x\n", 262 pContextRec->ctx_env[0], 263 pContextRec->ctx_env[1], 264 pContextRec->ctx_env[2], 265 pContextRec->ctx_env[3])); 266 267 dprintf((" Env[4]=%08x Env[5]=%08x Env[6]=%08x\n", 268 pContextRec->ctx_env[4], 269 pContextRec->ctx_env[5], 270 pContextRec->ctx_env[6])); 271 272 for (ulCounter = 0; 273 ulCounter < 8; /* see TOOLKIT\INCLUDE\BSEEXPT.H, _CONTEXT structure */ 274 ulCounter ++) 275 dprintf((" FP-Stack[%u] losig=%08x hisig=%08x signexp=%04x\n", 276 ulCounter, 277 pContextRec->ctx_stack[0].losig, 278 pContextRec->ctx_stack[0].hisig, 279 pContextRec->ctx_stack[0].signexp)); 280 } 281 282 return TRUE; 283 } 284 dprintf(("Win32 exception handler returned %x", rc)); 285 #endif 286 return FALSE; 342 } 343 344 SetFS(oldsel); //restore FS 345 346 return OSLibConvertExceptionResult(rc, &winContextRec, pContextRec); 287 347 } 288 //******************************************************************************289 //****************************************************************************** -
trunk/src/kernel32/oslibexcept.h
r9617 r21999 9 9 #define __OSLIBEXCEPT_H__ 10 10 11 #ifdef __cplusplus 12 extern "C" { 13 #endif 11 BOOL APIENTRY OSLibConvertExceptionInfo(PEXCEPTIONREPORTRECORD pReportRec, 12 PCONTEXTRECORD pContextRec, 13 PWINEXCEPTION_RECORD pWinReportRec, 14 PWINCONTEXT pWinContextRec, 15 TEB *pWinTEB); 14 16 15 //****************************************************************************** 16 //Dispatches OS/2 exception to win32 handler 17 //Returns: TRUE, win32 exception handler returned continue execution 18 // FALSE, otherwise 19 //****************************************************************************** 17 BOOL APIENTRY OSLibConvertExceptionResult(ULONG rc, 18 PWINCONTEXT pWinContextRec, 19 PCONTEXTRECORD pContextRec); 20 20 21 BOOL APIENTRY OSLibDispatchException(PEXCEPTIONREPORTRECORD pReportRec, 21 22 PEXCEPTIONREGISTRATIONRECORD pRegistrationRec, 22 PCONTEXTRECORD pContextRec, PVOID p); 23 24 #ifdef __cplusplus 25 } 26 #endif 23 PCONTEXTRECORD pContextRec, PVOID p, 24 BOOL fSEH); 27 25 28 26 #endif -
trunk/src/kernel32/seh/sehutil.s
r21916 r21999 8 8 9 9 .global ___seh_handler 10 .global ___seh_get_prev_frame 10 .global ___seh_handler_filter 11 .global ___seh_handler_win32 12 .global ___seh_get_prev_frame_win32 13 14 #define sizeof_WINEXCEPTION_RECORD 80 15 #define sizeof_WINCONTEXT 296 11 16 12 17 /* 13 18 * extern "C" 14 * int __seh_handler(PEXCEPTION _RECORD pRec,19 * int __seh_handler(PEXCEPTIONREPORTRECORD pRec, 15 20 * struct ___seh_EXCEPTION_FRAME *pFrame, 16 * PCONTEXT pContext, PVOID)17 * 18 * Win32 structuredexception handler that implements the __try/__except19 * functionality for GCC .21 * PCONTEXTRECORD pContext, PVOID) 22 * 23 * OS/2 exception handler that implements the __try/__except 24 * functionality for GCC in non-ODIN_FORCE_WIN32_TIB mode. 20 25 * 21 26 * NOTE: This is a heavily platform specific stuff. The code depends on the … … 26 31 * the stack. 27 32 */ 28 29 33 ___seh_handler: 30 34 31 pushl %ebp 32 movl %esp, %ebp 35 /* call the common handler to do the job */ 36 jmp OS2ExceptionHandler2ndLevel 37 38 /* 39 * extern "C" 40 * BOOL __seh_handler_filter(PEXCEPTIONREPORTRECORD pRec, 41 * struct ___seh_EXCEPTION_FRAME *pFrame, 42 * PCONTEXTRECORD pContext) 43 * 44 * Calls the filter expression of the __try/__except block 45 * in non-ODIN_FORCE_WIN32_TIB mode. 46 * 47 * Return TRUE if the filter asks to continue execution and FALSE 48 * otherwise. Note that if the filter chooses to execute the __except block, 49 * this function does not return. 50 * 51 * NOTE: This is a heavily platform specific stuff. The code depends on the 52 * struct ___seh_EXCEPTION_FRAME layout so be very careful and keep both 53 * in sync! 54 * 55 * __cdecl: EAX/ECX/EDX are not preserved, result in EAX/EDX, caller cleans up 56 * the stack. 57 */ 58 59 ___seh_handler_filter: 33 60 34 61 /* … … 36 63 * 12(%ebp) - pFrame 37 64 * 16(%ebp) - pContext 38 * 20(%ebp) - pVoid39 65 */ 66 67 pushl %ebp 68 movl %esp, %ebp 40 69 41 70 /* preserve used registers */ … … 44 73 pushl %esi 45 74 46 movl %fs, %eax47 andl $0x0000FFFF, %eax48 cmpl $Dos32TIB, %eax /* Running along the OS/2 chain? */49 jne ___seh_handler_Win32 /* No, assume the Win32 chain */50 51 /* Note: Unwinding is disabled here since a) it is more correct to do52 * centralized unwinding from OS2ExceptionHandler2ndLevel() (i.e. not only53 * for SEH frames) and b) it crashes under SMP kernel due to stack being54 * corrupt by the time when unwinding happens. See comments in55 * OS2ExceptionHandler2ndLevel() for more details. */56 57 #if 058 59 movl 8(%ebp), %eax60 movl 4(%eax), %eax /* fHandlerFlags */61 testl $0x02, %eax /* EH_UNWINDING? */62 jne ___seh_handler_OS2_Unwind63 64 /* restore the OS/2 chain in our frame */65 movl 12(%ebp), %eax66 movl 44(%eax), %ecx /* pPrevFrameOS2 */67 movl %ecx, 0(%eax) /* pPrev */68 69 xorl %eax, %eax /* return XCPT_CONTINUE_SEARCH (0) */70 jmp ___seh_handler_Return71 72 ___seh_handler_OS2_Unwind:73 74 /* unwind the Win32 chain including our frame as someone's definitely75 * jumping outside it if we're being unwound by OS/2 */76 movl 12(%ebp), %eax77 cmpl $0, 64(%eax) /* Win32FS == 0? */78 je ___seh_handler_OS2_Unwind_End /* Yes, we already unwound this frame */79 80 /* restore the Win32 chain in our frame */81 movl 60(%eax), %ebx /* pPrevFrameWin32 */82 movl %ebx, 0(%eax) /* pPrev */83 84 pushl %fs85 86 pushl 64(%eax) /* Win32FS */87 popl %fs88 89 pushl $0 /* DWORD (unused) */90 pushl $0 /* PEXCEPTION_RECORD */91 pushl $0 /* LPVOID (unused) */92 pushl %ebx /* PEXCEPTION_FRAME */93 call _RtlUnwind@16 /* _stdcall, rtl, callee cleans stack */94 95 popl %fs96 97 /* restore the OS/2 chain in our frame */98 movl 12(%ebp), %eax99 movl 44(%eax), %ecx /* pPrevFrameOS2 */100 movl %ecx, 0(%eax) /* pPrev */101 102 ___seh_handler_OS2_Unwind_End:103 104 xor %eax, %eax /* return code is irrelevant for EH_UNWINDING */105 jmp ___seh_handler_Return106 107 #else108 109 /* restore the OS/2 chain in our frame */110 movl 12(%ebp), %eax111 movl 44(%eax), %ecx /* pPrevFrameOS2 */112 movl %ecx, 0(%eax) /* pPrev */113 114 xorl %eax, %eax /* return XCPT_CONTINUE_SEARCH (0) */115 jmp ___seh_handler_Return116 117 #endif118 119 ___seh_handler_Win32:120 121 /* restore the Win32 chain in our frame */122 movl 12(%ebp), %eax123 movl 60(%eax), %ecx /* pPrevFrameWin32 */124 movl %ecx, 0(%eax) /* pPrev */125 126 /* skip EH_UNWINDING calls (for compatibility with MSVC) */127 movl 8(%ebp), %ebx128 movl 4(%ebx), %eax /* pRec->ExceptionFlags */129 testl $0x2, %eax /* EH_UNWINDING? */130 je ___seh_handler_Win32_NotUnwinding /* No, continue normally */131 132 /* See the comment above */133 #if 0134 /* clear out the Win32FS field so that we will not attempt to unwind twice135 * (first, as a result of forced unwind from ExitProcess/ExitThread/etc and136 * then from the OS/2 EH_UNWINDING call of our handler) */137 movl 12(%ebp), %eax138 movl $0, 64(%eax) /* Win32FS */139 #endif140 141 movl $1, %eax /* ExceptionContinueSearch */142 jmp ___seh_handler_Return143 144 ___seh_handler_Win32_NotUnwinding:145 146 75 /* save handler's context */ 147 76 pushl %ebp … … 153 82 154 83 /* get the size of the handler's stack */ 155 movl 40(%ebx), %ecx /* pFrame-> pTryRegs[4] isESP */84 movl 40(%ebx), %ecx /* pFrame->ESP */ 156 85 subl %esp, %ecx 157 86 jle ___seh_handler_Error /* Invalid stack! */ 158 87 movl %ecx, 4(%esp) /* save length */ 159 88 160 /* check that EXCEPTION_RECORD and CONTEXT are on our stack161 * and save their offsets in pFrame */162 movl 8(%ebp), %eax163 subl %esp, %eax164 jl ___seh_handler_Error /* Invalid stack! */165 cmpl %ecx, %eax166 jg ___seh_handler_Error /* Invalid stack! */167 movl %eax, 48(%ebx) /* pFrame->Pointers.ExceptionRecord */168 169 movl 16(%ebp), %eax170 subl %esp, %eax171 jl ___seh_handler_Error /* Invalid stack! */172 cmpl %ecx, %eax173 jg ___seh_handler_Error /* Invalid stack! */174 movl %eax, 52(%ebx) /* pFrame->Pointers.ContextRecord */175 176 89 /* save the handler's stack on heap */ 177 90 movl %ecx, %eax /* size_t */ 91 /* also reserve space for Win32 exeption info structs */ 92 addl $(sizeof_WINEXCEPTION_RECORD + sizeof_WINCONTEXT), %eax 178 93 subl $4, %esp 179 94 movl %eax, 0(%esp) … … 188 103 rep movsb 189 104 190 /* correct Pointers offsets to point to the saved stack on heap */ 105 /* convert OS/2 exception info -> Win32 */ 106 movl 16(%ebx), %eax /* pFrame->pHandlerContext */ 107 addl 4(%esp), %eax /* + size of stack = ptr to WINCONTEXT */ 108 movl %eax, 48(%ebx) /* pFrame->Pointers.ContextRecord */ 109 addl $sizeof_WINCONTEXT, %eax/* = ptr to WINEXCEPTION_RECORD */ 110 movl %eax, 44(%ebx) /* pFrame->Pointers.ExceptionRecord */ 111 pushl $0 /* TEB* */ 112 pushl 48(%ebx) /* WINCONTEXT */ 113 pushl 44(%ebx) /* WINEXCEPTION_RECORD */ 114 pushl 16(%ebp) /* pContext */ 115 pushl 8(%ebp) /* pRec */ 116 call OSLibConvertExceptionInfo 117 addl $20, %esp 118 jne ___seh_handler_CallFilter/* conversion successful? */ 119 120 /* free heap block */ 191 121 movl 16(%ebx), %eax /* pFrame->pHandlerContext */ 192 addl %eax, 48(%ebx) /* pFrame->Pointers.ExceptionRecord */ 193 addl %eax, 52(%ebx) /* pFrame->Pointers.ContextRecord */ 122 subl $4, %esp 123 movl %eax, 0(%esp) 124 call _free /* __cdecl (and _Optlink compatible -> EAX/EDX/ECX-in) */ 125 addl $4, %esp 126 jmp ___seh_handler_Error /* Info conversion error! */ 127 128 ___seh_handler_CallFilter: 194 129 195 130 /* restore __try/__catch context */ 196 131 movl 12(%ebp), %eax 197 movl 24(%eax), %ebx /* pFrame-> pTryRegs*/198 movl 28(%eax), %esi 199 movl 32(%eax), %edi 200 movl 36(%eax), %ebp 201 movl 40(%eax), %esp 132 movl 24(%eax), %ebx /* pFrame->EBX */ 133 movl 28(%eax), %esi /* pFrame->ESI */ 134 movl 32(%eax), %edi /* pFrame->EDI */ 135 movl 36(%eax), %ebp /* pFrame->EBP */ 136 movl 40(%eax), %esp /* pFrame->ESP */ 202 137 203 138 /* jump to the filter callback */ 204 movl $1, 5 6(%eax) /* pFrame->state */139 movl $1, 52(%eax) /* pFrame->state */ 205 140 jmp *8(%eax) /* pFrame->pFilterCallback */ 206 141 … … 232 167 cmpl $-1, %eax /* EXCEPTION_CONTINUE_EXECUTION? */ 233 168 jne 1f 234 movl $0, 56(%ebx) /* pFrame->state */ 235 movl $0, %eax /* ExceptionContinueExecution */ 169 movl $0, 52(%ebx) /* pFrame->state */ 170 //movl $-1, %eax /* XCPT_CONTINUE_EXECUTION (-1) */ 171 movl $1, %eax 236 172 jmp ___seh_handler_Return 237 173 1: 238 174 /* assume EXCEPTION_CONTINUE_SEARCH (0) */ 175 xorl %eax, %eax /* return XCPT_CONTINUE_SEARCH (0) */ 176 jmp ___seh_handler_Return 177 178 ___seh_handler_Unwind: 179 180 /* unwind OS/2 exception chain up to ours */ 181 pushl $0 /* PEXCEPTIONREPORTRECORD */ 182 pushl $1f /* PVOID pTargetIP */ 183 pushl 12(%ebp) /* PEXCEPTIONREGISTRATIONRECORD */ 184 call _DosUnwindException /* _syscall, rtl, but stack is not restored! */ 185 1: 186 /* restore __try/__except context */ 187 movl 12(%ebp), %eax 188 movl 24(%eax), %ebx 189 movl 28(%eax), %esi 190 movl 32(%eax), %edi 191 movl 36(%eax), %ebp 192 movl 40(%eax), %esp 193 194 /* jump to __except */ 195 movl $2, 52(%eax) /* pFrame->state */ 196 jmp *8(%eax) /* pFrame->pFilterCallback */ 197 198 ___seh_handler_Error: 199 200 addl $8, %esp 201 popl %ebp 202 203 xorl %eax, %eax /* return XCPT_CONTINUE_SEARCH (0) */ 204 205 ___seh_handler_Return: 206 207 popl %esi 208 popl %edi 209 popl %ebx 210 211 popl %ebp 212 ret 213 214 /* 215 * extern "C" 216 * int __seh_handler_win32(PEXCEPTION_RECORD pRec, 217 * struct ___seh_EXCEPTION_FRAME *pFrame, 218 * PCONTEXT pContext, PVOID) 219 * 220 * Win32 structured exception handler that implements the __try/__except 221 * functionality for GCC in ODIN_FORCE_WIN32_TIB mode. 222 * 223 * NOTE: This is a heavily platform specific stuff. The code depends on the 224 * struct ___seh_EXCEPTION_FRAME layout so be very careful and keep both 225 * in sync! 226 * 227 * __cdecl: EAX/ECX/EDX are not preserved, result in EAX/EDX, caller cleans up 228 * the stack. 229 */ 230 231 ___seh_handler_win32: 232 233 pushl %ebp 234 movl %esp, %ebp 235 236 /* 237 * 8(%ebp) - pRec 238 * 12(%ebp) - pFrame 239 * 16(%ebp) - pContext 240 * 20(%ebp) - pVoid 241 */ 242 243 /* preserve used registers */ 244 pushl %ebx 245 pushl %edi 246 pushl %esi 247 248 movl %fs, %eax 249 andl $0x0000FFFF, %eax 250 cmpl $Dos32TIB, %eax /* Running along the OS/2 chain? */ 251 jne __seh_handler_win32_Win32 /* No, assume the Win32 chain */ 252 253 /* Note: Unwinding is disabled here since a) it is more correct to do 254 * centralized unwinding from OS2ExceptionHandler2ndLevel() (i.e. not only 255 * for SEH frames) and b) it crashes under SMP kernel due to stack being 256 * corrupt by the time when unwinding happens. See comments in 257 * OS2ExceptionHandler2ndLevel() for more details. */ 258 259 #if 0 260 261 movl 8(%ebp), %eax 262 movl 4(%eax), %eax /* fHandlerFlags */ 263 testl $0x02, %eax /* EH_UNWINDING? */ 264 jne __seh_handler_win32_OS2_Unwind 265 266 /* restore the OS/2 chain in our frame */ 267 movl 12(%ebp), %eax 268 movl 44(%eax), %ecx /* pPrevFrameOS2 */ 269 movl %ecx, 0(%eax) /* pPrev */ 270 271 xorl %eax, %eax /* return XCPT_CONTINUE_SEARCH (0) */ 272 jmp __seh_handler_win32_Return 273 274 __seh_handler_win32_OS2_Unwind: 275 276 /* unwind the Win32 chain including our frame as someone's definitely 277 * jumping outside it if we're being unwound by OS/2 */ 278 movl 12(%ebp), %eax 279 cmpl $0, 64(%eax) /* Win32FS == 0? */ 280 je __seh_handler_win32_OS2_Unwind_End /* Yes, we already unwound this frame */ 281 282 /* restore the Win32 chain in our frame */ 283 movl 60(%eax), %ebx /* pPrevFrameWin32 */ 284 movl %ebx, 0(%eax) /* pPrev */ 285 286 pushl %fs 287 288 pushl 64(%eax) /* Win32FS */ 289 popl %fs 290 291 pushl $0 /* DWORD (unused) */ 292 pushl $0 /* PEXCEPTION_RECORD */ 293 pushl $0 /* LPVOID (unused) */ 294 pushl %ebx /* PEXCEPTION_FRAME */ 295 call _RtlUnwind@16 /* _stdcall, rtl, callee cleans stack */ 296 297 popl %fs 298 299 /* restore the OS/2 chain in our frame */ 300 movl 12(%ebp), %eax 301 movl 44(%eax), %ecx /* pPrevFrameOS2 */ 302 movl %ecx, 0(%eax) /* pPrev */ 303 304 __seh_handler_win32_OS2_Unwind_End: 305 306 xor %eax, %eax /* return code is irrelevant for EH_UNWINDING */ 307 jmp __seh_handler_win32_Return 308 309 #else 310 311 /* restore the OS/2 chain in our frame */ 312 movl 12(%ebp), %eax 313 movl 44(%eax), %ecx /* pPrevFrameOS2 */ 314 movl %ecx, 0(%eax) /* pPrev */ 315 316 xorl %eax, %eax /* return XCPT_CONTINUE_SEARCH (0) */ 317 jmp __seh_handler_win32_Return 318 319 #endif 320 321 __seh_handler_win32_Win32: 322 323 /* restore the Win32 chain in our frame */ 324 movl 12(%ebp), %eax 325 movl 60(%eax), %ecx /* pPrevFrameWin32 */ 326 movl %ecx, 0(%eax) /* pPrev */ 327 328 /* skip EH_UNWINDING calls (for compatibility with MSVC) */ 329 movl 8(%ebp), %ebx 330 movl 4(%ebx), %eax /* pRec->ExceptionFlags */ 331 testl $0x2, %eax /* EH_UNWINDING? */ 332 je ___seh_handler_win32_Win32_NotUnwinding /* No, continue normally */ 333 334 /* See the comment above */ 335 #if 0 336 /* clear out the Win32FS field so that we will not attempt to unwind twice 337 * (first, as a result of forced unwind from ExitProcess/ExitThread/etc and 338 * then from the OS/2 EH_UNWINDING call of our handler) */ 339 movl 12(%ebp), %eax 340 movl $0, 64(%eax) /* Win32FS */ 341 #endif 342 239 343 movl $1, %eax /* ExceptionContinueSearch */ 240 jmp ___seh_handler_Return 241 242 ___seh_handler_Unwind: 344 jmp __seh_handler_win32_Return 345 346 ___seh_handler_win32_Win32_NotUnwinding: 347 348 /* save handler's context */ 349 pushl %ebp 350 pushl $0 /* reserve space for length, must be saved right before ESP! */ 351 pushl %esp /* ESP must be saved last! */ 352 353 movl 12(%ebp), %ebx 354 movl $0f, 12(%ebx) /* pFrame->pHandlerCallback */ 355 356 /* get the size of the handler's stack */ 357 movl 40(%ebx), %ecx /* pFrame->pTryRegs[4] is ESP */ 358 subl %esp, %ecx 359 jle __seh_handler_win32_Error /* Invalid stack! */ 360 movl %ecx, 4(%esp) /* save length */ 361 362 /* check that EXCEPTION_RECORD and CONTEXT are on our stack 363 * and save their offsets in pFrame */ 364 movl 8(%ebp), %eax 365 subl %esp, %eax 366 jl __seh_handler_win32_Error /* Invalid stack! */ 367 cmpl %ecx, %eax 368 jg __seh_handler_win32_Error /* Invalid stack! */ 369 movl %eax, 48(%ebx) /* pFrame->Pointers.ExceptionRecord */ 370 371 movl 16(%ebp), %eax 372 subl %esp, %eax 373 jl __seh_handler_win32_Error /* Invalid stack! */ 374 cmpl %ecx, %eax 375 jg __seh_handler_win32_Error /* Invalid stack! */ 376 movl %eax, 52(%ebx) /* pFrame->Pointers.ContextRecord */ 377 378 /* save the handler's stack on heap */ 379 movl %ecx, %eax /* size_t */ 380 subl $4, %esp 381 movl %eax, 0(%esp) 382 call _malloc /* __cdecl (and _Optlink compatible -> EAX/EDX/ECX-in) */ 383 addl $4, %esp 384 testl %eax, %eax 385 je __seh_handler_win32_Error /* No memory! */ 386 movl 4(%esp), %ecx 387 movl %eax, %edi 388 movl %edi, 16(%ebx) /* pFrame->pHandlerContext */ 389 movl %esp, %esi 390 rep movsb 391 392 /* correct Pointers offsets to point to the saved stack on heap */ 393 movl 16(%ebx), %eax /* pFrame->pHandlerContext */ 394 addl %eax, 48(%ebx) /* pFrame->Pointers.ExceptionRecord */ 395 addl %eax, 52(%ebx) /* pFrame->Pointers.ContextRecord */ 396 397 /* restore __try/__catch context */ 398 movl 12(%ebp), %eax 399 movl 24(%eax), %ebx /* pFrame->pTryRegs */ 400 movl 28(%eax), %esi 401 movl 32(%eax), %edi 402 movl 36(%eax), %ebp 403 movl 40(%eax), %esp 404 405 /* jump to the filter callback */ 406 movl $1, 56(%eax) /* pFrame->state */ 407 jmp *8(%eax) /* pFrame->pFilterCallback */ 408 409 0: 410 /* restore handler's context (we assume that the callback puts the address 411 * of pFrame back to EBX!) */ 412 movl 16(%ebx), %esi /* pFrame->pHandlerContext */ 413 movl 0(%esi), %esp /* restore saved ESP */ 414 movl 4(%esi), %ecx /* saved stack length */ 415 subl $4, %esp /* correct ESP to compensate for PUSH ESP logic */ 416 movl %esp, %edi 417 rep movsb 418 419 popl %esp 420 addl $4, %esp 421 popl %ebp 422 423 /* free heap block */ 424 movl 16(%ebx), %eax /* pFrame->pHandlerContext */ 425 subl $4, %esp 426 movl %eax, 0(%esp) 427 call _free /* __cdecl (and _Optlink compatible -> EAX/EDX/ECX-in) */ 428 addl $4, %esp 429 430 /* analyze filter result */ 431 movl 20(%ebx), %eax /* pFrame->filterResult */ 432 cmpl $1, %eax /* EXCEPTION_EXECUTE_HANDLER? */ 433 je __seh_handler_win32_Unwind 434 cmpl $-1, %eax /* EXCEPTION_CONTINUE_EXECUTION? */ 435 jne 1f 436 movl $0, 56(%ebx) /* pFrame->state */ 437 movl $0, %eax /* ExceptionContinueExecution */ 438 jmp __seh_handler_win32_Return 439 1: 440 /* assume EXCEPTION_CONTINUE_SEARCH (0) */ 441 movl $1, %eax /* ExceptionContinueSearch */ 442 jmp __seh_handler_win32_Return 443 444 __seh_handler_win32_Unwind: 243 445 244 446 /* unwind Win32 exception chain up to ours */ … … 282 484 jmp *8(%eax) /* pFrame->pFilterCallback */ 283 485 284 __ _seh_handler_Error:486 __seh_handler_win32_Error: 285 487 286 488 addl $8, %esp … … 289 491 movl $1, %eax /* ExceptionContinueSearch */ 290 492 291 __ _seh_handler_Return:493 __seh_handler_win32_Return: 292 494 293 495 popl %esi … … 300 502 /* 301 503 * extern "C" 302 * EXCEPTION_FRAME *__seh_get_prev_frame (EXCEPTION_FRAME *pFrame)504 * EXCEPTION_FRAME *__seh_get_prev_frame_win32(EXCEPTION_FRAME *pFrame) 303 505 * 304 506 * Returns the previous Win32 exception frame given an existing frame. … … 319 521 */ 320 522 321 ___seh_get_prev_frame :523 ___seh_get_prev_frame_win32: 322 524 323 525 /* … … 328 530 /*leal ___seh_handler, %ecx*/ 329 531 movl 4(%eax), %ecx /* pFrame->Handler */ 330 cmpl $___seh_handler , %ecx331 jne ___seh_get_prev_frame_ Normal532 cmpl $___seh_handler_win32, %ecx 533 jne ___seh_get_prev_frame_win32_Normal 332 534 333 535 movl 60(%eax), %eax /* pPrevFrameWin32 */ 334 536 ret 335 537 336 ___seh_get_prev_frame_ Normal:538 ___seh_get_prev_frame_win32_Normal: 337 539 338 540 movl 0(%eax), %eax /* pFrame->Prev */ -
trunk/src/kernel32/winexelx.cpp
r21916 r21999 47 47 PTIB ptib; 48 48 49 if (!f SEHEnabled) {49 if (!fForceWin32TIB) { 50 50 //Signal to TEB management that we're a real OS/2 app and don't 51 51 //require setting FS to our special win32 selector -
trunk/src/kernel32/wprocess.cpp
r21916 r21999 79 79 BOOL fSwitchTIBSel = TRUE; // TRUE -> switch TIB selectors 80 80 // FALSE -> don't 81 BOOL f SEHEnabled = FALSE; // TRUE -> SEH support enabled81 BOOL fForceWin32TIB = FALSE; // TRUE -> force TIB switch 82 82 // FALSE -> not enabled 83 83 BOOL fExitProcess = FALSE; … … 113 113 //****************************************************************************** 114 114 //****************************************************************************** 115 VOID WIN32API EnableSEH()116 { 117 if(!f SEHEnabled) {115 VOID WIN32API ForceWin32TIB() 116 { 117 if(!fForceWin32TIB) { 118 118 ODIN_SetTIBSwitch(TRUE); 119 f SEHEnabled= TRUE;119 fForceWin32TIB = TRUE; 120 120 } 121 121 return; … … 510 510 { 511 511 dprintf(("ODIN_SetTIBSwitch %d", fSwitchTIB)); 512 if (!f SEHEnabled) {512 if (!fForceWin32TIB) { 513 513 fSwitchTIBSel = fSwitchTIB; 514 514 if(fSwitchTIBSel) { … … 517 517 else RestoreOS2TIB(); 518 518 } else { 519 dprintf(("ODIN_SetTIBSwitch: ignored due to f SEHEnabled= TRUE"));519 dprintf(("ODIN_SetTIBSwitch: ignored due to fForceWin32TIB = TRUE")); 520 520 } 521 521 } -
trunk/testapp/console/file/file.c
r21565 r21999 23 23 _argc = argc; 24 24 _argv = argv; 25 EnableSEH(); 25 #ifdef ODIN_FORCE_WIN32_TIB 26 ForceWin32TIB(); 27 #endif 26 28 RegisterLxExe(WinMain, NULL); 27 29 } -
trunk/testapp/console/fullpath/fullpath.c
r21631 r21999 25 25 _argc = argc; 26 26 _argv = argv; 27 EnableSEH(); 27 #ifdef ODIN_FORCE_WIN32_TIB 28 ForceWin32TIB(); 29 #endif 28 30 RegisterLxExe(WinMain, NULL); 29 31 } -
trunk/testapp/encodings/test.c
r21916 r21999 20 20 int main(int argc, char **argv) 21 21 { 22 EnableSEH(); 22 #ifdef ODIN_FORCE_WIN32_TIB 23 ForceWin32TIB(); 24 #endif 23 25 RegisterLxExe(WinMain, NULL); 24 26 } -
trunk/testapp/exceptions/GuardPages/main.cpp
r21982 r21999 149 149 /////////////////////////////////////////////////// 150 150 151 #if 1 152 151 153 printf ("\nTEST 1 (STACK)\n"); 152 154 … … 154 156 DWORD dwYellowZoneSize = sSysInfo.dwPageSize * 3; 155 157 156 #if 1157 158 if (VirtualAlloc ((LPVOID) dwStackBase, dwYellowZoneSize, 158 159 MEM_COMMIT, PAGE_READWRITE)) … … 186 187 } 187 188 } 188 #endif189 189 190 190 PrintMemLayout (&dwStackTop); 191 191 192 #endif 193 192 194 /////////////////////////////////////////////////// 195 196 #if 1 193 197 194 198 printf ("\nTEST 2 (PAGE_GUARD)\n"); … … 220 224 VirtualFree (pNonStack, 0, MEM_RELEASE); 221 225 226 #endif 227 222 228 return 0; 223 229 } … … 226 232 { 227 233 #ifdef __WIN32OS2__ 228 EnableSEH(); 234 #ifdef ODIN_FORCE_WIN32_TIB 235 ForceWin32TIB(); 236 #endif 229 237 #endif 230 238 -
trunk/testapp/exceptions/seh/crash.c
r21663 r21999 24 24 _argc = argc; 25 25 _argv = argv; 26 EnableSEH(); 26 #ifdef ODIN_FORCE_WIN32_TIB 27 ForceWin32TIB(); 28 #endif 27 29 RegisterLxExe(WinMain, NULL); 28 30 } … … 87 89 void foo(int code) 88 90 { 89 __try90 {91 printf("In foo(%d)...\n", code);91 __try 92 { 93 printf("In foo(%d)...\n", code); 92 94 93 if (code == 2)94 {95 throw_EXCEPTION_INT_DIVIDE_BY_ZERO();96 printf("FAILED: No exception!\n");97 }98 else99 {100 foo(code + 1);101 }102 }103 __except(exc_filter(exception_info()))104 {105 printf("FAILED: foo(%d) exception handled.\n", code);106 }95 if (code == 2) 96 { 97 throw_EXCEPTION_INT_DIVIDE_BY_ZERO(); 98 printf("FAILED: No exception!\n"); 99 } 100 else 101 { 102 foo(code + 1); 103 } 104 } 105 __except(exc_filter(exception_info())) 106 { 107 printf("FAILED: foo(%d) exception handled.\n", code); 108 } 107 109 } 108 110 … … 118 120 { 119 121 printf("The program should now expectedly crash " 120 "( but NO POPUPLOG.OS2 entry!)...\n");122 "(and may be a NO POPUPLOG.OS2 entry)...\n"); 121 123 122 124 HANDLE hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL); -
trunk/testapp/exceptions/seh/except.c
r21476 r21999 23 23 _argc = argc; 24 24 _argv = argv; 25 EnableSEH(); 25 #ifdef ODIN_FORCE_WIN32_TIB 26 ForceWin32TIB(); 27 #endif 26 28 RegisterLxExe(WinMain, NULL); 27 29 } -
trunk/testapp/exceptions/seh/finally.c
r21449 r21999 23 23 _argc = argc; 24 24 _argv = argv; 25 EnableSEH(); 25 #ifdef ODIN_FORCE_WIN32_TIB 26 ForceWin32TIB(); 27 #endif 26 28 RegisterLxExe(WinMain, NULL); 27 29 } -
trunk/testapp/exceptions/seh/longjmp.c
r21662 r21999 24 24 _argc = argc; 25 25 _argv = argv; 26 EnableSEH(); 26 #ifdef ODIN_FORCE_WIN32_TIB 27 ForceWin32TIB(); 28 #endif 27 29 RegisterLxExe(WinMain, NULL); 28 30 } -
trunk/testapp/gui/fontlist/fontlist.c
r21539 r21999 25 25 _argc = argc; 26 26 _argv = argv; 27 EnableSEH(); 27 #ifdef ODIN_FORCE_WIN32_TIB 28 ForceWin32TIB(); 29 #endif 28 30 RegisterLxExe(WinMain, NULL); 29 31 } -
trunk/testapp/gui/input/input.c
r21916 r21999 17 17 int main() 18 18 { 19 EnableSEH(); 19 #ifdef ODIN_FORCE_WIN32_TIB 20 ForceWin32TIB(); 21 #endif 20 22 RegisterLxExe(WinMain, NULL); 21 23 return 0; -
trunk/testapp/gui/systray/StealthDialog.cpp
r21603 r21999 29 29 int main(int argc, char **argv) 30 30 { 31 EnableSEH(); 31 #ifdef ODIN_FORCE_WIN32_TIB 32 ForceWin32TIB(); 33 #endif 32 34 RegisterLxExe((WINMAIN)_tWinMain, (PVOID)&Resource_PEResTab); 33 35 } -
trunk/testapp/threads/threads.c
r21916 r21999 59 59 int main(int argc, char **argv) 60 60 { 61 EnableSEH(); 61 #ifdef ODIN_FORCE_WIN32_TIB 62 ForceWin32TIB(); 63 #endif 62 64 RegisterLxExe((WINMAIN)WinMain, NULL); 63 65 return _tmain();
Note:
See TracChangeset
for help on using the changeset viewer.