[FORMATTING] Remove trailing whitespace. Addendum to 34593d93.
[reactos.git] / dll / ntdll / dispatch / amd64 / dispatch.S
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntdll/dispatch/amd64/dispatch.S
5 * PURPOSE: Usermode dispatcher stubs
6 *
7 * PROGRAMMER: Timo kreuzer (timo.kreuzer@reactos.org)
8 */
9
10 /* INCLUDES ******************************************************************/
11
12 #include <asm.inc>
13 #include <ksamd64.inc>
14
15 EXTERN NtContinue:PROC
16 EXTERN LdrpInit:PROC
17 EXTERN ZwCallbackReturn:PROC
18 EXTERN RtlRaiseStatus:PROC
19
20 .code
21
22 PUBLIC LdrInitializeThunk
23 .PROC LdrInitializeThunk
24 mov rbp, 0
25 .setframe rbp, 0
26 .endprolog
27
28 /* First parameter is the APC context */
29 mov rcx, r9
30 jmp LdrpInit
31
32 .ENDP
33
34 PUBLIC KiUserApcDispatcher
35 .PROC KiUserApcDispatcher
36 .endprolog
37 /* We enter with a 16 byte aligned stack */
38
39 mov rcx, [rsp + CONTEXT_P1Home] /* NormalContext */
40 mov rdx, [rsp + CONTEXT_P2Home] /* SystemArgument1 */
41 mov r8, [rsp + CONTEXT_P3Home] /* SystemArgument2 */
42 lea r9, [rsp] /* Context */
43 call qword ptr [rsp + CONTEXT_P4Home] /* NormalRoutine */
44
45 /* NtContinue(Context, TRUE); */
46 lea rcx, [rsp]
47 mov dl, 1
48 call NtContinue
49
50 nop
51 int 3
52 .ENDP
53
54
55 PUBLIC KiRaiseUserExceptionDispatcher
56 .PROC KiRaiseUserExceptionDispatcher
57 .endprolog
58 int 3
59
60 .ENDP
61
62 PUBLIC KiUserCallbackDispatcher
63 .PROC KiUserCallbackDispatcher
64
65 /* The stack is set up with a UCALLOUT_FRAME */
66 /* The frame ends with a MACHINE_FRAME. */
67 .PUSHFRAME
68
69 /* This is for the Home space, Buffer, Length and ApiNumber */
70 .ALLOCSTACK (6 * 8)
71 .ENDPROLOG
72
73 #if DBG
74 /* We enter the function with a fully setup stack, so it must be aligned! */
75 test rsp, 15
76 jz AlignmentOk
77 int HEX(2C)
78 AlignmentOk:
79 #endif
80
81 /* Get the parameters from the callout frame */
82 mov rcx, [rsp + CkBuffer]
83 mov edx, [rsp + CkLength]
84 mov r8d, [rsp + CkApiNumber]
85
86 /* Get the callback table */
87 mov rax, gs:[TePeb]
88 mov r9, [rax + PeKernelCallbackTable]
89
90 /* Call the routine */
91 call qword ptr [r9 + r8 * 8]
92
93 /* Return from callback */
94 xor ecx, ecx
95 xor edx, edx
96 mov r8d, eax
97 call ZwCallbackReturn
98
99 /* Save callback return value */
100 mov esi, eax
101
102 /* Raise status */
103 StatusRaise:
104 mov ecx, esi
105 call RtlRaiseStatus
106 jmp StatusRaise
107
108 .ENDP
109
110 /*
111 BOOLEAN
112 NTAPI
113 RtlDispatchException(
114 _In_ PEXCEPTION_RECORD ExceptionRecord,
115 _In_ PCONTEXT ContextRecord);
116 */
117 EXTERN RtlDispatchException:PROC
118
119 /*
120 NTSTATUS
121 NTAPI
122 ZwContinue(
123 _In_ PCONTEXT Context,
124 _In_ BOOLEAN TestAlert);
125 */
126 EXTERN ZwContinue:PROC
127
128 /*
129 NTSTATUS
130 NTAPI
131 ZwRaiseException(
132 _In_ PEXCEPTION_RECORD ExceptionRecord,
133 _In_ PCONTEXT Context,
134 _In_ BOOLEAN SearchFrames);
135 */
136 EXTERN ZwRaiseException:PROC
137
138 /*
139 VOID
140 NTAPI
141 RtlRaiseStatus(
142 _In_ PEXCEPTION_RECORD ExceptionRecord);
143 */
144 EXTERN RtlRaiseException:PROC
145
146 /*
147 VOID
148 KiUserExceptionDispatcher(
149 CONTEXT ContextRecord<rcx>,
150 PEXCEPTION_RECORD ExceptionRecord<rdx>);
151
152 This function is called with the following stack layout:
153 CONTEXT ContextRecord <- RSP, RCX
154 EXCEPTION_RECORD ExceptionRecord <- RDX
155 ULONG64 Alignment
156 MACHINE_FRAME MachineFrame
157 */
158 PUBLIC KiUserExceptionDispatcher
159 .PROC KiUserExceptionDispatcher
160
161 /* The stack is set up with a KUSER_EXCEPTION_STACK */
162 /* The frame ends with a MACHINE_FRAME. */
163 .PUSHFRAME
164
165 /* This is for the alignment, EXCEPTION_RECORD and CONTEXT */
166 .ALLOCSTACK 8 + EXCEPTION_RECORD_LENGTH + CONTEXT_FRAME_LENGTH
167 .ENDPROLOG
168
169 /* Clear direction flag */
170 cld
171
172 /* Dispatch the exception */
173 call RtlDispatchException
174
175 /* Check for success */
176 or al, al
177 jz RaiseException
178
179 /* We're fine, continue execution */
180 lea rcx, [rsp] /* ContextRecord */
181 mov dl, 0 /* TestAlert */
182 call ZwContinue
183
184 /* Exit */
185 jmp Exit
186
187 RaiseException:
188
189 /* Raise the exception */
190 lea rcx, [rsp + CONTEXT_FRAME_LENGTH] /* ExceptionRecord */
191 lea rdx, [rsp] /* ContextRecord */
192 xor r8, r8
193 call ZwRaiseException
194
195 Exit:
196 lea rcx, [rsp + CONTEXT_FRAME_LENGTH] /* ExceptionRecord */
197 mov rdx, rax
198 call KiUserExceptionDispatcherNested
199 ret
200
201 .ENDP
202
203 /*
204 VOID
205 KiUserExceptionDispatcherNested(
206 _In_ ExceptionRecord<rcx>,
207 _In_ Status<edx>
208 )
209 */
210 .PROC KiUserExceptionDispatcherNested
211 /* Allocate space for the nested exception record */
212 sub rsp, EXCEPTION_RECORD_LENGTH
213 .ALLOCSTACK EXCEPTION_RECORD_LENGTH
214 .ENDPROLOG
215
216 /* Set it up */
217 mov dword ptr [rsp + ErNumberParameters], 0
218 mov dword ptr [rsp + ErExceptionFlags], EXCEPTION_NONCONTINUABLE
219 mov [rsp + ErExceptionRecord], rcx
220 mov [rsp + ErExceptionCode], edx
221
222 /* Raise the exception */
223 mov rcx, rsp
224 call RtlRaiseException
225
226 /* Cleanup stack and return */
227 add rsp, EXCEPTION_RECORD_LENGTH
228 ret
229 .ENDP
230
231 END
232