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