Add !error command which checks NtStatus, Winerror and hResult.
[reactos.git] / msvc6 / ntoskrnl / rtl_i386_except.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2000 David Welch <welch@cwcom.net>
4 *
5 * Moved to MSVC-compatible inline assembler by Mike Nordell, 2003-12-26
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21 /*
22 * FILE: ntoskrnl/ke/i386/vm86_sup.S
23 * PURPOSE: V86 mode support
24 * PROGRAMMER: David Welch (welch@cwcom.net)
25 * UPDATE HISTORY:
26 * Created 09/10/00
27 */
28
29 /* INCLUDES ******************************************************************/
30
31 #pragma hdrstop
32
33 #include <ddk/ntddk.h>
34 #include <ddk/status.h>
35 #include <internal/i386/segment.h>
36 #include <internal/i386/fpu.h>
37 #include <internal/ps.h>
38 #include <ddk/defines.h>
39 #include <internal/v86m.h>
40 #include <ntos/tss.h>
41 //#include <ntos/service.h>
42 #include <internal/trap.h>
43 #include <internal/ps.h>
44
45 #include <roscfg.h>
46 #include <internal/ntoskrnl.h>
47 #include <internal/i386/segment.h>
48
49
50 #define EXCEPTION_UNWINDING 0x02
51
52 #define EREC_FLAGS 0x04
53
54 #define ExceptionContinueExecution 0
55 #define ExceptionContinueSearch 1
56 #define ExceptionNestedException 2
57 #define ExceptionCollidedUnwind 3
58
59 //.globl _RtlpExecuteHandlerForException
60 //.globl _RtlpExecuteHandlerForUnwind
61
62 #define CONTEXT_FLAGS 0x00
63 #define CONTEXT_SEGGS 0x8C
64 #define CONTEXT_SEGFS 0x90
65 #define CONTEXT_SEGES 0x94
66 #define CONTEXT_SEGDS 0x98
67 #define CONTEXT_EDI 0x9C
68 #define CONTEXT_ESI 0xA0
69 #define CONTEXT_EBX 0xA4
70 #define CONTEXT_EDX 0xA8
71 #define CONTEXT_ECX 0xAC
72 #define CONTEXT_EAX 0xB0
73 #define CONTEXT_EBP 0xB4
74 #define CONTEXT_EIP 0xB8
75 #define CONTEXT_SEGCS 0xBC
76 #define CONTEXT_EFLAGS 0xC0
77 #define CONTEXT_ESP 0xC4
78 #define CONTEXT_SEGSS 0xC8
79
80
81 #define RCC_CONTEXT 0x08
82
83
84 VOID STDCALL
85 AsmDebug(ULONG Value);
86
87
88 // EAX = value to print
89 __declspec(naked)
90 void do_debug()
91 {
92 __asm
93 {
94 pusha
95 push eax
96 call AsmDebug
97 popa
98 ret
99 }
100 }
101
102
103 #define REH_ERECORD 0x08
104 #define REH_RFRAME 0x0C
105 #define REH_CONTEXT 0x10
106 #define REH_DCONTEXT 0x14
107 #define REH_EROUTINE 0x18
108
109 // Parameters:
110 // None
111 // Registers:
112 // [EBP+08h] - PEXCEPTION_RECORD ExceptionRecord
113 // [EBP+0Ch] - PEXCEPTION_REGISTRATION RegistrationFrame
114 // [EBP+10h] - PVOID Context
115 // [EBP+14h] - PVOID DispatcherContext
116 // [EBP+18h] - PEXCEPTION_HANDLER ExceptionRoutine
117 // EDX - Address of protecting exception handler
118 // Returns:
119 // EXCEPTION_DISPOSITION
120 // Notes:
121 // Setup the protecting exception handler and call the exception
122 // handler in the right context.
123 __declspec(naked)
124 void RtlpExecuteHandler()
125 {
126 __asm
127 {
128 push ebp
129 mov ebp, esp
130 push REH_RFRAME[ebp]
131
132 push edx
133 push fs:0x0
134 mov fs:0x0, esp
135
136 // Prepare to call the exception handler
137 push REH_DCONTEXT[ebp]
138 push REH_CONTEXT[ebp]
139 push REH_RFRAME[ebp]
140 push REH_ERECORD[ebp]
141
142 // Now call the exception handler
143 mov eax, REH_EROUTINE[ebp]
144 call eax
145
146 cmp fs:0x0, -1
147 jne reh_stack_looks_ok
148
149 // This should not happen
150 push 0
151 push 0
152 push 0
153 push 0
154 call RtlAssert
155
156 reh_loop:
157 jmp reh_loop
158
159 reh_stack_looks_ok:
160 mov esp, fs:0x0
161
162 // Return to the 'front-end' for this function
163 pop dword ptr fs:0x0
164 mov esp, ebp
165 pop ebp
166 ret
167 }
168 }
169
170 #if 0
171
172 #endif // 0
173
174 #define REP_ERECORD 0x04
175 #define REP_RFRAME 0x08
176 #define REP_CONTEXT 0x0C
177 #define REP_DCONTEXT 0x10
178
179 // Parameters:
180 // [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
181 // [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
182 // [ESP+0Ch] - PCONTEXT Context
183 // [ESP+10h] - PVOID DispatcherContext
184 // Registers:
185 // None
186 // Returns:
187 // EXCEPTION_DISPOSITION
188 // Notes:
189 // This exception handler protects the exception handling
190 // mechanism by detecting nested exceptions.
191 __declspec(naked)
192 void RtlpExceptionProtector()
193 {
194 __asm
195 {
196 mov eax, ExceptionContinueSearch
197 mov ecx, REP_ERECORD[esp]
198 test EREC_FLAGS[ecx], EXCEPTION_UNWINDING
199 jnz rep_end
200
201 // Unwinding is not taking place, so return ExceptionNestedException
202
203 // Set DispatcherContext field to the exception registration for the
204 // exception handler that executed when a nested exception occurred
205 mov ecx, REP_DCONTEXT[esp]
206 mov eax, REP_RFRAME[esp]
207 mov [ecx], eax
208 mov eax, ExceptionNestedException
209
210 rep_end:
211 ret
212 }
213 }
214
215
216 // Parameters:
217 // [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
218 // [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
219 // [ESP+0Ch] - PCONTEXT Context
220 // [ESP+10h] - PVOID DispatcherContext
221 // [ESP+14h] - PEXCEPTION_HANDLER ExceptionHandler
222 // Registers:
223 // None
224 // Returns:
225 // EXCEPTION_DISPOSITION
226 // Notes:
227 // Front-end
228 __declspec(naked)
229 void RtlpExecuteHandlerForException()
230 {
231 __asm
232 {
233 mov edx, RtlpExceptionProtector
234 jmp RtlpExecuteHandler
235 }
236 }
237
238
239 #define RUP_ERECORD 0x04
240 #define RUP_RFRAME 0x08
241 #define RUP_CONTEXT 0x0C
242 #define RUP_DCONTEXT 0x10
243
244 // Parameters:
245 // [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
246 // [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
247 // [ESP+0Ch] - PCONTEXT Context
248 // [ESP+10h] - PVOID DispatcherContext
249 // Registers:
250 // None
251 // Returns:
252 // EXCEPTION_DISPOSITION
253 // Notes:
254 // This exception handler protects the exception handling
255 // mechanism by detecting collided unwinds.
256 __declspec(naked)
257 void RtlpUnwindProtector()
258 {
259 __asm
260 {
261 mov eax, ExceptionContinueSearch
262 mov RUP_ERECORD[esp], ecx
263 test EREC_FLAGS[ecx], EXCEPTION_UNWINDING
264 jz rup_end
265
266 // Unwinding is taking place, so return ExceptionCollidedUnwind
267
268 mov ecx, RUP_RFRAME[esp]
269 mov edx, RUP_DCONTEXT[esp]
270
271 // Set DispatcherContext field to the exception registration for the
272 // exception handler that executed when a collision occurred
273 mov eax, RUP_RFRAME[ecx]
274 mov [edx], eax
275 mov eax, ExceptionCollidedUnwind
276
277 rup_end:
278 ret
279 }
280 }
281
282
283 // Parameters:
284 // [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
285 // [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
286 // [ESP+0Ch] - PCONTEXT Context
287 // [ESP+10h] - PVOID DispatcherContext
288 // [ESP+14h] - PEXCEPTION_HANDLER ExceptionHandler
289 // Registers:
290 // None
291 // Returns:
292 // EXCEPTION_DISPOSITION
293 __declspec(naked)
294 void RtlpExecuteHandlerForUnwind()
295 {
296 __asm mov edx, RtlpUnwindProtector
297 __asm jmp RtlpExecuteHandler
298 }
299