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