ReactOS 0.4.16-dev-527-gdad3a09
except_x86_64.c
Go to the documentation of this file.
1/*
2 * msvcrt C++ exception handling
3 *
4 * Copyright 2011 Alexandre Julliard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#ifdef __x86_64__
22
23#include <setjmp.h>
24#include <stdarg.h>
25#include <fpieee.h>
26
27#include "ntstatus.h"
28#define WIN32_NO_STATUS
29#include "windef.h"
30#include "winbase.h"
31#include "winternl.h"
32#include "msvcrt.h"
33#include "wine/exception.h"
34#include "excpt.h"
35#include "wine/debug.h"
36
37#include "cppexcept.h"
38
40
41typedef struct
42{
43 int prev;
46
47typedef struct
48{
49 UINT flags;
51 int offset;
53 UINT frame;
55#define TYPE_FLAG_CONST 1
56#define TYPE_FLAG_VOLATILE 2
57#define TYPE_FLAG_REFERENCE 8
58
59typedef struct
60{
61 int start_level;
62 int end_level;
63 int catch_level;
64 int catchblock_count;
65 UINT catchblock;
67
68typedef struct
69{
70 int ip;
71 int state;
72} ipmap_info;
73
74typedef struct __cxx_function_descr
75{
76 UINT magic;
82 UINT ipmap;
83 UINT unwind_help;
85 UINT flags;
87
88typedef struct
89{
91 BOOL rethrow;
92 EXCEPTION_RECORD *prev_rec;
93} cxx_catch_ctx;
94
95typedef struct
96{
97 ULONG64 dest_frame;
98 ULONG64 orig_frame;
99 EXCEPTION_RECORD *seh_rec;
102} se_translator_ctx;
103
104static inline void* rva_to_ptr(UINT rva, ULONG64 base)
105{
106 return rva ? (void*)(base+rva) : NULL;
107}
108
109static inline void dump_type(UINT type_rva, ULONG64 base)
110{
111 const cxx_type_info *type = rva_to_ptr(type_rva, base);
112
113 TRACE("flags %x type %x %s offsets %d,%d,%d size %d copy ctor %x(%p)\n",
114 type->flags, type->type_info, dbgstr_type_info(rva_to_ptr(type->type_info, base)),
115 type->offsets.this_offset, type->offsets.vbase_descr, type->offsets.vbase_offset,
116 type->size, type->copy_ctor, rva_to_ptr(type->copy_ctor, base));
117}
118
119static void dump_exception_type(const cxx_exception_type *type, ULONG64 base)
120{
121 const cxx_type_info_table *type_info_table = rva_to_ptr(type->type_info_table, base);
122 UINT i;
123
124 TRACE("flags %x destr %x(%p) handler %x(%p) type info %x(%p)\n",
125 type->flags, type->destructor, rva_to_ptr(type->destructor, base),
126 type->custom_handler, rva_to_ptr(type->custom_handler, base),
127 type->type_info_table, type_info_table);
128 for (i = 0; i < type_info_table->count; i++)
129 {
130 TRACE(" %d: ", i);
131 dump_type(type_info_table->info[i], base);
132 }
133}
134
135static void dump_function_descr(const cxx_function_descr *descr, ULONG64 image_base)
136{
137 unwind_info *unwind_table = rva_to_ptr(descr->unwind_table, image_base);
138 tryblock_info *tryblock = rva_to_ptr(descr->tryblock, image_base);
139 ipmap_info *ipmap = rva_to_ptr(descr->ipmap, image_base);
140 UINT i, j;
141
142 TRACE("magic %x\n", descr->magic);
143 TRACE("unwind table: %x(%p) %d\n", descr->unwind_table, unwind_table, descr->unwind_count);
144 for (i=0; i<descr->unwind_count; i++)
145 {
146 TRACE(" %d: prev %d func %x(%p)\n", i, unwind_table[i].prev,
147 unwind_table[i].handler, rva_to_ptr(unwind_table[i].handler, image_base));
148 }
149 TRACE("try table: %x(%p) %d\n", descr->tryblock, tryblock, descr->tryblock_count);
150 for (i=0; i<descr->tryblock_count; i++)
151 {
152 catchblock_info *catchblock = rva_to_ptr(tryblock[i].catchblock, image_base);
153
154 TRACE(" %d: start %d end %d catchlevel %d catch %x(%p) %d\n", i,
155 tryblock[i].start_level, tryblock[i].end_level,
156 tryblock[i].catch_level, tryblock[i].catchblock,
157 catchblock, tryblock[i].catchblock_count);
158 for (j=0; j<tryblock[i].catchblock_count; j++)
159 {
160 TRACE(" %d: flags %x offset %d handler %x(%p) frame %x type %x %s\n",
161 j, catchblock[j].flags, catchblock[j].offset, catchblock[j].handler,
162 rva_to_ptr(catchblock[j].handler, image_base), catchblock[j].frame,
163 catchblock[j].type_info,
165 }
166 }
167 TRACE("ipmap: %x(%p) %d\n", descr->ipmap, ipmap, descr->ipmap_count);
168 for (i=0; i<descr->ipmap_count; i++)
169 {
170 TRACE(" %d: ip %x state %d\n", i, ipmap[i].ip, ipmap[i].state);
171 }
172 TRACE("unwind_help %d\n", descr->unwind_help);
173 if (descr->magic <= CXX_FRAME_MAGIC_VC6) return;
174 TRACE("expect list: %x\n", descr->expect_list);
175 if (descr->magic <= CXX_FRAME_MAGIC_VC7) return;
176 TRACE("flags: %08x\n", descr->flags);
177}
178
179static inline int ip_to_state(ipmap_info *ipmap, UINT count, int ip)
180{
181 UINT low = 0, high = count-1, med;
182
183 while (low < high) {
184 med = low + (high-low)/2;
185
186 if (ipmap[med].ip <= ip && ipmap[med+1].ip > ip)
187 {
188 low = med;
189 break;
190 }
191 if (ipmap[med].ip < ip) low = med+1;
192 else high = med-1;
193 }
194
195 TRACE("%x -> %d\n", ip, ipmap[low].state);
196 return ipmap[low].state;
197}
198
199/* check if the exception type is caught by a given catch block, and return the type that matched */
200static const cxx_type_info *find_caught_type(cxx_exception_type *exc_type, ULONG64 exc_base,
201 const type_info *catch_ti, UINT catch_flags)
202{
203 const cxx_type_info_table *type_info_table = rva_to_ptr(exc_type->type_info_table, exc_base);
204 UINT i;
205
206 for (i = 0; i < type_info_table->count; i++)
207 {
208 const cxx_type_info *type = rva_to_ptr(type_info_table->info[i], exc_base);
209 const type_info *ti = rva_to_ptr(type->type_info, exc_base);
210
211 if (!catch_ti) return type; /* catch(...) matches any type */
212 if (catch_ti != ti)
213 {
214 if (strcmp( catch_ti->mangled, ti->mangled )) continue;
215 }
216 /* type is the same, now check the flags */
217 if ((exc_type->flags & TYPE_FLAG_CONST) &&
218 !(catch_flags & TYPE_FLAG_CONST)) continue;
219 if ((exc_type->flags & TYPE_FLAG_VOLATILE) &&
220 !(catch_flags & TYPE_FLAG_VOLATILE)) continue;
221 return type; /* it matched */
222 }
223 return NULL;
224}
225
226static inline void copy_exception(void *object, ULONG64 frame,
228 const catchblock_info *catchblock,
229 const cxx_type_info *type, ULONG64 exc_base)
230{
231 const type_info *catch_ti = rva_to_ptr(catchblock->type_info, dispatch->ImageBase);
232 void **dest = rva_to_ptr(catchblock->offset, frame);
233
234 if (!catch_ti || !catch_ti->mangled[0]) return;
235 if (!catchblock->offset) return;
236
237 if (catchblock->flags & TYPE_FLAG_REFERENCE)
238 {
239 *dest = get_this_pointer(&type->offsets, object);
240 }
241 else if (type->flags & CLASS_IS_SIMPLE_TYPE)
242 {
243 memmove(dest, object, type->size);
244 /* if it is a pointer, adjust it */
245 if (type->size == sizeof(void*)) *dest = get_this_pointer(&type->offsets, *dest);
246 }
247 else /* copy the object */
248 {
249 if (type->copy_ctor)
250 {
252 {
253 void (__cdecl *copy_ctor)(void*, void*, int) =
254 rva_to_ptr(type->copy_ctor, exc_base);
255 copy_ctor(dest, get_this_pointer(&type->offsets, object), 1);
256 }
257 else
258 {
259 void (__cdecl *copy_ctor)(void*, void*) =
260 rva_to_ptr(type->copy_ctor, exc_base);
261 copy_ctor(dest, get_this_pointer(&type->offsets, object));
262 }
263 }
264 else
265 memmove(dest, get_this_pointer(&type->offsets,object), type->size);
266 }
267}
268
269static void cxx_local_unwind(ULONG64 frame, DISPATCHER_CONTEXT *dispatch,
270 const cxx_function_descr *descr, int last_level)
271{
272 const unwind_info *unwind_table = rva_to_ptr(descr->unwind_table, dispatch->ImageBase);
273 void (__cdecl *handler)(ULONG64 unk, ULONG64 rbp);
274 int *unwind_help = rva_to_ptr(descr->unwind_help, frame);
275 int trylevel;
276
277 if (unwind_help[0] == -2)
278 {
279 trylevel = ip_to_state(rva_to_ptr(descr->ipmap, dispatch->ImageBase),
280 descr->ipmap_count, dispatch->ControlPc-dispatch->ImageBase);
281 }
282 else
283 {
284 trylevel = unwind_help[0];
285 }
286
287 TRACE("current level: %d, last level: %d\n", trylevel, last_level);
288 while (trylevel > last_level)
289 {
290 if (trylevel<0 || trylevel>=descr->unwind_count)
291 {
292 ERR("invalid trylevel %d\n", trylevel);
293 terminate();
294 }
295 handler = rva_to_ptr(unwind_table[trylevel].handler, dispatch->ImageBase);
296 if (handler)
297 {
298 TRACE("handler: %p\n", handler);
299 handler(0, frame);
300 }
301 trylevel = unwind_table[trylevel].prev;
302 }
303 unwind_help[0] = trylevel;
304}
305
306static LONG CALLBACK cxx_rethrow_filter(PEXCEPTION_POINTERS eptrs, void *c)
307{
308 EXCEPTION_RECORD *rec = eptrs->ExceptionRecord;
309 cxx_catch_ctx *ctx = c;
310
311 if (rec->ExceptionCode != CXX_EXCEPTION)
313 if (!rec->ExceptionInformation[1] && !rec->ExceptionInformation[2])
315 if (rec->ExceptionInformation[1] == ctx->prev_rec->ExceptionInformation[1])
316 ctx->rethrow = TRUE;
318}
319
320static void CALLBACK cxx_catch_cleanup(BOOL normal, void *c)
321{
322 cxx_catch_ctx *ctx = c;
323 __CxxUnregisterExceptionObject(&ctx->frame_info, ctx->rethrow);
324}
325
326static void* WINAPI call_catch_block(EXCEPTION_RECORD *rec)
327{
328 ULONG64 frame = rec->ExceptionInformation[1];
329 const cxx_function_descr *descr = (void*)rec->ExceptionInformation[2];
330 EXCEPTION_RECORD *prev_rec = (void*)rec->ExceptionInformation[4];
331 EXCEPTION_RECORD *untrans_rec = (void*)rec->ExceptionInformation[6];
332 CONTEXT *context = (void*)rec->ExceptionInformation[7];
333 void* (__cdecl *handler)(ULONG64 unk, ULONG64 rbp) = (void*)rec->ExceptionInformation[5];
334 int *unwind_help = rva_to_ptr(descr->unwind_help, frame);
335 EXCEPTION_POINTERS ep = { prev_rec, context };
336 cxx_catch_ctx ctx;
337 void *ret_addr = NULL;
338
339 TRACE("calling handler %p\n", handler);
340
341 ctx.rethrow = FALSE;
342 ctx.prev_rec = prev_rec;
343 __CxxRegisterExceptionObject(&ep, &ctx.frame_info);
344 msvcrt_get_thread_data()->processing_throw--;
345 __TRY
346 {
347 __TRY
348 {
349 ret_addr = handler(0, frame);
350 }
351 __EXCEPT_CTX(cxx_rethrow_filter, &ctx)
352 {
353 TRACE("detect rethrow: exception code: %x\n", prev_rec->ExceptionCode);
354 ctx.rethrow = TRUE;
355
356 if (untrans_rec)
357 {
359 RaiseException(untrans_rec->ExceptionCode, untrans_rec->ExceptionFlags,
360 untrans_rec->NumberParameters, untrans_rec->ExceptionInformation);
361 }
362 else
363 {
364 RaiseException(prev_rec->ExceptionCode, prev_rec->ExceptionFlags,
365 prev_rec->NumberParameters, prev_rec->ExceptionInformation);
366 }
367 }
369 }
370 __FINALLY_CTX(cxx_catch_cleanup, &ctx)
371
372 unwind_help[0] = -2;
373 unwind_help[1] = -1;
374 return ret_addr;
375}
376
377static inline BOOL cxx_is_consolidate(const EXCEPTION_RECORD *rec)
378{
380 rec->ExceptionInformation[0]==(ULONG_PTR)call_catch_block;
381}
382
383static inline void find_catch_block(EXCEPTION_RECORD *rec, CONTEXT *context,
384 EXCEPTION_RECORD *untrans_rec,
387 cxx_exception_type *info, ULONG64 orig_frame)
388{
389 ULONG64 exc_base = (rec->NumberParameters == 4 ? rec->ExceptionInformation[3] : 0);
390 int trylevel = ip_to_state(rva_to_ptr(descr->ipmap, dispatch->ImageBase),
391 descr->ipmap_count, dispatch->ControlPc-dispatch->ImageBase);
393 const tryblock_info *in_catch;
394 EXCEPTION_RECORD catch_record;
395 CONTEXT ctx;
396 UINT i, j;
397 INT *unwind_help;
398
399 data->processing_throw++;
400 for (i=descr->tryblock_count; i>0; i--)
401 {
402 in_catch = rva_to_ptr(descr->tryblock, dispatch->ImageBase);
403 in_catch = &in_catch[i-1];
404
405 if (trylevel>in_catch->end_level && trylevel<=in_catch->catch_level)
406 break;
407 }
408 if (!i)
409 in_catch = NULL;
410
411 unwind_help = rva_to_ptr(descr->unwind_help, orig_frame);
412 if (trylevel > unwind_help[1])
413 unwind_help[0] = unwind_help[1] = trylevel;
414 else
415 trylevel = unwind_help[1];
416 TRACE("current trylevel: %d\n", trylevel);
417
418 for (i=0; i<descr->tryblock_count; i++)
419 {
420 const tryblock_info *tryblock = rva_to_ptr(descr->tryblock, dispatch->ImageBase);
421 tryblock = &tryblock[i];
422
423 if (trylevel < tryblock->start_level) continue;
424 if (trylevel > tryblock->end_level) continue;
425
426 if (in_catch)
427 {
428 if(tryblock->start_level <= in_catch->end_level) continue;
429 if(tryblock->end_level > in_catch->catch_level) continue;
430 }
431
432 /* got a try block */
433 for (j=0; j<tryblock->catchblock_count; j++)
434 {
435 const catchblock_info *catchblock = rva_to_ptr(tryblock->catchblock, dispatch->ImageBase);
436 catchblock = &catchblock[j];
437
438 if (info)
439 {
440 const cxx_type_info *type = find_caught_type(info, exc_base,
441 rva_to_ptr(catchblock->type_info, dispatch->ImageBase),
442 catchblock->flags);
443 if (!type) continue;
444
445 TRACE("matched type %p in tryblock %d catchblock %d\n", type, i, j);
446
447 /* copy the exception to its destination on the stack */
448 copy_exception((void*)rec->ExceptionInformation[1],
449 orig_frame, dispatch, catchblock, type, exc_base);
450 }
451 else
452 {
453 /* no CXX_EXCEPTION only proceed with a catch(...) block*/
454 if (catchblock->type_info)
455 continue;
456 TRACE("found catch(...) block\n");
457 }
458
459 /* unwind stack and call catch */
460 memset(&catch_record, 0, sizeof(catch_record));
463 catch_record.NumberParameters = 8;
464 catch_record.ExceptionInformation[0] = (ULONG_PTR)call_catch_block;
465 catch_record.ExceptionInformation[1] = orig_frame;
466 catch_record.ExceptionInformation[2] = (ULONG_PTR)descr;
467 catch_record.ExceptionInformation[3] = tryblock->start_level;
468 catch_record.ExceptionInformation[4] = (ULONG_PTR)rec;
469 catch_record.ExceptionInformation[5] =
470 (ULONG_PTR)rva_to_ptr(catchblock->handler, dispatch->ImageBase);
471 catch_record.ExceptionInformation[6] = (ULONG_PTR)untrans_rec;
472 catch_record.ExceptionInformation[7] = (ULONG_PTR)context;
473 RtlUnwindEx((void*)frame, (void*)dispatch->ControlPc, &catch_record, NULL, &ctx, NULL);
474 }
475 }
476
477 TRACE("no matching catch block found\n");
478 data->processing_throw--;
479}
480
481static LONG CALLBACK se_translation_filter(EXCEPTION_POINTERS *ep, void *c)
482{
483 se_translator_ctx *ctx = (se_translator_ctx *)c;
485 cxx_exception_type *exc_type;
486
487 if (rec->ExceptionCode != CXX_EXCEPTION)
488 {
489 TRACE("non-c++ exception thrown in SEH handler: %x\n", rec->ExceptionCode);
490 terminate();
491 }
492
493 exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
494 find_catch_block(rec, ep->ContextRecord, ctx->seh_rec, ctx->dest_frame, ctx->dispatch,
495 ctx->descr, exc_type, ctx->orig_frame);
496
499}
500
501static void check_noexcept( PEXCEPTION_RECORD rec,
503{
504 if (!nested && rec->ExceptionCode == CXX_EXCEPTION &&
505 descr->magic >= CXX_FRAME_MAGIC_VC8 &&
506 (descr->flags & FUNC_DESCR_NOEXCEPT))
507 {
508 ERR("noexcept function propagating exception\n");
509 terminate();
510 }
511}
512
513static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame,
516{
517 int trylevel = ip_to_state(rva_to_ptr(descr->ipmap, dispatch->ImageBase),
518 descr->ipmap_count, dispatch->ControlPc-dispatch->ImageBase);
519 cxx_exception_type *exc_type;
520 ULONG64 orig_frame = frame;
521 ULONG64 throw_base;
522 DWORD throw_func_off;
523 void *throw_func;
524 UINT i, j;
525 int unwindlevel = -1;
526
528 {
529 FIXME("unhandled frame magic %x\n", descr->magic);
531 }
532
533 if (descr->magic >= CXX_FRAME_MAGIC_VC8 &&
534 (descr->flags & FUNC_DESCR_SYNCHRONOUS) &&
535 (rec->ExceptionCode != CXX_EXCEPTION &&
536 !cxx_is_consolidate(rec) &&
538 return ExceptionContinueSearch; /* handle only c++ exceptions */
539
540 /* update orig_frame if it's a nested exception */
541 throw_func_off = RtlLookupFunctionEntry(dispatch->ControlPc, &throw_base, NULL)->BeginAddress;
542 throw_func = rva_to_ptr(throw_func_off, throw_base);
543 TRACE("reconstructed handler pointer: %p\n", throw_func);
544 for (i=descr->tryblock_count; i>0; i--)
545 {
546 const tryblock_info *tryblock = rva_to_ptr(descr->tryblock, dispatch->ImageBase);
547 tryblock = &tryblock[i-1];
548
549 if (trylevel>tryblock->end_level && trylevel<=tryblock->catch_level)
550 {
551 for (j=0; j<tryblock->catchblock_count; j++)
552 {
553 const catchblock_info *catchblock = rva_to_ptr(tryblock->catchblock, dispatch->ImageBase);
554 catchblock = &catchblock[j];
555
556 if (rva_to_ptr(catchblock->handler, dispatch->ImageBase) == throw_func)
557 {
558 TRACE("nested exception detected\n");
559 unwindlevel = tryblock->end_level;
560 orig_frame = *(ULONG64*)rva_to_ptr(catchblock->frame, frame);
561 TRACE("setting orig_frame to %lx\n", orig_frame);
562 }
563 }
564 }
565 }
566
568 {
570 cxx_local_unwind(orig_frame, dispatch, descr,
571 cxx_is_consolidate(rec) ? rec->ExceptionInformation[3] : trylevel);
572 else
573 cxx_local_unwind(orig_frame, dispatch, descr, unwindlevel);
575 }
576 if (!descr->tryblock_count)
577 {
578 check_noexcept(rec, descr, orig_frame != frame);
580 }
581
582 if (rec->ExceptionCode == CXX_EXCEPTION)
583 {
584 if (!rec->ExceptionInformation[1] && !rec->ExceptionInformation[2])
585 {
586 TRACE("rethrow detected.\n");
587 *rec = *msvcrt_get_thread_data()->exc_record;
588 }
589
590 exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
591
592 if (TRACE_ON(seh))
593 {
594 TRACE("handling C++ exception rec %p frame %lx descr %p\n", rec, frame, descr);
595 dump_exception_type(exc_type, rec->ExceptionInformation[3]);
596 dump_function_descr(descr, dispatch->ImageBase);
597 }
598 }
599 else
600 {
602
603 exc_type = NULL;
604 TRACE("handling C exception code %x rec %p frame %lx descr %p\n",
605 rec->ExceptionCode, rec, frame, descr);
606
607 if (data->se_translator) {
608 EXCEPTION_POINTERS except_ptrs;
609 se_translator_ctx ctx;
610
611 ctx.dest_frame = frame;
612 ctx.orig_frame = orig_frame;
613 ctx.seh_rec = rec;
614 ctx.dispatch = dispatch;
615 ctx.descr = descr;
616 __TRY
617 {
618 except_ptrs.ExceptionRecord = rec;
619 except_ptrs.ContextRecord = context;
620 data->se_translator(rec->ExceptionCode, &except_ptrs);
621 }
622 __EXCEPT_CTX(se_translation_filter, &ctx)
623 {
624 }
626 }
627 }
628
629 find_catch_block(rec, context, NULL, frame, dispatch, descr, exc_type, orig_frame);
630 check_noexcept(rec, descr, orig_frame != frame);
632}
633
634/*********************************************************************
635 * __CxxExceptionFilter (MSVCRT.@)
636 */
637int CDECL __CxxExceptionFilter( PEXCEPTION_POINTERS ptrs,
638 const type_info *ti, int flags, void **copy )
639{
640 FIXME( "%p %p %x %p: not implemented\n", ptrs, ti, flags, copy );
642}
643
644/*********************************************************************
645 * __CxxFrameHandler (MSVCRT.@)
646 */
647EXCEPTION_DISPOSITION CDECL __CxxFrameHandler( EXCEPTION_RECORD *rec, ULONG64 frame,
649{
650 TRACE( "%p %lx %p %p\n", rec, frame, context, dispatch );
651 return cxx_frame_handler( rec, frame, context, dispatch,
652 rva_to_ptr(*(UINT*)dispatch->HandlerData, dispatch->ImageBase) );
653}
654
655
656/*********************************************************************
657 * __CppXcptFilter (MSVCRT.@)
658 */
660{
661 /* only filter c++ exceptions */
663 return _XcptFilter( ex, ptr );
664}
665
666
667/*********************************************************************
668 * __CxxDetectRethrow (MSVCRT.@)
669 */
670BOOL CDECL __CxxDetectRethrow(PEXCEPTION_POINTERS ptrs)
671{
673
674 if (!ptrs)
675 return FALSE;
676
677 rec = ptrs->ExceptionRecord;
678
679 if (rec->ExceptionCode == CXX_EXCEPTION &&
680 rec->NumberParameters == 4 &&
682 rec->ExceptionInformation[2])
683 {
684 ptrs->ExceptionRecord = msvcrt_get_thread_data()->exc_record;
685 return TRUE;
686 }
687 return (msvcrt_get_thread_data()->exc_record == rec);
688}
689
690
691/*********************************************************************
692 * __CxxQueryExceptionSize (MSVCRT.@)
693 */
694unsigned int CDECL __CxxQueryExceptionSize(void)
695{
696 return sizeof(cxx_exception_type);
697}
698
699
700#ifndef __REACTOS__
701/*******************************************************************
702 * _setjmp (MSVCRT.@)
703 */
704__ASM_GLOBAL_FUNC( MSVCRT__setjmp,
705 "jmp " __ASM_NAME("__wine_setjmpex") );
706#endif
707
708/*******************************************************************
709 * longjmp (MSVCRT.@)
710 */
711void __cdecl MSVCRT_longjmp( _JUMP_BUFFER *jmp, int retval )
712{
714
715 if (!retval) retval = 1;
716 if (jmp->Frame)
717 {
719 rec.ExceptionFlags = 0;
720 rec.ExceptionRecord = NULL;
722 rec.NumberParameters = 1;
723 rec.ExceptionInformation[0] = (DWORD_PTR)jmp;
724 RtlUnwind( (void *)jmp->Frame, (void *)jmp->Rip, &rec, IntToPtr(retval) );
725 }
726 __wine_longjmp( (__wine_jmp_buf *)jmp, retval );
727}
728
729#ifndef __REACTOS__ // different file for ntdll
730/*******************************************************************
731 * _local_unwind (MSVCRT.@)
732 */
733void __cdecl _local_unwind( void *frame, void *target )
734{
735 RtlUnwind( frame, target, NULL, 0 );
736}
737#endif /* __REACTOS__ */
738
739/*********************************************************************
740 * _fpieee_flt (MSVCRT.@)
741 */
744{
745 FIXME("(%lx %p %p) opcode: %s\n", exception_code, ep, handler,
748}
749
750#if _MSVCR_VER>=110 && _MSVCR_VER<=120
751/*********************************************************************
752 * __crtCapturePreviousContext (MSVCR110.@)
753 */
754void __cdecl get_prev_context(CONTEXT *ctx, DWORD64 rip)
755{
756 ULONG64 frame, image_base;
758 void *data;
759
760 TRACE("(%p)\n", ctx);
761
763 if(!rf) {
764 FIXME("RtlLookupFunctionEntry failed\n");
765 return;
766 }
767
769 rf, ctx, &data, &frame, NULL);
770}
771
772__ASM_GLOBAL_FUNC( __crtCapturePreviousContext,
773 "movq %rcx,8(%rsp)\n\t"
774 "call " __ASM_NAME("RtlCaptureContext") "\n\t"
775 "movq 8(%rsp),%rcx\n\t" /* context */
776 "leaq 8(%rsp),%rax\n\t"
777 "movq %rax,0x98(%rcx)\n\t" /* context->Rsp */
778 "movq (%rsp),%rax\n\t"
779 "movq %rax,0xf8(%rcx)\n\t" /* context->Rip */
780 "jmp " __ASM_NAME("get_prev_context") )
781#endif
782
783#endif /* __x86_64__ */
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define __cdecl
Definition: accygwin.h:79
void __cdecl _local_unwind(void *frame, void *target)
Definition: ehandler.c:137
static int state
Definition: maze.c:121
#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
#define IntToPtr(i)
Definition: basetsd.h:89
_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 CDECL
Definition: compat.h:29
@ ExceptionContinueSearch
Definition: compat.h:91
#define __TRY
Definition: compat.h:80
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
enum _EXCEPTION_DISPOSITION EXCEPTION_DISPOSITION
#define TRACE_ON(x)
Definition: compat.h:75
#define __ENDTRY
Definition: compat.h:82
#define CALLBACK
Definition: compat.h:35
VOID WINAPI RaiseException(_In_ DWORD dwExceptionCode, _In_ DWORD dwExceptionFlags, _In_ DWORD nNumberOfArguments, _In_opt_ const ULONG_PTR *lpArguments)
Definition: except.c:700
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7512
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
static void * image_base(void)
Definition: dll_register.c:28
#define ULONG_PTR
Definition: config.h:101
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLintptr offset
Definition: glext.h:5920
const GLubyte * c
Definition: glext.h:8905
GLbitfield flags
Definition: glext.h:7161
GLenum target
Definition: glext.h:7315
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
#define UNW_FLAG_NHANDLER
Definition: gs_support.c:32
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 __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 c
Definition: ke_i.h:80
void MSVCRT() terminate()
Definition: cpp.c:716
if(dx< 0)
Definition: linetemp.h:194
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
unsigned __int64 ULONG64
Definition: imports.h:198
static PVOID ptr
Definition: dispmode.c:27
UINT WINAPI nested(MSIHANDLE hinst)
Definition: custom.c:565
struct __type_info type_info
thread_data_t * msvcrt_get_thread_data(void)
Definition: tls.c:31
static char * dest
Definition: rtl.c:135
#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:918
#define STATUS_LONGJUMP
Definition: ntstatus.h:217
#define STATUS_UNWIND_CONSOLIDATE
Definition: ntstatus.h:220
@ normal
Definition: optimize.h:166
long LONG
Definition: pedump.c:60
void * rva_to_ptr(unsigned char *buffer, PIMAGE_NT_HEADERS nt_header, DWORD rva)
Definition: pefixup.c:37
#define EH_EXIT_UNWIND
Definition: exception.h:15
#define EH_TARGET_UNWIND
Definition: exception.h:18
#define __EXCEPT_CTX(func, ctx)
Definition: exception.h:60
#define __FINALLY_CTX(func, ctx)
Definition: exception.h:65
#define EH_UNWINDING
Definition: exception.h:14
void CDECL __DestructExceptionObject(EXCEPTION_RECORD *rec)
Definition: except.c:409
void CDECL __CxxUnregisterExceptionObject(cxx_frame_info *frame_info, BOOL in_use)
Definition: except.c:468
BOOL CDECL __CxxRegisterExceptionObject(EXCEPTION_POINTERS *ep, cxx_frame_info *frame_info)
Definition: except.c:444
const char * descr
Definition: boot.c:45
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200
PCONTEXT ContextRecord
Definition: rtltypes.h:201
struct _EXCEPTION_RECORD * ExceptionRecord
Definition: compat.h:210
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
const type_info * type_info
Definition: cppexcept.h:67
void(* handler)(void)
Definition: cppexcept.h:69
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: http.c:7252
Definition: comerr.c:44
Definition: dhcpd.h:62
#define EXCEPTION_NONCONTINUABLE
Definition: stubs.h:23
#define DWORD_PTR
Definition: treelist.c:76
uint64_t DWORD64
Definition: typedefs.h:67
int32_t INT
Definition: typedefs.h:58
PEXCEPTION_ROUTINE NTAPI RtlVirtualUnwind(_In_ ULONG HandlerType, _In_ ULONG64 ImageBase, _In_ ULONG64 ControlPc, _In_ PRUNTIME_FUNCTION FunctionEntry, _Inout_ PCONTEXT Context, _Outptr_ PVOID *HandlerData, _Out_ PULONG64 EstablisherFrame, _Inout_opt_ PKNONVOLATILE_CONTEXT_POINTERS ContextPointers)
Definition: unwind.c:478
VOID NTAPI RtlUnwindEx(_In_opt_ PVOID TargetFrame, _In_opt_ PVOID TargetIp, _In_opt_ PEXCEPTION_RECORD ExceptionRecord, _In_ PVOID ReturnValue, _In_ PCONTEXT ContextRecord, _In_opt_ struct _UNWIND_HISTORY_TABLE *HistoryTable)
Definition: unwind.c:875
PRUNTIME_FUNCTION NTAPI RtlLookupFunctionEntry(IN DWORD64 ControlPc, OUT PDWORD64 ImageBase, OUT PUNWIND_HISTORY_TABLE HistoryTable)
Locates the RUNTIME_FUNCTION entry corresponding to a code address. http://msdn.microsoft....
Definition: unwind.c:124
int retval
Definition: wcstombs.cpp:91
#define WINAPI
Definition: msvc.h:6
#define FUNC_DESCR_NOEXCEPT
Definition: cppexcept.h:32
static void dump_type(type_t *t)
Definition: write_msft.c:1037