Changeset 21474
- Timestamp:
- Nov 14, 2010, 12:41:50 AM (15 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
-
include/excpt.h (modified) (6 diffs)
-
src/kernel32/seh/sehutil.s (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/excpt.h
r21448 r21474 13 13 * crash the application): 14 14 * 15 * 1. You cannot use return, goto and longjmp statements within __try or 16 * __except or __finally blocks. 15 * 1. You cannot use the return statement within __try or __except or __finally 16 * blocks. 17 * 18 * 2. You cannot use the goto statement or the longjmp() function within __try 19 * or __except or __finally blocks if it passes control outside these blocks. 17 20 * 18 21 * 2. If you use __try and friends inside a do/while/for/switch block, you will … … 39 42 #if defined(__GNUC__) 40 43 41 struct ___seh_ PEXCEPTION_FRAME;44 struct ___seh_EXCEPTION_FRAME; 42 45 typedef int (*__seh_PEXCEPTION_HANDLER)(PEXCEPTION_RECORD, 43 struct ___seh_ PEXCEPTION_FRAME *,46 struct ___seh_EXCEPTION_FRAME *, 44 47 PCONTEXT, PVOID); 45 48 46 typedef struct ___seh_PEXCEPTION_FRAME 49 #pragma pack(1) 50 51 typedef struct ___seh_EXCEPTION_FRAME 47 52 { 48 struct ___seh_PEXCEPTION_FRAME *pPrev; 49 __seh_PEXCEPTION_HANDLER pHandler; 50 void *pFilterCallback; 51 void *pHandlerCallback; 52 void *pHandlerContext; 53 int filterResult; 54 DWORD pTryRegs[6]; /* EBX/ESI/EDI/EBP/ESP/ExceptionHandler */ 55 EXCEPTION_POINTERS Pointers; 56 int state; 53 /* + 0 */ struct ___seh_EXCEPTION_FRAME *pPrev; 54 /* + 4 */ __seh_PEXCEPTION_HANDLER pHandler; 55 /* + 8 */ void *pFilterCallback; 56 /* +12 */ void *pHandlerCallback; 57 /* +16 */ void *pHandlerContext; 58 /* +20 */ int filterResult; 59 /* +24 */ DWORD EBX; 60 /* +28 */ DWORD ESI; 61 /* +32 */ DWORD EDI; 62 /* +36 */ DWORD EBP; 63 /* +40 */ DWORD ESP; 64 /* +44 */ DWORD pPrevFrameOS2; 65 /* +48 */ EXCEPTION_POINTERS Pointers; 66 /* +56 */ int state; 67 /* +60 */ DWORD pPrevFrameWin32; 57 68 } 58 __seh_ PEXCEPTION_FRAME;69 __seh_EXCEPTION_FRAME; 59 70 60 int __seh_handler(PEXCEPTION_RECORD pRec, 61 struct ___seh_PEXCEPTION_FRAME *pFrame, 62 PCONTEXT pContext, PVOID pVoid); 71 #pragma pack() 72 73 extern int __seh_handler(PEXCEPTION_RECORD pRec, 74 struct ___seh_EXCEPTION_FRAME *pFrame, 75 PCONTEXT pContext, PVOID pVoid); 63 76 64 77 #define _exception_code() (__seh_frame.Pointers.ExceptionRecord->ExceptionCode) 65 #define _exception_info() (&__seh_frame.Pointers) 78 #define _exception_info() ((void *)&__seh_frame.Pointers) 79 80 #define exception_code _exception_code 81 #define exception_info (PEXCEPTION_POINTERS)_exception_info 66 82 67 83 #define GetExceptionCode _exception_code 68 #define GetExceptionInformation _exception_info84 #define GetExceptionInformation (PEXCEPTION_POINTERS)_exception_info 69 85 70 86 #define __try \ 71 volatile __seh_PEXCEPTION_FRAME __seh_frame; \ 87 volatile __seh_EXCEPTION_FRAME __seh_frame; \ 88 __seh_frame.pHandler = __seh_handler; \ 72 89 __seh_frame.Pointers.ExceptionRecord = NULL; \ 73 90 __seh_frame.Pointers.ContextRecord = NULL; \ … … 77 94 if (__seh_frame.state == 0) \ 78 95 { \ 79 /* install exception handler */ \ 80 __asm__ ("\n.extern ___seh_handler\n" \ 81 "" \ 82 "leal %0, %%ecx; " \ 96 /* install exception handler (both Win32 and OS/2 chains) */ \ 97 __asm__ ("leal %0, %%ecx; " \ 83 98 "movl %%fs:0, %%eax; " \ 84 99 "movl %%eax, 0(%%ecx); " \ 85 "movl $___seh_handler, %%eax; " \ 86 "movl %%eax, 4(%%ecx); " \ 100 "movl %%eax, 60(%%ecx); " \ 87 101 "movl $0b, 8(%%ecx); " \ 88 102 "" \ … … 98 112 "movl %%fs:0, %%eax; " \ 99 113 "movl %%eax, 44(%%ecx); " \ 114 "movl %%ecx, %%fs:0; " \ 100 115 "popl %%fs; " \ 101 116 "" \ … … 119 134 else if (__seh_frame.state == 3) \ 120 135 /* remove exception handler */ \ 121 __asm__ ("movl %%fs:0, %%e ax; " \122 "movl 0(%%eax), %%eax; "\136 __asm__ ("movl %%fs:0, %%ecx; " \ 137 "movl 60(%%ecx), %%eax; " \ 123 138 "movl %%eax, %%fs:0; " \ 139 "" \ 140 "pushl %%fs; " \ 141 "pushl $Dos32TIB; " \ 142 "popl %%fs; " \ 143 "movl 44(%%ecx), %%eax; " \ 144 "movl %%eax, %%fs:0; " \ 145 "popl %%fs; " \ 124 146 : : \ 125 : "%eax" );\147 : "%eax", "%ecx"); \ 126 148 else /* __seh_frame.state == 2 -> execute except block */ 127 149 … … 140 162 else if (__seh_frame.state == 3) \ 141 163 /* remove exception handler */ \ 142 __asm__ ("movl %%fs:0, %%e ax; " \143 "movl 0(%%eax), %%eax; "\164 __asm__ ("movl %%fs:0, %%ecx; " \ 165 "movl 60(%%ecx), %%eax; " \ 144 166 "movl %%eax, %%fs:0; " \ 167 "" \ 168 "pushl %%fs; " \ 169 "pushl $Dos32TIB; " \ 170 "popl %%fs; " \ 171 "movl 44(%%ecx), %%eax; " \ 172 "movl %%eax, %%fs:0; " \ 173 "popl %%fs; " \ 145 174 : : \ 146 : "%eax" );\175 : "%eax", "%ecx"); \ 147 176 else /* __seh_frame.state == 2 -> execute finally block */ 148 177 -
trunk/src/kernel32/seh/sehutil.s
r21431 r21474 11 11 /* 12 12 * int __seh_handler(PEXCEPTION_RECORD pRec, 13 * struct ___seh_ PEXCEPTION_FRAME *pFrame,13 * struct ___seh_EXCEPTION_FRAME *pFrame, 14 14 * PCONTEXT pContext, PVOID) 15 15 * … … 18 18 * 19 19 * NOTE: This is a heavily platform specific stuff. The code depends on the 20 * struct ___seh_ PEXCEPTION_FRAME layout so be very careful and keep both20 * struct ___seh_EXCEPTION_FRAME layout so be very careful and keep both 21 21 * in sync! 22 22 * … … 33 33 * 12(%ebp) - pFrame 34 34 * 16(%ebp) - pContext 35 * 20(%ebp) - pV Oid35 * 20(%ebp) - pVoid 36 36 */ 37 37 … … 40 40 pushl %edi 41 41 pushl %esi 42 43 pushl %fs 44 popl %eax 45 andl $0x0000FFFF, %eax 46 cmpl $Dos32TIB, %eax /* Running along the OS/2 chain? */ 47 jne ___seh_handler_Win32 /* No, assume the Win32 chain */ 48 49 movl 8(%ebp), %eax 50 movl 0(%eax), %eax 51 cmpl $0xC0000026, %eax /* XCPT_UNWIND? */ 52 je ___seh_handler_OS2_Unwind 53 54 /* restore the OS/2 chain in our frame */ 55 movl 12(%ebp), %eax 56 movl 44(%eax), %ecx /* pPrevFrameOS2 */ 57 movl %ecx, 0(%eax) /* pPrev */ 58 59 xorl %eax, %eax /* return XCPT_CONTINUE_SEARCH (0) */ 60 jmp ___seh_handler_Return 61 62 ___seh_handler_OS2_Unwind: 63 64 /* restore the Win32 chain in our frame */ 65 movl 12(%ebp), %eax 66 movl 60(%eax), %ecx /* pPrevFrameWin32 */ 67 movl %ecx, 0(%eax) /* pPrev */ 68 69 /* unwind the Win32 chain including our frame as someone's definitely 70 * jumping outside it if we're being unwound */ 71 pushl %fs 72 pushl $1 73 call _SetWin32TIB@4 /* _stdcall, rtl, callee cleans stack */ 74 pushl $0 /* DWORD (unused) */ 75 pushl $0 /* PEXCEPTION_RECORD */ 76 pushl $0 /* LPVOID (unused) */ 77 pushl %ecx /* PEXCEPTION_FRAME */ 78 call _RtlUnwind@16 /* _stdcall, rtl, callee cleans stack */ 79 popl %fs 80 81 /* restore the OS/2 chain in our frame */ 82 movl 12(%ebp), %eax 83 movl 44(%eax), %ecx /* pPrevFrameOS2 */ 84 movl %ecx, 0(%eax) /* pPrev */ 85 86 xor %eax, %eax /* return code is irrelevant for XCPT_UNWIND */ 87 jmp ___seh_handler_Return 88 89 ___seh_handler_Win32: 90 91 /* restore the Win32 chain in our frame */ 92 movl 12(%ebp), %eax 93 movl 60(%eax), %ecx /* pPrevFrameWin32 */ 94 movl %ecx, 0(%eax) /* pPrev */ 42 95 43 96 /* skip EH_UNWINDING calls (for compatibility with MSVC) */ … … 140 193 jmp ___seh_handler_Return 141 194 1: 142 /* Assume EXCEPTION_CONTINUE_SEARCH (0) */195 /* assume EXCEPTION_CONTINUE_SEARCH (0) */ 143 196 movl $1, %eax /* ExceptionContinueSearch */ 144 197 jmp ___seh_handler_Return … … 146 199 ___seh_handler_Unwind: 147 200 148 /* Unwind Win32 exception chain up to ours */201 /* unwind Win32 exception chain up to ours */ 149 202 pushl $0 /* DWORD (unused) */ 150 203 pushl 8(%ebp) /* PEXCEPTION_RECORD */ … … 153 206 call _RtlUnwind@16 /* _stdcall, rtl, callee cleans stack */ 154 207 155 /* Unwind OS/2 exception chain */ 156 movl 12(%ebp), %eax 208 /* restore the OS/2 chain in our frame */ 209 movl 12(%ebp), %eax 210 movl 44(%eax), %ecx /* pPrevFrameOS2 */ 211 movl %ecx, 0(%eax) /* pPrev */ 212 213 /* unwind OS/2 exception chain up to ours */ 214 pushl %fs 215 pushl $Dos32TIB 216 popl %fs 157 217 pushl $0 /* PEXCEPTIONREPORTRECORD */ 158 218 pushl $1f /* PVOID pTargetIP */ 159 pushl 44(%eax) /* PEXCEPTIONREGISTRATIONRECORD */219 pushl 12(%ebp) /* PEXCEPTIONREGISTRATIONRECORD */ 160 220 call _DosUnwindException /* _syscall, rtl, caller cleans stack */ 161 221 1: 162 222 addl $12, %esp 223 popl %fs 224 225 /* restore the Win32 chain in our frame */ 226 movl 12(%ebp), %eax 227 movl 60(%eax), %ecx /* pPrevFrameWin32 */ 228 movl %ecx, 0(%eax) /* pPrev */ 163 229 164 230 /* restore __try/__except context */
Note:
See TracChangeset
for help on using the changeset viewer.
