source: trunk/src/kernel32/exceptutil.asm@ 21388

Last change on this file since 21388 was 10409, checked in by sandervl, 22 years ago

Assembly wrapper for clearing the direction flag before calling our real

File size: 9.9 KB
Line 
1; $Id: exceptutil.asm,v 1.26 2004-01-20 13:41:11 sandervl Exp $
2
3;/*
4; * Project Odin Software License can be found in LICENSE.TXT
5; * Win32 Exception handling + misc functions for OS/2
6; *
7; * Copyright 1998 Sander van Leeuwen
8; *
9; */
10.386p
11 NAME except
12
13DATA32 segment dword use32 public 'DATA'
14DATA32 ends
15CONST32_RO segment dword use32 public 'CONST'
16CONST32_RO ends
17BSS32 segment dword use32 public 'BSS'
18BSS32 ends
19DGROUP group BSS32, DATA32
20 assume cs:FLAT, ds:FLAT, ss:FLAT, es:FLAT
21
22DATA32 segment dword use32 public 'DATA'
23
24CONST32_RO segment
25 align 04h
26@CBE8 db "KERNEL32: Calling handle"
27db "r at %p code=%lx flags=%"
28db "lx",0ah,0h
29@CBE9 db "KERNEL32: Handler return"
30db "ed %lx",0ah,0h
31CONST32_RO ends
32DATA32 ends
33
34CODE32 SEGMENT DWORD PUBLIC USE32 'CODE'
35 public _RaiseException@16
36 extrn OS2RAISEEXCEPTION : near
37
38_RaiseException@16 proc near
39 push dword ptr [esp+4] ;DWORD dwExceptionCode
40 push dword ptr [esp+12] ;DWORD dwExceptionFlags
41 push dword ptr [esp+20] ;DWORD cArguments
42 push dword ptr [esp+28] ;DWORD *lpArguments
43 push dword ptr [esp+16] ;return address
44 push esp
45 add dword ptr [esp], 20
46 push ebp
47 pushfd
48 push eax
49 push ebx
50 push ecx
51 push edx
52 push edi
53 push esi
54 xor eax, eax
55 mov eax, cs
56 push eax
57 mov eax, ds
58 push eax
59 mov eax, es
60 push eax
61 mov eax, fs
62 push eax
63 mov eax, gs
64 push eax
65 mov eax, ss
66 push eax
67 call OS2RAISEEXCEPTION
68
69 ret 16 ;__stdcall
70_RaiseException@16 endp
71
72 public _RtlUnwind@16
73 extrn OS2RTLUNWIND : near
74
75_RtlUnwind@16 proc near
76 push dword ptr [esp+4] ;PWINEXCEPTION_FRAME pEndFrame
77 push dword ptr [esp+12] ;LPVOID unusedEip
78 push dword ptr [esp+20] ;PWINEXCEPTION_RECORD pRecord
79 push dword ptr [esp+28] ;DWORD returnEax
80 push dword ptr [esp+16] ;return address
81 push esp
82 add dword ptr [esp], 20
83 push ebp
84 pushfd
85 push eax
86 push ebx
87 push ecx
88 push edx
89 push edi
90 push esi
91 xor eax, eax
92 mov eax, cs
93 push eax
94 mov eax, ds
95 push eax
96 mov eax, es
97 push eax
98 mov eax, fs
99 push eax
100 mov eax, gs
101 push eax
102 mov eax, ss
103 push eax
104 call OS2RTLUNWIND
105
106 ret 16 ;__stdcall
107_RtlUnwind@16 endp
108
109
110 PUBLIC OS2ExceptionHandler
111 EXTRN OS2ExceptionHandler2ndLevel:NEAR
112
113OS2ExceptionHandler proc near
114 ;Clear the direction flag (as specified by the _System calling convention)
115 ;(OS/2 doesn't bother checking before calling our exception handler)
116 cld
117 jmp OS2ExceptionHandler2ndLevel
118OS2ExceptionHandler endp
119
120 PUBLIC QueryExceptionChain
121
122QueryExceptionChain proc near
123 mov eax, fs:[0]
124 ret
125QueryExceptionChain endp
126
127 PUBLIC GetExceptionRecord
128GetExceptionRecord proc near
129 push ebp
130 mov ebp, esp
131 push fs
132 push ebx
133
134 mov eax, [ebp+8]
135 mov fs, eax
136 mov ebx, [ebp+12]
137 mov eax, fs:[ebx]
138
139 pop ebx
140 pop fs
141 pop ebp
142 ret
143GetExceptionRecord endp
144
145 PUBLIC ChangeTIBStack
146ChangeTIBStack proc near
147; xor eax, eax
148 push ebx
149 mov eax, fs:[4]
150 mov ebx, fs:[8]
151 add ebx, 8
152 mov fs:[4], ebx
153 mov fs:[8], eax
154 pop ebx
155 ret
156ChangeTIBStack endp
157
158 PUBLIC _SetExceptionChain
159
160_SetExceptionChain proc near
161 mov eax, dword ptr [esp+4]
162 mov fs:[0], eax
163 ret
164_SetExceptionChain endp
165
166
167;;ULONG CDECL AsmCallThreadHandler(BOOL fAlignStack, ULONG handler, LPVOID parameter);
168 PUBLIC _AsmCallThreadHandler
169_AsmCallThreadHandler proc near
170 push ebp
171 mov ebp, esp
172
173;first check if we have 128kb stack or more; if not, then skip the stack alignment code
174 mov eax, [ebp+8]
175 cmp eax, 0
176 je @goodthreadstack
177
178;We're asking for problems if our stack start near a 64kb boundary
179;Some OS/2 thunking procedures can choke if there's not enough stack left
180 mov eax, esp
181 and eax, 0FFFFh
182 cmp eax, 0E000h
183 jge @goodthreadstack
184
185 ;set ESP to the top of the next 64kb block and touch each
186 ;page to make sure the guard page exception handler commits
187 ;those pages
188 mov edx, esp
189 sub edx, eax
190
191 and esp, 0FFFFF000h
192 dec esp
193
194@touchthreadstackpages:
195 mov al, byte ptr [esp]
196
197 sub esp, 1000h
198
199 cmp esp, edx
200 jg @touchthreadstackpages
201
202 mov esp, edx
203 sub esp, 16
204
205 ;also touch this page
206 mov eax, dword ptr [esp]
207
208@goodthreadstack:
209
210 mov eax, esp
211 sub eax, 16
212 and eax, 0FFFFFFF0h
213;now we make sure the stack is aligned at 16 bytes when the entrypoint is called
214;(8+4+4(return address) = 16)
215 add eax, 8
216 mov esp, eax
217
218 push dword ptr [ebp+16]
219 mov eax, dword ptr [ebp+12]
220 call eax
221
222 mov esp, ebp
223 pop ebp
224 ret
225_AsmCallThreadHandler endp
226
227 PUBLIC _CallEntryPoint
228_CallEntryPoint proc near
229 push ebp
230 mov ebp, esp
231
232;We're asking for problems if our stack start near a 64kb boundary
233;Some OS/2 thunking procedures can choke if there's not enough stack left
234 mov eax, esp
235 and eax, 0FFFFh
236 cmp eax, 0E000h
237 jge @goodmainstack
238
239 ;set ESP to the top of the next 64kb block and touch each
240 ;page to make sure the guard page exception handler commits
241 ;those pages
242 mov edx, esp
243 sub edx, eax
244
245 and esp, 0FFFFF000h
246 dec esp
247
248@touchmainstackpages:
249 mov al, byte ptr [esp]
250
251 sub esp, 1000h
252
253 cmp esp, edx
254 jg @touchmainstackpages
255
256 mov esp, edx
257 sub esp, 16
258
259 ;also touch this page
260 mov eax, dword ptr [esp]
261
262@goodmainstack:
263
264 mov eax, esp
265 sub eax, 16
266 and eax, 0FFFFFFF0h
267;now we make sure the stack is aligned at 16 bytes when the entrypoint is called
268;(8+4+4(return address) = 16)
269 add eax, 8
270 mov esp, eax
271
272 push dword ptr [ebp+12]
273 mov eax, dword ptr [ebp+8]
274 call eax
275
276 mov esp, ebp
277 pop ebp
278 ret
279_CallEntryPoint endp
280
281
282; 281 static DWORD EXC_CallHandler( WINEXCEPTION_RECORD *record, WINEXCEPTION_FRAME *frame,
283 EXTRN WriteLog:PROC
284 EXTRN _GetThreadTEB@0:PROC
285IFDEF DEBUG
286 EXTRN DbgEnabledKERNEL32:DWORD
287ENDIF
288
289EXC_push_frame__FP19_WINEXCEPTION_FRAME proc
290 push ebp
291 mov ebp,esp
292 sub esp,04h
293 mov [ebp+08h],eax; frame
294
295; 132 TEB *teb = GetThreadTEB();
296 call _GetThreadTEB@0
297 mov [ebp-04h],eax; teb
298
299; 133 frame->Prev = (PWINEXCEPTION_FRAME)teb->except;
300 mov ecx,[ebp-04h]; teb
301 mov ecx,[ecx]
302 mov eax,[ebp+08h]; frame
303 mov [eax],ecx
304
305; 134 teb->except = frame;
306 mov eax,[ebp-04h]; teb
307 mov ecx,[ebp+08h]; frame
308 mov [eax],ecx
309
310; 135 return frame->Prev;
311 mov eax,[ebp+08h]; frame
312 mov eax,[eax]
313 leave
314 ret
315EXC_push_frame__FP19_WINEXCEPTION_FRAME endp
316
317; 138 static inline WINEXCEPTION_FRAME * EXC_pop_frame( WINEXCEPTION_FRAME *frame )
318 align 04h
319
320EXC_pop_frame__FP19_WINEXCEPTION_FRAME proc
321 push ebp
322 mov ebp,esp
323 sub esp,04h
324 mov [ebp+08h],eax; frame
325
326; 141 TEB *teb = GetThreadTEB();
327 call _GetThreadTEB@0
328 mov [ebp-04h],eax; teb
329
330; 142 teb->except = frame->Prev;
331 mov ecx,[ebp+08h]; frame
332 mov ecx,[ecx]
333 mov eax,[ebp-04h]; teb
334 mov [eax],ecx
335
336; 143 return frame->Prev;
337 mov eax,[ebp+08h]; frame
338 mov eax,[eax]
339 leave
340 ret
341EXC_pop_frame__FP19_WINEXCEPTION_FRAME endp
342
343 align 04h
344 PUBLIC EXC_CallHandler__FP20_WINEXCEPTION_RECORDP19_WINEXCEPTION_FRAMEP10WINCONTEXTPP19_WINEXCEPTION_FRAMEPFP20_WINEXCEPTION_RECORDP19_WINEXCEPTION_FRAMEP10WINCONTEXTPv_UlT5
345
346EXC_CallHandler__FP20_WINEXCEPTION_RECORDP19_WINEXCEPTION_FRAMEP10WINCONTEXTPP19_WINEXCEPTION_FRAMEPFP20_WINEXCEPTION_RECORDP19_WINEXCEPTION_FRAMEP10WINCONTEXTPv_UlT5 proc
347 push ebp
348 mov ebp,esp
349 sub esp,010h
350 sub esp,04h
351 mov [ebp+08h],eax; record
352 mov [ebp+0ch],edx; frame
353 mov [ebp+010h],ecx; context
354
355; 296 newframe.frame.Handler = nested_handler;
356 mov eax,[ebp+01ch]; nested_handler
357 mov [ebp-08h],eax; newframe
358
359; 297 newframe.prevFrame = frame;
360 mov eax,[ebp+0ch]; frame
361 mov [ebp-04h],eax; newframe
362
363; 298 EXC_push_frame( &newframe.frame );
364 lea eax,[ebp-0ch]; newframe
365 call EXC_push_frame__FP19_WINEXCEPTION_FRAME
366
367; 299 dprintf(("KERNEL32: Calling handler at %p code=%lx flags=%lx\n",
368IFDEF DEBUG
369 cmp word ptr DbgEnabledKERNEL32+020h,01h
370 jne @BLBL20
371 mov eax,[ebp+08h]; record
372 push dword ptr [eax+04h]
373 mov eax,[ebp+08h]; record
374 push dword ptr [eax]
375 push dword ptr [ebp+018h]; handler
376 push offset FLAT:@CBE8
377 call WriteLog
378 add esp,010h
379ENDIF
380
381; 300 handler, record->ExceptionCode, record->ExceptionFlags));
382@BLBL20:
383
384; 301 ret = handler( record, frame, context, dispatcher );
385 push dword ptr [ebp+014h]; dispatcher
386 push dword ptr [ebp+010h]; context
387 push dword ptr [ebp+0ch]; frame
388 push dword ptr [ebp+08h]; record
389 call dword ptr [ebp+018h]; handler
390 mov [ebp-010h],eax; ret
391
392IFDEF DEBUG
393; 302 dprintf(("KERNEL32: Handler returned %lx\n", ret));
394 cmp word ptr DbgEnabledKERNEL32+020h,01h
395 jne @BLBL21
396 push dword ptr [ebp-010h]; ret
397 push offset FLAT:@CBE9
398 call WriteLog
399 add esp,08h
400@BLBL21:
401ENDIF
402
403; 303 EXC_pop_frame( &newframe.frame );
404 lea eax,[ebp-0ch]; newframe
405 call EXC_pop_frame__FP19_WINEXCEPTION_FRAME
406
407; 304 return ret;
408 mov eax,[ebp-010h]; ret
409 add esp,04h
410 leave
411 ret
412EXC_CallHandler__FP20_WINEXCEPTION_RECORDP19_WINEXCEPTION_FRAMEP10WINCONTEXTPP19_WINEXCEPTION_FRAMEPFP20_WINEXCEPTION_RECORDP19_WINEXCEPTION_FRAMEP10WINCONTEXTPv_UlT5 endp
413
414CODE32 ENDS
415
416 END
Note: See TracBrowser for help on using the repository browser.