ReactOS 0.4.15-dev-7953-g1f49173
except_i386.c
Go to the documentation of this file.
1/*
2 * msvcrt C++ exception handling
3 *
4 * Copyright 2000 Jon Griffiths
5 * Copyright 2002 Alexandre Julliard
6 * Copyright 2005 Juan Lang
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 *
22 * NOTES
23 * A good reference is the article "How a C++ compiler implements
24 * exception handling" by Vishal Kochhar, available on
25 * www.thecodeproject.com.
26 */
27
28#include "config.h"
29#include "wine/port.h"
30
31#ifdef __i386__
32
33#include <stdarg.h>
34
35#include "windef.h"
36#include "winbase.h"
37#include "winternl.h"
38#include "msvcrt.h"
39#include "wine/exception.h"
40#include "excpt.h"
41#include "wine/debug.h"
42
43#include "cppexcept.h"
44
46
47
48/* the exception frame used by CxxFrameHandler */
49typedef struct __cxx_exception_frame
50{
51 EXCEPTION_REGISTRATION_RECORD frame; /* the standard exception frame */
52 int trylevel;
53 DWORD ebp;
55
56/* info about a single catch {} block */
57typedef struct __catchblock_info
58{
59 UINT flags; /* flags (see below) */
60 const type_info *type_info; /* C++ type caught by this block */
61 int offset; /* stack offset to copy exception object to */
62 void * (*handler)(void);/* catch block handler code */
64#define TYPE_FLAG_CONST 1
65#define TYPE_FLAG_VOLATILE 2
66#define TYPE_FLAG_REFERENCE 8
67
68/* info about a single try {} block */
69typedef struct __tryblock_info
70{
71 int start_level; /* start trylevel of that block */
72 int end_level; /* end trylevel of that block */
73 int catch_level; /* initial trylevel of the catch block */
74 int catchblock_count; /* count of catch blocks in array */
75 const catchblock_info *catchblock; /* array of catch blocks */
77
78/* info about the unwind handler for a given trylevel */
79typedef struct __unwind_info
80{
81 int prev; /* prev trylevel unwind handler, to run after this one */
82 void * (*handler)(void);/* unwind handler */
84
85/* descriptor of all try blocks of a given function */
86typedef struct __cxx_function_descr
87{
88 UINT magic; /* must be CXX_FRAME_MAGIC */
89 UINT unwind_count; /* number of unwind handlers */
90 const unwind_info *unwind_table; /* array of unwind handlers */
91 UINT tryblock_count; /* number of try blocks */
92 const tryblock_info *tryblock; /* array of try blocks */
94 const void *ipmap;
95 const void *expect_list; /* expected exceptions list when magic >= VC7 */
96 UINT flags; /* flags when magic >= VC8 */
98
99/* exception frame for nested exceptions in catch block */
100typedef struct
101{
102 EXCEPTION_REGISTRATION_RECORD frame; /* standard exception frame */
103 cxx_exception_frame *cxx_frame; /* frame of parent exception */
104 const cxx_function_descr *descr; /* descriptor of parent exception */
105 int trylevel; /* current try level */
107} catch_func_nested_frame;
108
109typedef struct
110{
111 cxx_exception_frame *frame;
113 catch_func_nested_frame *nested_frame;
114} se_translator_ctx;
115
116typedef struct _SCOPETABLE
117{
118 int previousTryLevel;
119 int (*lpfnFilter)(PEXCEPTION_POINTERS);
120 void * (*lpfnHandler)(void);
121} SCOPETABLE, *PSCOPETABLE;
122
123typedef struct _MSVCRT_EXCEPTION_FRAME
124{
128 PSCOPETABLE scopetable;
129 int trylevel;
130 int _ebp;
131 PEXCEPTION_POINTERS xpointers;
132} MSVCRT_EXCEPTION_FRAME;
133
134typedef struct
135{
136 int gs_cookie_offset;
137 ULONG gs_cookie_xor;
138 int eh_cookie_offset;
139 ULONG eh_cookie_xor;
140 SCOPETABLE entries[1];
141} SCOPETABLE_V4;
142
143#define TRYLEVEL_END (-1) /* End of trylevel list */
144
145DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame,
148 catch_func_nested_frame* nested_frame ) DECLSPEC_HIDDEN;
149
150/* call a copy constructor */
151extern void call_copy_ctor( void *func, void *this, void *src, int has_vbase );
152
153__ASM_GLOBAL_FUNC( call_copy_ctor,
154 "pushl %ebp\n\t"
155 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
156 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
157 "movl %esp, %ebp\n\t"
158 __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
159 "pushl $1\n\t"
160 "movl 12(%ebp), %ecx\n\t"
161 "pushl 16(%ebp)\n\t"
162 "call *8(%ebp)\n\t"
163 "leave\n"
164 __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
165 __ASM_CFI(".cfi_same_value %ebp\n\t")
166 "ret" );
167
168/* continue execution to the specified address after exception is caught */
169extern void DECLSPEC_NORETURN continue_after_catch( cxx_exception_frame* frame, void *addr );
170
171__ASM_GLOBAL_FUNC( continue_after_catch,
172 "movl 4(%esp), %edx\n\t"
173 "movl 8(%esp), %eax\n\t"
174 "movl -4(%edx), %esp\n\t"
175 "leal 12(%edx), %ebp\n\t"
176 "jmp *%eax" );
177
178extern void DECLSPEC_NORETURN call_finally_block( void *code_block, void *base_ptr );
179
180__ASM_GLOBAL_FUNC( call_finally_block,
181 "movl 8(%esp), %ebp\n\t"
182 "jmp *4(%esp)" );
183
184extern int call_filter( int (*func)(PEXCEPTION_POINTERS), void *arg, void *ebp );
185
186__ASM_GLOBAL_FUNC( call_filter,
187 "pushl %ebp\n\t"
188 "pushl 12(%esp)\n\t"
189 "movl 20(%esp), %ebp\n\t"
190 "call *12(%esp)\n\t"
191 "popl %ebp\n\t"
192 "popl %ebp\n\t"
193 "ret" );
194
195extern void *call_handler( void * (*func)(void), void *ebp );
196
197__ASM_GLOBAL_FUNC( call_handler,
198 "pushl %ebp\n\t"
199 "pushl %ebx\n\t"
200 "pushl %esi\n\t"
201 "pushl %edi\n\t"
202 "movl 24(%esp), %ebp\n\t"
203 "call *20(%esp)\n\t"
204 "popl %edi\n\t"
205 "popl %esi\n\t"
206 "popl %ebx\n\t"
207 "popl %ebp\n\t"
208 "ret" );
209
210static inline void dump_type( const cxx_type_info *type )
211{
212 TRACE( "flags %x type %p %s offsets %d,%d,%d size %d copy ctor %p\n",
213 type->flags, type->type_info, dbgstr_type_info(type->type_info),
214 type->offsets.this_offset, type->offsets.vbase_descr, type->offsets.vbase_offset,
215 type->size, type->copy_ctor );
216}
217
218static void dump_exception_type( const cxx_exception_type *type )
219{
220 UINT i;
221
222 TRACE( "flags %x destr %p handler %p type info %p\n",
223 type->flags, type->destructor, type->custom_handler, type->type_info_table );
224 for (i = 0; i < type->type_info_table->count; i++)
225 {
226 TRACE( " %d: ", i );
227 dump_type( type->type_info_table->info[i] );
228 }
229}
230
231static void dump_function_descr( const cxx_function_descr *descr )
232{
233 UINT i;
234 int j;
235
236 TRACE( "magic %x\n", descr->magic );
237 TRACE( "unwind table: %p %d\n", descr->unwind_table, descr->unwind_count );
238 for (i = 0; i < descr->unwind_count; i++)
239 {
240 TRACE( " %d: prev %d func %p\n", i,
241 descr->unwind_table[i].prev, descr->unwind_table[i].handler );
242 }
243 TRACE( "try table: %p %d\n", descr->tryblock, descr->tryblock_count );
244 for (i = 0; i < descr->tryblock_count; i++)
245 {
246 TRACE( " %d: start %d end %d catchlevel %d catch %p %d\n", i,
247 descr->tryblock[i].start_level, descr->tryblock[i].end_level,
248 descr->tryblock[i].catch_level, descr->tryblock[i].catchblock,
249 descr->tryblock[i].catchblock_count );
250 for (j = 0; j < descr->tryblock[i].catchblock_count; j++)
251 {
252 const catchblock_info *ptr = &descr->tryblock[i].catchblock[j];
253 TRACE( " %d: flags %x offset %d handler %p type %p %s\n",
254 j, ptr->flags, ptr->offset, ptr->handler,
255 ptr->type_info, dbgstr_type_info( ptr->type_info ) );
256 }
257 }
258 if (descr->magic <= CXX_FRAME_MAGIC_VC6) return;
259 TRACE( "expect list: %p\n", descr->expect_list );
260 if (descr->magic <= CXX_FRAME_MAGIC_VC7) return;
261 TRACE( "flags: %08x\n", descr->flags );
262}
263
264/* check if the exception type is caught by a given catch block, and return the type that matched */
265static const cxx_type_info *find_caught_type( cxx_exception_type *exc_type,
266 const type_info *catch_ti, UINT catch_flags )
267{
268 UINT i;
269
270 for (i = 0; i < exc_type->type_info_table->count; i++)
271 {
272 const cxx_type_info *type = exc_type->type_info_table->info[i];
273
274 if (!catch_ti) return type; /* catch(...) matches any type */
275 if (catch_ti != type->type_info)
276 {
277 if (strcmp( catch_ti->mangled, type->type_info->mangled )) continue;
278 }
279 /* type is the same, now check the flags */
280 if ((exc_type->flags & TYPE_FLAG_CONST) &&
281 !(catch_flags & TYPE_FLAG_CONST)) continue;
282 if ((exc_type->flags & TYPE_FLAG_VOLATILE) &&
283 !(catch_flags & TYPE_FLAG_VOLATILE)) continue;
284 return type; /* it matched */
285 }
286 return NULL;
287}
288
289
290/* copy the exception object where the catch block wants it */
291static void copy_exception( void *object, cxx_exception_frame *frame,
292 const catchblock_info *catchblock, const cxx_type_info *type )
293{
294 void **dest_ptr;
295
296 if (!catchblock->type_info || !catchblock->type_info->mangled[0]) return;
297 if (!catchblock->offset) return;
298 dest_ptr = (void **)((char *)&frame->ebp + catchblock->offset);
299
300 if (catchblock->flags & TYPE_FLAG_REFERENCE)
301 {
302 *dest_ptr = get_this_pointer( &type->offsets, object );
303 }
304 else if (type->flags & CLASS_IS_SIMPLE_TYPE)
305 {
306 memmove( dest_ptr, object, type->size );
307 /* if it is a pointer, adjust it */
308 if (type->size == sizeof(void *)) *dest_ptr = get_this_pointer( &type->offsets, *dest_ptr );
309 }
310 else /* copy the object */
311 {
312 if (type->copy_ctor)
313 call_copy_ctor( type->copy_ctor, dest_ptr, get_this_pointer(&type->offsets,object),
315 else
316 memmove( dest_ptr, get_this_pointer(&type->offsets,object), type->size );
317 }
318}
319
320/* unwind the local function up to a given trylevel */
321static void cxx_local_unwind( cxx_exception_frame* frame, const cxx_function_descr *descr, int last_level)
322{
323 void * (*handler)(void);
324 int trylevel = frame->trylevel;
325
326 while (trylevel != last_level)
327 {
328 if (trylevel < 0 || trylevel >= descr->unwind_count)
329 {
330 ERR( "invalid trylevel %d\n", trylevel );
332 }
333 handler = descr->unwind_table[trylevel].handler;
334 if (handler)
335 {
336 TRACE( "calling unwind handler %p trylevel %d last %d ebp %p\n",
337 handler, trylevel, last_level, &frame->ebp );
338 call_handler( handler, &frame->ebp );
339 }
340 trylevel = descr->unwind_table[trylevel].prev;
341 }
342 frame->trylevel = last_level;
343}
344
345/* handler for exceptions happening while calling a catch function */
346static DWORD catch_function_nested_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame,
348{
349 catch_func_nested_frame *nested_frame = (catch_func_nested_frame *)frame;
350
352 {
353 __CxxUnregisterExceptionObject(&nested_frame->frame_info, FALSE);
355 }
356
357 TRACE( "got nested exception in catch function\n" );
358
359 if(rec->ExceptionCode == CXX_EXCEPTION)
360 {
361 PEXCEPTION_RECORD prev_rec = msvcrt_get_thread_data()->exc_record;
362
363 if((rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0) ||
364 (prev_rec->ExceptionCode == CXX_EXCEPTION &&
365 rec->ExceptionInformation[1] == prev_rec->ExceptionInformation[1] &&
366 rec->ExceptionInformation[2] == prev_rec->ExceptionInformation[2]))
367 {
368 /* exception was rethrown */
369 *rec = *prev_rec;
370 rec->ExceptionFlags &= ~EH_UNWINDING;
371 if(TRACE_ON(seh)) {
372 TRACE("detect rethrow: exception code: %x\n", rec->ExceptionCode);
373 if(rec->ExceptionCode == CXX_EXCEPTION)
374 TRACE("re-propagate: obj: %lx, type: %lx\n",
376 }
377 }
378 else
379 {
380 TRACE("detect threw new exception in catch block\n");
381 }
382 }
383
384 return cxx_frame_handler( rec, nested_frame->cxx_frame, context,
385 NULL, nested_frame->descr, nested_frame );
386}
387
388/* find and call the appropriate catch block for an exception */
389/* returns the address to continue execution to after the catch block was called */
390static inline void call_catch_block( PEXCEPTION_RECORD rec, CONTEXT *context,
391 cxx_exception_frame *frame,
393 catch_func_nested_frame *catch_frame,
395{
396 UINT i;
397 int j;
398 void *addr, *object = (void *)rec->ExceptionInformation[1];
399 catch_func_nested_frame nested_frame;
400 int trylevel = frame->trylevel;
401 DWORD save_esp = ((DWORD*)frame)[-1];
403
404 data->processing_throw++;
405 for (i = 0; i < descr->tryblock_count; i++)
406 {
407 const tryblock_info *tryblock = &descr->tryblock[i];
408
409 /* only handle try blocks inside current catch block */
410 if (catch_frame && catch_frame->trylevel > tryblock->start_level) continue;
411
412 if (trylevel < tryblock->start_level) continue;
413 if (trylevel > tryblock->end_level) continue;
414
415 /* got a try block */
416 for (j = 0; j < tryblock->catchblock_count; j++)
417 {
418 const catchblock_info *catchblock = &tryblock->catchblock[j];
419 if(info)
420 {
421 const cxx_type_info *type = find_caught_type( info,
422 catchblock->type_info, catchblock->flags );
423 if (!type) continue;
424
425 TRACE( "matched type %p in tryblock %d catchblock %d\n", type, i, j );
426
427 /* copy the exception to its destination on the stack */
428 copy_exception( object, frame, catchblock, type );
429 }
430 else
431 {
432 /* no CXX_EXCEPTION only proceed with a catch(...) block*/
433 if(catchblock->type_info)
434 continue;
435 TRACE("found catch(...) block\n");
436 }
437
438 /* Add frame info here so exception is not freed inside RtlUnwind call */
439 _CreateFrameInfo(&nested_frame.frame_info.frame_info,
440 (void*)rec->ExceptionInformation[1]);
441
442 /* unwind the stack */
443 RtlUnwind( catch_frame ? &catch_frame->frame : &frame->frame, 0, rec, 0 );
444 cxx_local_unwind( frame, descr, tryblock->start_level );
445 frame->trylevel = tryblock->end_level + 1;
446
447 nested_frame.frame_info.rec = data->exc_record;
448 nested_frame.frame_info.context = data->ctx_record;
449 data->exc_record = rec;
450 data->ctx_record = context;
451 data->processing_throw--;
452
453 /* call the catch block */
454 TRACE( "calling catch block %p addr %p ebp %p\n",
455 catchblock, catchblock->handler, &frame->ebp );
456
457 /* setup an exception block for nested exceptions */
458 nested_frame.frame.Handler = catch_function_nested_handler;
459 nested_frame.cxx_frame = frame;
460 nested_frame.descr = descr;
461 nested_frame.trylevel = tryblock->end_level + 1;
462
463 __wine_push_frame( &nested_frame.frame );
464 addr = call_handler( catchblock->handler, &frame->ebp );
465 __wine_pop_frame( &nested_frame.frame );
466
467 ((DWORD*)frame)[-1] = save_esp;
468 __CxxUnregisterExceptionObject(&nested_frame.frame_info, FALSE);
469 TRACE( "done, continuing at %p\n", addr );
470
471 continue_after_catch( frame, addr );
472 }
473 }
474 data->processing_throw--;
475}
476
477/*********************************************************************
478 * __CxxExceptionFilter (MSVCRT.@)
479 */
480int CDECL __CxxExceptionFilter( PEXCEPTION_POINTERS ptrs,
481 const type_info *ti, int flags, void **copy)
482{
483 const cxx_type_info *type;
485
486 TRACE( "%p %p %x %p\n", ptrs, ti, flags, copy );
487
488 if (!ptrs) return EXCEPTION_CONTINUE_SEARCH;
489
490 /* handle catch(...) */
491 if (!ti) return EXCEPTION_EXECUTE_HANDLER;
492
493 rec = ptrs->ExceptionRecord;
494 if (rec->ExceptionCode != CXX_EXCEPTION || rec->NumberParameters != 3 ||
498
499 if (rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0)
500 {
501 rec = msvcrt_get_thread_data()->exc_record;
502 if (!rec) return EXCEPTION_CONTINUE_SEARCH;
503 }
504
505 type = find_caught_type( (cxx_exception_type*)rec->ExceptionInformation[2], ti, flags );
506 if (!type) return EXCEPTION_CONTINUE_SEARCH;
507
508 if (copy)
509 {
510 void *object = (void *)rec->ExceptionInformation[1];
511
513 {
514 *copy = get_this_pointer( &type->offsets, object );
515 }
516 else if (type->flags & CLASS_IS_SIMPLE_TYPE)
517 {
518 memmove( copy, object, type->size );
519 /* if it is a pointer, adjust it */
520 if (type->size == sizeof(void*)) *copy = get_this_pointer( &type->offsets, *copy );
521 }
522 else /* copy the object */
523 {
524 if (type->copy_ctor)
525 call_copy_ctor( type->copy_ctor, copy, get_this_pointer(&type->offsets,object),
527 else
528 memmove( copy, get_this_pointer(&type->offsets,object), type->size );
529 }
530 }
532}
533
534static LONG CALLBACK se_translation_filter( EXCEPTION_POINTERS *ep, void *c )
535{
536 se_translator_ctx *ctx = (se_translator_ctx *)c;
538 cxx_exception_type *exc_type;
539
540 if (rec->ExceptionCode != CXX_EXCEPTION)
541 {
542 TRACE( "non-c++ exception thrown in SEH handler: %x\n", rec->ExceptionCode );
544 }
545
546 exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
547 call_catch_block( rec, ep->ContextRecord, ctx->frame, ctx->descr,
548 ctx->nested_frame, exc_type );
549
552}
553
554/*********************************************************************
555 * cxx_frame_handler
556 *
557 * Implementation of __CxxFrameHandler.
558 */
559DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame,
562 catch_func_nested_frame* nested_frame )
563{
564 cxx_exception_type *exc_type;
565
566 if (descr->magic < CXX_FRAME_MAGIC_VC6 || descr->magic > CXX_FRAME_MAGIC_VC8)
567 {
568 ERR( "invalid frame magic %x\n", descr->magic );
570 }
571 if (descr->magic >= CXX_FRAME_MAGIC_VC8 &&
572 (descr->flags & FUNC_DESCR_SYNCHRONOUS) &&
574 return ExceptionContinueSearch; /* handle only c++ exceptions */
575
577 {
578 if (descr->unwind_count && !nested_frame) cxx_local_unwind( frame, descr, -1 );
580 }
581 if (!descr->tryblock_count) return ExceptionContinueSearch;
582
583 if(rec->ExceptionCode == CXX_EXCEPTION &&
584 rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0)
585 {
586 *rec = *msvcrt_get_thread_data()->exc_record;
587 rec->ExceptionFlags &= ~EH_UNWINDING;
588 if(TRACE_ON(seh)) {
589 TRACE("detect rethrow: exception code: %x\n", rec->ExceptionCode);
590 if(rec->ExceptionCode == CXX_EXCEPTION)
591 TRACE("re-propagate: obj: %lx, type: %lx\n",
593 }
594 }
595
596 if(rec->ExceptionCode == CXX_EXCEPTION)
597 {
598 exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
599
601 exc_type->custom_handler)
602 {
603 return exc_type->custom_handler( rec, frame, context, dispatch, descr,
604 nested_frame ? nested_frame->trylevel : 0,
605 nested_frame ? &nested_frame->frame : NULL, 0 );
606 }
607
608 if (TRACE_ON(seh))
609 {
610 TRACE("handling C++ exception rec %p frame %p trylevel %d descr %p nested_frame %p\n",
611 rec, frame, frame->trylevel, descr, nested_frame );
612 dump_exception_type( exc_type );
613 dump_function_descr( descr );
614 }
615 }
616 else
617 {
619
620 exc_type = NULL;
621 TRACE("handling C exception code %x rec %p frame %p trylevel %d descr %p nested_frame %p\n",
622 rec->ExceptionCode, rec, frame, frame->trylevel, descr, nested_frame );
623
624 if (data->se_translator) {
625 EXCEPTION_POINTERS except_ptrs;
626 se_translator_ctx ctx;
627
628 ctx.frame = frame;
629 ctx.descr = descr;
630 ctx.nested_frame = nested_frame;
631 __TRY
632 {
633 except_ptrs.ExceptionRecord = rec;
634 except_ptrs.ContextRecord = context;
635 data->se_translator( rec->ExceptionCode, &except_ptrs );
636 }
637 __EXCEPT_CTX(se_translation_filter, &ctx)
638 {
639 }
641 }
642 }
643
644 call_catch_block( rec, context, frame, descr,
645 nested_frame, exc_type );
647}
648
649
650/*********************************************************************
651 * __CxxFrameHandler (MSVCRT.@)
652 */
653extern DWORD CDECL __CxxFrameHandler( PEXCEPTION_RECORD rec, EXCEPTION_REGISTRATION_RECORD* frame,
655__ASM_GLOBAL_FUNC( __CxxFrameHandler,
656 "pushl $0\n\t" /* nested_trylevel */
657 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
658 "pushl $0\n\t" /* nested_frame */
659 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
660 "pushl %eax\n\t" /* descr */
661 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
662 "pushl 28(%esp)\n\t" /* dispatch */
663 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
664 "pushl 28(%esp)\n\t" /* context */
665 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
666 "pushl 28(%esp)\n\t" /* frame */
667 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
668 "pushl 28(%esp)\n\t" /* rec */
669 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
670 "call " __ASM_NAME("cxx_frame_handler") "\n\t"
671 "add $28,%esp\n\t"
672 __ASM_CFI(".cfi_adjust_cfa_offset -28\n\t")
673 "ret" )
674
675
676/*********************************************************************
677 * __CxxLongjmpUnwind (MSVCRT.@)
678 *
679 * Callback meant to be used as UnwindFunc for setjmp/longjmp.
680 */
681void __stdcall __CxxLongjmpUnwind( const struct MSVCRT___JUMP_BUFFER *buf )
682{
683 cxx_exception_frame *frame = (cxx_exception_frame *)buf->Registration;
684 const cxx_function_descr *descr = (const cxx_function_descr *)buf->UnwindData[0];
685
686 TRACE( "unwinding frame %p descr %p trylevel %ld\n", frame, descr, buf->TryLevel );
687 cxx_local_unwind( frame, descr, buf->TryLevel );
688}
689
690/*********************************************************************
691 * __CppXcptFilter (MSVCRT.@)
692 */
694{
695 /* only filter c++ exceptions */
697 return _XcptFilter( ex, ptr );
698}
699
700/*********************************************************************
701 * __CxxDetectRethrow (MSVCRT.@)
702 */
703BOOL CDECL __CxxDetectRethrow(PEXCEPTION_POINTERS ptrs)
704{
706
707 if (!ptrs)
708 return FALSE;
709
710 rec = ptrs->ExceptionRecord;
711
712 if (rec->ExceptionCode == CXX_EXCEPTION &&
713 rec->NumberParameters == 3 &&
715 rec->ExceptionInformation[2])
716 {
717 ptrs->ExceptionRecord = msvcrt_get_thread_data()->exc_record;
718 return TRUE;
719 }
720 return (msvcrt_get_thread_data()->exc_record == rec);
721}
722
723/*********************************************************************
724 * __CxxQueryExceptionSize (MSVCRT.@)
725 */
726unsigned int CDECL __CxxQueryExceptionSize(void)
727{
728 return sizeof(cxx_exception_type);
729}
730
731
732/*********************************************************************
733 * _EH_prolog (MSVCRT.@)
734 */
735
736/* Provided for VC++ binary compatibility only */
737__ASM_GLOBAL_FUNC(_EH_prolog,
738 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") /* skip ret addr */
739 "pushl $-1\n\t"
740 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
741 "pushl %eax\n\t"
742 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
743 "pushl %fs:0\n\t"
744 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
745 "movl %esp, %fs:0\n\t"
746 "movl 12(%esp), %eax\n\t"
747 "movl %ebp, 12(%esp)\n\t"
748 "leal 12(%esp), %ebp\n\t"
749 "pushl %eax\n\t"
750 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
751 "ret")
752
753static const SCOPETABLE_V4 *get_scopetable_v4( MSVCRT_EXCEPTION_FRAME *frame, ULONG_PTR cookie )
754{
755 return (const SCOPETABLE_V4 *)((ULONG_PTR)frame->scopetable ^ cookie);
756}
757
758static DWORD MSVCRT_nested_handler(PEXCEPTION_RECORD rec,
762{
765 *dispatch = frame;
767}
768
769static void msvcrt_local_unwind2(MSVCRT_EXCEPTION_FRAME* frame, int trylevel, void *ebp)
770{
772
773 TRACE("(%p,%d,%d)\n",frame, frame->trylevel, trylevel);
774
775 /* Register a handler in case of a nested exception */
776 reg.Handler = MSVCRT_nested_handler;
777 reg.Prev = NtCurrentTeb()->Tib.ExceptionList;
779
780 while (frame->trylevel != TRYLEVEL_END && frame->trylevel != trylevel)
781 {
782 int level = frame->trylevel;
783 frame->trylevel = frame->scopetable[level].previousTryLevel;
784 if (!frame->scopetable[level].lpfnFilter)
785 {
786 TRACE( "__try block cleanup level %d handler %p ebp %p\n",
787 level, frame->scopetable[level].lpfnHandler, ebp );
788 call_handler( frame->scopetable[level].lpfnHandler, ebp );
789 }
790 }
792 TRACE("unwound OK\n");
793}
794
795static void msvcrt_local_unwind4( ULONG *cookie, MSVCRT_EXCEPTION_FRAME* frame, int trylevel, void *ebp )
796{
798 const SCOPETABLE_V4 *scopetable = get_scopetable_v4( frame, *cookie );
799
800 TRACE("(%p,%d,%d)\n",frame, frame->trylevel, trylevel);
801
802 /* Register a handler in case of a nested exception */
803 reg.Handler = MSVCRT_nested_handler;
804 reg.Prev = NtCurrentTeb()->Tib.ExceptionList;
806
807 while (frame->trylevel != -2 && frame->trylevel != trylevel)
808 {
809 int level = frame->trylevel;
810 frame->trylevel = scopetable->entries[level].previousTryLevel;
811 if (!scopetable->entries[level].lpfnFilter)
812 {
813 TRACE( "__try block cleanup level %d handler %p ebp %p\n",
814 level, scopetable->entries[level].lpfnHandler, ebp );
815 call_handler( scopetable->entries[level].lpfnHandler, ebp );
816 }
817 }
819 TRACE("unwound OK\n");
820}
821#ifndef __REACTOS__
822/*******************************************************************
823 * _local_unwind2 (MSVCRT.@)
824 */
825void CDECL _local_unwind2(MSVCRT_EXCEPTION_FRAME* frame, int trylevel)
826{
827 msvcrt_local_unwind2( frame, trylevel, &frame->_ebp );
828}
829#endif
830/*******************************************************************
831 * _local_unwind4 (MSVCRT.@)
832 */
833void CDECL _local_unwind4( ULONG *cookie, MSVCRT_EXCEPTION_FRAME* frame, int trylevel )
834{
835 msvcrt_local_unwind4( cookie, frame, trylevel, &frame->_ebp );
836}
837
838#ifndef __REACTOS__
839/*******************************************************************
840 * _global_unwind2 (MSVCRT.@)
841 */
842void CDECL _global_unwind2(EXCEPTION_REGISTRATION_RECORD* frame)
843{
844 TRACE("(%p)\n",frame);
845 RtlUnwind( frame, 0, 0, 0 );
846}
847#else
848void CDECL _global_unwind2(EXCEPTION_REGISTRATION_RECORD* frame);
849#endif
850
851#ifndef __REACTOS__
852/*********************************************************************
853 * _except_handler2 (MSVCRT.@)
854 */
855int CDECL _except_handler2(PEXCEPTION_RECORD rec,
859{
860 FIXME("exception %x flags=%x at %p handler=%p %p %p stub\n",
862 frame->Handler, context, dispatcher);
864}
865
866/*********************************************************************
867 * _except_handler3 (MSVCRT.@)
868 */
869int CDECL _except_handler3(PEXCEPTION_RECORD rec,
870 MSVCRT_EXCEPTION_FRAME* frame,
871 PCONTEXT context, void* dispatcher)
872{
873 int retval, trylevel;
874 EXCEPTION_POINTERS exceptPtrs;
875 PSCOPETABLE pScopeTable;
876
877 TRACE("exception %x flags=%x at %p handler=%p %p %p semi-stub\n",
879 frame->handler, context, dispatcher);
880
881#ifdef _MSC_VER
882 __asm{ cld }
883#else
884 __asm__ __volatile__("cld");
885#endif
887 {
888 /* Unwinding the current frame */
889 msvcrt_local_unwind2(frame, TRYLEVEL_END, &frame->_ebp);
890 TRACE("unwound current frame, returning ExceptionContinueSearch\n");
892 }
893 else
894 {
895 /* Hunting for handler */
896 exceptPtrs.ExceptionRecord = rec;
897 exceptPtrs.ContextRecord = context;
898 *((DWORD *)frame-1) = (DWORD)&exceptPtrs;
899 trylevel = frame->trylevel;
900 pScopeTable = frame->scopetable;
901
902 while (trylevel != TRYLEVEL_END)
903 {
904 TRACE( "level %d prev %d filter %p\n", trylevel, pScopeTable[trylevel].previousTryLevel,
905 pScopeTable[trylevel].lpfnFilter );
906 if (pScopeTable[trylevel].lpfnFilter)
907 {
908 retval = call_filter( pScopeTable[trylevel].lpfnFilter, &exceptPtrs, &frame->_ebp );
909
910 TRACE("filter returned %s\n", retval == EXCEPTION_CONTINUE_EXECUTION ?
911 "CONTINUE_EXECUTION" : retval == EXCEPTION_EXECUTE_HANDLER ?
912 "EXECUTE_HANDLER" : "CONTINUE_SEARCH");
913
914 if (retval == EXCEPTION_CONTINUE_EXECUTION)
916
917 if (retval == EXCEPTION_EXECUTE_HANDLER)
918 {
919 /* Unwind all higher frames, this one will handle the exception */
920 _global_unwind2((EXCEPTION_REGISTRATION_RECORD*)frame);
921 msvcrt_local_unwind2(frame, trylevel, &frame->_ebp);
922
923 /* Set our trylevel to the enclosing block, and call the __finally
924 * code, which won't return
925 */
926 frame->trylevel = pScopeTable[trylevel].previousTryLevel;
927 TRACE("__finally block %p\n",pScopeTable[trylevel].lpfnHandler);
928 call_finally_block(pScopeTable[trylevel].lpfnHandler, &frame->_ebp);
929 }
930 }
931 trylevel = pScopeTable[trylevel].previousTryLevel;
932 }
933 }
934 TRACE("reached TRYLEVEL_END, returning ExceptionContinueSearch\n");
936}
937#endif /* __REACTOS__ */
938/*********************************************************************
939 * _except_handler4_common (MSVCRT.@)
940 */
941int CDECL _except_handler4_common( ULONG *cookie, void (*check_cookie)(void),
942 EXCEPTION_RECORD *rec, MSVCRT_EXCEPTION_FRAME *frame,
944{
945 int retval, trylevel;
946 EXCEPTION_POINTERS exceptPtrs;
947 const SCOPETABLE_V4 *scope_table = get_scopetable_v4( frame, *cookie );
948
949 TRACE( "exception %x flags=%x at %p handler=%p %p %p cookie=%x scope table=%p cookies=%d/%x,%d/%x\n",
951 frame->handler, context, dispatcher, *cookie, scope_table,
952 scope_table->gs_cookie_offset, scope_table->gs_cookie_xor,
953 scope_table->eh_cookie_offset, scope_table->eh_cookie_xor );
954
955 /* FIXME: no cookie validation yet */
956
958 {
959 /* Unwinding the current frame */
960 msvcrt_local_unwind4( cookie, frame, -2, &frame->_ebp );
961 TRACE("unwound current frame, returning ExceptionContinueSearch\n");
963 }
964 else
965 {
966 /* Hunting for handler */
967 exceptPtrs.ExceptionRecord = rec;
968 exceptPtrs.ContextRecord = context;
969 *((DWORD *)frame-1) = (DWORD)&exceptPtrs;
970 trylevel = frame->trylevel;
971
972 while (trylevel != -2)
973 {
974 TRACE( "level %d prev %d filter %p\n", trylevel,
975 scope_table->entries[trylevel].previousTryLevel,
976 scope_table->entries[trylevel].lpfnFilter );
977 if (scope_table->entries[trylevel].lpfnFilter)
978 {
979 retval = call_filter( scope_table->entries[trylevel].lpfnFilter, &exceptPtrs, &frame->_ebp );
980
981 TRACE("filter returned %s\n", retval == EXCEPTION_CONTINUE_EXECUTION ?
982 "CONTINUE_EXECUTION" : retval == EXCEPTION_EXECUTE_HANDLER ?
983 "EXECUTE_HANDLER" : "CONTINUE_SEARCH");
984
985 if (retval == EXCEPTION_CONTINUE_EXECUTION)
987
988 if (retval == EXCEPTION_EXECUTE_HANDLER)
989 {
991
992 /* Unwind all higher frames, this one will handle the exception */
993 _global_unwind2((EXCEPTION_REGISTRATION_RECORD*)frame);
994 msvcrt_local_unwind4( cookie, frame, trylevel, &frame->_ebp );
995
996 /* Set our trylevel to the enclosing block, and call the __finally
997 * code, which won't return
998 */
999 frame->trylevel = scope_table->entries[trylevel].previousTryLevel;
1000 TRACE("__finally block %p\n",scope_table->entries[trylevel].lpfnHandler);
1001 call_finally_block(scope_table->entries[trylevel].lpfnHandler, &frame->_ebp);
1002 }
1003 }
1004 trylevel = scope_table->entries[trylevel].previousTryLevel;
1005 }
1006 }
1007 TRACE("reached -2, returning ExceptionContinueSearch\n");
1009}
1010
1011
1012/*
1013 * setjmp/longjmp implementation
1014 */
1015
1016#define MSVCRT_JMP_MAGIC 0x56433230 /* ID value for new jump structure */
1017typedef void (__stdcall *MSVCRT_unwind_function)(const struct MSVCRT___JUMP_BUFFER *);
1018
1019/* define an entrypoint for setjmp/setjmp3 that stores the registers in the jmp buf */
1020/* and then jumps to the C backend function */
1021#define DEFINE_SETJMP_ENTRYPOINT(name) \
1022 __ASM_GLOBAL_FUNC( name, \
1023 "movl 4(%esp),%ecx\n\t" /* jmp_buf */ \
1024 "movl %ebp,0(%ecx)\n\t" /* jmp_buf.Ebp */ \
1025 "movl %ebx,4(%ecx)\n\t" /* jmp_buf.Ebx */ \
1026 "movl %edi,8(%ecx)\n\t" /* jmp_buf.Edi */ \
1027 "movl %esi,12(%ecx)\n\t" /* jmp_buf.Esi */ \
1028 "movl %esp,16(%ecx)\n\t" /* jmp_buf.Esp */ \
1029 "movl 0(%esp),%eax\n\t" \
1030 "movl %eax,20(%ecx)\n\t" /* jmp_buf.Eip */ \
1031 "jmp " __ASM_NAME("__regs_") # name )
1032
1033/*******************************************************************
1034 * _setjmp (MSVCRT.@)
1035 */
1036DEFINE_SETJMP_ENTRYPOINT(MSVCRT__setjmp)
1037int CDECL DECLSPEC_HIDDEN __regs_MSVCRT__setjmp(struct MSVCRT___JUMP_BUFFER *jmp)
1038{
1039 jmp->Registration = (unsigned long)NtCurrentTeb()->Tib.ExceptionList;
1040 if (jmp->Registration == ~0UL)
1041 jmp->TryLevel = TRYLEVEL_END;
1042 else
1043 jmp->TryLevel = ((MSVCRT_EXCEPTION_FRAME*)jmp->Registration)->trylevel;
1044
1045 TRACE("buf=%p ebx=%08lx esi=%08lx edi=%08lx ebp=%08lx esp=%08lx eip=%08lx frame=%08lx\n",
1046 jmp, jmp->Ebx, jmp->Esi, jmp->Edi, jmp->Ebp, jmp->Esp, jmp->Eip, jmp->Registration );
1047 return 0;
1048}
1049
1050/*******************************************************************
1051 * _setjmp3 (MSVCRT.@)
1052 */
1053DEFINE_SETJMP_ENTRYPOINT( MSVCRT__setjmp3 )
1054int WINAPIV DECLSPEC_HIDDEN __regs_MSVCRT__setjmp3(struct MSVCRT___JUMP_BUFFER *jmp, int nb_args, ...)
1055{
1056 jmp->Cookie = MSVCRT_JMP_MAGIC;
1057 jmp->UnwindFunc = 0;
1058 jmp->Registration = (unsigned long)NtCurrentTeb()->Tib.ExceptionList;
1059 if (jmp->Registration == ~0UL)
1060 {
1061 jmp->TryLevel = TRYLEVEL_END;
1062 }
1063 else
1064 {
1065 int i;
1066 va_list args;
1067
1068 va_start( args, nb_args );
1069 if (nb_args > 0) jmp->UnwindFunc = va_arg( args, unsigned long );
1070 if (nb_args > 1) jmp->TryLevel = va_arg( args, unsigned long );
1071 else jmp->TryLevel = ((MSVCRT_EXCEPTION_FRAME*)jmp->Registration)->trylevel;
1072 for (i = 0; i < 6 && i < nb_args - 2; i++)
1073 jmp->UnwindData[i] = va_arg( args, unsigned long );
1074 va_end( args );
1075 }
1076
1077 TRACE("buf=%p ebx=%08lx esi=%08lx edi=%08lx ebp=%08lx esp=%08lx eip=%08lx frame=%08lx\n",
1078 jmp, jmp->Ebx, jmp->Esi, jmp->Edi, jmp->Ebp, jmp->Esp, jmp->Eip, jmp->Registration );
1079 return 0;
1080}
1081
1082/*********************************************************************
1083 * longjmp (MSVCRT.@)
1084 */
1085void CDECL MSVCRT_longjmp(struct MSVCRT___JUMP_BUFFER *jmp, int retval)
1086{
1087 unsigned long cur_frame = 0;
1088
1089 TRACE("buf=%p ebx=%08lx esi=%08lx edi=%08lx ebp=%08lx esp=%08lx eip=%08lx frame=%08lx retval=%08x\n",
1090 jmp, jmp->Ebx, jmp->Esi, jmp->Edi, jmp->Ebp, jmp->Esp, jmp->Eip, jmp->Registration, retval );
1091
1092 cur_frame=(unsigned long)NtCurrentTeb()->Tib.ExceptionList;
1093 TRACE("cur_frame=%lx\n",cur_frame);
1094
1095 if (cur_frame != jmp->Registration)
1096 _global_unwind2((EXCEPTION_REGISTRATION_RECORD*)jmp->Registration);
1097
1098 if (jmp->Registration)
1099 {
1100 if (IsBadReadPtr(&jmp->Cookie, sizeof(long)) || jmp->Cookie != MSVCRT_JMP_MAGIC)
1101 {
1102 msvcrt_local_unwind2((MSVCRT_EXCEPTION_FRAME*)jmp->Registration,
1103 jmp->TryLevel, (void *)jmp->Ebp);
1104 }
1105 else if(jmp->UnwindFunc)
1106 {
1107 MSVCRT_unwind_function unwind_func;
1108
1109 unwind_func=(MSVCRT_unwind_function)jmp->UnwindFunc;
1110 unwind_func(jmp);
1111 }
1112 }
1113
1114 if (!retval)
1115 retval = 1;
1116
1117 __wine_longjmp( (__wine_jmp_buf *)jmp, retval );
1118}
1119
1120/*********************************************************************
1121 * _seh_longjmp_unwind (MSVCRT.@)
1122 */
1123void __stdcall _seh_longjmp_unwind(struct MSVCRT___JUMP_BUFFER *jmp)
1124{
1125 msvcrt_local_unwind2( (MSVCRT_EXCEPTION_FRAME *)jmp->Registration, jmp->TryLevel, (void *)jmp->Ebp );
1126}
1127
1128/*********************************************************************
1129 * _seh_longjmp_unwind4 (MSVCRT.@)
1130 */
1131void __stdcall _seh_longjmp_unwind4(struct MSVCRT___JUMP_BUFFER *jmp)
1132{
1133 msvcrt_local_unwind4( (ULONG *)&jmp->Cookie, (MSVCRT_EXCEPTION_FRAME *)jmp->Registration,
1134 jmp->TryLevel, (void *)jmp->Ebp );
1135}
1136
1137/*********************************************************************
1138 * _fpieee_flt (MSVCRT.@)
1139 */
1140int __cdecl _fpieee_flt(ULONG exception_code, EXCEPTION_POINTERS *ep,
1142{
1144 _FPIEEE_RECORD rec;
1145 int ret;
1146
1147 TRACE("(%x %p %p)\n", exception_code, ep, handler);
1148
1149 switch(exception_code) {
1155 break;
1156 default:
1158 }
1159
1160 memset(&rec, 0, sizeof(rec));
1161 rec.RoundingMode = ctx->ControlWord >> 10;
1162 switch((ctx->ControlWord >> 8) & 0x3) {
1163 case 0: rec.Precision = 2; break;
1164 case 1: rec.Precision = 3; break;
1165 case 2: rec.Precision = 1; break;
1166 case 3: rec.Precision = 0; break;
1167 }
1168 rec.Status.InvalidOperation = ctx->StatusWord & 0x1;
1169 rec.Status.ZeroDivide = ((ctx->StatusWord & 0x4) != 0);
1170 rec.Status.Overflow = ((ctx->StatusWord & 0x8) != 0);
1171 rec.Status.Underflow = ((ctx->StatusWord & 0x10) != 0);
1172 rec.Status.Inexact = ((ctx->StatusWord & 0x20) != 0);
1173 rec.Enable.InvalidOperation = ((ctx->ControlWord & 0x1) == 0);
1174 rec.Enable.ZeroDivide = ((ctx->ControlWord & 0x4) == 0);
1175 rec.Enable.Overflow = ((ctx->ControlWord & 0x8) == 0);
1176 rec.Enable.Underflow = ((ctx->ControlWord & 0x10) == 0);
1177 rec.Enable.Inexact = ((ctx->ControlWord & 0x20) == 0);
1180 rec.Cause.Overflow = rec.Enable.Overflow & rec.Status.Overflow;
1182 rec.Cause.Inexact = rec.Enable.Inexact & rec.Status.Inexact;
1183
1184 TRACE("opcode: %x\n", *(ULONG*)ep->ContextRecord->FloatSave.ErrorOffset);
1185
1186 if(*(WORD*)ctx->ErrorOffset == 0x35dc) { /* fdiv m64fp */
1187 if(exception_code==STATUS_FLOAT_DIVIDE_BY_ZERO || exception_code==STATUS_FLOAT_INVALID_OPERATION) {
1188 rec.Operand1.OperandValid = 1;
1189 rec.Result.OperandValid = 0;
1190 } else {
1191 rec.Operand1.OperandValid = 0;
1192 rec.Result.OperandValid = 1;
1193 }
1194 rec.Operand2.OperandValid = 1;
1197 memcpy(&rec.Operand1.Value.Fp80Value, ctx->RegisterArea, sizeof(rec.Operand1.Value.Fp80Value));
1199 rec.Operand2.Value.Fp64Value = *(double*)ctx->DataOffset;
1201 memcpy(&rec.Result.Value.Fp80Value, ctx->RegisterArea, sizeof(rec.Operand1.Value.Fp80Value));
1202
1203 ret = handler(&rec);
1204
1206 memcpy(ctx->RegisterArea, &rec.Result.Value.Fp80Value, sizeof(rec.Operand1.Value.Fp80Value));
1207 return ret;
1208 }
1209
1210 FIXME("unsupported opcode: %x\n", *(ULONG*)ep->ContextRecord->FloatSave.ErrorOffset);
1212}
1213
1214#endif /* __i386__ */
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define __cdecl
Definition: accygwin.h:79
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define va_arg(ap, T)
Definition: acmsvcex.h:89
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
LONG NTSTATUS
Definition: precomp.h:26
void dispatch(HANDLE hStopEvent)
Definition: dispatch.c:70
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
#define FIXME(fmt,...)
Definition: debug.h:111
#define ERR(fmt,...)
Definition: debug.h:110
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define DECLSPEC_HIDDEN
Definition: precomp.h:8
#define CDECL
Definition: compat.h:29
@ ExceptionContinueSearch
Definition: compat.h:91
@ ExceptionCollidedUnwind
Definition: compat.h:93
@ ExceptionContinueExecution
Definition: compat.h:90
CONTEXT * PCONTEXT
Definition: compat.h:699
#define __TRY
Definition: compat.h:80
#define TRACE_ON(x)
Definition: compat.h:75
#define __ENDTRY
Definition: compat.h:82
struct _EXCEPTION_RECORD * PEXCEPTION_RECORD
#define CALLBACK
Definition: compat.h:35
BOOL WINAPI IsBadReadPtr(IN LPCVOID lp, IN UINT_PTR ucb)
Definition: except.c:805
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7482
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define ULONG_PTR
Definition: config.h:101
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
@ _FpCodeDivide
Definition: fpieee.h:33
@ _FpFormatFp64
Definition: fpieee.h:22
@ _FpFormatFp80
Definition: fpieee.h:22
_CRTIMP int __cdecl _fpieee_flt(unsigned long _ExceptionCode, struct _EXCEPTION_POINTERS *_PtExceptionPtr, int(__cdecl *_Handler)(_FPIEEE_RECORD *))
GLint level
Definition: gl.h:1546
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLenum func
Definition: glext.h:6028
GLenum src
Definition: glext.h:6340
const GLubyte * c
Definition: glext.h:8905
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLbitfield flags
Definition: glext.h:7161
GLenum const GLvoid * addr
Definition: glext.h:9621
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
static int reg
Definition: i386-dis.c:1290
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:86
#define EXCEPTION_CONTINUE_EXECUTION
Definition: excpt.h:87
int CDECL _XcptFilter(NTSTATUS, PEXCEPTION_POINTERS)
Definition: except.c:274
#define CXX_EXCEPTION
Definition: cppexcept.h:27
static const char * dbgstr_type_info(const type_info *info)
Definition: cppexcept.h:155
struct __tryblock_info tryblock_info
#define CLASS_IS_SIMPLE_TYPE
Definition: cppexcept.h:127
#define CXX_FRAME_MAGIC_VC7
Definition: cppexcept.h:25
struct __catchblock_info catchblock_info
#define CXX_FRAME_MAGIC_VC6
Definition: cppexcept.h:24
#define CLASS_HAS_VIRTUAL_BASE_CLASS
Definition: cppexcept.h:128
struct __cxx_exception_type cxx_exception_type
#define CXX_FRAME_MAGIC_VC8
Definition: cppexcept.h:26
#define FUNC_DESCR_SYNCHRONOUS
Definition: cppexcept.h:106
struct __cxx_exception_frame cxx_exception_frame
struct __unwind_info unwind_info
int CDECL __CppXcptFilter(NTSTATUS, PEXCEPTION_POINTERS)
#define TYPE_FLAG_CONST
Definition: cppexcept.h:71
struct __cxx_function_descr cxx_function_descr
#define TYPE_FLAG_VOLATILE
Definition: cppexcept.h:72
static void * get_this_pointer(const this_ptr_offsets *off, void *object)
Definition: cppexcept.h:163
#define TYPE_FLAG_REFERENCE
Definition: cppexcept.h:73
#define NtCurrentTeb
if(dx< 0)
Definition: linetemp.h:194
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
static PVOID ptr
Definition: dispmode.c:27
void __cdecl MSVCRT_terminate(void)
Definition: cpp.c:1275
thread_data_t * msvcrt_get_thread_data(void)
Definition: tls.c:31
#define __ASM_NAME(name)
Definition: config.h:934
#define __ASM_GLOBAL_FUNC(name, code)
Definition: port.h:201
unsigned int UINT
Definition: ndis.h:50
NTSYSAPI VOID NTAPI RtlUnwind(_In_opt_ PVOID TargetFrame, _In_opt_ PVOID TargetIp, _In_opt_ PEXCEPTION_RECORD ExceptionRecord, _In_ PVOID ReturnValue)
Definition: unwind.c:912
#define DWORD
Definition: nt_native.h:44
#define DECLSPEC_NORETURN
Definition: ntbasedef.h:176
#define STATUS_FLOAT_UNDERFLOW
Definition: ntstatus.h:383
#define STATUS_FLOAT_OVERFLOW
Definition: ntstatus.h:381
#define STATUS_FLOAT_DIVIDE_BY_ZERO
Definition: ntstatus.h:378
#define STATUS_FLOAT_INVALID_OPERATION
Definition: ntstatus.h:380
#define STATUS_FLOAT_INEXACT_RESULT
Definition: ntstatus.h:379
long LONG
Definition: pedump.c:60
__asm__(".p2align 4, 0x90\n" ".seh_proc __seh2_global_filter_func\n" "__seh2_global_filter_func:\n" "\tpush %rbp\n" "\t.seh_pushreg %rbp\n" "\tsub $32, %rsp\n" "\t.seh_stackalloc 32\n" "\t.seh_endprologue\n" "\tmov %rdx, %rbp\n" "\tjmp *%rax\n" "__seh2_global_filter_func_exit:\n" "\t.p2align 4\n" "\tadd $32, %rsp\n" "\tpop %rbp\n" "\tret\n" "\t.seh_endproc")
#define long
Definition: qsort.c:33
#define __ASM_CFI(str)
Definition: asm.h:39
#define EH_EXIT_UNWIND
Definition: exception.h:18
static EXCEPTION_REGISTRATION_RECORD * __wine_push_frame(EXCEPTION_REGISTRATION_RECORD *frame)
Definition: exception.h:104
#define __EXCEPT_CTX(func, ctx)
Definition: exception.h:85
#define EH_UNWINDING
Definition: exception.h:17
static EXCEPTION_REGISTRATION_RECORD * __wine_pop_frame(EXCEPTION_REGISTRATION_RECORD *frame)
Definition: exception.h:118
#define WINAPIV
Definition: sdbpapi.h:64
void CDECL __DestructExceptionObject(EXCEPTION_RECORD *rec)
Definition: except.c:405
frame_info *CDECL _CreateFrameInfo(frame_info *fi, void *obj)
Definition: except.c:344
void CDECL __CxxUnregisterExceptionObject(cxx_frame_info *frame_info, BOOL in_use)
Definition: except.c:464
const char * descr
Definition: boot.c:45
#define memset(x, y, z)
Definition: compat.h:39
#define args
Definition: format.c:66
#define TRACE(s)
Definition: solgame.cpp:4
FLOATING_SAVE_AREA FloatSave
Definition: nt_native.h:1446
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200
PCONTEXT ContextRecord
Definition: rtltypes.h:201
DWORD ExceptionCode
Definition: compat.h:208
DWORD NumberParameters
Definition: compat.h:212
DWORD ExceptionFlags
Definition: compat.h:209
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:213
PVOID ExceptionAddress
Definition: compat.h:211
PEXCEPTION_ROUTINE Handler
Definition: compat.h:727
unsigned int Overflow
Definition: fpieee.h:324
unsigned int Inexact
Definition: fpieee.h:322
unsigned int ZeroDivide
Definition: fpieee.h:325
unsigned int Underflow
Definition: fpieee.h:323
unsigned int InvalidOperation
Definition: fpieee.h:326
_FPIEEE_EXCEPTION_FLAGS Status
Definition: fpieee.h:335
_FPIEEE_VALUE Operand2
Definition: fpieee.h:337
unsigned int Operation
Definition: fpieee.h:332
_FPIEEE_EXCEPTION_FLAGS Cause
Definition: fpieee.h:333
unsigned int Precision
Definition: fpieee.h:331
unsigned int RoundingMode
Definition: fpieee.h:330
_FPIEEE_EXCEPTION_FLAGS Enable
Definition: fpieee.h:334
_FPIEEE_VALUE Result
Definition: fpieee.h:338
_FPIEEE_VALUE Operand1
Definition: fpieee.h:336
union _FPIEEE_VALUE::@1885 Value
unsigned int Format
Definition: fpieee.h:318
_FP64 Fp64Value
Definition: fpieee.h:302
_FP80 Fp80Value
Definition: fpieee.h:303
unsigned int OperandValid
Definition: fpieee.h:317
const type_info * type_info
Definition: cppexcept.h:67
void(* handler)(void)
Definition: cppexcept.h:69
EXCEPTION_REGISTRATION_RECORD frame
Definition: cppexcept.h:58
cxx_exc_custom_handler custom_handler
Definition: cppexcept.h:147
const cxx_type_info_table * type_info_table
Definition: cppexcept.h:148
const tryblock_info * tryblock
Definition: cppexcept.h:99
const void * ipmap
Definition: cppexcept.h:101
const void * expect_list
Definition: cppexcept.h:102
const unwind_info * unwind_table
Definition: cppexcept.h:97
const cxx_type_info * info[3]
Definition: cppexcept.h:134
int catchblock_count
Definition: cppexcept.h:81
const catchblock_info * catchblock
Definition: cppexcept.h:82
char mangled[16]
Definition: cpp.c:36
Definition: match.c:390
Definition: http.c:7252
Definition: cookie.c:34
Definition: comerr.c:44
ecx edi movl ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl edx movl TEMP incl eax andl eax ecx incl ebx testl eax jnz xchgl ecx incl TEMP esp ecx subl ebx pushl ecx ecx edx ecx shrl ecx mm0 mm4 mm0 mm4 mm1 mm5 mm1 mm5 mm2 mm6 mm2 mm6 mm3 mm7 mm3 mm7 paddd mm0 paddd mm4 paddd mm0 paddd mm4 paddd mm0 paddd mm4 movq mm1 movq mm5 psrlq mm1 psrlq mm5 paddd mm0 paddd mm4 psrad mm0 psrad mm4 packssdw mm0 packssdw mm4 mm1 punpckldq mm0 pand mm1 pand mm0 por mm1 movq edi esi edx edi decl ecx jnz popl ecx andl ecx jecxz mm0 mm0 mm1 mm1 mm2 mm2 mm3 mm3 paddd mm0 paddd mm0 paddd mm0 movq mm1 psrlq mm1 paddd mm0 psrad mm0 packssdw mm0 movd eax movw edi esi edx esi movl ecx mm0 mm4 mm0 mm4 mm1 mm5 mm1 mm5 mm2 mm6 mm2 mm6 mm3 mm7 mm3 mm7 paddd mm0 paddd mm4 paddd mm0 paddd mm4 paddd mm0 paddd mm4 movq mm1 movq mm5 psrlq mm1 psrlq mm5 paddd mm1 paddd mm5 psrad mm1 psrad mm5 packssdw mm1 packssdw mm5 psubd mm0 psubd mm4 psubsw mm0 psubsw mm4 mm1 punpckldq mm0 pand mm1 pand mm0 por mm1 movq edi subl esi addl edx edi decl ecx jnz mm0 mm0 mm1 mm1 mm2 mm2 mm3 mm3 paddd mm0 paddd mm0 paddd mm0 movq mm1 psrlq mm1 paddd mm1 psrad mm1 packssdw mm1 psubd mm0 psubsw mm0 movd eax movw edi emms popl ebx popl esi popl edi mov ebp
Definition: synth_sse3d.h:266
#define UL
Definition: tui.h:165
#define __stdcall
Definition: typedefs.h:25
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
int ret
static void dump_type(type_t *t)
Definition: write_msft.c:1037
struct _EXCEPTION_POINTERS * PEXCEPTION_POINTERS
#define const
Definition: zconf.h:233