ReactOS 0.4.16-dev-747-gbc52d5f
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#ifdef __i386__
29
30#include <setjmp.h>
31#include <stdarg.h>
32#include <fpieee.h>
33
34#include "windef.h"
35#include "winbase.h"
36#include "winternl.h"
37#include "msvcrt.h"
38#include "wine/exception.h"
39#include "excpt.h"
40#include "wine/debug.h"
41
42#include "cppexcept.h"
43
45
46
47/* the exception frame used by CxxFrameHandler */
48typedef struct __cxx_exception_frame
49{
50 EXCEPTION_REGISTRATION_RECORD frame; /* the standard exception frame */
51 int trylevel;
52 DWORD ebp;
54
55/* info about a single catch {} block */
56typedef struct __catchblock_info
57{
58 UINT flags; /* flags (see below) */
59 const type_info *type_info; /* C++ type caught by this block */
60 int offset; /* stack offset to copy exception object to */
61 void * (*handler)(void);/* catch block handler code */
63#define TYPE_FLAG_CONST 1
64#define TYPE_FLAG_VOLATILE 2
65#define TYPE_FLAG_REFERENCE 8
66
67/* info about a single try {} block */
68typedef struct __tryblock_info
69{
70 int start_level; /* start trylevel of that block */
71 int end_level; /* end trylevel of that block */
72 int catch_level; /* initial trylevel of the catch block */
73 int catchblock_count; /* count of catch blocks in array */
74 const catchblock_info *catchblock; /* array of catch blocks */
76
77/* info about the unwind handler for a given trylevel */
78typedef struct __unwind_info
79{
80 int prev; /* prev trylevel unwind handler, to run after this one */
81 void * (*handler)(void);/* unwind handler */
83
84/* descriptor of all try blocks of a given function */
85typedef struct __cxx_function_descr
86{
87 UINT magic; /* must be CXX_FRAME_MAGIC */
88 UINT unwind_count; /* number of unwind handlers */
89 const unwind_info *unwind_table; /* array of unwind handlers */
90 UINT tryblock_count; /* number of try blocks */
91 const tryblock_info *tryblock; /* array of try blocks */
93 const void *ipmap;
94 const void *expect_list; /* expected exceptions list when magic >= VC7 */
95 UINT flags; /* flags when magic >= VC8 */
97
98/* exception frame for nested exceptions in catch block */
99typedef struct
100{
101 EXCEPTION_REGISTRATION_RECORD frame; /* standard exception frame */
102 cxx_exception_frame *cxx_frame; /* frame of parent exception */
103 const cxx_function_descr *descr; /* descriptor of parent exception */
104 int trylevel; /* current try level */
106} catch_func_nested_frame;
107
108typedef struct
109{
110 cxx_exception_frame *frame;
112 catch_func_nested_frame *nested_frame;
113} se_translator_ctx;
114
115typedef struct _SCOPETABLE
116{
117 int previousTryLevel;
118 int (*lpfnFilter)(PEXCEPTION_POINTERS);
119 void * (*lpfnHandler)(void);
120} SCOPETABLE, *PSCOPETABLE;
121
122typedef struct MSVCRT_EXCEPTION_FRAME
123{
127 PSCOPETABLE scopetable;
128 int trylevel;
129 int _ebp;
130 PEXCEPTION_POINTERS xpointers;
131} MSVCRT_EXCEPTION_FRAME;
132
133typedef struct
134{
135 int gs_cookie_offset;
136 ULONG gs_cookie_xor;
137 int eh_cookie_offset;
138 ULONG eh_cookie_xor;
139 SCOPETABLE entries[1];
140} SCOPETABLE_V4;
141
142#define TRYLEVEL_END (-1) /* End of trylevel list */
143
144DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame,
147 catch_func_nested_frame* nested_frame ) DECLSPEC_HIDDEN;
148
149/* call a copy constructor */
150extern void call_copy_ctor( void *func, void *this, void *src, int has_vbase );
151
152__ASM_GLOBAL_FUNC( call_copy_ctor,
153 "pushl %ebp\n\t"
154 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
155 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
156 "movl %esp, %ebp\n\t"
157 __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
158 "pushl $1\n\t"
159 "movl 12(%ebp), %ecx\n\t"
160 "pushl 16(%ebp)\n\t"
161 "call *8(%ebp)\n\t"
162 "leave\n"
163 __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
164 __ASM_CFI(".cfi_same_value %ebp\n\t")
165 "ret" );
166
167/* continue execution to the specified address after exception is caught */
168extern void DECLSPEC_NORETURN continue_after_catch( cxx_exception_frame* frame, void *addr );
169
170__ASM_GLOBAL_FUNC( continue_after_catch,
171 "movl 4(%esp), %edx\n\t"
172 "movl 8(%esp), %eax\n\t"
173 "movl -4(%edx), %esp\n\t"
174 "leal 12(%edx), %ebp\n\t"
175 "jmp *%eax" );
176
177extern void DECLSPEC_NORETURN call_finally_block( void *code_block, void *base_ptr );
178
179__ASM_GLOBAL_FUNC( call_finally_block,
180 "movl 8(%esp), %ebp\n\t"
181 "jmp *4(%esp)" );
182
183extern int call_filter( int (*func)(PEXCEPTION_POINTERS), void *arg, void *ebp );
184
185__ASM_GLOBAL_FUNC( call_filter,
186 "pushl %ebp\n\t"
187 "pushl 12(%esp)\n\t"
188 "movl 20(%esp), %ebp\n\t"
189 "call *12(%esp)\n\t"
190 "popl %ebp\n\t"
191 "popl %ebp\n\t"
192 "ret" );
193
194extern void *call_handler( void * (*func)(void), void *ebp );
195
196__ASM_GLOBAL_FUNC( call_handler,
197 "pushl %ebp\n\t"
198 "pushl %ebx\n\t"
199 "pushl %esi\n\t"
200 "pushl %edi\n\t"
201 "movl 24(%esp), %ebp\n\t"
202 "call *20(%esp)\n\t"
203 "popl %edi\n\t"
204 "popl %esi\n\t"
205 "popl %ebx\n\t"
206 "popl %ebp\n\t"
207 "ret" );
208
209static inline void dump_type( const cxx_type_info *type )
210{
211 TRACE( "flags %x type %p %s offsets %d,%d,%d size %d copy ctor %p\n",
212 type->flags, type->type_info, dbgstr_type_info(type->type_info),
213 type->offsets.this_offset, type->offsets.vbase_descr, type->offsets.vbase_offset,
214 type->size, type->copy_ctor );
215}
216
217static void dump_exception_type( const cxx_exception_type *type )
218{
219 UINT i;
220
221 TRACE( "flags %x destr %p handler %p type info %p\n",
222 type->flags, type->destructor, type->custom_handler, type->type_info_table );
223 for (i = 0; i < type->type_info_table->count; i++)
224 {
225 TRACE( " %d: ", i );
226 dump_type( type->type_info_table->info[i] );
227 }
228}
229
230static void dump_function_descr( const cxx_function_descr *descr )
231{
232 UINT i;
233 int j;
234
235 TRACE( "magic %x\n", descr->magic );
236 TRACE( "unwind table: %p %d\n", descr->unwind_table, descr->unwind_count );
237 for (i = 0; i < descr->unwind_count; i++)
238 {
239 TRACE( " %d: prev %d func %p\n", i,
240 descr->unwind_table[i].prev, descr->unwind_table[i].handler );
241 }
242 TRACE( "try table: %p %d\n", descr->tryblock, descr->tryblock_count );
243 for (i = 0; i < descr->tryblock_count; i++)
244 {
245 TRACE( " %d: start %d end %d catchlevel %d catch %p %d\n", i,
246 descr->tryblock[i].start_level, descr->tryblock[i].end_level,
247 descr->tryblock[i].catch_level, descr->tryblock[i].catchblock,
248 descr->tryblock[i].catchblock_count );
249 for (j = 0; j < descr->tryblock[i].catchblock_count; j++)
250 {
251 const catchblock_info *ptr = &descr->tryblock[i].catchblock[j];
252 TRACE( " %d: flags %x offset %d handler %p type %p %s\n",
253 j, ptr->flags, ptr->offset, ptr->handler,
254 ptr->type_info, dbgstr_type_info( ptr->type_info ) );
255 }
256 }
257 if (descr->magic <= CXX_FRAME_MAGIC_VC6) return;
258 TRACE( "expect list: %p\n", descr->expect_list );
259 if (descr->magic <= CXX_FRAME_MAGIC_VC7) return;
260 TRACE( "flags: %08x\n", descr->flags );
261}
262
263/* check if the exception type is caught by a given catch block, and return the type that matched */
264static const cxx_type_info *find_caught_type( cxx_exception_type *exc_type,
265 const type_info *catch_ti, UINT catch_flags )
266{
267 UINT i;
268
269 for (i = 0; i < exc_type->type_info_table->count; i++)
270 {
271 const cxx_type_info *type = exc_type->type_info_table->info[i];
272
273 if (!catch_ti) return type; /* catch(...) matches any type */
274 if (catch_ti != type->type_info)
275 {
276 if (strcmp( catch_ti->mangled, type->type_info->mangled )) continue;
277 }
278 /* type is the same, now check the flags */
279 if ((exc_type->flags & TYPE_FLAG_CONST) &&
280 !(catch_flags & TYPE_FLAG_CONST)) continue;
281 if ((exc_type->flags & TYPE_FLAG_VOLATILE) &&
282 !(catch_flags & TYPE_FLAG_VOLATILE)) continue;
283 return type; /* it matched */
284 }
285 return NULL;
286}
287
288
289/* copy the exception object where the catch block wants it */
290static void copy_exception( void *object, cxx_exception_frame *frame,
291 const catchblock_info *catchblock, const cxx_type_info *type )
292{
293 void **dest_ptr;
294
295 if (!catchblock->type_info || !catchblock->type_info->mangled[0]) return;
296 if (!catchblock->offset) return;
297 dest_ptr = (void **)((char *)&frame->ebp + catchblock->offset);
298
299 if (catchblock->flags & TYPE_FLAG_REFERENCE)
300 {
301 *dest_ptr = get_this_pointer( &type->offsets, object );
302 }
303 else if (type->flags & CLASS_IS_SIMPLE_TYPE)
304 {
305 memmove( dest_ptr, object, type->size );
306 /* if it is a pointer, adjust it */
307 if (type->size == sizeof(void *)) *dest_ptr = get_this_pointer( &type->offsets, *dest_ptr );
308 }
309 else /* copy the object */
310 {
311 if (type->copy_ctor)
312 call_copy_ctor( type->copy_ctor, dest_ptr, get_this_pointer(&type->offsets,object),
314 else
315 memmove( dest_ptr, get_this_pointer(&type->offsets,object), type->size );
316 }
317}
318
319/* unwind the local function up to a given trylevel */
320static void cxx_local_unwind( cxx_exception_frame* frame, const cxx_function_descr *descr, int last_level)
321{
322 void * (*handler)(void);
323 int trylevel = frame->trylevel;
324
325 while (trylevel != last_level)
326 {
327 if (trylevel < 0 || trylevel >= descr->unwind_count)
328 {
329 ERR( "invalid trylevel %d\n", trylevel );
330 terminate();
331 }
332 handler = descr->unwind_table[trylevel].handler;
333 if (handler)
334 {
335 TRACE( "calling unwind handler %p trylevel %d last %d ebp %p\n",
336 handler, trylevel, last_level, &frame->ebp );
337 call_handler( handler, &frame->ebp );
338 }
339 trylevel = descr->unwind_table[trylevel].prev;
340 }
341 frame->trylevel = last_level;
342}
343
344/* handler for exceptions happening while calling a catch function */
345static DWORD catch_function_nested_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame,
347{
348 catch_func_nested_frame *nested_frame = (catch_func_nested_frame *)frame;
349
351 {
352 __CxxUnregisterExceptionObject(&nested_frame->frame_info, FALSE);
354 }
355
356 TRACE( "got nested exception in catch function\n" );
357
358 if(rec->ExceptionCode == CXX_EXCEPTION)
359 {
360 PEXCEPTION_RECORD prev_rec = msvcrt_get_thread_data()->exc_record;
361
362 if((rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0) ||
363 (prev_rec->ExceptionCode == CXX_EXCEPTION &&
364 rec->ExceptionInformation[1] == prev_rec->ExceptionInformation[1] &&
365 rec->ExceptionInformation[2] == prev_rec->ExceptionInformation[2]))
366 {
367 /* exception was rethrown */
368 *rec = *prev_rec;
369 rec->ExceptionFlags &= ~EH_UNWINDING;
370 if(TRACE_ON(seh)) {
371 TRACE("detect rethrow: exception code: %x\n", rec->ExceptionCode);
372 if(rec->ExceptionCode == CXX_EXCEPTION)
373 TRACE("re-propagate: obj: %lx, type: %lx\n",
375 }
376 }
377 else
378 {
379 TRACE("detect threw new exception in catch block\n");
380 }
381 }
382
383 return cxx_frame_handler( rec, nested_frame->cxx_frame, context,
384 NULL, nested_frame->descr, nested_frame );
385}
386
387/* find and call the appropriate catch block for an exception */
388/* returns the address to continue execution to after the catch block was called */
389static inline void call_catch_block( PEXCEPTION_RECORD rec, CONTEXT *context,
390 cxx_exception_frame *frame,
392 catch_func_nested_frame *catch_frame,
394{
395 UINT i;
396 int j;
397 void *addr, *object = (void *)rec->ExceptionInformation[1];
398 catch_func_nested_frame nested_frame;
399 int trylevel = frame->trylevel;
400 DWORD save_esp = ((DWORD*)frame)[-1];
402
403 data->processing_throw++;
404 for (i = 0; i < descr->tryblock_count; i++)
405 {
406 const tryblock_info *tryblock = &descr->tryblock[i];
407
408 /* only handle try blocks inside current catch block */
409 if (catch_frame && catch_frame->trylevel > tryblock->start_level) continue;
410
411 if (trylevel < tryblock->start_level) continue;
412 if (trylevel > tryblock->end_level) continue;
413
414 /* got a try block */
415 for (j = 0; j < tryblock->catchblock_count; j++)
416 {
417 const catchblock_info *catchblock = &tryblock->catchblock[j];
418 if(info)
419 {
420 const cxx_type_info *type = find_caught_type( info,
421 catchblock->type_info, catchblock->flags );
422 if (!type) continue;
423
424 TRACE( "matched type %p in tryblock %d catchblock %d\n", type, i, j );
425
426 /* copy the exception to its destination on the stack */
427 copy_exception( object, frame, catchblock, type );
428 }
429 else
430 {
431 /* no CXX_EXCEPTION only proceed with a catch(...) block*/
432 if(catchblock->type_info)
433 continue;
434 TRACE("found catch(...) block\n");
435 }
436
437 /* Add frame info here so exception is not freed inside RtlUnwind call */
438 _CreateFrameInfo(&nested_frame.frame_info.frame_info,
439 (void*)rec->ExceptionInformation[1]);
440
441 /* unwind the stack */
442 RtlUnwind( catch_frame ? &catch_frame->frame : &frame->frame, 0, rec, 0 );
443 cxx_local_unwind( frame, descr, tryblock->start_level );
444 frame->trylevel = tryblock->end_level + 1;
445
446 nested_frame.frame_info.rec = data->exc_record;
447 nested_frame.frame_info.context = data->ctx_record;
448 data->exc_record = rec;
449 data->ctx_record = context;
450 data->processing_throw--;
451
452 /* call the catch block */
453 TRACE( "calling catch block %p addr %p ebp %p\n",
454 catchblock, catchblock->handler, &frame->ebp );
455
456 /* setup an exception block for nested exceptions */
457 nested_frame.frame.Handler = catch_function_nested_handler;
458 nested_frame.cxx_frame = frame;
459 nested_frame.descr = descr;
460 nested_frame.trylevel = tryblock->end_level + 1;
461
462 __wine_push_frame( &nested_frame.frame );
463 addr = call_handler( catchblock->handler, &frame->ebp );
464 __wine_pop_frame( &nested_frame.frame );
465
466 ((DWORD*)frame)[-1] = save_esp;
467 __CxxUnregisterExceptionObject(&nested_frame.frame_info, FALSE);
468 TRACE( "done, continuing at %p\n", addr );
469
470 continue_after_catch( frame, addr );
471 }
472 }
473 data->processing_throw--;
474}
475
476/*********************************************************************
477 * __CxxExceptionFilter (MSVCRT.@)
478 */
479int CDECL __CxxExceptionFilter( PEXCEPTION_POINTERS ptrs,
480 const type_info *ti, int flags, void **copy)
481{
482 const cxx_type_info *type;
484
485 TRACE( "%p %p %x %p\n", ptrs, ti, flags, copy );
486
487 if (!ptrs) return EXCEPTION_CONTINUE_SEARCH;
488
489 /* handle catch(...) */
490 if (!ti) return EXCEPTION_EXECUTE_HANDLER;
491
492 rec = ptrs->ExceptionRecord;
493 if (rec->ExceptionCode != CXX_EXCEPTION || rec->NumberParameters != 3 ||
497
498 if (rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0)
499 {
500 rec = msvcrt_get_thread_data()->exc_record;
501 if (!rec) return EXCEPTION_CONTINUE_SEARCH;
502 }
503
504 type = find_caught_type( (cxx_exception_type*)rec->ExceptionInformation[2], ti, flags );
505 if (!type) return EXCEPTION_CONTINUE_SEARCH;
506
507 if (copy)
508 {
509 void *object = (void *)rec->ExceptionInformation[1];
510
512 {
513 *copy = get_this_pointer( &type->offsets, object );
514 }
515 else if (type->flags & CLASS_IS_SIMPLE_TYPE)
516 {
517 memmove( copy, object, type->size );
518 /* if it is a pointer, adjust it */
519 if (type->size == sizeof(void*)) *copy = get_this_pointer( &type->offsets, *copy );
520 }
521 else /* copy the object */
522 {
523 if (type->copy_ctor)
524 call_copy_ctor( type->copy_ctor, copy, get_this_pointer(&type->offsets,object),
526 else
527 memmove( copy, get_this_pointer(&type->offsets,object), type->size );
528 }
529 }
531}
532
533static LONG CALLBACK se_translation_filter( EXCEPTION_POINTERS *ep, void *c )
534{
535 se_translator_ctx *ctx = (se_translator_ctx *)c;
537 cxx_exception_type *exc_type;
538
539 if (rec->ExceptionCode != CXX_EXCEPTION)
540 {
541 TRACE( "non-c++ exception thrown in SEH handler: %x\n", rec->ExceptionCode );
542 terminate();
543 }
544
545 exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
546 call_catch_block( rec, ep->ContextRecord, ctx->frame, ctx->descr,
547 ctx->nested_frame, exc_type );
548
551}
552
553static void check_noexcept( PEXCEPTION_RECORD rec,
555{
556 if (!nested && rec->ExceptionCode == CXX_EXCEPTION &&
557 descr->magic >= CXX_FRAME_MAGIC_VC8 &&
558 (descr->flags & FUNC_DESCR_NOEXCEPT))
559 {
560 ERR("noexcept function propagating exception\n");
561 terminate();
562 }
563}
564
565/*********************************************************************
566 * cxx_frame_handler
567 *
568 * Implementation of __CxxFrameHandler.
569 */
570DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame,
573 catch_func_nested_frame* nested_frame )
574{
575 cxx_exception_type *exc_type;
576
577 if (descr->magic < CXX_FRAME_MAGIC_VC6 || descr->magic > CXX_FRAME_MAGIC_VC8)
578 {
579 ERR( "invalid frame magic %x\n", descr->magic );
581 }
582 if (descr->magic >= CXX_FRAME_MAGIC_VC8 &&
583 (descr->flags & FUNC_DESCR_SYNCHRONOUS) &&
585 return ExceptionContinueSearch; /* handle only c++ exceptions */
586
588 {
589 if (descr->unwind_count && !nested_frame) cxx_local_unwind( frame, descr, -1 );
591 }
592 if (!descr->tryblock_count)
593 {
594 check_noexcept(rec, descr, nested_frame != NULL);
596 }
597
598 if(rec->ExceptionCode == CXX_EXCEPTION &&
599 rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0)
600 {
601 *rec = *msvcrt_get_thread_data()->exc_record;
602 rec->ExceptionFlags &= ~EH_UNWINDING;
603 if(TRACE_ON(seh)) {
604 TRACE("detect rethrow: exception code: %x\n", rec->ExceptionCode);
605 if(rec->ExceptionCode == CXX_EXCEPTION)
606 TRACE("re-propagate: obj: %lx, type: %lx\n",
608 }
609 }
610
611 if(rec->ExceptionCode == CXX_EXCEPTION)
612 {
613 exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
614
616 exc_type->custom_handler)
617 {
618 return exc_type->custom_handler( rec, frame, context, dispatch, descr,
619 nested_frame ? nested_frame->trylevel : 0,
620 nested_frame ? &nested_frame->frame : NULL, 0 );
621 }
622
623 if (TRACE_ON(seh))
624 {
625 TRACE("handling C++ exception rec %p frame %p trylevel %d descr %p nested_frame %p\n",
626 rec, frame, frame->trylevel, descr, nested_frame );
627 dump_exception_type( exc_type );
628 dump_function_descr( descr );
629 }
630 }
631 else
632 {
634
635 exc_type = NULL;
636 TRACE("handling C exception code %x rec %p frame %p trylevel %d descr %p nested_frame %p\n",
637 rec->ExceptionCode, rec, frame, frame->trylevel, descr, nested_frame );
638
639 if (data->se_translator) {
640 EXCEPTION_POINTERS except_ptrs;
641 se_translator_ctx ctx;
642
643 ctx.frame = frame;
644 ctx.descr = descr;
645 ctx.nested_frame = nested_frame;
646 __TRY
647 {
648 except_ptrs.ExceptionRecord = rec;
649 except_ptrs.ContextRecord = context;
650 data->se_translator( rec->ExceptionCode, &except_ptrs );
651 }
652 __EXCEPT_CTX(se_translation_filter, &ctx)
653 {
654 }
656 }
657 }
658
659 call_catch_block( rec, context, frame, descr,
660 nested_frame, exc_type );
661 check_noexcept(rec, descr, nested_frame != NULL);
663}
664
665
666/*********************************************************************
667 * __CxxFrameHandler (MSVCRT.@)
668 */
669extern DWORD CDECL __CxxFrameHandler( PEXCEPTION_RECORD rec, EXCEPTION_REGISTRATION_RECORD* frame,
671__ASM_GLOBAL_FUNC( __CxxFrameHandler,
672 "pushl $0\n\t" /* nested_trylevel */
673 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
674 "pushl $0\n\t" /* nested_frame */
675 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
676 "pushl %eax\n\t" /* descr */
677 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
678 "pushl 28(%esp)\n\t" /* dispatch */
679 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
680 "pushl 28(%esp)\n\t" /* context */
681 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
682 "pushl 28(%esp)\n\t" /* frame */
683 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
684 "pushl 28(%esp)\n\t" /* rec */
685 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
686 "call " __ASM_NAME("cxx_frame_handler") "\n\t"
687 "add $28,%esp\n\t"
688 __ASM_CFI(".cfi_adjust_cfa_offset -28\n\t")
689 "ret" )
690
691
692/*********************************************************************
693 * __CxxLongjmpUnwind (MSVCRT.@)
694 *
695 * Callback meant to be used as UnwindFunc for setjmp/longjmp.
696 */
697void __stdcall __CxxLongjmpUnwind( const _JUMP_BUFFER *buf )
698{
699 cxx_exception_frame *frame = (cxx_exception_frame *)buf->Registration;
700 const cxx_function_descr *descr = (const cxx_function_descr *)buf->UnwindData[0];
701
702 TRACE( "unwinding frame %p descr %p trylevel %ld\n", frame, descr, buf->TryLevel );
703 cxx_local_unwind( frame, descr, buf->TryLevel );
704}
705
706/*********************************************************************
707 * __CppXcptFilter (MSVCRT.@)
708 */
710{
711 /* only filter c++ exceptions */
713 return _XcptFilter( ex, ptr );
714}
715
716/*********************************************************************
717 * __CxxDetectRethrow (MSVCRT.@)
718 */
719BOOL CDECL __CxxDetectRethrow(PEXCEPTION_POINTERS ptrs)
720{
722
723 if (!ptrs)
724 return FALSE;
725
726 rec = ptrs->ExceptionRecord;
727
728 if (rec->ExceptionCode == CXX_EXCEPTION &&
729 rec->NumberParameters == 3 &&
731 rec->ExceptionInformation[2])
732 {
733 ptrs->ExceptionRecord = msvcrt_get_thread_data()->exc_record;
734 return TRUE;
735 }
736 return (msvcrt_get_thread_data()->exc_record == rec);
737}
738
739/*********************************************************************
740 * __CxxQueryExceptionSize (MSVCRT.@)
741 */
742unsigned int CDECL __CxxQueryExceptionSize(void)
743{
744 return sizeof(cxx_exception_type);
745}
746
747
748/*********************************************************************
749 * _EH_prolog (MSVCRT.@)
750 */
751
752/* Provided for VC++ binary compatibility only */
753__ASM_GLOBAL_FUNC(_EH_prolog,
754 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") /* skip ret addr */
755 "pushl $-1\n\t"
756 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
757 "pushl %eax\n\t"
758 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
759 "pushl %fs:0\n\t"
760 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
761 "movl %esp, %fs:0\n\t"
762 "movl 12(%esp), %eax\n\t"
763 "movl %ebp, 12(%esp)\n\t"
764 "leal 12(%esp), %ebp\n\t"
765 "pushl %eax\n\t"
766 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
767 "ret")
768
769static const SCOPETABLE_V4 *get_scopetable_v4( MSVCRT_EXCEPTION_FRAME *frame, ULONG_PTR cookie )
770{
771 return (const SCOPETABLE_V4 *)((ULONG_PTR)frame->scopetable ^ cookie);
772}
773
774static DWORD MSVCRT_nested_handler(PEXCEPTION_RECORD rec,
778{
781 *dispatch = frame;
783}
784
785static void msvcrt_local_unwind2(MSVCRT_EXCEPTION_FRAME* frame, int trylevel, void *ebp)
786{
788
789 TRACE("(%p,%d,%d)\n",frame, frame->trylevel, trylevel);
790
791 /* Register a handler in case of a nested exception */
792 reg.Handler = MSVCRT_nested_handler;
793 reg.Prev = NtCurrentTeb()->Tib.ExceptionList;
795
796 while (frame->trylevel != TRYLEVEL_END && frame->trylevel != trylevel)
797 {
798 int level = frame->trylevel;
799 frame->trylevel = frame->scopetable[level].previousTryLevel;
800 if (!frame->scopetable[level].lpfnFilter)
801 {
802 TRACE( "__try block cleanup level %d handler %p ebp %p\n",
803 level, frame->scopetable[level].lpfnHandler, ebp );
804 call_handler( frame->scopetable[level].lpfnHandler, ebp );
805 }
806 }
808 TRACE("unwound OK\n");
809}
810
811static void msvcrt_local_unwind4( ULONG *cookie, MSVCRT_EXCEPTION_FRAME* frame, int trylevel, void *ebp )
812{
814 const SCOPETABLE_V4 *scopetable = get_scopetable_v4( frame, *cookie );
815
816 TRACE("(%p,%d,%d)\n",frame, frame->trylevel, trylevel);
817
818 /* Register a handler in case of a nested exception */
819 reg.Handler = MSVCRT_nested_handler;
820 reg.Prev = NtCurrentTeb()->Tib.ExceptionList;
822
823 while (frame->trylevel != -2 && frame->trylevel != trylevel)
824 {
825 int level = frame->trylevel;
826 frame->trylevel = scopetable->entries[level].previousTryLevel;
827 if (!scopetable->entries[level].lpfnFilter)
828 {
829 TRACE( "__try block cleanup level %d handler %p ebp %p\n",
830 level, scopetable->entries[level].lpfnHandler, ebp );
831 call_handler( scopetable->entries[level].lpfnHandler, ebp );
832 }
833 }
835 TRACE("unwound OK\n");
836}
837#ifndef __REACTOS__
838/*******************************************************************
839 * _local_unwind2 (MSVCRT.@)
840 */
841void CDECL _local_unwind2(MSVCRT_EXCEPTION_FRAME* frame, int trylevel)
842{
843 msvcrt_local_unwind2( frame, trylevel, &frame->_ebp );
844}
845#endif
846/*******************************************************************
847 * _local_unwind4 (MSVCRT.@)
848 */
849void CDECL _local_unwind4( ULONG *cookie, MSVCRT_EXCEPTION_FRAME* frame, int trylevel )
850{
851 msvcrt_local_unwind4( cookie, frame, trylevel, &frame->_ebp );
852}
853
854#ifndef __REACTOS__
855/*******************************************************************
856 * _global_unwind2 (MSVCRT.@)
857 */
858void CDECL _global_unwind2(EXCEPTION_REGISTRATION_RECORD* frame)
859{
860 TRACE("(%p)\n",frame);
861 RtlUnwind( frame, 0, 0, 0 );
862}
863#else
864void CDECL _global_unwind2(EXCEPTION_REGISTRATION_RECORD* frame);
865#endif
866
867#ifndef __REACTOS__
868/*********************************************************************
869 * _except_handler2 (MSVCRT.@)
870 */
871int CDECL _except_handler2(PEXCEPTION_RECORD rec,
875{
876 FIXME("exception %x flags=%x at %p handler=%p %p %p stub\n",
878 frame->Handler, context, dispatcher);
880}
881
882/*********************************************************************
883 * _except_handler3 (MSVCRT.@)
884 */
885int CDECL _except_handler3(PEXCEPTION_RECORD rec,
886 MSVCRT_EXCEPTION_FRAME* frame,
887 PCONTEXT context, void* dispatcher)
888{
889 int retval, trylevel;
890 EXCEPTION_POINTERS exceptPtrs;
891 PSCOPETABLE pScopeTable;
892
893 TRACE("exception %x flags=%x at %p handler=%p %p %p semi-stub\n",
895 frame->handler, context, dispatcher);
896
897#ifdef _MSC_VER
898 __asm{ cld }
899#else
900 __asm__ __volatile__("cld");
901#endif
903 {
904 /* Unwinding the current frame */
905 msvcrt_local_unwind2(frame, TRYLEVEL_END, &frame->_ebp);
906 TRACE("unwound current frame, returning ExceptionContinueSearch\n");
908 }
909 else
910 {
911 /* Hunting for handler */
912 exceptPtrs.ExceptionRecord = rec;
913 exceptPtrs.ContextRecord = context;
914 *((DWORD *)frame-1) = (DWORD)&exceptPtrs;
915 trylevel = frame->trylevel;
916 pScopeTable = frame->scopetable;
917
918 while (trylevel != TRYLEVEL_END)
919 {
920 TRACE( "level %d prev %d filter %p\n", trylevel, pScopeTable[trylevel].previousTryLevel,
921 pScopeTable[trylevel].lpfnFilter );
922 if (pScopeTable[trylevel].lpfnFilter)
923 {
924 retval = call_filter( pScopeTable[trylevel].lpfnFilter, &exceptPtrs, &frame->_ebp );
925
926 TRACE("filter returned %s\n", retval == EXCEPTION_CONTINUE_EXECUTION ?
927 "CONTINUE_EXECUTION" : retval == EXCEPTION_EXECUTE_HANDLER ?
928 "EXECUTE_HANDLER" : "CONTINUE_SEARCH");
929
932
934 {
935 /* Unwind all higher frames, this one will handle the exception */
936 _global_unwind2((EXCEPTION_REGISTRATION_RECORD*)frame);
937 msvcrt_local_unwind2(frame, trylevel, &frame->_ebp);
938
939 /* Set our trylevel to the enclosing block, and call the __finally
940 * code, which won't return
941 */
942 frame->trylevel = pScopeTable[trylevel].previousTryLevel;
943 TRACE("__finally block %p\n",pScopeTable[trylevel].lpfnHandler);
944 call_finally_block(pScopeTable[trylevel].lpfnHandler, &frame->_ebp);
945 }
946 }
947 trylevel = pScopeTable[trylevel].previousTryLevel;
948 }
949 }
950 TRACE("reached TRYLEVEL_END, returning ExceptionContinueSearch\n");
952}
953#endif /* __REACTOS__ */
954/*********************************************************************
955 * _except_handler4_common (MSVCRT.@)
956 */
957int CDECL _except_handler4_common( ULONG *cookie, void (*check_cookie)(void),
958 EXCEPTION_RECORD *rec, MSVCRT_EXCEPTION_FRAME *frame,
960{
961 int retval, trylevel;
962 EXCEPTION_POINTERS exceptPtrs;
963 const SCOPETABLE_V4 *scope_table = get_scopetable_v4( frame, *cookie );
964
965 TRACE( "exception %x flags=%x at %p handler=%p %p %p cookie=%x scope table=%p cookies=%d/%x,%d/%x\n",
967 frame->handler, context, dispatcher, *cookie, scope_table,
968 scope_table->gs_cookie_offset, scope_table->gs_cookie_xor,
969 scope_table->eh_cookie_offset, scope_table->eh_cookie_xor );
970
971 /* FIXME: no cookie validation yet */
972
974 {
975 /* Unwinding the current frame */
976 msvcrt_local_unwind4( cookie, frame, -2, &frame->_ebp );
977 TRACE("unwound current frame, returning ExceptionContinueSearch\n");
979 }
980 else
981 {
982 /* Hunting for handler */
983 exceptPtrs.ExceptionRecord = rec;
984 exceptPtrs.ContextRecord = context;
985 *((DWORD *)frame-1) = (DWORD)&exceptPtrs;
986 trylevel = frame->trylevel;
987
988 while (trylevel != -2)
989 {
990 TRACE( "level %d prev %d filter %p\n", trylevel,
991 scope_table->entries[trylevel].previousTryLevel,
992 scope_table->entries[trylevel].lpfnFilter );
993 if (scope_table->entries[trylevel].lpfnFilter)
994 {
995 retval = call_filter( scope_table->entries[trylevel].lpfnFilter, &exceptPtrs, &frame->_ebp );
996
997 TRACE("filter returned %s\n", retval == EXCEPTION_CONTINUE_EXECUTION ?
998 "CONTINUE_EXECUTION" : retval == EXCEPTION_EXECUTE_HANDLER ?
999 "EXECUTE_HANDLER" : "CONTINUE_SEARCH");
1000
1003
1005 {
1007
1008 /* Unwind all higher frames, this one will handle the exception */
1009 _global_unwind2((EXCEPTION_REGISTRATION_RECORD*)frame);
1010 msvcrt_local_unwind4( cookie, frame, trylevel, &frame->_ebp );
1011
1012 /* Set our trylevel to the enclosing block, and call the __finally
1013 * code, which won't return
1014 */
1015 frame->trylevel = scope_table->entries[trylevel].previousTryLevel;
1016 TRACE("__finally block %p\n",scope_table->entries[trylevel].lpfnHandler);
1017 call_finally_block(scope_table->entries[trylevel].lpfnHandler, &frame->_ebp);
1018 }
1019 }
1020 trylevel = scope_table->entries[trylevel].previousTryLevel;
1021 }
1022 }
1023 TRACE("reached -2, returning ExceptionContinueSearch\n");
1025}
1026
1027
1028/*
1029 * setjmp/longjmp implementation
1030 */
1031
1032#define MSVCRT_JMP_MAGIC 0x56433230 /* ID value for new jump structure */
1033typedef void (__stdcall *MSVCRT_unwind_function)(const _JUMP_BUFFER *);
1034
1035/* define an entrypoint for setjmp/setjmp3 that stores the registers in the jmp buf */
1036/* and then jumps to the C backend function */
1037#define DEFINE_SETJMP_ENTRYPOINT(name) \
1038 __ASM_GLOBAL_FUNC( name, \
1039 "movl 4(%esp),%ecx\n\t" /* jmp_buf */ \
1040 "movl %ebp,0(%ecx)\n\t" /* jmp_buf.Ebp */ \
1041 "movl %ebx,4(%ecx)\n\t" /* jmp_buf.Ebx */ \
1042 "movl %edi,8(%ecx)\n\t" /* jmp_buf.Edi */ \
1043 "movl %esi,12(%ecx)\n\t" /* jmp_buf.Esi */ \
1044 "movl %esp,16(%ecx)\n\t" /* jmp_buf.Esp */ \
1045 "movl 0(%esp),%eax\n\t" \
1046 "movl %eax,20(%ecx)\n\t" /* jmp_buf.Eip */ \
1047 "jmp " __ASM_NAME("__regs_") # name )
1048
1049/*******************************************************************
1050 * _setjmp (MSVCRT.@)
1051 */
1052DEFINE_SETJMP_ENTRYPOINT(MSVCRT__setjmp)
1053int CDECL DECLSPEC_HIDDEN __regs_MSVCRT__setjmp(_JUMP_BUFFER *jmp)
1054{
1055 jmp->Registration = (unsigned long)NtCurrentTeb()->Tib.ExceptionList;
1056 if (jmp->Registration == ~0UL)
1057 jmp->TryLevel = TRYLEVEL_END;
1058 else
1059 jmp->TryLevel = ((MSVCRT_EXCEPTION_FRAME*)jmp->Registration)->trylevel;
1060
1061 TRACE("buf=%p ebx=%08lx esi=%08lx edi=%08lx ebp=%08lx esp=%08lx eip=%08lx frame=%08lx\n",
1062 jmp, jmp->Ebx, jmp->Esi, jmp->Edi, jmp->Ebp, jmp->Esp, jmp->Eip, jmp->Registration );
1063 return 0;
1064}
1065
1066/*******************************************************************
1067 * _setjmp3 (MSVCRT.@)
1068 */
1069DEFINE_SETJMP_ENTRYPOINT( MSVCRT__setjmp3 )
1070int WINAPIV DECLSPEC_HIDDEN __regs_MSVCRT__setjmp3(_JUMP_BUFFER *jmp, int nb_args, ...)
1071{
1072 jmp->Cookie = MSVCRT_JMP_MAGIC;
1073 jmp->UnwindFunc = 0;
1074 jmp->Registration = (unsigned long)NtCurrentTeb()->Tib.ExceptionList;
1075 if (jmp->Registration == ~0UL)
1076 {
1077 jmp->TryLevel = TRYLEVEL_END;
1078 }
1079 else
1080 {
1081 int i;
1082 va_list args;
1083
1084 va_start( args, nb_args );
1085 if (nb_args > 0) jmp->UnwindFunc = va_arg( args, unsigned long );
1086 if (nb_args > 1) jmp->TryLevel = va_arg( args, unsigned long );
1087 else jmp->TryLevel = ((MSVCRT_EXCEPTION_FRAME*)jmp->Registration)->trylevel;
1088 for (i = 0; i < 6 && i < nb_args - 2; i++)
1089 jmp->UnwindData[i] = va_arg( args, unsigned long );
1090 va_end( args );
1091 }
1092
1093 TRACE("buf=%p ebx=%08lx esi=%08lx edi=%08lx ebp=%08lx esp=%08lx eip=%08lx frame=%08lx\n",
1094 jmp, jmp->Ebx, jmp->Esi, jmp->Edi, jmp->Ebp, jmp->Esp, jmp->Eip, jmp->Registration );
1095 return 0;
1096}
1097
1098/*********************************************************************
1099 * longjmp (MSVCRT.@)
1100 */
1101void CDECL MSVCRT_longjmp(_JUMP_BUFFER *jmp, int retval)
1102{
1103 unsigned long cur_frame = 0;
1104
1105 TRACE("buf=%p ebx=%08lx esi=%08lx edi=%08lx ebp=%08lx esp=%08lx eip=%08lx frame=%08lx retval=%08x\n",
1106 jmp, jmp->Ebx, jmp->Esi, jmp->Edi, jmp->Ebp, jmp->Esp, jmp->Eip, jmp->Registration, retval );
1107
1108 cur_frame=(unsigned long)NtCurrentTeb()->Tib.ExceptionList;
1109 TRACE("cur_frame=%lx\n",cur_frame);
1110
1111 if (cur_frame != jmp->Registration)
1112 _global_unwind2((EXCEPTION_REGISTRATION_RECORD*)jmp->Registration);
1113
1114 if (jmp->Registration)
1115 {
1116 if (IsBadReadPtr(&jmp->Cookie, sizeof(long)) || jmp->Cookie != MSVCRT_JMP_MAGIC)
1117 {
1118 msvcrt_local_unwind2((MSVCRT_EXCEPTION_FRAME*)jmp->Registration,
1119 jmp->TryLevel, (void *)jmp->Ebp);
1120 }
1121 else if(jmp->UnwindFunc)
1122 {
1123 MSVCRT_unwind_function unwind_func;
1124
1125 unwind_func=(MSVCRT_unwind_function)jmp->UnwindFunc;
1126 unwind_func(jmp);
1127 }
1128 }
1129
1130 if (!retval)
1131 retval = 1;
1132
1133 __wine_longjmp( (__wine_jmp_buf *)jmp, retval );
1134}
1135
1136/*********************************************************************
1137 * _seh_longjmp_unwind (MSVCRT.@)
1138 */
1139void __stdcall _seh_longjmp_unwind(_JUMP_BUFFER *jmp)
1140{
1141 msvcrt_local_unwind2( (MSVCRT_EXCEPTION_FRAME *)jmp->Registration, jmp->TryLevel, (void *)jmp->Ebp );
1142}
1143
1144/*********************************************************************
1145 * _seh_longjmp_unwind4 (MSVCRT.@)
1146 */
1147void __stdcall _seh_longjmp_unwind4(_JUMP_BUFFER *jmp)
1148{
1149 msvcrt_local_unwind4( (ULONG *)&jmp->Cookie, (MSVCRT_EXCEPTION_FRAME *)jmp->Registration,
1150 jmp->TryLevel, (void *)jmp->Ebp );
1151}
1152
1153/*********************************************************************
1154 * _fpieee_flt (MSVCRT.@)
1155 */
1158{
1160 _FPIEEE_RECORD rec;
1161 int ret;
1162
1163 TRACE("(%lx %p %p)\n", exception_code, ep, handler);
1164
1165 switch(exception_code) {
1171 break;
1172 default:
1174 }
1175
1176 memset(&rec, 0, sizeof(rec));
1177 rec.RoundingMode = ctx->ControlWord >> 10;
1178 switch((ctx->ControlWord >> 8) & 0x3) {
1179 case 0: rec.Precision = 2; break;
1180 case 1: rec.Precision = 3; break;
1181 case 2: rec.Precision = 1; break;
1182 case 3: rec.Precision = 0; break;
1183 }
1184 rec.Status.InvalidOperation = ctx->StatusWord & 0x1;
1185 rec.Status.ZeroDivide = ((ctx->StatusWord & 0x4) != 0);
1186 rec.Status.Overflow = ((ctx->StatusWord & 0x8) != 0);
1187 rec.Status.Underflow = ((ctx->StatusWord & 0x10) != 0);
1188 rec.Status.Inexact = ((ctx->StatusWord & 0x20) != 0);
1189 rec.Enable.InvalidOperation = ((ctx->ControlWord & 0x1) == 0);
1190 rec.Enable.ZeroDivide = ((ctx->ControlWord & 0x4) == 0);
1191 rec.Enable.Overflow = ((ctx->ControlWord & 0x8) == 0);
1192 rec.Enable.Underflow = ((ctx->ControlWord & 0x10) == 0);
1193 rec.Enable.Inexact = ((ctx->ControlWord & 0x20) == 0);
1196 rec.Cause.Overflow = rec.Enable.Overflow & rec.Status.Overflow;
1198 rec.Cause.Inexact = rec.Enable.Inexact & rec.Status.Inexact;
1199
1200 TRACE("opcode: %x\n", *(ULONG*)ep->ContextRecord->FloatSave.ErrorOffset);
1201
1202 if(*(WORD*)ctx->ErrorOffset == 0x35dc) { /* fdiv m64fp */
1204 rec.Operand1.OperandValid = 1;
1205 rec.Result.OperandValid = 0;
1206 } else {
1207 rec.Operand1.OperandValid = 0;
1208 rec.Result.OperandValid = 1;
1209 }
1210 rec.Operand2.OperandValid = 1;
1213 memcpy(&rec.Operand1.Value.Fp80Value, ctx->RegisterArea, sizeof(rec.Operand1.Value.Fp80Value));
1215 rec.Operand2.Value.Fp64Value = *(double*)ctx->DataOffset;
1217 memcpy(&rec.Result.Value.Fp80Value, ctx->RegisterArea, sizeof(rec.Operand1.Value.Fp80Value));
1218
1219 ret = handler(&rec);
1220
1222 memcpy(ctx->RegisterArea, &rec.Result.Value.Fp80Value, sizeof(rec.Operand1.Value.Fp80Value));
1223 return ret;
1224 }
1225
1226 FIXME("unsupported opcode: %x\n", *(ULONG*)ep->ContextRecord->FloatSave.ErrorOffset);
1228}
1229
1230#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: precomp.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
@ _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 *))
#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:7512
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
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
int CDECL _XcptFilter(NTSTATUS, PEXCEPTION_POINTERS)
Definition: except.c:278
#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 EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define exception_code
Definition: excpt.h:84
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:91
#define EXCEPTION_CONTINUE_EXECUTION
Definition: excpt.h:92
#define NtCurrentTeb
void MSVCRT() terminate()
Definition: cpp.c:716
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
UINT WINAPI nested(MSIHANDLE hinst)
Definition: custom.c:565
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:935
#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" "\tsub %rbp, %rax\n" "\tpush %rbp\n" "\t.seh_pushreg %rbp\n" "\tsub $32, %rsp\n" "\t.seh_stackalloc 32\n" "\t.seh_endprologue\n" "\tsub %rax, %rdx\n" "\tmov %rdx, %rbp\n" "\tjmp *%r8\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:15
static EXCEPTION_REGISTRATION_RECORD * __wine_push_frame(EXCEPTION_REGISTRATION_RECORD *frame)
Definition: exception.h:90
#define __EXCEPT_CTX(func, ctx)
Definition: exception.h:60
#define EH_UNWINDING
Definition: exception.h:14
static EXCEPTION_REGISTRATION_RECORD * __wine_pop_frame(EXCEPTION_REGISTRATION_RECORD *frame)
Definition: exception.h:104
#define WINAPIV
Definition: sdbpapi.h:64
void CDECL __DestructExceptionObject(EXCEPTION_RECORD *rec)
Definition: except.c:409
frame_info *CDECL _CreateFrameInfo(frame_info *fi, void *obj)
Definition: except.c:348
void CDECL __CxxUnregisterExceptionObject(cxx_frame_info *frame_info, BOOL in_use)
Definition: except.c:468
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::@1897 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:164
#define __stdcall
Definition: typedefs.h:25
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
int ret
int retval
Definition: wcstombs.cpp:91
#define FUNC_DESCR_NOEXCEPT
Definition: cppexcept.h:32
static void dump_type(type_t *t)
Definition: write_msft.c:1037
struct _EXCEPTION_POINTERS * PEXCEPTION_POINTERS
#define const
Definition: zconf.h:233