c17374e9ed1e0d1a340c88a9ba152b98f776a371
[reactos.git] / dll / ntdll / dispatch / i386 / dispatch.S
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NT Library
4 * FILE: dl/ntdll/dispatch/i386/dispatch.S
5 * PURPOSE: User-Mode NT Dispatchers
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <ndk/asm.h>
12 .intel_syntax noprefix
13
14 /* FUNCTIONS ****************************************************************/
15
16 .func LdrInitializeThunk@16
17 .globl _LdrInitializeThunk@16
18 _LdrInitializeThunk@16:
19
20 /* Get the APC Context */
21 lea eax, [esp+16]
22
23 /* Send it as the first parameter */
24 mov [esp+4], eax
25
26 /* Terminate the frame list */
27 xor ebp, ebp
28
29 /* Jump into the C initialization routine */
30 jmp _LdrpInit@12
31 .endfunc
32
33 .func KiUserApcExceptionHandler
34 _KiUserApcExceptionHandler:
35
36 /* Put the exception record in ECX and check the Flags */
37 mov ecx, [esp+4]
38 test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING
39 jz .return
40
41 /* Test alert the thread */
42 call _NtTestAlert@0
43
44 .return:
45 /* We'll execute handler */
46 mov eax, EXCEPTION_EXECUTE_HANDLER
47 ret 16
48 .endfunc
49
50 .func KiUserApcDispatcher@16
51 .globl _KiUserApcDispatcher@16
52 _KiUserApcDispatcher@16:
53
54 /* Setup SEH stack */
55 lea eax, [esp+CONTEXT_ALIGNED_SIZE+16]
56 mov ecx, fs:[TEB_EXCEPTION_LIST]
57 mov edx, offset _KiUserApcExceptionHandler
58 mov [eax], ecx
59 mov [eax+4], edx
60
61 /* Enable SEH */
62 mov fs:[TEB_EXCEPTION_LIST], eax
63
64 /* Put the Context in EDI */
65 pop eax
66 lea edi, [esp+12]
67
68 /* Call the APC Routine */
69 call eax
70
71 /* Restore exception list */
72 mov ecx, [edi+CONTEXT_ALIGNED_SIZE]
73 mov fs:[TEB_EXCEPTION_LIST], ecx
74
75 /* Switch back to the context */
76 push 1
77 push edi
78 call _ZwContinue@8
79
80 /* Save callback return value */
81 mov esi, eax
82
83 /* Raise status */
84 StatusRaiseApc:
85 push esi
86 call _RtlRaiseStatus@4
87 jmp StatusRaiseApc
88 ret 16
89 .endfunc
90
91 .func KiUserCallbackExceptionHandler
92 _KiUserCallbackExceptionHandler:
93
94 /* Put the exception record in ECX and check the Flags */
95 mov ecx, [esp+4]
96 test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING
97 jz return
98
99 /* Tell the kernel to invalidate the stack */
100 push STATUS_CALLBACK_POP_STACK
101 push 0
102 push 0
103 call _ZwCallbackReturn@12
104
105 return:
106 /* We'll execute the handler */
107 mov eax, EXCEPTION_EXECUTE_HANDLER
108 ret 16
109 .endfunc
110
111 .func KiUserCallbackDispatcher@12
112 .globl _KiUserCallbackDispatcher@12
113 _KiUserCallbackDispatcher@12:
114
115 /* Setup SEH stack */
116 mov ecx, fs:[TEB_EXCEPTION_LIST]
117 mov edx, offset _KiUserCallbackExceptionHandler
118 lea eax, [esp+16]
119 mov [esp+16], ecx
120 mov [esp+20], edx
121
122 /* Enable SEH */
123 mov fs:[TEB_EXCEPTION_LIST], eax
124
125 /* Get the callback Index */
126 add esp, 4
127 pop edx
128
129 /* Get the callback table */
130 mov eax, [fs:TEB_PEB]
131 mov eax, [eax+PEB_KERNEL_CALLBACK_TABLE]
132
133 /* Call the routine */
134 call [eax+edx*4]
135
136 /* Return from callback */
137 push eax
138 push 0
139 push 0
140 call _ZwCallbackReturn@12
141
142 /* Save callback return value */
143 mov esi, eax
144
145 /* Raise status */
146 StatusRaise:
147 push esi
148 call _RtlRaiseStatus@4
149 jmp StatusRaise
150 ret 12
151 .endfunc
152
153 .func KiRaiseUserExceptionDispatcher@0
154 .globl _KiRaiseUserExceptionDispatcher@0
155 _KiRaiseUserExceptionDispatcher@0:
156
157 /* Setup stack for EXCEPTION_RECORD */
158 push ebp
159 mov ebp, esp
160 sub esp, EXCEPTION_RECORD_LENGTH
161
162 /* Fill out the record */
163 mov [esp+EXCEPTION_RECORD_EXCEPTION_ADDRESS], eax
164 mov eax, [fs:KPCR_TEB]
165 mov eax, [eax+TEB_EXCEPTION_CODE]
166 mov [esp+EXCEPTION_RECORD_EXCEPTION_CODE], eax
167 mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_FLAGS], 0
168 mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_RECORD], 0
169 mov dword ptr [esp+EXCEPTION_RECORD_NUMBER_PARAMETERS], 0
170
171 /* Raise the exception */
172 push esp
173 call _RtlRaiseException@4
174
175 /* Return exception code */
176 mov eax, [esp+EXCEPTION_RECORD_EXCEPTION_CODE]
177 mov esp, ebp
178 pop ebp
179 ret
180 .endfunc
181
182 .func KiUserExceptionDispatcher@8
183 .globl _KiUserExceptionDispatcher@8
184 _KiUserExceptionDispatcher@8:
185
186 /* Clear direction flag */
187 cld
188
189 /* Save the Context and Exception Records */
190 mov ecx, [esp+4]
191 mov ebx, [esp]
192
193 /* Dispatch the exception */
194 push ecx
195 push ebx
196 call _RtlDispatchException@8
197
198 /* Check for success */
199 or al, al
200 jz RaiseException
201
202 /* Pop off the records */
203 pop ebx
204 pop ecx
205
206 /* We're fine, continue execution */
207 push 0
208 push ecx
209 call _ZwContinue@8
210
211 /* Exit */
212 jmp Exit
213
214 RaiseException:
215 /* Pop off the records */
216 pop ebx
217 pop ecx
218
219 /* Raise the exception */
220 push 0
221 push ecx
222 push ebx
223 call _ZwRaiseException@12
224
225 Exit:
226 /* Allocate space for the nested exception record */
227 add esp, -SIZEOF_EXCEPTION_RECORD
228
229 /* Set it up */
230 mov [esp+EXCEPTION_RECORD_EXCEPTION_CODE], eax
231 mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_NONCONTINUABLE
232 mov [esp+EXCEPTION_RECORD_EXCEPTION_RECORD], ebx
233 mov dword ptr [esp+EXCEPTION_RECORD_NUMBER_PARAMETERS], 0
234
235 /* Raise the exception */
236 push esp
237 call _RtlRaiseException@4
238 ret 8
239 .endfunc
240
241 .func KiIntSystemCall@0
242 .globl _KiIntSystemCall@0
243 _KiIntSystemCall@0:
244
245 /* Set stack in EDX and do the interrupt */
246 lea edx, [esp+8]
247 int 0x2E
248
249 /* Return to caller */
250 ret
251 .endfunc
252
253 .func KiFastSystemCall@0
254 .globl _KiFastSystemCall@0
255 _KiFastSystemCall@0:
256
257 /* Put ESP in EDX and do the SYSENTER */
258 mov edx, esp
259 sysenter
260 .endfunc
261
262 .func KiFastSystemCallRet@0
263 .globl _KiFastSystemCallRet@0
264 _KiFastSystemCallRet@0:
265
266 /* Just return to caller */
267 ret
268 .endfunc
269
270 .func RtlpGetStackLimits@8
271 .globl _RtlpGetStackLimits@8
272 _RtlpGetStackLimits@8:
273
274 /* Get the stack limits */
275 mov eax, [fs:TEB_STACK_LIMIT]
276 mov ecx, [fs:TEB_STACK_BASE]
277
278 /* Return them */
279 mov edx, [esp+4]
280 mov [edx], eax
281 mov edx, [esp+8]
282 mov [edx], ecx
283
284 /* return */
285 ret 8
286 .endfunc