source: trunk/src/kernel32/exceptutil.asm

Last change on this file was 21999, checked in by dmik, 13 years ago

kernel32: Make SEH work in OS/2 context.

See #82 for details.

File size: 10.7 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
36
37 public _RaiseException@16
38 extrn _OS2RaiseException : near
39
40_RaiseException@16 proc near
41
42 ; _OS2RaiseException is _cdecl
43
44 push ebp
45 mov ebp, esp
46 push eax
47
48 mov eax, 0
49 mov eax, ss
50 push eax
51 mov eax, gs
52 push eax
53 mov eax, fs
54 push eax
55 mov eax, es
56 push eax
57 mov eax, ds
58 push eax
59 mov eax, cs
60 push cs
61 push esi
62 push edi
63 push edx
64 push ecx
65 push ebx
66 push dword ptr [ebp-4] ; original eax
67 pushfd
68 push dword ptr [ebp] ; original ebp
69 push ebp
70 add dword ptr [esp], 4 ; original esp
71 push dword ptr [ebp + 4] ; original eip (return address)
72
73 push dword ptr [ebp + 20] ; arg 4 (DWORD *lpArguments)
74 push dword ptr [ebp + 16] ; arg 3 (DWORD cArguments)
75 push dword ptr [ebp + 12] ; arg 2 (DWORD dwExceptionFlags)
76 push dword ptr [ebp + 8] ; arg 1 (DWORD dwExceptionCode)
77
78 call _OS2RaiseException
79
80 add esp, 20 * 4
81
82 pop eax
83 pop ebp
84
85 ret 16 ;__stdcall
86
87_RaiseException@16 endp
88
89
90 public _RtlUnwind@16
91 extrn _OS2RtlUnwind : near
92
93_RtlUnwind@16 proc near
94
95 ; OS2RtlUnwind is _cdecl
96
97 push ebp
98 mov ebp, esp
99 push eax
100
101 mov eax, 0
102 mov eax, ss
103 push eax
104 mov eax, gs
105 push eax
106 mov eax, fs
107 push eax
108 mov eax, es
109 push eax
110 mov eax, ds
111 push eax
112 mov eax, cs
113 push cs
114 push esi
115 push edi
116 push edx
117 push ecx
118 push ebx
119 push dword ptr [ebp-4] ; original eax
120 pushfd
121 push dword ptr [ebp] ; original ebp
122 push ebp
123 add dword ptr [esp], 4 ; original esp
124 push dword ptr [ebp + 4] ; original eip (return address)
125
126 push dword ptr [ebp + 20] ; arg 4 (DWORD returnEax)
127 push dword ptr [ebp + 16] ; arg 3 (PWINEXCEPTION_RECORD pRecord)
128 push dword ptr [ebp + 12] ; arg 2 (LPVOID unusedEip)
129 push dword ptr [ebp + 8] ; arg 1 (PWINEXCEPTION_FRAME pEndFrame)
130
131 call _OS2RtlUnwind
132
133 add esp, 20 * 4
134
135 pop eax
136 pop ebp
137
138 ret 16 ;__stdcall
139
140_RtlUnwind@16 endp
141
142
143 PUBLIC OS2ExceptionHandler
144 EXTRN OS2ExceptionHandler2ndLevel:NEAR
145
146OS2ExceptionHandler proc near
147 ;Clear the direction flag (as specified by the _System calling convention)
148 ;(OS/2 doesn't bother checking before calling our exception handler)
149 cld
150 jmp OS2ExceptionHandler2ndLevel
151OS2ExceptionHandler endp
152
153
154 PUBLIC OSLibDispatchException
155 EXTRN OSLibDispatchExceptionWin32:NEAR
156 EXTRN ___seh_handler_filter:NEAR
157
158; BOOL APIENTRY OSLibDispatchException(PEXCEPTIONREPORTRECORD pReportRec,
159; PEXCEPTIONREGISTRATIONRECORD pRegistrationRec,
160; PCONTEXTRECORD pContextRec, PVOID p,
161; BOOL fSEH);
162OSLibDispatchException proc near
163 cmp dword ptr [esp + 20], 0 ; fSEH == FALSE?
164 jz OSLibDispatchExceptionWin32
165 jmp ___seh_handler_filter
166OSLibDispatchException endp
167
168
169 PUBLIC _QueryExceptionChain
170
171_QueryExceptionChain proc near
172 mov eax, fs:[0]
173 ret
174_QueryExceptionChain endp
175
176 PUBLIC GetExceptionRecord
177GetExceptionRecord proc near
178 push ebp
179 mov ebp, esp
180 push fs
181 push ebx
182
183 mov eax, [ebp+8]
184 mov fs, eax
185 mov ebx, [ebp+12]
186 mov eax, fs:[ebx]
187
188 pop ebx
189 pop fs
190 pop ebp
191 ret
192GetExceptionRecord endp
193
194 PUBLIC ChangeTIBStack
195ChangeTIBStack proc near
196; xor eax, eax
197 push ebx
198 mov eax, fs:[4]
199 mov ebx, fs:[8]
200 add ebx, 8
201 mov fs:[4], ebx
202 mov fs:[8], eax
203 pop ebx
204 ret
205ChangeTIBStack endp
206
207 PUBLIC _SetExceptionChain
208
209_SetExceptionChain proc near
210 mov eax, dword ptr [esp+4]
211 mov fs:[0], eax
212 ret
213_SetExceptionChain endp
214
215
216;;ULONG CDECL AsmCallThreadHandler(BOOL fAlignStack, ULONG handler, LPVOID parameter);
217 PUBLIC _AsmCallThreadHandler
218_AsmCallThreadHandler proc near
219 push ebp
220 mov ebp, esp
221
222;first check if we have 128kb stack or more; if not, then skip the stack alignment code
223 mov eax, [ebp+8]
224 cmp eax, 0
225 je @goodthreadstack
226
227;We're asking for problems if our stack start near a 64kb boundary
228;Some OS/2 thunking procedures can choke if there's not enough stack left
229 mov eax, esp
230 and eax, 0FFFFh
231 cmp eax, 0E000h
232 jge @goodthreadstack
233
234 ;set ESP to the top of the next 64kb block and touch each
235 ;page to make sure the guard page exception handler commits
236 ;those pages
237 mov edx, esp
238 sub edx, eax
239
240 and esp, 0FFFFF000h
241 dec esp
242
243@touchthreadstackpages:
244 mov al, byte ptr [esp]
245
246 sub esp, 1000h
247
248 cmp esp, edx
249 jg @touchthreadstackpages
250
251 mov esp, edx
252 sub esp, 16
253
254 ;also touch this page
255 mov eax, dword ptr [esp]
256
257@goodthreadstack:
258
259 mov eax, esp
260 sub eax, 16
261 and eax, 0FFFFFFF0h
262;now we make sure the stack is aligned at 16 bytes when the entrypoint is called
263;(8+4+4(return address) = 16)
264 add eax, 8
265 mov esp, eax
266
267 push dword ptr [ebp+16]
268 mov eax, dword ptr [ebp+12]
269 call eax
270
271 mov esp, ebp
272 pop ebp
273 ret
274_AsmCallThreadHandler endp
275
276 PUBLIC _CallEntryPoint
277_CallEntryPoint proc near
278 push ebp
279 mov ebp, esp
280
281;We're asking for problems if our stack start near a 64kb boundary
282;Some OS/2 thunking procedures can choke if there's not enough stack left
283 mov eax, esp
284 and eax, 0FFFFh
285 cmp eax, 0E000h
286 jge @goodmainstack
287
288 ;set ESP to the top of the next 64kb block and touch each
289 ;page to make sure the guard page exception handler commits
290 ;those pages
291 mov edx, esp
292 sub edx, eax
293
294 and esp, 0FFFFF000h
295 dec esp
296
297@touchmainstackpages:
298 mov al, byte ptr [esp]
299
300 sub esp, 1000h
301
302 cmp esp, edx
303 jg @touchmainstackpages
304
305 mov esp, edx
306 sub esp, 16
307
308 ;also touch this page
309 mov eax, dword ptr [esp]
310
311@goodmainstack:
312
313 mov eax, esp
314 sub eax, 16
315 and eax, 0FFFFFFF0h
316;now we make sure the stack is aligned at 16 bytes when the entrypoint is called
317;(8+4+4(return address) = 16)
318 add eax, 8
319 mov esp, eax
320
321 push dword ptr [ebp+12]
322 mov eax, dword ptr [ebp+8]
323 call eax
324
325 mov esp, ebp
326 pop ebp
327 ret
328_CallEntryPoint endp
329
330ifndef __EMX__
331
332 EXTRN WriteLog:PROC
333 EXTRN _GetThreadTEB@0:PROC
334IFDEF DEBUG
335 EXTRN _DbgEnabledKERNEL32:DWORD
336ENDIF
337
338; 129 static inline WINEXCEPTION_FRAME * EXC_push_frame( WINEXCEPTION_FRAME *frame )
339 align 04h
340
341EXC_push_frame proc
342 push ebp
343 mov ebp,esp
344 sub esp,04h
345 mov [ebp+08h],eax; frame
346
347; 132 TEB *teb = GetThreadTEB();
348 call _GetThreadTEB@0
349 mov [ebp-04h],eax; teb
350
351; 133 frame->Prev = (PWINEXCEPTION_FRAME)teb->except;
352 mov ecx,[ebp-04h]; teb
353 mov ecx,[ecx]
354 mov eax,[ebp+08h]; frame
355 mov [eax],ecx
356
357; 134 teb->except = frame;
358 mov eax,[ebp-04h]; teb
359 mov ecx,[ebp+08h]; frame
360 mov [eax],ecx
361
362; 135 return frame->Prev;
363 mov eax,[ebp+08h]; frame
364 mov eax,[eax]
365 leave
366 ret
367EXC_push_frame endp
368
369; 138 static inline WINEXCEPTION_FRAME * EXC_pop_frame( WINEXCEPTION_FRAME *frame )
370 align 04h
371
372EXC_pop_frame proc
373 push ebp
374 mov ebp,esp
375 sub esp,04h
376 mov [ebp+08h],eax; frame
377
378; 141 TEB *teb = GetThreadTEB();
379 call _GetThreadTEB@0
380 mov [ebp-04h],eax; teb
381
382; 142 teb->except = frame->Prev;
383 mov ecx,[ebp+08h]; frame
384 mov ecx,[ecx]
385 mov eax,[ebp-04h]; teb
386 mov [eax],ecx
387
388; 143 return frame->Prev;
389 mov eax,[ebp+08h]; frame
390 mov eax,[eax]
391 leave
392 ret
393EXC_pop_frame endp
394
395; 281 static extern "C" DWORD EXC_CallHandler( WINEXCEPTION_RECORD *record, WINEXCEPTION_FRAME *frame,
396 align 04h
397 PUBLIC _EXC_CallHandler
398
399_EXC_CallHandler proc
400 push ebp
401 mov ebp,esp
402 sub esp,010h
403 sub esp,04h
404 mov [ebp+08h],eax; record
405 mov [ebp+0ch],edx; frame
406 mov [ebp+010h],ecx; context
407
408; 296 newframe.frame.Handler = nested_handler;
409 mov eax,[ebp+01ch]; nested_handler
410 mov [ebp-08h],eax; newframe
411
412; 297 newframe.prevFrame = frame;
413 mov eax,[ebp+0ch]; frame
414 mov [ebp-04h],eax; newframe
415
416; 298 EXC_push_frame( &newframe.frame );
417 lea eax,[ebp-0ch]; newframe
418 call EXC_push_frame
419
420; 299 dprintf(("KERNEL32: Calling handler at %p code=%lx flags=%lx\n",
421IFDEF DEBUG
422 cmp word ptr _DbgEnabledKERNEL32+020h,01h
423 jne @BLBL20
424 mov eax,[ebp+08h]; record
425 push dword ptr [eax+04h]
426 mov eax,[ebp+08h]; record
427 push dword ptr [eax]
428 push dword ptr [ebp+018h]; handler
429 push offset FLAT:@CBE8
430 call WriteLog
431 add esp,010h
432ENDIF
433
434; 300 handler, record->ExceptionCode, record->ExceptionFlags));
435@BLBL20:
436
437; 301 ret = handler( record, frame, context, dispatcher );
438 push dword ptr [ebp+014h]; dispatcher
439 push dword ptr [ebp+010h]; context
440 push dword ptr [ebp+0ch]; frame
441 push dword ptr [ebp+08h]; record
442 call dword ptr [ebp+018h]; handler
443 mov [ebp-010h],eax; ret
444
445IFDEF DEBUG
446; 302 dprintf(("KERNEL32: Handler returned %lx\n", ret));
447 cmp word ptr _DbgEnabledKERNEL32+020h,01h
448 jne @BLBL21
449 push dword ptr [ebp-010h]; ret
450 push offset FLAT:@CBE9
451 call WriteLog
452 add esp,08h
453@BLBL21:
454ENDIF
455
456; 303 EXC_pop_frame( &newframe.frame );
457 lea eax,[ebp-0ch]; newframe
458 call EXC_pop_frame
459
460; 304 return ret;
461 mov eax,[ebp-010h]; ret
462 add esp,04h
463 leave
464 ret
465_EXC_CallHandler endp
466
467endif ; ifndef __EMX__
468
469CODE32 ENDS
470
471 END
Note: See TracBrowser for help on using the repository browser.