source: branches/swt/src/kernel32/exceptutil.asm

Last change on this file was 22087, checked in by rousseau, 11 years ago

Fix crash in exception handling when using JWasm

When externs are declared in the code-segment, JWasm generates
fixups relative to that segment. Because CODE32 is not part of CGROUP,
and JWasm does not treat FLAT as special, these fixups are incorrect.

One way would be to move the extern declarations outside of the
code-segment, but then the symantic difference between JWasm and Alp
would remain.

A better solution is to make CODE32 part of CGROUP, which causes JWasm
to generate the correct GROUP relative fixups.

This issue applies to linking object modules generated with GCC and
regular PC tools, which introduce TEXT32 and CODE32 segments. Grouping
them ensures group relative fixups are calculated.

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