3 * COPYRIGHT: See COPYING in the top level directory
\r
4 * PROJECT: ReactOS kernel
\r
5 * PURPOSE: User-mode exception support for IA-32
\r
6 * FILE: lib/ntdll/rtl/i386/except.s
\r
7 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
\r
8 * NOTES: This file is shared with ntoskrnl/rtl/i386/except.s.
\r
9 * Please keep them in sync.
\r
12 #define EXCEPTION_UNWINDING 0x02
\r
14 #define EREC_FLAGS 0x04
\r
16 #define ExceptionContinueExecution 0
\r
17 #define ExceptionContinueSearch 1
\r
18 #define ExceptionNestedException 2
\r
19 #define ExceptionCollidedUnwind 3
\r
21 .globl _RtlpExecuteHandlerForException
\r
22 .globl _RtlpExecuteHandlerForUnwind
\r
24 #define CONTEXT_FLAGS 0x00
\r
25 #define CONTEXT_SEGGS 0x8C
\r
26 #define CONTEXT_SEGFS 0x90
\r
27 #define CONTEXT_SEGES 0x94
\r
28 #define CONTEXT_SEGDS 0x98
\r
29 #define CONTEXT_EDI 0x9C
\r
30 #define CONTEXT_ESI 0xA0
\r
31 #define CONTEXT_EBX 0xA4
\r
32 #define CONTEXT_EDX 0xA8
\r
33 #define CONTEXT_ECX 0xAC
\r
34 #define CONTEXT_EAX 0xB0
\r
35 #define CONTEXT_EBP 0xB4
\r
36 #define CONTEXT_EIP 0xB8
\r
37 #define CONTEXT_SEGCS 0xBC
\r
38 #define CONTEXT_EFLAGS 0xC0
\r
39 #define CONTEXT_ESP 0xC4
\r
40 #define CONTEXT_SEGSS 0xC8
\r
43 #define RCC_CONTEXT 0x08
\r
45 // EAX = value to print
\r
53 #ifndef __NTOSKRNL__
\r
57 // RtlpCaptureContext(PCONTEXT pContext);
\r
60 // [ESP+08h] - PCONTEXT_X86 pContext
\r
66 // Grabs the current CPU context.
\r
67 .globl _RtlpCaptureContext
\r
68 _RtlpCaptureContext:
\r
71 movl RCC_CONTEXT(%ebp), %edx // EDX = Address of context structure
\r
76 movl %eax, CONTEXT_EFLAGS(%edx)
\r
78 movl %eax, CONTEXT_EAX(%edx)
\r
79 movl %eax, CONTEXT_EBX(%edx)
\r
80 movl %eax, CONTEXT_ECX(%edx)
\r
81 movl %eax, CONTEXT_EDX(%edx)
\r
82 movl %eax, CONTEXT_ESI(%edx)
\r
83 movl %eax, CONTEXT_EDI(%edx)
\r
85 movl %eax, CONTEXT_SEGCS(%edx)
\r
87 movl %eax, CONTEXT_SEGDS(%edx)
\r
89 movl %eax, CONTEXT_SEGES(%edx)
\r
91 movl %eax, CONTEXT_SEGFS(%edx)
\r
93 movl %eax, CONTEXT_SEGGS(%edx)
\r
95 movl %eax, CONTEXT_SEGSS(%edx)
\r
98 // STACK LAYOUT: - (ESP to put in context structure)
\r
99 // - RETURN ADDRESS OF CALLER OF CALLER
\r
100 // - EBP OF CALLER OF CALLER
\r
102 // - RETURN ADDRESS OF CALLER
\r
107 // Get return address of the caller of the caller of this function
\r
109 //movl 4(%ebx), %eax // EAX = return address of caller
\r
110 movl (%ebx), %ebx // EBX = EBP of caller
\r
112 movl 4(%ebx), %eax // EAX = return address of caller of caller
\r
113 movl (%ebx), %ebx // EBX = EBP of caller of caller
\r
115 movl %eax, CONTEXT_EIP(%edx) // EIP = return address of caller of caller
\r
116 movl %ebx, CONTEXT_EBP(%edx) // EBP = EBP of caller of caller
\r
118 movl %ebx, CONTEXT_ESP(%edx) // ESP = EBP of caller of caller + 8
\r
124 #endif /* !__NTOSKRNL__ */
\r
126 #define REH_ERECORD 0x08
\r
127 #define REH_RFRAME 0x0C
\r
128 #define REH_CONTEXT 0x10
\r
129 #define REH_DCONTEXT 0x14
\r
130 #define REH_EROUTINE 0x18
\r
135 // [EBP+08h] - PEXCEPTION_RECORD ExceptionRecord
\r
136 // [EBP+0Ch] - PEXCEPTION_REGISTRATION RegistrationFrame
\r
137 // [EBP+10h] - PVOID Context
\r
138 // [EBP+14h] - PVOID DispatcherContext
\r
139 // [EBP+18h] - PEXCEPTION_HANDLER ExceptionRoutine
\r
140 // EDX - Address of protecting exception handler
\r
142 // EXCEPTION_DISPOSITION
\r
144 // Setup the protecting exception handler and call the exception
\r
145 // handler in the right context.
\r
146 _RtlpExecuteHandler:
\r
149 pushl REH_RFRAME(%ebp)
\r
155 // Prepare to call the exception handler
\r
156 pushl REH_DCONTEXT(%ebp)
\r
157 pushl REH_CONTEXT(%ebp)
\r
158 pushl REH_RFRAME(%ebp)
\r
159 pushl REH_ERECORD(%ebp)
\r
161 // Now call the exception handler
\r
162 movl REH_EROUTINE(%ebp), %eax
\r
166 jne .reh_stack_looks_ok
\r
168 // This should not happen
\r
178 .reh_stack_looks_ok:
\r
181 // Return to the 'front-end' for this function
\r
188 #define REP_ERECORD 0x04
\r
189 #define REP_RFRAME 0x08
\r
190 #define REP_CONTEXT 0x0C
\r
191 #define REP_DCONTEXT 0x10
\r
194 // [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
\r
195 // [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
\r
196 // [ESP+0Ch] - PCONTEXT Context
\r
197 // [ESP+10h] - PVOID DispatcherContext
\r
201 // EXCEPTION_DISPOSITION
\r
203 // This exception handler protects the exception handling
\r
204 // mechanism by detecting nested exceptions.
\r
205 _RtlpExceptionProtector:
\r
206 movl $ExceptionContinueSearch, %eax
\r
207 movl REP_ERECORD(%esp), %ecx
\r
208 testl $EXCEPTION_UNWINDING, EREC_FLAGS(%ecx)
\r
211 // Unwinding is not taking place, so return ExceptionNestedException
\r
213 // Set DispatcherContext field to the exception registration for the
\r
214 // exception handler that executed when a nested exception occurred
\r
215 movl REP_DCONTEXT(%esp), %ecx
\r
216 movl REP_RFRAME(%esp), %eax
\r
218 movl $ExceptionNestedException, %eax
\r
225 // [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
\r
226 // [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
\r
227 // [ESP+0Ch] - PCONTEXT Context
\r
228 // [ESP+10h] - PVOID DispatcherContext
\r
229 // [ESP+14h] - PEXCEPTION_HANDLER ExceptionHandler
\r
233 // EXCEPTION_DISPOSITION
\r
236 _RtlpExecuteHandlerForException:
\r
237 movl $_RtlpExceptionProtector, %edx
\r
238 jmp _RtlpExecuteHandler
\r
241 #define RUP_ERECORD 0x04
\r
242 #define RUP_RFRAME 0x08
\r
243 #define RUP_CONTEXT 0x0C
\r
244 #define RUP_DCONTEXT 0x10
\r
247 // [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
\r
248 // [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
\r
249 // [ESP+0Ch] - PCONTEXT Context
\r
250 // [ESP+10h] - PVOID DispatcherContext
\r
254 // EXCEPTION_DISPOSITION
\r
256 // This exception handler protects the exception handling
\r
257 // mechanism by detecting collided unwinds.
\r
258 _RtlpUnwindProtector:
\r
259 movl $ExceptionContinueSearch, %eax
\r
260 movl %ecx, RUP_ERECORD(%esp)
\r
261 testl $EXCEPTION_UNWINDING, EREC_FLAGS(%ecx)
\r
264 // Unwinding is taking place, so return ExceptionCollidedUnwind
\r
266 movl RUP_RFRAME(%esp), %ecx
\r
267 movl RUP_DCONTEXT(%esp), %edx
\r
269 // Set DispatcherContext field to the exception registration for the
\r
270 // exception handler that executed when a collision occurred
\r
271 movl RUP_RFRAME(%ecx), %eax
\r
273 movl $ExceptionCollidedUnwind, %eax
\r
280 // [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
\r
281 // [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
\r
282 // [ESP+0Ch] - PCONTEXT Context
\r
283 // [ESP+10h] - PVOID DispatcherContext
\r
284 // [ESP+14h] - PEXCEPTION_HANDLER ExceptionHandler
\r
288 // EXCEPTION_DISPOSITION
\r
289 _RtlpExecuteHandlerForUnwind:
\r
290 movl $_RtlpUnwindProtector, %edx
\r
291 jmp _RtlpExecuteHandler
\r