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)
9 /* INCLUDES ******************************************************************/
12 .intel_syntax noprefix
14 /* FUNCTIONS ****************************************************************/
16 .func LdrInitializeThunk@16
17 .globl _LdrInitializeThunk@16
18 _LdrInitializeThunk@16:
20 /* Get the APC Context */
23 /* Send it as the first parameter */
26 /* Terminate the frame list */
29 /* Jump into the C initialization routine */
33 .func KiUserApcExceptionHandler
34 _KiUserApcExceptionHandler:
36 /* Put the exception record in ECX and check the Flags */
38 test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING
41 /* Test alert the thread */
45 /* We'll execute handler */
46 mov eax, EXCEPTION_EXECUTE_HANDLER
50 .func KiUserApcDispatcher@16
51 .globl _KiUserApcDispatcher@16
52 _KiUserApcDispatcher@16:
55 lea eax, [esp+CONTEXT_ALIGNED_SIZE+16]
56 mov ecx, fs:[TEB_EXCEPTION_LIST]
57 mov edx, offset _KiUserApcExceptionHandler
62 mov fs:[TEB_EXCEPTION_LIST], eax
64 /* Put the Context in EDI */
68 /* Call the APC Routine */
71 /* Restore exception list */
72 mov ecx, [edi+CONTEXT_ALIGNED_SIZE]
73 mov fs:[TEB_EXCEPTION_LIST], ecx
75 /* Switch back to the context */
80 /* Save callback return value */
86 call _RtlRaiseStatus@4
91 .func KiUserCallbackExceptionHandler
92 _KiUserCallbackExceptionHandler:
94 /* Put the exception record in ECX and check the Flags */
96 test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING
99 /* Tell the kernel to invalidate the stack */
100 push STATUS_CALLBACK_POP_STACK
103 call _ZwCallbackReturn@12
106 /* We'll execute the handler */
107 mov eax, EXCEPTION_EXECUTE_HANDLER
111 .func KiUserCallbackDispatcher@12
112 .globl _KiUserCallbackDispatcher@12
113 _KiUserCallbackDispatcher@12:
115 /* Setup SEH stack */
116 mov ecx, fs:[TEB_EXCEPTION_LIST]
117 mov edx, offset _KiUserCallbackExceptionHandler
123 mov fs:[TEB_EXCEPTION_LIST], eax
125 /* Get the callback Index */
129 /* Get the callback table */
130 mov eax, [fs:TEB_PEB]
131 mov eax, [eax+PEB_KERNEL_CALLBACK_TABLE]
133 /* Call the routine */
136 /* Return from callback */
140 call _ZwCallbackReturn@12
142 /* Save callback return value */
148 call _RtlRaiseStatus@4
153 .func KiRaiseUserExceptionDispatcher@0
154 .globl _KiRaiseUserExceptionDispatcher@0
155 _KiRaiseUserExceptionDispatcher@0:
157 /* Setup stack for EXCEPTION_RECORD */
160 sub esp, EXCEPTION_RECORD_LENGTH
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
171 /* Raise the exception */
173 call _RtlRaiseException@4
175 /* Return exception code */
176 mov eax, [esp+EXCEPTION_RECORD_EXCEPTION_CODE]
182 .func KiUserExceptionDispatcher@8
183 .globl _KiUserExceptionDispatcher@8
184 _KiUserExceptionDispatcher@8:
186 /* Clear direction flag */
189 /* Save the Context and Exception Records */
193 /* Dispatch the exception */
196 call _RtlDispatchException@8
198 /* Check for success */
202 /* Pop off the records */
206 /* We're fine, continue execution */
215 /* Pop off the records */
219 /* Raise the exception */
223 call _ZwRaiseException@12
226 /* Allocate space for the nested exception record */
227 add esp, -SIZEOF_EXCEPTION_RECORD
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
235 /* Raise the exception */
237 call _RtlRaiseException@4
241 .func KiIntSystemCall@0
242 .globl _KiIntSystemCall@0
245 /* Set stack in EDX and do the interrupt */
249 /* Return to caller */
253 .func KiFastSystemCall@0
254 .globl _KiFastSystemCall@0
257 /* Put ESP in EDX and do the SYSENTER */
262 .func KiFastSystemCallRet@0
263 .globl _KiFastSystemCallRet@0
264 _KiFastSystemCallRet@0:
266 /* Just return to caller */
270 .func RtlpGetStackLimits@8
271 .globl _RtlpGetStackLimits@8
272 _RtlpGetStackLimits@8:
274 /* Get the stack limits */
275 mov eax, [fs:TEB_STACK_LIMIT]
276 mov ecx, [fs:TEB_STACK_BASE]