ReactOS  0.4.15-dev-3303-g1ade494
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 
42 typedef struct
43 {
44  int prev;
45  UINT handler;
46 } unwind_info;
47 
48 typedef struct
49 {
50  UINT flags;
52  int offset;
53  UINT handler;
54  UINT frame;
56 #define TYPE_FLAG_CONST 1
57 #define TYPE_FLAG_VOLATILE 2
58 #define TYPE_FLAG_REFERENCE 8
59 
60 typedef struct
61 {
62  int start_level;
63  int end_level;
64  int catch_level;
65  int catchblock_count;
66  UINT catchblock;
68 
69 typedef struct
70 {
71  int ip;
72  int state;
73 } ipmap_info;
74 
75 typedef struct __cxx_function_descr
76 {
77  UINT magic;
81  UINT tryblock;
83  UINT ipmap;
84  UINT unwind_help;
86  UINT flags;
88 
89 typedef struct
90 {
92  BOOL rethrow;
93 } cxx_catch_ctx;
94 
95 typedef struct
96 {
97  ULONG64 dest_frame;
98  ULONG64 orig_frame;
99  EXCEPTION_RECORD *seh_rec;
101  const cxx_function_descr *descr;
102 } se_translator_ctx;
103 
104 static inline void* rva_to_ptr(UINT rva, ULONG64 base)
105 {
106  return rva ? (void*)(base+rva) : NULL;
107 }
108 
109 static 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 
119 static 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 
135 static 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,
164  dbgstr_type_info(rva_to_ptr(catchblock[j].type_info, image_base)));
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 
179 static 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 */
200 static 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 
226 static 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  {
251  if (type->flags & CLASS_HAS_VIRTUAL_BASE_CLASS)
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 
269 static 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 
306 static 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 
321 static 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 
327 static 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  {
358  __DestructExceptionObject(prev_rec);
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  }
368  __ENDTRY
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 
377 static inline BOOL cxx_is_consolidate(const EXCEPTION_RECORD *rec)
378 {
379  return rec->ExceptionCode==STATUS_UNWIND_CONSOLIDATE && rec->NumberParameters==8 &&
380  rec->ExceptionInformation[0]==(ULONG_PTR)call_catch_block;
381 }
382 
383 static inline void find_catch_block(EXCEPTION_RECORD *rec, CONTEXT *context,
384  EXCEPTION_RECORD *untrans_rec,
386  const cxx_function_descr *descr,
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 
481 static 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 
501 static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame,
503  const cxx_function_descr *descr)
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 
515  if (descr->magic<CXX_FRAME_MAGIC_VC6 || descr->magic>CXX_FRAME_MAGIC_VC8)
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  {
557  if (rec->ExceptionFlags & EH_TARGET_UNWIND)
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  }
603  __ENDTRY
604  }
605  }
606 
607  find_catch_block(rec, context, NULL, frame, dispatch, descr, exc_type, orig_frame);
609 }
610 
611 /*********************************************************************
612  * __CxxExceptionFilter (MSVCRT.@)
613  */
614 int 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  */
624 EXCEPTION_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  */
647 BOOL CDECL __CxxDetectRethrow(PEXCEPTION_POINTERS ptrs)
648 {
649  PEXCEPTION_RECORD rec;
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  */
671 unsigned 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  */
688 void __cdecl MSVCRT_longjmp( struct MSVCRT___JUMP_BUFFER *jmp, int retval )
689 {
690  EXCEPTION_RECORD rec;
691 
692  if (!retval) retval = 1;
693  if (jmp->Frame)
694  {
696  rec.ExceptionFlags = 0;
697  rec.ExceptionRecord = NULL;
698  rec.ExceptionAddress = 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  */
710 void __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  */
719 int __cdecl _fpieee_flt(ULONG exception_code, EXCEPTION_POINTERS *ep,
720  int (__cdecl *handler)(_FPIEEE_RECORD*))
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  */
731 void __cdecl get_prev_context(CONTEXT *ctx, DWORD64 rip)
732 {
733  ULONG64 frame, image_base;
734  RUNTIME_FUNCTION *rf;
735  void *data;
736 
737  TRACE("(%p)\n", ctx);
738 
739  rf = RtlLookupFunctionEntry(ctx->Rip, &image_base, NULL);
740  if(!rf) {
741  FIXME("RtlLookupFunctionEntry failed\n");
742  return;
743  }
744 
745  RtlVirtualUnwind(UNW_FLAG_NHANDLER, image_base, ctx->Rip,
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__ */
#define STATUS_UNWIND_CONSOLIDATE
Definition: ntstatus.h:220
#define __FINALLY_CTX(func, ctx)
Definition: exception.h:90
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
void * rva_to_ptr(unsigned char *buffer, PIMAGE_NT_HEADERS nt_header, DWORD rva)
Definition: pefixup.c:37
_CRTIMP int __cdecl _fpieee_flt(unsigned long _ExceptionCode, struct _EXCEPTION_POINTERS *_PtExceptionPtr, int(__cdecl *_Handler)(_FPIEEE_RECORD *))
Definition: comerr.c:44
#define EH_TARGET_UNWIND
Definition: exception.h:21
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define DWORD_PTR
Definition: treelist.c:76
#define __cdecl
Definition: accygwin.h:79
#define CXX_FRAME_MAGIC_VC6
Definition: cppexcept.h:24
Definition: http.c:7251
#define TYPE_FLAG_VOLATILE
Definition: cppexcept.h:72
#define TRUE
Definition: types.h:120
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:496
struct __cxx_function_descr cxx_function_descr
GLuint GLuint GLsizei count
Definition: gl.h:1545
LONG NTSTATUS
Definition: precomp.h:26
#define CALLBACK
Definition: compat.h:35
#define TYPE_FLAG_REFERENCE
Definition: cppexcept.h:73
#define EXCEPTION_NONCONTINUABLE
Definition: rtltypes.h:154
const unwind_info * unwind_table
Definition: cppexcept.h:97
NTSYSAPI VOID NTAPI RtlUnwind(_In_opt_ PVOID TargetFrame, _In_opt_ PVOID TargetIp, _In_opt_ PEXCEPTION_RECORD ExceptionRecord, _In_ PVOID ReturnValue)
Definition: except.c:47
int catchblock_count
Definition: cppexcept.h:81
#define __EXCEPT_CTX(func, ctx)
Definition: exception.h:85
if(dx==0 &&dy==0)
Definition: linetemp.h:174
int32_t INT
Definition: typedefs.h:58
const catchblock_info * catchblock
Definition: cppexcept.h:82
PVOID ExceptionAddress
Definition: compat.h:211
char mangled[16]
Definition: cpp.c:36
#define __ASM_GLOBAL_FUNC(name, code)
Definition: port.h:201
DWORD ExceptionCode
Definition: compat.h:208
#define CXX_FRAME_MAGIC_VC8
Definition: cppexcept.h:26
struct __tryblock_info tryblock_info
void CDECL __DestructExceptionObject(EXCEPTION_RECORD *rec)
Definition: except.c:405
#define CLASS_IS_SIMPLE_TYPE
Definition: cppexcept.h:127
static void * get_this_pointer(const this_ptr_offsets *off, void *object)
Definition: cppexcept.h:163
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
#define TYPE_FLAG_CONST
Definition: cppexcept.h:71
#define __ASM_NAME(name)
Definition: config.h:934
#define FIXME(fmt,...)
Definition: debug.h:111
static PVOID ptr
Definition: dispmode.c:27
int ip[4]
Definition: rtl.c:1176
struct _frame_info frame_info
struct __type_info type_info
#define __TRY
Definition: compat.h:80
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:885
#define STATUS_LONGJUMP
Definition: ntstatus.h:217
int CDECL __CppXcptFilter(NTSTATUS, PEXCEPTION_POINTERS)
const void * expect_list
Definition: cppexcept.h:102
#define IntToPtr(i)
Definition: basetsd.h:89
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
PCONTEXT ContextRecord
Definition: rtltypes.h:201
#define EH_UNWINDING
Definition: exception.h:17
#define CXX_EXCEPTION
Definition: cppexcept.h:27
#define TRACE(s)
Definition: solgame.cpp:4
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:213
Definition: dhcpd.h:61
#define FUNC_DESCR_SYNCHRONOUS
Definition: cppexcept.h:106
struct __catchblock_info catchblock_info
GLintptr offset
Definition: glext.h:5920
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define CXX_FRAME_MAGIC_VC7
Definition: cppexcept.h:25
#define WINAPI
Definition: msvc.h:6
void(* handler)(void)
Definition: cppexcept.h:69
const GLubyte * c
Definition: glext.h:8905
const char * descr
Definition: boot.c:45
unsigned long DWORD
Definition: ntddk_ex.h:95
const type_info * type_info
Definition: cppexcept.h:67
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
_In_opt_ PVOID _In_ ULONG _In_ PVOID context
Definition: wdfdriver.h:113
GLbitfield flags
Definition: glext.h:7161
unsigned __int64 ULONG64
Definition: imports.h:198
#define __ENDTRY
Definition: compat.h:82
void __cdecl _local_unwind(void *frame, void *target)
Definition: ehandler.c:137
static int state
Definition: maze.c:121
struct __unwind_info unwind_info
thread_data_t * msvcrt_get_thread_data(void)
Definition: tls.c:31
void dispatch(HANDLE hStopEvent)
Definition: dispatch.c:70
struct __cxx_exception_type cxx_exception_type
#define EH_EXIT_UNWIND
Definition: exception.h:18
struct _EXCEPTION_RECORD * ExceptionRecord
Definition: compat.h:210
#define ERR(fmt,...)
Definition: debug.h:110
uint64_t DWORD64
Definition: typedefs.h:67
static const char * dbgstr_type_info(const type_info *info)
Definition: cppexcept.h:155
VOID WINAPI RaiseException(IN DWORD dwExceptionCode, IN DWORD dwExceptionFlags, IN DWORD nNumberOfArguments, IN CONST ULONG_PTR *lpArguments OPTIONAL)
Definition: except.c:700
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
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:86
#define CDECL
Definition: compat.h:29
const cxx_type_info_table * type_info_table
Definition: cppexcept.h:148
#define CLASS_HAS_VIRTUAL_BASE_CLASS
Definition: cppexcept.h:128
const void * ipmap
Definition: cppexcept.h:101
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
static void dump_type(type_t *t)
Definition: write_msft.c:1037
BOOL CDECL __CxxRegisterExceptionObject(EXCEPTION_POINTERS *ep, cxx_frame_info *frame_info)
Definition: except.c:440
#define c
Definition: ke_i.h:80
unsigned int ULONG
Definition: retypes.h:1
GLenum target
Definition: glext.h:7315
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
enum _EXCEPTION_DISPOSITION EXCEPTION_DISPOSITION
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define ULONG_PTR
Definition: config.h:101
DWORD ExceptionFlags
Definition: compat.h:209
static char * dest
Definition: rtl.c:135
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7786
DWORD NumberParameters
Definition: compat.h:212
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:117
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE_ON(x)
Definition: compat.h:75
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
void CDECL __CxxUnregisterExceptionObject(cxx_frame_info *frame_info, BOOL in_use)
Definition: except.c:464
void __cdecl MSVCRT_terminate(void)
Definition: cpp.c:1277
int CDECL _XcptFilter(NTSTATUS, PEXCEPTION_POINTERS)
Definition: except.c:274
const tryblock_info * tryblock
Definition: cppexcept.h:99
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define UNW_FLAG_NHANDLER
Definition: gs_support.c:32
const cxx_type_info * info[3]
Definition: cppexcept.h:134