source: branches/gcc-kmk/src/kernel32/exceptutil.asm@ 21838

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