Add back support for older binutils versions
[reactos.git] / reactos / lib / ntdll / main / i386 / dispatch.S
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NT Library
4 * FILE: lib/ntdll/main/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 #include <ndk/i386/segment.h>
13 .intel_syntax noprefix
14
15 #define EXCEPTION_NONCONTINUABLE 1
16 #define EXCEPTION_UNWINDING 2
17 #define EXCEPTION_EXIT_UNWIND 4
18 #define EXCEPTION_UNWIND (EXCEPTION_UNWINDING + EXCEPTION_EXIT_UNWIND)
19
20 #define STATUS_CALLBACK_POP_STACK 0xC0000423
21
22 #define ExceptionContinueSearch 1
23
24 /* FUNCTIONS ****************************************************************/
25
26 .globl _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 .globl _KiUserExceptionApcHandler@16
42 _KiUserApcExceptionHandler@16:
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_UNWIND
47 jz .return
48
49 /* Test alert the thread */
50 call _NtTestAlert@0
51
52 .return:
53 /* We'll continue */
54 mov eax, ExceptionContinueSearch
55 ret 16
56
57 .globl _KiUserApcDispatcher@16
58 _KiUserApcDispatcher@16:
59
60 /* Put the Context in EDI */
61 lea edi, [esp+16]
62
63 /* Get the ApcRoutine and call it */
64 pop eax
65 call eax
66
67 /* Switch back to the context */
68 push 1
69 push edi
70 call _ZwContinue@8
71
72 .globl _KiUserCallbackExceptionHandler@16
73 _KiUserCallbackExceptionHandler@16:
74
75 /* Put the exception record in ECX and check the Flags */
76 mov ecx, [esp+4]
77 test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_UNWIND
78 jz return
79
80 /* Tell the kernel to invalidate the stack */
81 push STATUS_CALLBACK_POP_STACK
82 push 0
83 push 0
84 call _ZwCallbackReturn@12
85
86 return:
87 /* We'll continue */
88 mov eax, ExceptionContinueSearch
89 ret 16
90
91 .globl _KiUserCallbackDispatcher@12
92 _KiUserCallbackDispatcher@12:
93
94 /* Get the callback Index */
95 add esp, 4
96 pop edx
97
98 /* Get the callback table */
99 mov eax, [fs:TEB_PEB]
100 mov eax, [eax+PEB_KERNEL_CALLBACK_TABLE]
101
102 /* Call the routine */
103 call [eax+edx*4]
104
105 /* Return from callback */
106 push eax
107 push 0
108 push 0
109 call _ZwCallbackReturn@12
110
111 .globl _KiRaiseUserExceptionDispatcher@0
112 _KiRaiseUserExceptionDispatcher@0:
113
114 /* Setup stack for EXCEPTION_RECORD */
115 push ebp
116 mov ebp, esp
117 sub esp, SIZEOF_EXCEPTION_RECORD
118
119 /* Fill out the record */
120 mov eax, [fs:TEB_SELECTOR]
121 mov eax, [eax+TEB_EXCEPTION_CODE]
122 mov [esp+EXCEPTION_RECORD_EXCEPTION_CODE], eax
123 mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_FLAGS], 0
124 mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_RECORD], 0
125 mov dword ptr [esp+EXCEPTION_RECORD_NUMBER_PARAMETERS], 0
126
127 /* Raise the exception */
128 push esp
129 call _RtlRaiseException@4
130
131 /* Return exception code */
132 mov eax, [esp+EXCEPTION_RECORD_EXCEPTION_CODE]
133 mov esp, ebp
134 pop ebp
135 ret
136
137 .globl _KiUserExceptionDispatcher@8
138 _KiUserExceptionDispatcher@8:
139
140 /* Save the Context and Exception Records */
141 mov ecx, [esp+4]
142 mov ebx, [esp]
143
144 /* Dispatch the exception */
145 push ecx
146 push ebx
147 call _RtlDispatchException@8
148
149 /* Check for success */
150 or al, al
151 jz RaiseException
152
153 /* Pop off the records */
154 pop ebx
155 pop ecx
156
157 /* We're fine, continue execution */
158 push 0
159 push ecx
160 call _ZwContinue@8
161
162 /* Exit */
163 jmp Exit
164
165 RaiseException:
166 /* Pop off the records */
167 pop ebx
168 pop ecx
169
170 /* Raise the exception */
171 push 0
172 push ecx
173 push ebx
174 call _ZwRaiseException@12
175
176 Exit:
177 /* Allocate space for the nested exception record */
178 add esp, -SIZEOF_EXCEPTION_RECORD
179
180 /* Set it up */
181 mov [esp+EXCEPTION_RECORD_EXCEPTION_CODE], eax
182 mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_NONCONTINUABLE
183 mov [esp+EXCEPTION_RECORD_EXCEPTION_RECORD], ebx
184 mov dword ptr [esp+EXCEPTION_RECORD_NUMBER_PARAMETERS], 0
185
186 /* Raise the exception */
187 push esp
188 call _RtlRaiseException@4
189 ret 8
190
191 .globl _RtlpGetStackLimits@8
192 _RtlpGetStackLimits@8:
193
194 /* Get the stack limits */
195 mov eax, [fs:TEB_STACK_LIMIT]
196 mov ecx, [fs:TEB_STACK_BASE]
197
198 /* Return them */
199 mov edx, [esp+4]
200 mov [edx], eax
201 mov edx, [esp+8]
202 mov [edx], ecx
203
204 /* return */
205 ret 8
206