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 ******************************************************************/
12 .intel_syntax noprefix
14 #define DISPOSITION_DISMISS 0
15 #define DISPOSITION_CONTINUE_SEARCH 1
16 #define DISPOSITION_COLLIDED_UNWIND 3
18 /* GLOBALS *******************************************************************/
20 .globl __global_unwind2
21 .globl __local_unwind2
22 .globl __abnormal_termination
23 .globl __except_handler2
24 .globl __except_handler3
26 /* FUNCTIONS *****************************************************************/
31 /* Check if we were unwinding and continue search if not */
33 test dword ptr [ecx+4], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING
34 mov eax, DISPOSITION_CONTINUE_SEARCH
35 jz unwind_handler_return
37 /* We have a collision, do a local unwind */
49 /* Set new try level */
54 /* Return collided unwind */
55 mov eax, DISPOSITION_COLLIDED_UNWIND
57 unwind_handler_return:
64 /* Create stack and save all registers */
80 /* Restore registers and return */
90 .func _abnormal_termination
91 __abnormal_termination:
96 /* Check if the handler is the unwind handler */
98 cmp dword ptr [ecx+4], offset _unwind_handler
101 /* Get the try level */
125 /* Get the exception registration */
128 /* Setup SEH to protect the unwind */
132 push offset _unwind_handler
137 /* Get the exception registration and try level */
142 /* Validate the unwind */
145 cmp dword ptr [esp+40], -1
151 /* Get the new enclosing level and save it */
157 /* Check the filter type */
158 cmp dword ptr [ebx+esi*4+4], 0
161 /* FIXME: NLG Notification */
163 /* Call the handler */
164 call dword ptr [ebx+esi*4+8]
180 .func _except_handler2
183 /* Setup stack and save volatiles */
192 /* Clear direction flag */
195 /* Get exception registration and record */
199 /* Check if this is an unwind */
200 test dword ptr [eax+4], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING
203 /* Save exception pointers structure */
210 /* Get the try level and scope table */
215 /* Validate try level */
219 /* Check if this is the termination handler */
221 cmp dword ptr [edi+ecx*4+4], 0
224 /* Save registers and call filter, then restore them */
228 call dword ptr [edi+ecx*4+4]
232 /* Restore ebx and check the result */
238 /* So this is an accept, call the termination handlers */
241 call __global_unwind2
247 /* Do local unwind */
253 /* Set new try level */
258 /* Call except handler */
262 /* Reload try level and except again */
270 mov eax, DISPOSITION_DISMISS
274 /* Continue searching */
275 mov eax, DISPOSITION_CONTINUE_SEARCH
278 /* Do local unwind */
287 /* Retore EBP and set return disposition */
289 mov eax, DISPOSITION_CONTINUE_SEARCH
292 /* Restore registers and stack */
302 .func _except_handler3
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 */