2 * COPYRIGHT: See COPYING in the top level directory
4 * FILE: lib/crt/misc/i386/seh.S
5 * PURPOSE: SEH Support for the CRT
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
11 #include <reactos/asm.h>
13 #define DISPOSITION_DISMISS 0
14 #define DISPOSITION_CONTINUE_SEARCH 1
15 #define DISPOSITION_COLLIDED_UNWIND 3
17 #define EXCEPTION_EXIT_UNWIND 4
18 #define EXCEPTION_UNWINDING 2
21 EXTERN _RtlUnwind@16:PROC
23 /* GLOBALS *******************************************************************/
25 PUBLIC __global_unwind2
26 PUBLIC __local_unwind2
27 PUBLIC __abnormal_termination
28 PUBLIC __except_handler2
29 PUBLIC __except_handler3
31 /* FUNCTIONS *****************************************************************/
36 /* Check if we were unwinding and continue search if not */
38 test dword ptr [ecx+4], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING
39 mov eax, DISPOSITION_CONTINUE_SEARCH
40 jz unwind_handler_return
42 /* We have a collision, do a local unwind */
54 /* Set new try level */
59 /* Return collided unwind */
60 mov eax, DISPOSITION_COLLIDED_UNWIND
62 unwind_handler_return:
68 /* Create stack and save all registers */
84 /* Restore registers and return */
94 __abnormal_termination:
99 /* Check if the handler is the unwind handler */
101 cmp dword ptr [ecx+4], offset _unwind_handler
104 /* Get the try level */
127 /* Get the exception registration */
130 /* Setup SEH to protect the unwind */
134 push offset _unwind_handler
139 /* Get the exception registration and try level */
144 /* Validate the unwind */
147 cmp dword ptr [esp+40], -1
153 /* Get the new enclosing level and save it */
159 /* Check the filter type */
160 cmp dword ptr [ebx+esi*4+4], 0
163 /* FIXME: NLG Notification */
165 /* Call the handler */
166 call dword ptr [ebx+esi*4+8]
184 /* Setup stack and save volatiles */
193 /* Clear direction flag */
196 /* Get exception registration and record */
200 /* Check if this is an unwind */
201 test dword ptr [eax+4], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING
204 /* Save exception pointers structure */
211 /* Get the try level and scope table */
216 /* Validate try level */
220 /* Check if this is the termination handler */
222 cmp dword ptr [edi+ecx*4+4], 0
225 /* Save registers and call filter, then restore them */
229 call dword ptr [edi+ecx*4+4]
233 /* Restore ebx and check the result */
239 /* So this is an accept, call the termination handlers */
242 call __global_unwind2
248 /* Do local unwind */
254 /* Set new try level */
259 /* Call except handler */
260 call dword ptr [edi+ecx*4+8]
263 /* Reload try level and except again */
271 mov eax, DISPOSITION_DISMISS
275 /* Continue searching */
276 mov eax, DISPOSITION_CONTINUE_SEARCH
279 /* Do local unwind */
288 /* Retore EBP and set return disposition */
290 mov eax, DISPOSITION_CONTINUE_SEARCH
293 /* Restore registers and stack */
305 /* Setup stack and save volatiles */
314 /* Clear direction flag */
317 /* Get exception registration and record */
321 /* Check if this is an unwind */
322 test dword ptr [eax+4], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING
325 /* Save exception pointers structure */
332 /* Get the try level and scope table */
336 /* FIXME: Validate the SEH exception */
339 /* Validate try level */
343 /* Check if this is the termination handler */
345 mov eax, [edi+ecx*4+4]
349 /* Save registers clear them all */
359 /* Call the filter and restore our registers */
364 /* Restore ebx and check the result */
370 /* So this is an accept, call the termination handlers */
373 call __global_unwind2
379 /* Do local unwind */
385 /* FIXME: Do NLG Notification */
387 /* Set new try level */
392 /* Clear registers and call except handler */
393 mov eax, [edi+ecx*4+8]
402 /* Reload try level and except again */
410 mov eax, DISPOSITION_DISMISS
414 /* Continue searching */
415 mov eax, DISPOSITION_CONTINUE_SEARCH
418 /* Do local unwind */
427 /* Retore EBP and set return disposition */
429 mov eax, DISPOSITION_CONTINUE_SEARCH
432 /* Restore registers and stack */