[NTDLL]
[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 <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 _KiUserExceptionDispatcher@8:
188
189 /* Clear direction flag */
190 cld
191
192 /* Save the Context and Exception Records */
193 mov ecx, [esp+4]
194 mov ebx, [esp]
195
196 /* Dispatch the exception */
197 push ecx
198 push ebx
199 call _RtlDispatchException@8
200
201 /* Check for success */
202 or al, al
203 jz RaiseException
204
205 /* Pop off the records */
206 pop ebx
207 pop ecx
208
209 /* We're fine, continue execution */
210 push 0
211 push ecx
212 call _ZwContinue@8
213
214 /* Exit */
215 jmp Exit
216
217 RaiseException:
218 /* Pop off the records */
219 pop ebx
220 pop ecx
221
222 /* Raise the exception */
223 push 0
224 push ecx
225 push ebx
226 call _ZwRaiseException@12
227
228 Exit:
229 /* Allocate space for the nested exception record */
230 add esp, -SIZEOF_EXCEPTION_RECORD
231
232 /* Set it up */
233 mov [esp+EXCEPTION_RECORD_EXCEPTION_CODE], eax
234 mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_NONCONTINUABLE
235 mov [esp+EXCEPTION_RECORD_EXCEPTION_RECORD], ebx
236 mov dword ptr [esp+EXCEPTION_RECORD_NUMBER_PARAMETERS], 0
237
238 /* Raise the exception */
239 push esp
240 call _RtlRaiseException@4
241 ret 8
242
243
244 PUBLIC _KiIntSystemCall@0
245 _KiIntSystemCall@0:
246
247 /* Set stack in EDX and do the interrupt */
248 lea edx, [esp+8]
249 int HEX(2E)
250
251 /* Return to caller */
252 ret
253
254
255 PUBLIC _KiFastSystemCall@0
256 _KiFastSystemCall@0:
257
258 /* Put ESP in EDX and do the SYSENTER */
259 mov edx, esp
260 sysenter
261
262
263 PUBLIC _KiFastSystemCallRet@0
264 _KiFastSystemCallRet@0:
265
266 /* Just return to caller */
267 ret
268
269
270 PUBLIC _RtlpGetStackLimits@8
271 _RtlpGetStackLimits@8:
272
273 /* Get the stack limits */
274 mov eax, [fs:TEB_STACK_LIMIT]
275 mov ecx, [fs:TEB_STACK_BASE]
276
277 /* Return them */
278 mov edx, [esp+4]
279 mov [edx], eax
280 mov edx, [esp+8]
281 mov [edx], ecx
282
283 /* return */
284 ret 8
285
286 END