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

Last change on this file since 21916 was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

File size: 10.1 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 PUBLIC _QueryExceptionChain
154
155_QueryExceptionChain proc near
156 mov eax, fs:[0]
157 ret
158_QueryExceptionChain endp
159
160 PUBLIC GetExceptionRecord
161GetExceptionRecord proc near
162 push ebp
163 mov ebp, esp
164 push fs
165 push ebx
166
167 mov eax, [ebp+8]
168 mov fs, eax
169 mov ebx, [ebp+12]
170 mov eax, fs:[ebx]
171
172 pop ebx
173 pop fs
174 pop ebp
175 ret
176GetExceptionRecord endp
177
178 PUBLIC ChangeTIBStack
179ChangeTIBStack proc near
180; xor eax, eax
181 push ebx
182 mov eax, fs:[4]
183 mov ebx, fs:[8]
184 add ebx, 8
185 mov fs:[4], ebx
186 mov fs:[8], eax
187 pop ebx
188 ret
189ChangeTIBStack endp
190
191 PUBLIC _SetExceptionChain
192
193_SetExceptionChain proc near
194 mov eax, dword ptr [esp+4]
195 mov fs:[0], eax
196 ret
197_SetExceptionChain endp
198
199
200;;ULONG CDECL AsmCallThreadHandler(BOOL fAlignStack, ULONG handler, LPVOID parameter);
201 PUBLIC _AsmCallThreadHandler
202_AsmCallThreadHandler proc near
203 push ebp
204 mov ebp, esp
205
206;first check if we have 128kb stack or more; if not, then skip the stack alignment code
207 mov eax, [ebp+8]
208 cmp eax, 0
209 je @goodthreadstack
210
211;We're asking for problems if our stack start near a 64kb boundary
212;Some OS/2 thunking procedures can choke if there's not enough stack left
213 mov eax, esp
214 and eax, 0FFFFh
215 cmp eax, 0E000h
216 jge @goodthreadstack
217
218 ;set ESP to the top of the next 64kb block and touch each
219 ;page to make sure the guard page exception handler commits
220 ;those pages
221 mov edx, esp
222 sub edx, eax
223
224 and esp, 0FFFFF000h
225 dec esp
226
227@touchthreadstackpages:
228 mov al, byte ptr [esp]
229
230 sub esp, 1000h
231
232 cmp esp, edx
233 jg @touchthreadstackpages
234
235 mov esp, edx
236 sub esp, 16
237
238 ;also touch this page
239 mov eax, dword ptr [esp]
240
241@goodthreadstack:
242
243 mov eax, esp
244 sub eax, 16
245 and eax, 0FFFFFFF0h
246;now we make sure the stack is aligned at 16 bytes when the entrypoint is called
247;(8+4+4(return address) = 16)
248 add eax, 8
249 mov esp, eax
250
251 push dword ptr [ebp+16]
252 mov eax, dword ptr [ebp+12]
253 call eax
254
255 mov esp, ebp
256 pop ebp
257 ret
258_AsmCallThreadHandler endp
259
260 PUBLIC _CallEntryPoint
261_CallEntryPoint proc near
262 push ebp
263 mov ebp, esp
264
265;We're asking for problems if our stack start near a 64kb boundary
266;Some OS/2 thunking procedures can choke if there's not enough stack left
267 mov eax, esp
268 and eax, 0FFFFh
269 cmp eax, 0E000h
270 jge @goodmainstack
271
272 ;set ESP to the top of the next 64kb block and touch each
273 ;page to make sure the guard page exception handler commits
274 ;those pages
275 mov edx, esp
276 sub edx, eax
277
278 and esp, 0FFFFF000h
279 dec esp
280
281@touchmainstackpages:
282 mov al, byte ptr [esp]
283
284 sub esp, 1000h
285
286 cmp esp, edx
287 jg @touchmainstackpages
288
289 mov esp, edx
290 sub esp, 16
291
292 ;also touch this page
293 mov eax, dword ptr [esp]
294
295@goodmainstack:
296
297 mov eax, esp
298 sub eax, 16
299 and eax, 0FFFFFFF0h
300;now we make sure the stack is aligned at 16 bytes when the entrypoint is called
301;(8+4+4(return address) = 16)
302 add eax, 8
303 mov esp, eax
304
305 push dword ptr [ebp+12]
306 mov eax, dword ptr [ebp+8]
307 call eax
308
309 mov esp, ebp
310 pop ebp
311 ret
312_CallEntryPoint endp
313
314ifndef __EMX__
315
316 EXTRN WriteLog:PROC
317 EXTRN _GetThreadTEB@0:PROC
318IFDEF DEBUG
319 EXTRN _DbgEnabledKERNEL32:DWORD
320ENDIF
321
322; 129 static inline WINEXCEPTION_FRAME * EXC_push_frame( WINEXCEPTION_FRAME *frame )
323 align 04h
324
325EXC_push_frame proc
326 push ebp
327 mov ebp,esp
328 sub esp,04h
329 mov [ebp+08h],eax; frame
330
331; 132 TEB *teb = GetThreadTEB();
332 call _GetThreadTEB@0
333 mov [ebp-04h],eax; teb
334
335; 133 frame->Prev = (PWINEXCEPTION_FRAME)teb->except;
336 mov ecx,[ebp-04h]; teb
337 mov ecx,[ecx]
338 mov eax,[ebp+08h]; frame
339 mov [eax],ecx
340
341; 134 teb->except = frame;
342 mov eax,[ebp-04h]; teb
343 mov ecx,[ebp+08h]; frame
344 mov [eax],ecx
345
346; 135 return frame->Prev;
347 mov eax,[ebp+08h]; frame
348 mov eax,[eax]
349 leave
350 ret
351EXC_push_frame endp
352
353; 138 static inline WINEXCEPTION_FRAME * EXC_pop_frame( WINEXCEPTION_FRAME *frame )
354 align 04h
355
356EXC_pop_frame proc
357 push ebp
358 mov ebp,esp
359 sub esp,04h
360 mov [ebp+08h],eax; frame
361
362; 141 TEB *teb = GetThreadTEB();
363 call _GetThreadTEB@0
364 mov [ebp-04h],eax; teb
365
366; 142 teb->except = frame->Prev;
367 mov ecx,[ebp+08h]; frame
368 mov ecx,[ecx]
369 mov eax,[ebp-04h]; teb
370 mov [eax],ecx
371
372; 143 return frame->Prev;
373 mov eax,[ebp+08h]; frame
374 mov eax,[eax]
375 leave
376 ret
377EXC_pop_frame endp
378
379; 281 static extern "C" DWORD EXC_CallHandler( WINEXCEPTION_RECORD *record, WINEXCEPTION_FRAME *frame,
380 align 04h
381 PUBLIC _EXC_CallHandler
382
383_EXC_CallHandler proc
384 push ebp
385 mov ebp,esp
386 sub esp,010h
387 sub esp,04h
388 mov [ebp+08h],eax; record
389 mov [ebp+0ch],edx; frame
390 mov [ebp+010h],ecx; context
391
392; 296 newframe.frame.Handler = nested_handler;
393 mov eax,[ebp+01ch]; nested_handler
394 mov [ebp-08h],eax; newframe
395
396; 297 newframe.prevFrame = frame;
397 mov eax,[ebp+0ch]; frame
398 mov [ebp-04h],eax; newframe
399
400; 298 EXC_push_frame( &newframe.frame );
401 lea eax,[ebp-0ch]; newframe
402 call EXC_push_frame
403
404; 299 dprintf(("KERNEL32: Calling handler at %p code=%lx flags=%lx\n",
405IFDEF DEBUG
406 cmp word ptr _DbgEnabledKERNEL32+020h,01h
407 jne @BLBL20
408 mov eax,[ebp+08h]; record
409 push dword ptr [eax+04h]
410 mov eax,[ebp+08h]; record
411 push dword ptr [eax]
412 push dword ptr [ebp+018h]; handler
413 push offset FLAT:@CBE8
414 call WriteLog
415 add esp,010h
416ENDIF
417
418; 300 handler, record->ExceptionCode, record->ExceptionFlags));
419@BLBL20:
420
421; 301 ret = handler( record, frame, context, dispatcher );
422 push dword ptr [ebp+014h]; dispatcher
423 push dword ptr [ebp+010h]; context
424 push dword ptr [ebp+0ch]; frame
425 push dword ptr [ebp+08h]; record
426 call dword ptr [ebp+018h]; handler
427 mov [ebp-010h],eax; ret
428
429IFDEF DEBUG
430; 302 dprintf(("KERNEL32: Handler returned %lx\n", ret));
431 cmp word ptr _DbgEnabledKERNEL32+020h,01h
432 jne @BLBL21
433 push dword ptr [ebp-010h]; ret
434 push offset FLAT:@CBE9
435 call WriteLog
436 add esp,08h
437@BLBL21:
438ENDIF
439
440; 303 EXC_pop_frame( &newframe.frame );
441 lea eax,[ebp-0ch]; newframe
442 call EXC_pop_frame
443
444; 304 return ret;
445 mov eax,[ebp-010h]; ret
446 add esp,04h
447 leave
448 ret
449_EXC_CallHandler endp
450
451endif ; ifndef __EMX__
452
453CODE32 ENDS
454
455 END
Note: See TracBrowser for help on using the repository browser.