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

Last change on this file since 22145 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
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
20CGROUP group CODE32
21
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
36CODE32 SEGMENT DWORD PUBLIC USE32 'CODE'
37
38
39 public _RaiseException@16
40 extrn _OS2RaiseException : near
41
42_RaiseException@16 proc near
43
44 ; _OS2RaiseException is _cdecl
45
46 push ebp
47 mov ebp, esp
48 push eax
49
50 mov eax, 0
51 mov eax, ss
52 push eax
53 mov eax, gs
54 push eax
55 mov eax, fs
56 push eax
57 mov eax, es
58 push eax
59 mov eax, ds
60 push eax
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)
74
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
87 ret 16 ;__stdcall
88
89_RaiseException@16 endp
90
91
92 public _RtlUnwind@16
93 extrn _OS2RtlUnwind : near
94
95_RtlUnwind@16 proc near
96
97 ; OS2RtlUnwind is _cdecl
98
99 push ebp
100 mov ebp, esp
101 push eax
102
103 mov eax, 0
104 mov eax, ss
105 push eax
106 mov eax, gs
107 push eax
108 mov eax, fs
109 push eax
110 mov eax, es
111 push eax
112 mov eax, ds
113 push eax
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)
127
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
140 ret 16 ;__stdcall
141
142_RtlUnwind@16 endp
143
144
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
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
171 PUBLIC _QueryExceptionChain
172
173_QueryExceptionChain proc near
174 mov eax, fs:[0]
175 ret
176_QueryExceptionChain endp
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
218;;ULONG CDECL AsmCallThreadHandler(BOOL fAlignStack, ULONG handler, LPVOID parameter);
219 PUBLIC _AsmCallThreadHandler
220_AsmCallThreadHandler proc near
221 push ebp
222 mov ebp, esp
223
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
229;We're asking for problems if our stack start near a 64kb boundary
230;Some OS/2 thunking procedures can choke if there's not enough stack left
231 mov eax, esp
232 and eax, 0FFFFh
233 cmp eax, 0E000h
234 jge @goodthreadstack
235
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
256 ;also touch this page
257 mov eax, dword ptr [esp]
258
259@goodthreadstack:
260
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
269 push dword ptr [ebp+16]
270 mov eax, dword ptr [ebp+12]
271 call eax
272
273 mov esp, ebp
274 pop ebp
275 ret
276_AsmCallThreadHandler endp
277
278 PUBLIC _CallEntryPoint
279_CallEntryPoint proc near
280 push ebp
281 mov ebp, esp
282
283;We're asking for problems if our stack start near a 64kb boundary
284;Some OS/2 thunking procedures can choke if there's not enough stack left
285 mov eax, esp
286 and eax, 0FFFFh
287 cmp eax, 0E000h
288 jge @goodmainstack
289
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
295
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
310 ;also touch this page
311 mov eax, dword ptr [esp]
312
313@goodmainstack:
314
315 mov eax, esp
316 sub eax, 16
317 and eax, 0FFFFFFF0h
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
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
332ifndef __EMX__
333
334 EXTRN WriteLog:PROC
335 EXTRN _GetThreadTEB@0:PROC
336IFDEF DEBUG
337 EXTRN _DbgEnabledKERNEL32:DWORD
338ENDIF
339
340; 129 static inline WINEXCEPTION_FRAME * EXC_push_frame( WINEXCEPTION_FRAME *frame )
341 align 04h
342
343EXC_push_frame proc
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
369EXC_push_frame endp
370
371; 138 static inline WINEXCEPTION_FRAME * EXC_pop_frame( WINEXCEPTION_FRAME *frame )
372 align 04h
373
374EXC_pop_frame proc
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
395EXC_pop_frame endp
396
397; 281 static extern "C" DWORD EXC_CallHandler( WINEXCEPTION_RECORD *record, WINEXCEPTION_FRAME *frame,
398 align 04h
399 PUBLIC _EXC_CallHandler
400
401_EXC_CallHandler proc
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
420 call EXC_push_frame
421
422; 299 dprintf(("KERNEL32: Calling handler at %p code=%lx flags=%lx\n",
423IFDEF DEBUG
424 cmp word ptr _DbgEnabledKERNEL32+020h,01h
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));
449 cmp word ptr _DbgEnabledKERNEL32+020h,01h
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
460 call EXC_pop_frame
461
462; 304 return ret;
463 mov eax,[ebp-010h]; ret
464 add esp,04h
465 leave
466 ret
467_EXC_CallHandler endp
468
469endif ; ifndef __EMX__
470
471CODE32 ENDS
472
473 END
Note: See TracBrowser for help on using the repository browser.