ReactOS 0.4.15-dev-7906-g1b85a5f
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#include "config.h"
22#include "wine/port.h"
23
24#ifdef __x86_64__
25
26#include <stdarg.h>
27
28#include "ntstatus.h"
29#define WIN32_NO_STATUS
30#include "windef.h"
31#include "winbase.h"
32#include "winternl.h"
33#include "msvcrt.h"
34#include "wine/exception.h"
35#include "excpt.h"
36#include "wine/debug.h"
37
38#include "cppexcept.h"
39
41
42typedef struct
43{
44 int prev;
47
48typedef struct
49{
50 UINT flags;
52 int offset;
54 UINT frame;
56#define TYPE_FLAG_CONST 1
57#define TYPE_FLAG_VOLATILE 2
58#define TYPE_FLAG_REFERENCE 8
59
60typedef struct
61{
62 int start_level;
63 int end_level;
64 int catch_level;
65 int catchblock_count;
66 UINT catchblock;
68
69typedef struct
70{
71 int ip;
72 int state;
73} ipmap_info;
74
75typedef struct __cxx_function_descr
76{
77 UINT magic;
83 UINT ipmap;
84 UINT unwind_help;
86 UINT flags;
88
89typedef struct
90{
92 BOOL rethrow;
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);
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;
310 cxx_catch_ctx *ctx = c;
311
312 if (rec->ExceptionCode != CXX_EXCEPTION)
314 if (!rec->ExceptionInformation[1] && !rec->ExceptionInformation[2])
316 if (rec->ExceptionInformation[1] == data->exc_record->ExceptionInformation[1])
317 ctx->rethrow = TRUE;
319}
320
321static void CALLBACK cxx_catch_cleanup(BOOL normal, void *c)
322{
323 cxx_catch_ctx *ctx = c;
324 __CxxUnregisterExceptionObject(&ctx->frame_info, ctx->rethrow);
325}
326
327static void* WINAPI call_catch_block(EXCEPTION_RECORD *rec)
328{
329 ULONG64 frame = rec->ExceptionInformation[1];
330 const cxx_function_descr *descr = (void*)rec->ExceptionInformation[2];
331 EXCEPTION_RECORD *prev_rec = (void*)rec->ExceptionInformation[4];
332 EXCEPTION_RECORD *untrans_rec = (void*)rec->ExceptionInformation[6];
333 CONTEXT *context = (void*)rec->ExceptionInformation[7];
334 void* (__cdecl *handler)(ULONG64 unk, ULONG64 rbp) = (void*)rec->ExceptionInformation[5];
335 int *unwind_help = rva_to_ptr(descr->unwind_help, frame);
336 EXCEPTION_POINTERS ep = { prev_rec, context };
337 cxx_catch_ctx ctx;
338 void *ret_addr = NULL;
339
340 TRACE("calling handler %p\n", handler);
341
342 ctx.rethrow = FALSE;
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);
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 DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame,
504{
505 int trylevel = ip_to_state(rva_to_ptr(descr->ipmap, dispatch->ImageBase),
506 descr->ipmap_count, dispatch->ControlPc-dispatch->ImageBase);
507 cxx_exception_type *exc_type;
508 ULONG64 orig_frame = frame;
509 ULONG64 throw_base;
510 DWORD throw_func_off;
511 void *throw_func;
512 UINT i, j;
513 int unwindlevel = -1;
514
516 {
517 FIXME("unhandled frame magic %x\n", descr->magic);
519 }
520
521 if (descr->magic >= CXX_FRAME_MAGIC_VC8 &&
522 (descr->flags & FUNC_DESCR_SYNCHRONOUS) &&
523 (rec->ExceptionCode != CXX_EXCEPTION &&
524 !cxx_is_consolidate(rec) &&
526 return ExceptionContinueSearch; /* handle only c++ exceptions */
527
528 /* update orig_frame if it's a nested exception */
529 throw_func_off = RtlLookupFunctionEntry(dispatch->ControlPc, &throw_base, NULL)->BeginAddress;
530 throw_func = rva_to_ptr(throw_func_off, throw_base);
531 TRACE("reconstructed handler pointer: %p\n", throw_func);
532 for (i=descr->tryblock_count; i>0; i--)
533 {
534 const tryblock_info *tryblock = rva_to_ptr(descr->tryblock, dispatch->ImageBase);
535 tryblock = &tryblock[i-1];
536
537 if (trylevel>tryblock->end_level && trylevel<=tryblock->catch_level)
538 {
539 for (j=0; j<tryblock->catchblock_count; j++)
540 {
541 const catchblock_info *catchblock = rva_to_ptr(tryblock->catchblock, dispatch->ImageBase);
542 catchblock = &catchblock[j];
543
544 if (rva_to_ptr(catchblock->handler, dispatch->ImageBase) == throw_func)
545 {
546 TRACE("nested exception detected\n");
547 unwindlevel = tryblock->end_level;
548 orig_frame = *(ULONG64*)rva_to_ptr(catchblock->frame, frame);
549 TRACE("setting orig_frame to %lx\n", orig_frame);
550 }
551 }
552 }
553 }
554
556 {
558 cxx_local_unwind(orig_frame, dispatch, descr,
559 cxx_is_consolidate(rec) ? rec->ExceptionInformation[3] : trylevel);
560 else
561 cxx_local_unwind(orig_frame, dispatch, descr, unwindlevel);
563 }
564 if (!descr->tryblock_count) return ExceptionContinueSearch;
565
566 if (rec->ExceptionCode == CXX_EXCEPTION)
567 {
568 exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
569
570 if (TRACE_ON(seh))
571 {
572 TRACE("handling C++ exception rec %p frame %lx descr %p\n", rec, frame, descr);
573 dump_exception_type(exc_type, rec->ExceptionInformation[3]);
574 dump_function_descr(descr, dispatch->ImageBase);
575 }
576 }
577 else
578 {
580
581 exc_type = NULL;
582 TRACE("handling C exception code %x rec %p frame %lx descr %p\n",
583 rec->ExceptionCode, rec, frame, descr);
584
585 if (data->se_translator) {
586 EXCEPTION_POINTERS except_ptrs;
587 se_translator_ctx ctx;
588
589 ctx.dest_frame = frame;
590 ctx.orig_frame = orig_frame;
591 ctx.seh_rec = rec;
592 ctx.dispatch = dispatch;
593 ctx.descr = descr;
594 __TRY
595 {
596 except_ptrs.ExceptionRecord = rec;
597 except_ptrs.ContextRecord = context;
598 data->se_translator(rec->ExceptionCode, &except_ptrs);
599 }
600 __EXCEPT_CTX(se_translation_filter, &ctx)
601 {
602 }
604 }
605 }
606
607 find_catch_block(rec, context, NULL, frame, dispatch, descr, exc_type, orig_frame);
609}
610
611/*********************************************************************
612 * __CxxExceptionFilter (MSVCRT.@)
613 */
614int CDECL __CxxExceptionFilter( PEXCEPTION_POINTERS ptrs,
615 const type_info *ti, int flags, void **copy )
616{
617 FIXME( "%p %p %x %p: not implemented\n", ptrs, ti, flags, copy );
619}
620
621/*********************************************************************
622 * __CxxFrameHandler (MSVCRT.@)
623 */
624EXCEPTION_DISPOSITION CDECL __CxxFrameHandler( EXCEPTION_RECORD *rec, ULONG64 frame,
626{
627 TRACE( "%p %lx %p %p\n", rec, frame, context, dispatch );
628 return cxx_frame_handler( rec, frame, context, dispatch,
629 rva_to_ptr(*(UINT*)dispatch->HandlerData, dispatch->ImageBase) );
630}
631
632
633/*********************************************************************
634 * __CppXcptFilter (MSVCRT.@)
635 */
637{
638 /* only filter c++ exceptions */
640 return _XcptFilter( ex, ptr );
641}
642
643
644/*********************************************************************
645 * __CxxDetectRethrow (MSVCRT.@)
646 */
647BOOL CDECL __CxxDetectRethrow(PEXCEPTION_POINTERS ptrs)
648{
650
651 if (!ptrs)
652 return FALSE;
653
654 rec = ptrs->ExceptionRecord;
655
656 if (rec->ExceptionCode == CXX_EXCEPTION &&
657 rec->NumberParameters == 4 &&
659 rec->ExceptionInformation[2])
660 {
661 ptrs->ExceptionRecord = msvcrt_get_thread_data()->exc_record;
662 return TRUE;
663 }
664 return (msvcrt_get_thread_data()->exc_record == rec);
665}
666
667
668/*********************************************************************
669 * __CxxQueryExceptionSize (MSVCRT.@)
670 */
671unsigned int CDECL __CxxQueryExceptionSize(void)
672{
673 return sizeof(cxx_exception_type);
674}
675
676
677#ifndef __REACTOS__
678/*******************************************************************
679 * _setjmp (MSVCRT.@)
680 */
681__ASM_GLOBAL_FUNC( MSVCRT__setjmp,
682 "jmp " __ASM_NAME("__wine_setjmpex") );
683#endif
684
685/*******************************************************************
686 * longjmp (MSVCRT.@)
687 */
688void __cdecl MSVCRT_longjmp( struct MSVCRT___JUMP_BUFFER *jmp, int retval )
689{
691
692 if (!retval) retval = 1;
693 if (jmp->Frame)
694 {
696 rec.ExceptionFlags = 0;
697 rec.ExceptionRecord = NULL;
699 rec.NumberParameters = 1;
700 rec.ExceptionInformation[0] = (DWORD_PTR)jmp;
701 RtlUnwind( (void *)jmp->Frame, (void *)jmp->Rip, &rec, IntToPtr(retval) );
702 }
703 __wine_longjmp( (__wine_jmp_buf *)jmp, retval );
704}
705
706#ifndef __REACTOS__ // different file for ntdll
707/*******************************************************************
708 * _local_unwind (MSVCRT.@)
709 */
710void __cdecl _local_unwind( void *frame, void *target )
711{
712 RtlUnwind( frame, target, NULL, 0 );
713}
714#endif /* __REACTOS__ */
715
716/*********************************************************************
717 * _fpieee_flt (MSVCRT.@)
718 */
719int __cdecl _fpieee_flt(ULONG exception_code, EXCEPTION_POINTERS *ep,
721{
722 FIXME("(%x %p %p) opcode: %s\n", exception_code, ep, handler,
725}
726
727#if _MSVCR_VER>=110 && _MSVCR_VER<=120
728/*********************************************************************
729 * __crtCapturePreviousContext (MSVCR110.@)
730 */
731void __cdecl get_prev_context(CONTEXT *ctx, DWORD64 rip)
732{
733 ULONG64 frame, image_base;
735 void *data;
736
737 TRACE("(%p)\n", ctx);
738
740 if(!rf) {
741 FIXME("RtlLookupFunctionEntry failed\n");
742 return;
743 }
744
746 rf, ctx, &data, &frame, NULL);
747}
748
749__ASM_GLOBAL_FUNC( __crtCapturePreviousContext,
750 "movq %rcx,8(%rsp)\n\t"
751 "call " __ASM_NAME("RtlCaptureContext") "\n\t"
752 "movq 8(%rsp),%rcx\n\t" /* context */
753 "leaq 8(%rsp),%rax\n\t"
754 "movq %rax,0x98(%rcx)\n\t" /* context->Rsp */
755 "movq (%rsp),%rax\n\t"
756 "movq %rax,0xf8(%rcx)\n\t" /* context->Rip */
757 "jmp " __ASM_NAME("get_prev_context") )
758#endif
759
760#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 IntToPtr(i)
Definition: basetsd.h:89
#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 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:7482
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
_CRTIMP int __cdecl _fpieee_flt(unsigned long _ExceptionCode, struct _EXCEPTION_POINTERS *_PtExceptionPtr, int(__cdecl *_Handler)(_FPIEEE_RECORD *))
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
const GLubyte * c
Definition: glext.h:8905
GLbitfield flags
Definition: glext.h:7161
GLintptr offset
Definition: glext.h:5920
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
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:86
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 __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 c
Definition: ke_i.h:80
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
struct __type_info type_info
void __cdecl MSVCRT_terminate(void)
Definition: cpp.c:1275
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:912
#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:18
#define EH_TARGET_UNWIND
Definition: exception.h:21
#define __EXCEPT_CTX(func, ctx)
Definition: exception.h:85
#define __FINALLY_CTX(func, ctx)
Definition: exception.h:90
#define EH_UNWINDING
Definition: exception.h:17
void CDECL __DestructExceptionObject(EXCEPTION_RECORD *rec)
Definition: except.c:405
void CDECL __CxxUnregisterExceptionObject(cxx_frame_info *frame_info, BOOL in_use)
Definition: except.c:464
BOOL CDECL __CxxRegisterExceptionObject(EXCEPTION_POINTERS *ep, cxx_frame_info *frame_info)
Definition: except.c:440
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
uint32_t ULONG
Definition: typedefs.h:59
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:869
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
#define WINAPI
Definition: msvc.h:6
static void dump_type(type_t *t)
Definition: write_msft.c:1037