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

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

Fix calling _Pascal GCC functions from assembler.

In GCC, _Pascal is equvalent to _cdecl.

File size: 11.5 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
380
381; 281 static extern "C" DWORD EXC_CallHandler( WINEXCEPTION_RECORD *record, WINEXCEPTION_FRAME *frame,
382 EXTRN WriteLog:PROC
383 EXTRN _GetThreadTEB@0:PROC
384IFDEF DEBUG
385 EXTRN _DbgEnabledKERNEL32:DWORD
386ENDIF
387
388EXC_push_frame proc
389 push ebp
390 mov ebp,esp
391 sub esp,04h
392 mov [ebp+08h],eax; frame
393
394; 132 TEB *teb = GetThreadTEB();
395 call _GetThreadTEB@0
396 mov [ebp-04h],eax; teb
397
398; 133 frame->Prev = (PWINEXCEPTION_FRAME)teb->except;
399 mov ecx,[ebp-04h]; teb
400 mov ecx,[ecx]
401 mov eax,[ebp+08h]; frame
402 mov [eax],ecx
403
404; 134 teb->except = frame;
405 mov eax,[ebp-04h]; teb
406 mov ecx,[ebp+08h]; frame
407 mov [eax],ecx
408
409; 135 return frame->Prev;
410 mov eax,[ebp+08h]; frame
411 mov eax,[eax]
412 leave
413 ret
414EXC_push_frame endp
415
416; 138 static inline WINEXCEPTION_FRAME * EXC_pop_frame( WINEXCEPTION_FRAME *frame )
417 align 04h
418
419EXC_pop_frame proc
420 push ebp
421 mov ebp,esp
422 sub esp,04h
423 mov [ebp+08h],eax; frame
424
425; 141 TEB *teb = GetThreadTEB();
426 call _GetThreadTEB@0
427 mov [ebp-04h],eax; teb
428
429; 142 teb->except = frame->Prev;
430 mov ecx,[ebp+08h]; frame
431 mov ecx,[ecx]
432 mov eax,[ebp-04h]; teb
433 mov [eax],ecx
434
435; 143 return frame->Prev;
436 mov eax,[ebp+08h]; frame
437 mov eax,[eax]
438 leave
439 ret
440EXC_pop_frame endp
441
442 align 04h
443 PUBLIC _EXC_CallHandler
444
445_EXC_CallHandler proc
446 push ebp
447 mov ebp,esp
448 sub esp,010h
449 sub esp,04h
450 mov [ebp+08h],eax; record
451 mov [ebp+0ch],edx; frame
452 mov [ebp+010h],ecx; context
453
454; 296 newframe.frame.Handler = nested_handler;
455 mov eax,[ebp+01ch]; nested_handler
456 mov [ebp-08h],eax; newframe
457
458; 297 newframe.prevFrame = frame;
459 mov eax,[ebp+0ch]; frame
460 mov [ebp-04h],eax; newframe
461
462; 298 EXC_push_frame( &newframe.frame );
463 lea eax,[ebp-0ch]; newframe
464 call EXC_push_frame
465
466; 299 dprintf(("KERNEL32: Calling handler at %p code=%lx flags=%lx\n",
467IFDEF DEBUG
468 cmp word ptr _DbgEnabledKERNEL32+020h,01h
469 jne @BLBL20
470 mov eax,[ebp+08h]; record
471 push dword ptr [eax+04h]
472 mov eax,[ebp+08h]; record
473 push dword ptr [eax]
474 push dword ptr [ebp+018h]; handler
475 push offset FLAT:@CBE8
476 call WriteLog
477 add esp,010h
478ENDIF
479
480; 300 handler, record->ExceptionCode, record->ExceptionFlags));
481@BLBL20:
482
483; 301 ret = handler( record, frame, context, dispatcher );
484 push dword ptr [ebp+014h]; dispatcher
485 push dword ptr [ebp+010h]; context
486 push dword ptr [ebp+0ch]; frame
487 push dword ptr [ebp+08h]; record
488 call dword ptr [ebp+018h]; handler
489 mov [ebp-010h],eax; ret
490
491IFDEF DEBUG
492; 302 dprintf(("KERNEL32: Handler returned %lx\n", ret));
493 cmp word ptr _DbgEnabledKERNEL32+020h,01h
494 jne @BLBL21
495 push dword ptr [ebp-010h]; ret
496 push offset FLAT:@CBE9
497 call WriteLog
498 add esp,08h
499@BLBL21:
500ENDIF
501
502; 303 EXC_pop_frame( &newframe.frame );
503 lea eax,[ebp-0ch]; newframe
504 call EXC_pop_frame
505
506; 304 return ret;
507 mov eax,[ebp-010h]; ret
508 add esp,04h
509 leave
510 ret
511_EXC_CallHandler endp
512
513CODE32 ENDS
514
515 END
Note: See TracBrowser for help on using the repository browser.