23#if defined(__x86_64__) && _MSVCR_VER>=140
35static DWORD fls_index;
48} cxx_function_descr_v4;
49#define FUNC_DESCR_IS_CATCH 0x01
50#define FUNC_DESCR_IS_SEPARATED 0x02
51#define FUNC_DESCR_BBT 0x04
52#define FUNC_DESCR_UNWIND_MAP 0x08
53#define FUNC_DESCR_TRYBLOCK_MAP 0x10
54#define FUNC_DESCR_EHS 0x20
55#define FUNC_DESCR_NO_EXCEPT 0x40
56#define FUNC_DESCR_RESERVED 0x80
75#define CATCHBLOCK_FLAGS 0x01
76#define CATCHBLOCK_TYPE_INFO 0x02
77#define CATCHBLOCK_OFFSET 0x04
78#define CATCHBLOCK_SEPARATED 0x08
79#define CATCHBLOCK_RET_ADDR_MASK 0x30
80#define CATCHBLOCK_RET_ADDR 0x10
81#define CATCHBLOCK_TWO_RET_ADDRS 0x20
83#define UNWIND_TYPE_NO_HANDLER 0
84#define UNWIND_TYPE_DTOR_OBJ 1
85#define UNWIND_TYPE_DTOR_PTR 2
86#define UNWIND_TYPE_FRAME 3
88#define CONSOLIDATE_UNWIND_PARAMETER_COUNT 10
105 const cxx_function_descr_v4 *
descr;
119 else if ((*
p & 3) == 1)
121 ret = (
p[0] >> 2) + (
p[1] << 6);
124 else if ((*
p & 7) == 3)
126 ret = (
p[0] >> 3) + (
p[1] << 5) + (
p[2] << 13);
129 else if ((*
p & 15) == 7)
131 ret = (
p[0] >> 4) + (
p[1] << 4) + (
p[2] << 12) + (
p[3] << 20);
136 FIXME(
"not implemented - expect crash\n");
152static void read_unwind_info(
BYTE **
b, unwind_info_v4 *
ui)
157 ui->type = decode_uint(
b);
158 ui->prev =
p - (
ui->type >> 2);
163 case UNWIND_TYPE_NO_HANDLER:
165 case UNWIND_TYPE_DTOR_OBJ:
166 ui->handler = read_rva(
b);
167 ui->object = decode_uint(
b);
169 case UNWIND_TYPE_DTOR_PTR:
170 ui->handler = read_rva(
b);
171 ui->object = decode_uint(
b);
173 case UNWIND_TYPE_FRAME:
174 ui->handler = read_rva(
b);
200static BOOL read_catchblock_info(
BYTE **
b, catchblock_info_v4 *ci,
DWORD func_rva)
203 memset(ci, 0,
sizeof(*ci));
206 if (ci->header & ~(CATCHBLOCK_FLAGS | CATCHBLOCK_TYPE_INFO | CATCHBLOCK_OFFSET |
207 CATCHBLOCK_SEPARATED | CATCHBLOCK_RET_ADDR_MASK))
209 FIXME(
"unknown header: %x\n", ci->header);
212 ret_addr_type = ci->header & CATCHBLOCK_RET_ADDR_MASK;
213 if (ret_addr_type == (CATCHBLOCK_RET_ADDR | CATCHBLOCK_TWO_RET_ADDRS))
215 FIXME(
"unsupported ret addr type.\n");
219 if (ci->header & CATCHBLOCK_FLAGS) ci->flags = decode_uint(
b);
220 if (ci->header & CATCHBLOCK_TYPE_INFO) ci->type_info = read_rva(
b);
221 if (ci->header & CATCHBLOCK_OFFSET) ci->offset = decode_uint(
b);
222 ci->handler = read_rva(
b);
223 if (ci->header & CATCHBLOCK_SEPARATED)
225 if (ret_addr_type == CATCHBLOCK_RET_ADDR || ret_addr_type == CATCHBLOCK_TWO_RET_ADDRS)
226 ci->ret_addr[0] = read_rva(
b);
227 if (ret_addr_type == CATCHBLOCK_TWO_RET_ADDRS)
228 ci->ret_addr[1] = read_rva(
b);
232 if (ret_addr_type == CATCHBLOCK_RET_ADDR || ret_addr_type == CATCHBLOCK_TWO_RET_ADDRS)
233 ci->ret_addr[0] = decode_uint(
b) + func_rva;
234 if (ret_addr_type == CATCHBLOCK_TWO_RET_ADDRS)
235 ci->ret_addr[1] = decode_uint(
b) + func_rva;
243 ii->
ip = decode_uint(
b);
257 TRACE(
"basic block transformations flags: 0x%x\n",
descr->bbt_flags);
259 TRACE(
"unwind table: 0x%x(%p) %d\n",
descr->unwind_map, unwind_map,
descr->unwind_count);
260 for (
i = 0;
i <
descr->unwind_count;
i++)
265 read_unwind_info(&unwind_map, &
ui);
267 TRACE(
" %d (%p): type 0x%x prev %p func 0x%x object 0x%x\n",
271 TRACE(
"try table: 0x%x(%p) %d\n",
descr->tryblock_map, tryblock_map,
descr->tryblock_count);
272 for (
i = 0;
i <
descr->tryblock_count;
i++)
277 read_tryblock_info(&tryblock_map, &ti,
image_base);
279 TRACE(
" %d: start %d end %d catchlevel %d catch 0x%x(%p) %d\n",
284 catchblock_info_v4 ci;
285 if (!read_catchblock_info(&catchblock, &ci,
287 TRACE(
" %d: header 0x%x offset %d handler 0x%x "
288 "ret addr[0] %#x ret_addr[1] %#x type %#x %s\n",
j, ci.header, ci.offset,
289 ci.handler, ci.ret_addr[0], ci.ret_addr[1], ci.type_info,
296 for (
i = 0;
i <
descr->ip_count;
i++)
300 read_ipmap_info(&ip_map, &ii);
305 TRACE(
"establisher frame: %x\n",
descr->frame);
318 for (
i = 0;
i <
descr->ip_count;
i++)
320 read_ipmap_info(&ip_map, &ii);
322 if (
ip < state_ip)
break;
331 const cxx_function_descr_v4 *
descr,
int trylevel,
int last_level)
341 TRACE(
"current level: %d, last level: %d\n", trylevel, last_level);
343 if (trylevel<-1 || trylevel>=(
int)
descr->unwind_count)
345 ERR(
"invalid trylevel %d\n", trylevel);
349 if (trylevel <= last_level)
return;
352 last = unwind_data - 1;
353 for (
i = 0;
i < trylevel;
i++)
356 read_unwind_info(&unwind_data, &
ui);
360 while (unwind_data >
last)
362 read_unwind_info(&unwind_data, &
ui);
363 unwind_data =
ui.prev;
368 obj = (
void *)(frame +
ui.object);
369 if(
ui.type == UNWIND_TYPE_DTOR_PTR)
371 TRACE(
"handler: %p object: %p\n", handler_dtor,
obj);
372 handler_dtor(
obj, frame);
408 void *ret_addr =
NULL;
414 ctx.prev_rec = prev_rec;
424 TRACE(
"detect rethrow: exception code: %lx\n", prev_rec->ExceptionCode);
431 RaiseException(untrans_rec->ExceptionCode, untrans_rec->ExceptionFlags,
432 untrans_rec->NumberParameters, untrans_rec->ExceptionInformation);
437 prev_rec->NumberParameters, prev_rec->ExceptionInformation);
445 TRACE(
"handler returned %p, ret_addr[0] %#Ix, ret_addr[1] %#Ix.\n",
452 ERR(
"unexpected handler result %p.\n", ret_addr);
470 ULONG64 orig_frame,
int trylevel)
479 (*processing_throw)++;
482 TRACE(
"current trylevel: %d\n", trylevel);
485 for (
i=0;
i<
descr->tryblock_count;
i++)
490 read_tryblock_info(&tryblock_map, &tryblock,
dispatch->ImageBase);
493 if (trylevel > tryblock.
end_level)
continue;
499 catchblock_info_v4 ci;
501 read_catchblock_info(&catchblock, &ci,
dispatch->FunctionEntry->BeginAddress);
511 TRACE(
"matched type %p in tryblock %d catchblock %d\n",
type,
i,
j);
513 if (catch_ti && catch_ti->
mangled[0] && ci.offset)
516 void **
dest = (
void **)(orig_frame + ci.offset);
525 TRACE(
"found catch(...) block\n");
529 memset(&catch_record, 0,
sizeof(catch_record));
545 ci.ret_addr[0],
dispatch->ImageBase);
550 ci.ret_addr[1],
dispatch->ImageBase);
556 TRACE(
"no matching catch block found\n");
557 (*processing_throw)--;
574 ctx->descr, exc_type,
ctx->orig_frame,
ctx->trylevel);
588 if (!(
descr->header & FUNC_DESCR_IS_CATCH) &&
590 (
descr->header & FUNC_DESCR_NO_EXCEPT))
592 ERR(
"noexcept function propagating exception\n");
599 const cxx_function_descr_v4 *
descr,
int trylevel)
604 if (
descr->header & FUNC_DESCR_IS_CATCH)
606 TRACE(
"nested exception detected\n");
608 TRACE(
"setting orig_frame to %Ix\n", orig_frame);
619 cxx_local_unwind4(orig_frame,
dispatch,
descr, trylevel, last_level);
622 if (!
descr->tryblock_map)
632 TRACE(
"rethrow detected.\n");
640 TRACE(
"handling C++ exception rec %p frame %Ix descr %p\n", rec, frame,
descr);
649 TRACE(
"handling C exception code %lx rec %p frame %Ix descr %p\n",
656 ctx.dest_frame = frame;
657 ctx.orig_frame = orig_frame;
661 ctx.trylevel = trylevel;
683 cxx_function_descr_v4
descr;
696 if ((
descr.header & FUNC_DESCR_EHS) &&
702 if (
descr.header & ~(FUNC_DESCR_IS_CATCH | FUNC_DESCR_IS_SEPARATED |
703 FUNC_DESCR_UNWIND_MAP | FUNC_DESCR_TRYBLOCK_MAP | FUNC_DESCR_EHS |
704 FUNC_DESCR_NO_EXCEPT))
706 FIXME(
"unsupported flags: %x\n",
descr.header);
710 if (
descr.header & FUNC_DESCR_BBT)
descr.bbt_flags = decode_uint(&
p);
711 if (
descr.header & FUNC_DESCR_UNWIND_MAP)
713 descr.unwind_map = read_rva(&
p);
715 descr.unwind_count = decode_uint(&count_end);
718 if (
descr.header & FUNC_DESCR_TRYBLOCK_MAP)
720 descr.tryblock_map = read_rva(&
p);
722 descr.tryblock_count = decode_uint(&count_end);
725 descr.ip_map = read_rva(&
p);
726 if (
descr.header & FUNC_DESCR_IS_SEPARATED)
741 FIXME(
"function ip_map not found\n");
746 descr.ip_count = decode_uint(&count_end);
748 if (
descr.header & FUNC_DESCR_IS_CATCH)
descr.frame = decode_uint(&
p);
756BOOL msvcrt_init_handler4(
void)
761 msvcrt_attach_handler4();
765void msvcrt_attach_handler4(
void)
770void msvcrt_free_handler4(
void)
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
void dispatch(HANDLE hStopEvent)
@ ExceptionContinueSearch
enum _EXCEPTION_DISPOSITION EXCEPTION_DISPOSITION
VOID WINAPI RaiseException(_In_ DWORD dwExceptionCode, _In_ DWORD dwExceptionFlags, _In_ DWORD nNumberOfArguments, _In_opt_ const ULONG_PTR *lpArguments)
PVOID WINAPI FlsGetValue(DWORD dwFlsIndex)
BOOL WINAPI FlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData)
BOOL WINAPI FlsFree(DWORD dwFlsIndex)
DWORD WINAPI FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback)
UINT(* handler)(MSIPACKAGE *)
void CDECL terminate(void)
static const char * dbgstr_type_info(const type_info *info)
static const cxx_type_info * find_caught_type(cxx_exception_type *exc_type, uintptr_t base, const type_info *catch_ti, UINT catch_flags)
#define TRACE_EXCEPTION_TYPE(type, base)
static void copy_exception(void *object, void **dest, UINT catch_flags, const cxx_type_info *type, uintptr_t base)
void * call_catch_handler(EXCEPTION_RECORD *rec)
ULONG_PTR get_exception_pc(DISPATCHER_CONTEXT *dispatch)
struct __type_info type_info
static void * rtti_rva(unsigned int rva, uintptr_t base)
static void check_noexcept(PEXCEPTION_RECORD rec, const cxx_function_descr *descr, BOOL nested)
void CDECL __DestructExceptionObject(EXCEPTION_RECORD *rec)
static BOOL cxx_is_consolidate(const EXCEPTION_RECORD *rec)
static void CALLBACK cxx_catch_cleanup(BOOL normal, void *c)
static LONG CALLBACK se_translation_filter(EXCEPTION_POINTERS *ep, void *c)
void CDECL __CxxUnregisterExceptionObject(cxx_frame_info *frame_info, BOOL in_use)
BOOL CDECL __CxxRegisterExceptionObject(EXCEPTION_POINTERS *ep, cxx_frame_info *frame_info)
static LONG CALLBACK cxx_rethrow_filter(PEXCEPTION_POINTERS eptrs, void *c)
void(__cdecl * _se_translator_function)(unsigned int code, struct _EXCEPTION_POINTERS *info)
void **__cdecl __current_exception(void)
int *__cdecl __processing_throw(void)
static void * image_base(void)
GLuint GLuint GLsizei count
GLuint GLuint GLsizei GLenum type
GLboolean GLboolean GLboolean b
GLenum const GLvoid * addr
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
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
#define EXCEPTION_EXECUTE_HANDLER
#define EXCEPTION_CONTINUE_SEARCH
static void __cdecl se_translator(unsigned int u, EXCEPTION_POINTERS *ep)
#define STATUS_UNWIND_CONSOLIDATE
NTSYSAPI void WINAPI RtlUnwindEx(void *, void *, EXCEPTION_RECORD *, void *, CONTEXT *, UNWIND_HISTORY_TABLE *)
PEXCEPTION_RECORD ExceptionRecord
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
#define EXCEPTION_NONCONTINUABLE
#define FLS_OUT_OF_INDEXES
#define __EXCEPT_CTX(func, ctx)
#define __FINALLY_CTX(func, ctx)
#define EXCEPTION_EXIT_UNWIND
#define EXCEPTION_UNWINDING
#define EXCEPTION_TARGET_UNWIND