2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NT Library
4 * FILE: lib/rtl/i386/except.S
5 * PURPOSE: User-mode exception support for IA-32
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7 * Casper S. Hornstrup (chorns@users.sourceforge.net)
10 /* INCLUDES ******************************************************************/
13 #include <ndk/i386/segment.h>
14 .intel_syntax noprefix
16 #define EXCEPTION_UNWINDING 2
17 #define EXCEPTION_EXIT_UNWIND 4
18 #define EXCEPTION_UNWIND (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND)
20 #define ExceptionContinueExecution 0
21 #define ExceptionContinueSearch 1
22 #define ExceptionNestedException 2
23 #define ExceptionCollidedUnwind 3
25 /* FUNCTIONS ****************************************************************/
27 .globl _RtlpGetExceptionList@0
28 _RtlpGetExceptionList@0:
30 /* Return the exception list */
31 mov eax, [fs:TEB_EXCEPTION_LIST]
34 .globl _RtlpSetExceptionList@4
35 _RtlpSetExceptionList@4:
37 /* Get the new list */
42 mov [fs:TEB_EXCEPTION_LIST], ecx
47 .globl _RtlpGetExceptionAddress@0
48 _RtlpGetExceptionAddress@0:
50 /* Return the address from the stack */
56 .globl _RtlCaptureContext@4
59 /* Preserve EBX and put the context in it */
63 /* Save the basic register context */
64 mov [ebx+CONTEXT_EAX], eax
65 mov [ebx+CONTEXT_ECX], ecx
66 mov [ebx+CONTEXT_EDX], edx
67 mov eax, [esp] /* We pushed EBX, remember? ;) */
68 mov [ebx+CONTEXT_EBX], eax
69 mov [ebx+CONTEXT_ESI], esi
70 mov [ebx+CONTEXT_EDI], edi
72 /* Capture the other regs */
75 .globl _RtlpCaptureContext@4
76 _RtlpCaptureContext@4:
78 /* Preserve EBX and put the context in it */
82 /* Clear the basic register context */
83 mov dword ptr [ebx+CONTEXT_EAX], 0
84 mov dword ptr [ebx+CONTEXT_ECX], 0
85 mov dword ptr [ebx+CONTEXT_EDX], 0
86 mov dword ptr [ebx+CONTEXT_EBX], 0
87 mov dword ptr [ebx+CONTEXT_ESI], 0
88 mov dword ptr [ebx+CONTEXT_EDI], 0
91 /* Capture the segment registers */
92 mov [ebx+CONTEXT_SEGCS], cs
93 mov [ebx+CONTEXT_SEGDS], ds
94 mov [ebx+CONTEXT_SEGES], es
95 mov [ebx+CONTEXT_SEGFS], fs
96 mov [ebx+CONTEXT_SEGGS], gs
97 mov [ebx+CONTEXT_SEGSS], ss
101 pop [ebx+CONTEXT_EFLAGS]
103 /* The return address should be in [ebp+4] */
105 mov [ebx+CONTEXT_EIP], eax
109 mov [ebx+CONTEXT_EBP], eax
113 mov [ebx+CONTEXT_ESP], eax
115 /* Return to the caller */
119 .globl _RtlpExecuteHandlerForException@20
120 _RtlpExecuteHandlerForException@20:
122 /* Copy the routine in EDX */
123 mov edx, offset _RtlpExceptionProtector
125 /* Jump to common routine */
126 jmp _RtlpExecuteHandler@20
128 .globl _RtlpExecuteHandlerForUnwind@20
129 _RtlpExecuteHandlerForUnwind@20:
131 /* Copy the routine in EDX */
132 mov edx, offset _RtlpExceptionProtector
134 /* Run the common routine */
135 _RtlpExecuteHandler@20:
137 /* Save non-volatile */
142 /* Clear registers */
148 /* Call the 2nd-stage executer */
154 call _RtlpExecuteHandler2@20
156 /* Restore non-volatile */
162 .globl _RtlpExecuteHandler2@20
163 _RtlpExecuteHandler2@20:
165 /* Set up stack frame */
172 /* Push handler address */
175 /* Push the exception list */
176 push [fs:TEB_EXCEPTION_LIST]
179 mov [fs:TEB_EXCEPTION_LIST], esp
181 /* Call the handler */
190 mov esp, [fs:TEB_EXCEPTION_LIST]
193 pop [fs:TEB_EXCEPTION_LIST]
195 /* Undo stack frame and return */
200 _RtlpExceptionProtector:
202 /* Assume we'll continue */
203 mov eax, ExceptionContinueSearch
205 /* Put the exception record in ECX and check the Flags */
207 test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_UNWIND
210 /* Save the frame in ECX and Context in EDX */
214 /* Get the nested frame */
217 /* Set it as the dispatcher context */
220 /* Return nested exception */
221 mov eax, ExceptionNestedException
226 _RtlpUnwindProtector:
227 /* Assume we'll continue */
228 mov eax, ExceptionContinueSearch
230 /* Put the exception record in ECX and check the Flags */
232 test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_UNWIND
235 /* Save the frame in ECX and Context in EDX */
239 /* Get the nested frame */
242 /* Set it as the dispatcher context */
245 /* Return collided unwind */
246 mov eax, ExceptionCollidedUnwind