From ec1169363d3b4c86ee4a70162790130266ae8a14 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 13 Jun 2010 01:24:42 +0000 Subject: [PATCH] [CRT] - CRT update part 1/x - sync C++ / exception related CRT code with wine - add support for non-underscored symbols - Patch by Samuel Serapion, slightly modified by me svn path=/trunk/; revision=47770 --- reactos/ReactOS-amd64.rbuild | 1 + reactos/include/reactos/wine/config.h | 8 + reactos/include/reactos/wine/exception.h | 58 ++++- reactos/include/reactos/wine/windef16.h | 2 +- reactos/lib/sdk/crt/crt.rbuild | 1 + reactos/lib/sdk/crt/except/amd64/seh.s | 20 +- reactos/lib/sdk/crt/except/cpp.c | 139 ++++++++--- reactos/lib/sdk/crt/except/cppexcept.c | 40 +++- reactos/lib/sdk/crt/except/except.c | 220 ++++++++++++++++++ reactos/lib/sdk/crt/except/xcptfil.c | 19 +- .../sdk/crt/include/internal/wine/cppexcept.h | 111 +++------ reactos/lib/sdk/crt/precomp.h | 2 + 12 files changed, 462 insertions(+), 159 deletions(-) create mode 100644 reactos/lib/sdk/crt/except/except.c diff --git a/reactos/ReactOS-amd64.rbuild b/reactos/ReactOS-amd64.rbuild index b82bb361d0c..aed1245aba4 100644 --- a/reactos/ReactOS-amd64.rbuild +++ b/reactos/ReactOS-amd64.rbuild @@ -18,6 +18,7 @@ + diff --git a/reactos/include/reactos/wine/config.h b/reactos/include/reactos/wine/config.h index 404783b1d26..d0e2e778758 100644 --- a/reactos/include/reactos/wine/config.h +++ b/reactos/include/reactos/wine/config.h @@ -988,7 +988,11 @@ #define __ASM_CFI(str) str /* Define to a macro to define an assembly function */ +#ifndef NO_UNDERSCORE_PREFIX #define __ASM_DEFINE_FUNC(name,suffix,code) asm(".text\n\t.align 4\n\t.globl _" #name suffix "\n\t.def _" #name suffix "; .scl 2; .type 32; .endef\n_" #name suffix ":\n\t.cfi_startproc\n\t" code "\n\t.cfi_endproc"); +#else +#define __ASM_DEFINE_FUNC(name,suffix,code) asm(".text\n\t.align 4\n\t.globl " #name suffix "\n\t.def " #name suffix "; .scl 2; .type 32; .endef\n" #name suffix ":\n\t.cfi_startproc\n\t" code "\n\t.cfi_endproc"); +#endif /* Define to a macro to generate an assembly function directive */ #define __ASM_FUNC(name) ".def " __ASM_NAME(name) "; .scl 2; .type 32; .endef" @@ -998,7 +1002,11 @@ #define __ASM_GLOBAL_FUNC(name,code) __ASM_DEFINE_FUNC(name,"",code) /* Define to a macro to generate an assembly name from a C symbol */ +#ifndef NO_UNDERSCORE_PREFIX #define __ASM_NAME(name) "_" name +#else +#define __ASM_NAME(name) name +#endif /* Define to a macro to generate an stdcall suffix */ #define __ASM_STDCALL(args) "@" #args diff --git a/reactos/include/reactos/wine/exception.h b/reactos/include/reactos/wine/exception.h index ec156adf928..17ba84c0909 100644 --- a/reactos/include/reactos/wine/exception.h +++ b/reactos/include/reactos/wine/exception.h @@ -1,6 +1,7 @@ #ifndef __WINE_WINE_EXCEPTION_H #define __WINE_WINE_EXCEPTION_H +#include #include #include #include @@ -9,6 +10,21 @@ extern "C" { #endif +/* Win32 seems to use the same flags as ExceptionFlags in an EXCEPTION_RECORD */ +#define EH_NONCONTINUABLE 0x01 +#define EH_UNWINDING 0x02 +#define EH_EXIT_UNWIND 0x04 +#define EH_STACK_INVALID 0x08 +#define EH_NESTED_CALL 0x10 + +#define EXCEPTION_WINE_STUB 0x80000100 +#define EXCEPTION_WINE_ASSERTION 0x80000101 + +#define EXCEPTION_VM86_INTx 0x80000110 +#define EXCEPTION_VM86_STI 0x80000111 +#define EXCEPTION_VM86_PICRETURN 0x80000112 + +#ifndef _RTLTYPES_H typedef EXCEPTION_DISPOSITION (*PEXCEPTION_HANDLER) (struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*); @@ -20,6 +36,17 @@ struct _EXCEPTION_REGISTRATION_RECORD struct _EXCEPTION_REGISTRATION_RECORD * Prev; PEXCEPTION_HANDLER Handler; }; +#else +typedef struct _WINE_EXCEPTION_REGISTRATION_RECORD +{ + PVOID Prev; + PEXCEPTION_ROUTINE Handler; +} WINE_EXCEPTION_REGISTRATION_RECORD, *PWINE_EXCEPTION_REGISTRATION_RECORD; + +#define _EXCEPTION_REGISTRATION_RECORD _WINE_EXCEPTION_REGISTRATION_RECORD +#define EXCEPTION_REGISTRATION_RECORD WINE_EXCEPTION_REGISTRATION_RECORD +#define PEXCEPTION_REGISTRATION_RECORD PWINE_EXCEPTION_REGISTRATION_RECORD +#endif #define __TRY _SEH2_TRY #define __EXCEPT(func) _SEH2_EXCEPT(func(_SEH2_GetExceptionInformation())) @@ -40,31 +67,38 @@ struct _EXCEPTION_REGISTRATION_RECORD #define AbnormalTermination() _SEH2_AbnormalTermination() #endif -/* Win32 seems to use the same flags as ExceptionFlags in an EXCEPTION_RECORD */ -#define EH_NONCONTINUABLE 0x01 -#define EH_UNWINDING 0x02 -#define EH_EXIT_UNWIND 0x04 -#define EH_STACK_INVALID 0x08 -#define EH_NESTED_CALL 0x10 -#define EXCEPTION_WINE_STUB 0x80000100 -#define EXCEPTION_WINE_ASSERTION 0x80000101 - -#define EXCEPTION_VM86_INTx 0x80000110 -#define EXCEPTION_VM86_STI 0x80000111 -#define EXCEPTION_VM86_PICRETURN 0x80000112 +#if defined(__MINGW32__) || defined(__CYGWIN__) +#define sigjmp_buf jmp_buf +#define sigsetjmp(buf,sigs) setjmp(buf) +#define siglongjmp(buf,val) longjmp(buf,val) +#endif static inline EXCEPTION_REGISTRATION_RECORD *__wine_push_frame( EXCEPTION_REGISTRATION_RECORD *frame ) { +#ifdef __i386__ frame->Prev = (struct _EXCEPTION_REGISTRATION_RECORD *)__readfsdword(0); __writefsdword(0, (unsigned long)frame); return frame->Prev; +#else + NT_TIB *teb = (NT_TIB *)NtCurrentTeb(); + frame->Prev = teb->ExceptionList; + teb->ExceptionList = frame; + return frame->Prev; +#endif } static inline EXCEPTION_REGISTRATION_RECORD *__wine_pop_frame( EXCEPTION_REGISTRATION_RECORD *frame ) { +#ifdef __i386__ __writefsdword(0, (unsigned long)frame->Prev); return frame->Prev; +#else + NT_TIB *teb = (NT_TIB *)NtCurrentTeb(); + frame->Prev = teb->ExceptionList; + teb->ExceptionList = frame; + return frame->Prev; +#endif } extern void __wine_enter_vm86( CONTEXT *context ); diff --git a/reactos/include/reactos/wine/windef16.h b/reactos/include/reactos/wine/windef16.h index 5db952eeeb5..002eeaa7e5d 100644 --- a/reactos/include/reactos/wine/windef16.h +++ b/reactos/include/reactos/wine/windef16.h @@ -28,7 +28,7 @@ #endif #include #include -#include // ROS Hack +#include /* Standard data types */ typedef unsigned short BOOL16; diff --git a/reactos/lib/sdk/crt/crt.rbuild b/reactos/lib/sdk/crt/crt.rbuild index c87fd5f81f4..0fd49d12b1c 100644 --- a/reactos/lib/sdk/crt/crt.rbuild +++ b/reactos/lib/sdk/crt/crt.rbuild @@ -56,6 +56,7 @@ checkesp.c cpp.c cppexcept.c + except.c matherr.c diff --git a/reactos/lib/sdk/crt/except/amd64/seh.s b/reactos/lib/sdk/crt/except/amd64/seh.s index 9a7974c3020..82ed5acb594 100644 --- a/reactos/lib/sdk/crt/except/amd64/seh.s +++ b/reactos/lib/sdk/crt/except/amd64/seh.s @@ -17,11 +17,11 @@ /* GLOBALS *******************************************************************/ -.globl __global_unwind2 -.globl __local_unwind2 -.globl __abnormal_termination -.globl __except_handler2 -.globl __except_handler3 +.globl _global_unwind2 +.globl _local_unwind2 +.globl _abnormal_termination +.globl _except_handler2 +.globl _except_handler3 /* FUNCTIONS *****************************************************************/ @@ -31,26 +31,26 @@ _unwind_handler: .endfunc .func _global_unwind2 -__global_unwind2: +_global_unwind2: ret .endfunc .func _abnormal_termination -__abnormal_termination: +_abnormal_termination: ret .endfunc .func _local_unwind2 -__local_unwind2: +_local_unwind2: ret .endfunc .func _except_handler2 -__except_handler2: +_except_handler2: ret .endfunc .func _except_handler3 -__except_handler3: +_except_handler3: ret .endfunc diff --git a/reactos/lib/sdk/crt/except/cpp.c b/reactos/lib/sdk/crt/except/cpp.c index 24b5c3d6c63..445ce084691 100644 --- a/reactos/lib/sdk/crt/except/cpp.c +++ b/reactos/lib/sdk/crt/except/cpp.c @@ -21,6 +21,7 @@ #include +#include #include #include @@ -62,18 +63,18 @@ typedef struct _rtti_object_locator #define THISCALL(func) __thiscall_ ## func #define THISCALL_NAME(func) __ASM_NAME("__thiscall_" #func) -#define DEFINE_THISCALL_WRAPPER(func) \ - extern void THISCALL(func)(); \ +#define DEFINE_THISCALL_WRAPPER(func,args) \ + extern void THISCALL(func)(void); \ __ASM_GLOBAL_FUNC(__thiscall_ ## func, \ "popl %eax\n\t" \ "pushl %ecx\n\t" \ "pushl %eax\n\t" \ - "jmp " __ASM_NAME(#func) ) + "jmp " __ASM_NAME(#func) __ASM_STDCALL(args) ) #else /* __i386__ */ #define THISCALL(func) func #define THISCALL_NAME(func) __ASM_NAME(#func) -#define DEFINE_THISCALL_WRAPPER(func) /* nothing */ +#define DEFINE_THISCALL_WRAPPER(func,args) /* nothing */ #endif /* __i386__ */ @@ -125,7 +126,7 @@ static void WINAPI EXCEPTION_ctor(exception *_this, const char** name) _this->vtable = &MSVCRT_exception_vtable; if (*name) { - size_t name_len = strlen(*name) + 1; + unsigned int name_len = strlen(*name) + 1; _this->name = MSVCRT_malloc(name_len); memcpy(_this->name, *name, name_len); _this->do_free = TRUE; @@ -140,7 +141,7 @@ static void WINAPI EXCEPTION_ctor(exception *_this, const char** name) /****************************************************************** * ??0exception@@QAE@ABQBD@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_exception_ctor) +DEFINE_THISCALL_WRAPPER(MSVCRT_exception_ctor,8) exception * __stdcall MSVCRT_exception_ctor(exception * _this, const char ** name) { TRACE("(%p,%s)\n", _this, *name); @@ -148,10 +149,23 @@ exception * __stdcall MSVCRT_exception_ctor(exception * _this, const char ** nam return _this; } +/****************************************************************** + * ??0exception@@QAE@ABQBDH@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_exception_ctor_noalloc,12) +exception * __stdcall MSVCRT_exception_ctor_noalloc(exception * _this, char ** name, int noalloc) +{ + TRACE("(%p,%s)\n", _this, *name); + _this->vtable = &MSVCRT_exception_vtable; + _this->name = *name; + _this->do_free = FALSE; + return _this; +} + /****************************************************************** * ??0exception@@QAE@ABV0@@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_exception_copy_ctor) +DEFINE_THISCALL_WRAPPER(MSVCRT_exception_copy_ctor,8) exception * __stdcall MSVCRT_exception_copy_ctor(exception * _this, const exception * rhs) { TRACE("(%p,%p)\n", _this, rhs); @@ -171,7 +185,7 @@ exception * __stdcall MSVCRT_exception_copy_ctor(exception * _this, const except /****************************************************************** * ??0exception@@QAE@XZ (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_exception_default_ctor) +DEFINE_THISCALL_WRAPPER(MSVCRT_exception_default_ctor,4) exception * __stdcall MSVCRT_exception_default_ctor(exception * _this) { static const char* empty = NULL; @@ -184,7 +198,7 @@ exception * __stdcall MSVCRT_exception_default_ctor(exception * _this) /****************************************************************** * ??1exception@@UAE@XZ (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_exception_dtor) +DEFINE_THISCALL_WRAPPER(MSVCRT_exception_dtor,4) void __stdcall MSVCRT_exception_dtor(exception * _this) { TRACE("(%p)\n", _this); @@ -195,7 +209,7 @@ void __stdcall MSVCRT_exception_dtor(exception * _this) /****************************************************************** * ??4exception@@QAEAAV0@ABV0@@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_exception_opequals) +DEFINE_THISCALL_WRAPPER(MSVCRT_exception_opequals,8) exception * __stdcall MSVCRT_exception_opequals(exception * _this, const exception * rhs) { TRACE("(%p %p)\n", _this, rhs); @@ -211,7 +225,7 @@ exception * __stdcall MSVCRT_exception_opequals(exception * _this, const excepti /****************************************************************** * ??_Eexception@@UAEPAXI@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_exception_vector_dtor) +DEFINE_THISCALL_WRAPPER(MSVCRT_exception_vector_dtor,8) void * __stdcall MSVCRT_exception_vector_dtor(exception * _this, unsigned int flags) { TRACE("(%p %x)\n", _this, flags); @@ -234,7 +248,7 @@ void * __stdcall MSVCRT_exception_vector_dtor(exception * _this, unsigned int fl /****************************************************************** * ??_Gexception@@UAEPAXI@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_exception_scalar_dtor) +DEFINE_THISCALL_WRAPPER(MSVCRT_exception_scalar_dtor,8) void * __stdcall MSVCRT_exception_scalar_dtor(exception * _this, unsigned int flags) { TRACE("(%p %x)\n", _this, flags); @@ -246,7 +260,7 @@ void * __stdcall MSVCRT_exception_scalar_dtor(exception * _this, unsigned int fl /****************************************************************** * ?what@exception@@UBEPBDXZ (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_what_exception) +DEFINE_THISCALL_WRAPPER(MSVCRT_what_exception,4) const char * __stdcall MSVCRT_what_exception(exception * _this) { TRACE("(%p) returning %s\n", _this, _this->name); @@ -256,7 +270,7 @@ const char * __stdcall MSVCRT_what_exception(exception * _this) /****************************************************************** * ??0bad_typeid@@QAE@ABV0@@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_copy_ctor) +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_copy_ctor,8) bad_typeid * __stdcall MSVCRT_bad_typeid_copy_ctor(bad_typeid * _this, const bad_typeid * rhs) { TRACE("(%p %p)\n", _this, rhs); @@ -268,7 +282,7 @@ bad_typeid * __stdcall MSVCRT_bad_typeid_copy_ctor(bad_typeid * _this, const bad /****************************************************************** * ??0bad_typeid@@QAE@PBD@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_ctor) +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_ctor,8) bad_typeid * __stdcall MSVCRT_bad_typeid_ctor(bad_typeid * _this, const char * name) { TRACE("(%p %s)\n", _this, name); @@ -277,10 +291,19 @@ bad_typeid * __stdcall MSVCRT_bad_typeid_ctor(bad_typeid * _this, const char * n return _this; } +/****************************************************************** + * ??_Fbad_typeid@@QAEXXZ (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_default_ctor,4) +bad_typeid * __stdcall MSVCRT_bad_typeid_default_ctor(bad_typeid * _this) +{ + return MSVCRT_bad_typeid_ctor( _this, "bad typeid" ); +} + /****************************************************************** * ??1bad_typeid@@UAE@XZ (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_dtor) +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_dtor,4) void __stdcall MSVCRT_bad_typeid_dtor(bad_typeid * _this) { TRACE("(%p)\n", _this); @@ -290,7 +313,7 @@ void __stdcall MSVCRT_bad_typeid_dtor(bad_typeid * _this) /****************************************************************** * ??4bad_typeid@@QAEAAV0@ABV0@@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_opequals) +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_opequals,8) bad_typeid * __stdcall MSVCRT_bad_typeid_opequals(bad_typeid * _this, const bad_typeid * rhs) { TRACE("(%p %p)\n", _this, rhs); @@ -301,7 +324,7 @@ bad_typeid * __stdcall MSVCRT_bad_typeid_opequals(bad_typeid * _this, const bad_ /****************************************************************** * ??_Ebad_typeid@@UAEPAXI@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_vector_dtor) +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_vector_dtor,8) void * __stdcall MSVCRT_bad_typeid_vector_dtor(bad_typeid * _this, unsigned int flags) { TRACE("(%p %x)\n", _this, flags); @@ -324,7 +347,7 @@ void * __stdcall MSVCRT_bad_typeid_vector_dtor(bad_typeid * _this, unsigned int /****************************************************************** * ??_Gbad_typeid@@UAEPAXI@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_scalar_dtor) +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_scalar_dtor,8) void * __stdcall MSVCRT_bad_typeid_scalar_dtor(bad_typeid * _this, unsigned int flags) { TRACE("(%p %x)\n", _this, flags); @@ -336,7 +359,7 @@ void * __stdcall MSVCRT_bad_typeid_scalar_dtor(bad_typeid * _this, unsigned int /****************************************************************** * ??0__non_rtti_object@@QAE@ABV0@@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_copy_ctor) +DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_copy_ctor,8) __non_rtti_object * __stdcall MSVCRT___non_rtti_object_copy_ctor(__non_rtti_object * _this, const __non_rtti_object * rhs) { @@ -349,7 +372,7 @@ __non_rtti_object * __stdcall MSVCRT___non_rtti_object_copy_ctor(__non_rtti_obje /****************************************************************** * ??0__non_rtti_object@@QAE@PBD@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_ctor) +DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_ctor,8) __non_rtti_object * __stdcall MSVCRT___non_rtti_object_ctor(__non_rtti_object * _this, const char * name) { @@ -362,7 +385,7 @@ __non_rtti_object * __stdcall MSVCRT___non_rtti_object_ctor(__non_rtti_object * /****************************************************************** * ??1__non_rtti_object@@UAE@XZ (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_dtor) +DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_dtor,4) void __stdcall MSVCRT___non_rtti_object_dtor(__non_rtti_object * _this) { TRACE("(%p)\n", _this); @@ -372,7 +395,7 @@ void __stdcall MSVCRT___non_rtti_object_dtor(__non_rtti_object * _this) /****************************************************************** * ??4__non_rtti_object@@QAEAAV0@ABV0@@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_opequals) +DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_opequals,8) __non_rtti_object * __stdcall MSVCRT___non_rtti_object_opequals(__non_rtti_object * _this, const __non_rtti_object *rhs) { @@ -384,7 +407,7 @@ __non_rtti_object * __stdcall MSVCRT___non_rtti_object_opequals(__non_rtti_objec /****************************************************************** * ??_E__non_rtti_object@@UAEPAXI@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_vector_dtor) +DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_vector_dtor,8) void * __stdcall MSVCRT___non_rtti_object_vector_dtor(__non_rtti_object * _this, unsigned int flags) { TRACE("(%p %x)\n", _this, flags); @@ -407,7 +430,7 @@ void * __stdcall MSVCRT___non_rtti_object_vector_dtor(__non_rtti_object * _this, /****************************************************************** * ??_G__non_rtti_object@@UAEPAXI@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_scalar_dtor) +DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_scalar_dtor,8) void * __stdcall MSVCRT___non_rtti_object_scalar_dtor(__non_rtti_object * _this, unsigned int flags) { TRACE("(%p %x)\n", _this, flags); @@ -417,9 +440,10 @@ void * __stdcall MSVCRT___non_rtti_object_scalar_dtor(__non_rtti_object * _this, } /****************************************************************** + * ??0bad_cast@@AAE@PBQBD@Z (MSVCRT.@) * ??0bad_cast@@QAE@ABQBD@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_ctor) +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_ctor,8) bad_cast * __stdcall MSVCRT_bad_cast_ctor(bad_cast * _this, const char ** name) { TRACE("(%p %s)\n", _this, *name); @@ -431,7 +455,7 @@ bad_cast * __stdcall MSVCRT_bad_cast_ctor(bad_cast * _this, const char ** name) /****************************************************************** * ??0bad_cast@@QAE@ABV0@@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_copy_ctor) +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_copy_ctor,8) bad_cast * __stdcall MSVCRT_bad_cast_copy_ctor(bad_cast * _this, const bad_cast * rhs) { TRACE("(%p %p)\n", _this, rhs); @@ -440,10 +464,31 @@ bad_cast * __stdcall MSVCRT_bad_cast_copy_ctor(bad_cast * _this, const bad_cast return _this; } +/****************************************************************** + * ??0bad_cast@@QAE@PBD@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_ctor_charptr,8) +bad_cast * __stdcall MSVCRT_bad_cast_ctor_charptr(bad_cast * _this, const char * name) +{ + TRACE("(%p %s)\n", _this, name); + EXCEPTION_ctor(_this, &name); + _this->vtable = &MSVCRT_bad_cast_vtable; + return _this; +} + +/****************************************************************** + * ??_Fbad_cast@@QAEXXZ (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_default_ctor,4) +bad_cast * __stdcall MSVCRT_bad_cast_default_ctor(bad_cast * _this) +{ + return MSVCRT_bad_cast_ctor_charptr( _this, "bad cast" ); +} + /****************************************************************** * ??1bad_cast@@UAE@XZ (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_dtor) +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_dtor,4) void __stdcall MSVCRT_bad_cast_dtor(bad_cast * _this) { TRACE("(%p)\n", _this); @@ -453,7 +498,7 @@ void __stdcall MSVCRT_bad_cast_dtor(bad_cast * _this) /****************************************************************** * ??4bad_cast@@QAEAAV0@ABV0@@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_opequals) +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_opequals,8) bad_cast * __stdcall MSVCRT_bad_cast_opequals(bad_cast * _this, const bad_cast * rhs) { TRACE("(%p %p)\n", _this, rhs); @@ -464,7 +509,7 @@ bad_cast * __stdcall MSVCRT_bad_cast_opequals(bad_cast * _this, const bad_cast * /****************************************************************** * ??_Ebad_cast@@UAEPAXI@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_vector_dtor) +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_vector_dtor,8) void * __stdcall MSVCRT_bad_cast_vector_dtor(bad_cast * _this, unsigned int flags) { TRACE("(%p %x)\n", _this, flags); @@ -487,7 +532,7 @@ void * __stdcall MSVCRT_bad_cast_vector_dtor(bad_cast * _this, unsigned int flag /****************************************************************** * ??_Gbad_cast@@UAEPAXI@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_scalar_dtor) +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_scalar_dtor,8) void * __stdcall MSVCRT_bad_cast_scalar_dtor(bad_cast * _this, unsigned int flags) { TRACE("(%p %x)\n", _this, flags); @@ -499,7 +544,7 @@ void * __stdcall MSVCRT_bad_cast_scalar_dtor(bad_cast * _this, unsigned int flag /****************************************************************** * ??8type_info@@QBEHABV0@@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_opequals_equals) +DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_opequals_equals,8) int __stdcall MSVCRT_type_info_opequals_equals(type_info * _this, const type_info * rhs) { int ret = !strcmp(_this->mangled + 1, rhs->mangled + 1); @@ -510,7 +555,7 @@ int __stdcall MSVCRT_type_info_opequals_equals(type_info * _this, const type_inf /****************************************************************** * ??9type_info@@QBEHABV0@@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_opnot_equals) +DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_opnot_equals,8) int __stdcall MSVCRT_type_info_opnot_equals(type_info * _this, const type_info * rhs) { int ret = !!strcmp(_this->mangled + 1, rhs->mangled + 1); @@ -521,7 +566,7 @@ int __stdcall MSVCRT_type_info_opnot_equals(type_info * _this, const type_info * /****************************************************************** * ?before@type_info@@QBEHABV1@@Z (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_before) +DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_before,8) int __stdcall MSVCRT_type_info_before(type_info * _this, const type_info * rhs) { int ret = strcmp(_this->mangled + 1, rhs->mangled + 1) < 0; @@ -532,7 +577,7 @@ int __stdcall MSVCRT_type_info_before(type_info * _this, const type_info * rhs) /****************************************************************** * ??1type_info@@UAE@XZ (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_dtor) +DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_dtor,4) void __stdcall MSVCRT_type_info_dtor(type_info * _this) { TRACE("(%p)\n", _this); @@ -542,7 +587,7 @@ void __stdcall MSVCRT_type_info_dtor(type_info * _this) /****************************************************************** * ?name@type_info@@QBEPBDXZ (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_name) +DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_name,4) const char * __stdcall MSVCRT_type_info_name(type_info * _this) { if (!_this->name) @@ -583,7 +628,7 @@ const char * __stdcall MSVCRT_type_info_name(type_info * _this) /****************************************************************** * ?raw_name@type_info@@QBEPBDXZ (MSVCRT.@) */ -DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_raw_name) +DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_raw_name,4) const char * __stdcall MSVCRT_type_info_raw_name(type_info * _this) { TRACE("(%p) returning %s\n", _this, _this->mangled); @@ -591,7 +636,7 @@ const char * __stdcall MSVCRT_type_info_raw_name(type_info * _this) } /* Unexported */ -DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_vector_dtor) +DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_vector_dtor,8) void * __stdcall MSVCRT_type_info_vector_dtor(type_info * _this, unsigned int flags) { TRACE("(%p %x)\n", _this, flags); @@ -613,6 +658,22 @@ void * __stdcall MSVCRT_type_info_vector_dtor(type_info * _this, unsigned int fl /* vtables */ +#ifdef _WIN64 + +#define __ASM_VTABLE(name,funcs) \ + __asm__(".data\n" \ + "\t.align 8\n" \ + "\t.quad " __ASM_NAME(#name "_rtti") "\n" \ + "\t.globl " __ASM_NAME("MSVCRT_" #name "_vtable") "\n" \ + __ASM_NAME("MSVCRT_" #name "_vtable") ":\n" \ + "\t.quad " THISCALL_NAME(MSVCRT_ ## name ## _vector_dtor) "\n" \ + funcs "\n\t.text"); + +#define __ASM_EXCEPTION_VTABLE(name) \ + __ASM_VTABLE(name, "\t.quad " THISCALL_NAME(MSVCRT_what_exception) ) + +#else + #define __ASM_VTABLE(name,funcs) \ __asm__(".data\n" \ "\t.align 4\n" \ @@ -625,6 +686,8 @@ void * __stdcall MSVCRT_type_info_vector_dtor(type_info * _this, unsigned int fl #define __ASM_EXCEPTION_VTABLE(name) \ __ASM_VTABLE(name, "\t.long " THISCALL_NAME(MSVCRT_what_exception) ) +#endif /* _WIN64 */ + #ifndef __GNUC__ void __asm_dummy_vtables(void) { #endif diff --git a/reactos/lib/sdk/crt/except/cppexcept.c b/reactos/lib/sdk/crt/except/cppexcept.c index f84682d61e9..02a74a952e9 100644 --- a/reactos/lib/sdk/crt/except/cppexcept.c +++ b/reactos/lib/sdk/crt/except/cppexcept.c @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -123,7 +124,6 @@ static void dump_function_descr( const cxx_function_descr *descr ) descr->tryblock[i].start_level, descr->tryblock[i].end_level, descr->tryblock[i].catch_level, descr->tryblock[i].catchblock, descr->tryblock[i].catchblock_count ); - for (j = 0; j < descr->tryblock[i].catchblock_count; j++) { const catchblock_info *ptr = &descr->tryblock[i].catchblock[j]; @@ -133,6 +133,10 @@ static void dump_function_descr( const cxx_function_descr *descr ) } } #endif + if (descr->magic <= CXX_FRAME_MAGIC_VC6) return; + TRACE( "expect list: %p\n", descr->expect_list ); + if (descr->magic <= CXX_FRAME_MAGIC_VC7) return; + TRACE( "flags: %08x\n", descr->flags ); } /* check if the exception type is caught by a given catch block, and return the type that matched */ @@ -194,7 +198,7 @@ static void copy_exception( void *object, cxx_exception_frame *frame, /* unwind the local function up to a given trylevel */ static void cxx_local_unwind( cxx_exception_frame* frame, const cxx_function_descr *descr, int last_level) { - void (*handler)(); + void (*handler)(void); int trylevel = frame->trylevel; while (trylevel != last_level) @@ -358,11 +362,16 @@ DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame { cxx_exception_type *exc_type; - if (descr->magic != CXX_FRAME_MAGIC) + if (descr->magic < CXX_FRAME_MAGIC_VC6 || descr->magic > CXX_FRAME_MAGIC_VC8) { ERR( "invalid frame magic %x\n", descr->magic ); return ExceptionContinueSearch; } + if (descr->magic >= CXX_FRAME_MAGIC_VC8 && + (descr->flags & FUNC_DESCR_SYNCHRONOUS) && + (rec->ExceptionCode != CXX_EXCEPTION)) + return ExceptionContinueSearch; /* handle only c++ exceptions */ + if (rec->ExceptionFlags & (EH_UNWINDING|EH_EXIT_UNWIND)) { if (descr->unwind_count && !nested_trylevel) cxx_local_unwind( frame, descr, -1 ); @@ -374,7 +383,7 @@ DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame { exc_type = (cxx_exception_type *)rec->ExceptionInformation[2]; - if (rec->ExceptionInformation[0] > CXX_FRAME_MAGIC && + if (rec->ExceptionInformation[0] > CXX_FRAME_MAGIC_VC8 && exc_type->custom_handler) { return exc_type->custom_handler( rec, frame, context, dispatch, @@ -408,14 +417,22 @@ extern DWORD CDECL __CxxFrameHandler( PEXCEPTION_RECORD rec, EXCEPTION_REGISTRAT PCONTEXT context, EXCEPTION_REGISTRATION_RECORD** dispatch ); __ASM_GLOBAL_FUNC( __CxxFrameHandler, "pushl $0\n\t" /* nested_trylevel */ + __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") "pushl $0\n\t" /* nested_frame */ + __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") "pushl %eax\n\t" /* descr */ + __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") "pushl 28(%esp)\n\t" /* dispatch */ + __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") "pushl 28(%esp)\n\t" /* context */ + __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") "pushl 28(%esp)\n\t" /* frame */ + __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") "pushl 28(%esp)\n\t" /* rec */ + __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") "call " __ASM_NAME("cxx_frame_handler") "\n\t" "add $28,%esp\n\t" + __ASM_CFI(".cfi_adjust_cfa_offset -28\n\t") "ret" ) @@ -435,6 +452,17 @@ void __stdcall __CxxLongjmpUnwind( const struct MSVCRT___JUMP_BUFFER *buf ) #endif /* __i386__ */ + +/********************************************************************* + * __CppXcptFilter (MSVCRT.@) + */ +int CDECL __CppXcptFilter(NTSTATUS ex, PEXCEPTION_POINTERS ptr) +{ + /* only filter c++ exceptions */ + if (ex != CXX_EXCEPTION) return EXCEPTION_CONTINUE_SEARCH; + return _XcptFilter( ex, ptr ); +} + /********************************************************************* * _CxxThrowException (MSVCRT.@) */ @@ -442,7 +470,7 @@ void CDECL _CxxThrowException( exception *object, const cxx_exception_type *type { ULONG_PTR args[3]; - args[0] = CXX_FRAME_MAGIC; + args[0] = CXX_FRAME_MAGIC_VC6; args[1] = (ULONG_PTR)object; args[2] = (ULONG_PTR)type; RaiseException( CXX_EXCEPTION, EH_NONCONTINUABLE, 3, args ); @@ -462,7 +490,7 @@ BOOL CDECL __CxxDetectRethrow(PEXCEPTION_POINTERS ptrs) if (rec->ExceptionCode == CXX_EXCEPTION && rec->NumberParameters == 3 && - rec->ExceptionInformation[0] == CXX_FRAME_MAGIC && + rec->ExceptionInformation[0] == CXX_FRAME_MAGIC_VC6 && rec->ExceptionInformation[2]) { ptrs->ExceptionRecord = msvcrt_get_thread_data()->exc_record; diff --git a/reactos/lib/sdk/crt/except/except.c b/reactos/lib/sdk/crt/except/except.c new file mode 100644 index 00000000000..663677776fd --- /dev/null +++ b/reactos/lib/sdk/crt/except/except.c @@ -0,0 +1,220 @@ +/* + * msvcrt.dll exception handling + * + * Copyright 2000 Jon Griffiths + * Copyright 2005 Juan Lang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + * FIXME: Incomplete support for nested exceptions/try block cleanup. + */ + +#include +#include "excpt.h" +#include + +void CDECL _global_unwind2(EXCEPTION_REGISTRATION_RECORD* frame); + +/* VC++ extensions to Win32 SEH */ +typedef struct _SCOPETABLE +{ + int previousTryLevel; + int (*lpfnFilter)(PEXCEPTION_POINTERS); + int (*lpfnHandler)(void); +} SCOPETABLE, *PSCOPETABLE; + +typedef struct _MSVCRT_EXCEPTION_FRAME +{ + EXCEPTION_REGISTRATION_RECORD *prev; + void (*handler)(PEXCEPTION_RECORD, EXCEPTION_REGISTRATION_RECORD*, + PCONTEXT, PEXCEPTION_RECORD); + PSCOPETABLE scopetable; + int trylevel; + int _ebp; + PEXCEPTION_POINTERS xpointers; +} MSVCRT_EXCEPTION_FRAME; + +typedef struct +{ + int gs_cookie_offset; + ULONG gs_cookie_xor; + int eh_cookie_offset; + ULONG eh_cookie_xor; + SCOPETABLE entries[1]; +} SCOPETABLE_V4; + +#ifdef __i386__ + +static const SCOPETABLE_V4 *get_scopetable_v4( MSVCRT_EXCEPTION_FRAME *frame, ULONG_PTR cookie ) +{ + return (const SCOPETABLE_V4 *)((ULONG_PTR)frame->scopetable ^ cookie); +} + +#if defined(__GNUC__) +static inline void call_finally_block( void *code_block, void *base_ptr ) +{ + __asm__ __volatile__ ("movl %1,%%ebp; call *%%eax" + : : "a" (code_block), "g" (base_ptr)); +} + +static inline int call_filter( int (*func)(PEXCEPTION_POINTERS), void *arg, void *ebp ) +{ + int ret; + __asm__ __volatile__ ("pushl %%ebp; pushl %3; movl %2,%%ebp; call *%%eax; popl %%ebp; popl %%ebp" + : "=a" (ret) + : "0" (func), "r" (ebp), "r" (arg) + : "ecx", "edx", "memory" ); + return ret; +} +static inline int call_unwind_func( int (*func)(void), void *ebp ) +{ + int ret; + __asm__ __volatile__ ("pushl %%ebp\n\t" + "pushl %%ebx\n\t" + "pushl %%esi\n\t" + "pushl %%edi\n\t" + "movl %2,%%ebp\n\t" + "call *%0\n\t" + "popl %%edi\n\t" + "popl %%esi\n\t" + "popl %%ebx\n\t" + "popl %%ebp" + : "=a" (ret) + : "0" (func), "r" (ebp) + : "ecx", "edx", "memory" ); + return ret; +} +#endif + +static DWORD MSVCRT_nested_handler(PEXCEPTION_RECORD rec, + EXCEPTION_REGISTRATION_RECORD* frame, + PCONTEXT context, + EXCEPTION_REGISTRATION_RECORD** dispatch) +{ + if (!(rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))) + return ExceptionContinueSearch; + *dispatch = frame; + return ExceptionCollidedUnwind; +} + +void msvcrt_local_unwind4( ULONG *cookie, MSVCRT_EXCEPTION_FRAME* frame, int trylevel, void *ebp ) +{ + EXCEPTION_REGISTRATION_RECORD reg; + const SCOPETABLE_V4 *scopetable = get_scopetable_v4( frame, *cookie ); + + TRACE("(%p,%d,%d)\n",frame, frame->trylevel, trylevel); + + /* Register a handler in case of a nested exception */ + reg.Handler = (PEXCEPTION_ROUTINE)MSVCRT_nested_handler; + reg.Prev = NtCurrentTeb()->NtTib.ExceptionList; + __wine_push_frame(®); + + while (frame->trylevel != -2 && frame->trylevel != trylevel) + { + int level = frame->trylevel; + frame->trylevel = scopetable->entries[level].previousTryLevel; + if (!scopetable->entries[level].lpfnFilter) + { + TRACE( "__try block cleanup level %d handler %p ebp %p\n", + level, scopetable->entries[level].lpfnHandler, ebp ); + call_unwind_func( scopetable->entries[level].lpfnHandler, ebp ); + } + } + __wine_pop_frame(®); + TRACE("unwound OK\n"); +} + +/********************************************************************* + * _except_handler4_common (MSVCRT.@) + */ +int CDECL _except_handler4_common( ULONG *cookie, void (*check_cookie)(void), + EXCEPTION_RECORD *rec, MSVCRT_EXCEPTION_FRAME *frame, + CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher ) +{ + int retval, trylevel; + EXCEPTION_POINTERS exceptPtrs; + const SCOPETABLE_V4 *scope_table = get_scopetable_v4( frame, *cookie ); + + TRACE( "exception %x flags=%x at %p handler=%p %p %p cookie=%x scope table=%p cookies=%d/%x,%d/%x\n", + rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress, + frame->handler, context, dispatcher, *cookie, scope_table, + scope_table->gs_cookie_offset, scope_table->gs_cookie_xor, + scope_table->eh_cookie_offset, scope_table->eh_cookie_xor ); + + /* FIXME: no cookie validation yet */ + + if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)) + { + /* Unwinding the current frame */ + msvcrt_local_unwind4( cookie, frame, -2, &frame->_ebp ); + TRACE("unwound current frame, returning ExceptionContinueSearch\n"); + return ExceptionContinueSearch; + } + else + { + /* Hunting for handler */ + exceptPtrs.ExceptionRecord = rec; + exceptPtrs.ContextRecord = context; + *((DWORD *)frame-1) = (DWORD)&exceptPtrs; + trylevel = frame->trylevel; + + while (trylevel != -2) + { + TRACE( "level %d prev %d filter %p\n", trylevel, + scope_table->entries[trylevel].previousTryLevel, + scope_table->entries[trylevel].lpfnFilter ); + if (scope_table->entries[trylevel].lpfnFilter) + { + retval = call_filter( scope_table->entries[trylevel].lpfnFilter, &exceptPtrs, &frame->_ebp ); + + TRACE("filter returned %s\n", retval == EXCEPTION_CONTINUE_EXECUTION ? + "CONTINUE_EXECUTION" : retval == EXCEPTION_EXECUTE_HANDLER ? + "EXECUTE_HANDLER" : "CONTINUE_SEARCH"); + + if (retval == EXCEPTION_CONTINUE_EXECUTION) + return ExceptionContinueExecution; + + if (retval == EXCEPTION_EXECUTE_HANDLER) + { + /* Unwind all higher frames, this one will handle the exception */ + _global_unwind2((EXCEPTION_REGISTRATION_RECORD*)frame); + msvcrt_local_unwind4( cookie, frame, trylevel, &frame->_ebp ); + + /* Set our trylevel to the enclosing block, and call the __finally + * code, which won't return + */ + frame->trylevel = scope_table->entries[trylevel].previousTryLevel; + TRACE("__finally block %p\n",scope_table->entries[trylevel].lpfnHandler); + call_finally_block(scope_table->entries[trylevel].lpfnHandler, &frame->_ebp); + ERR("Returned from __finally block - expect crash!\n"); + } + } + trylevel = scope_table->entries[trylevel].previousTryLevel; + } + } + TRACE("reached -2, returning ExceptionContinueSearch\n"); + return ExceptionContinueSearch; +} + +#endif + +/****************************************************************** + * __uncaught_exception + */ +BOOL CDECL __uncaught_exception(void) +{ + return FALSE; +} + diff --git a/reactos/lib/sdk/crt/except/xcptfil.c b/reactos/lib/sdk/crt/except/xcptfil.c index e294e127a81..c5b8d1d1e76 100644 --- a/reactos/lib/sdk/crt/except/xcptfil.c +++ b/reactos/lib/sdk/crt/except/xcptfil.c @@ -23,8 +23,8 @@ static const struct /* * @implemented */ -int -_XcptFilter(DWORD ExceptionCode, +int CDECL +_XcptFilter(NTSTATUS ExceptionCode, struct _EXCEPTION_POINTERS * except) { LONG ret = EXCEPTION_CONTINUE_SEARCH; @@ -61,7 +61,8 @@ _XcptFilter(DWORD ExceptionCode, { if (handler != SIG_IGN) { - int i, float_signal = _FPE_INVALID; + unsigned int i; + int float_signal = _FPE_INVALID; sighandlers[SIGFPE] = SIG_DFL; for (i = 0; i < sizeof(float_exception_map) / @@ -80,6 +81,7 @@ _XcptFilter(DWORD ExceptionCode, } break; case EXCEPTION_ILLEGAL_INSTRUCTION: + case EXCEPTION_PRIV_INSTRUCTION: if ((handler = sighandlers[SIGILL]) != SIG_DFL) { if (handler != SIG_IGN) @@ -94,14 +96,3 @@ _XcptFilter(DWORD ExceptionCode, return ret; } -int CDECL __CppXcptFilter(unsigned long ex, PEXCEPTION_POINTERS ptr) -{ - /* only filter c++ exceptions */ - if (ex != CXX_EXCEPTION) return EXCEPTION_CONTINUE_SEARCH; - return _XcptFilter( ex, ptr ); -} - - - - - diff --git a/reactos/lib/sdk/crt/include/internal/wine/cppexcept.h b/reactos/lib/sdk/crt/include/internal/wine/cppexcept.h index 97f9fb81fc0..1d0942e2f1f 100644 --- a/reactos/lib/sdk/crt/include/internal/wine/cppexcept.h +++ b/reactos/lib/sdk/crt/include/internal/wine/cppexcept.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __MSVCRT_CPPEXCEPT_H @@ -23,71 +23,19 @@ #include +#define CXX_FRAME_MAGIC_VC6 0x19930520 +#define CXX_FRAME_MAGIC_VC7 0x19930521 +#define CXX_FRAME_MAGIC_VC8 0x19930522 +#define CXX_EXCEPTION 0xe06d7363 + /* Macros to define assembler functions somewhat portably */ -#define __ASM_FUNC(name) ".def " __ASM_NAME(name) "; .scl 2; .type 32; .endef" -#define __ASM_NAME(name) "_" name - -#ifdef __GNUC__ -# define __ASM_GLOBAL_FUNC(name,code) \ - __asm__( ".align 4\n\t" \ - ".globl " __ASM_NAME(#name) "\n\t" \ - __ASM_FUNC(#name) "\n" \ - __ASM_NAME(#name) ":\n\t" \ - code ); -#else /* __GNUC__ */ -# define __ASM_GLOBAL_FUNC(name,code) \ - void __asm_dummy_##name(void) { \ - asm( ".align 4\n\t" \ - ".globl " __ASM_NAME(#name) "\n\t" \ - __ASM_FUNC(#name) "\n" \ - __ASM_NAME(#name) ":\n\t" \ - code ); \ - } -#endif /* __GNUC__ */ - #define EH_NONCONTINUABLE 0x01 #define EH_UNWINDING 0x02 #define EH_EXIT_UNWIND 0x04 #define EH_STACK_INVALID 0x08 #define EH_NESTED_CALL 0x10 -#ifndef _M_ARM - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4733) -#endif - -static inline EXCEPTION_REGISTRATION_RECORD *__wine_push_frame( EXCEPTION_REGISTRATION_RECORD *frame ) -{ - frame->Next = (struct _EXCEPTION_REGISTRATION_RECORD *)__readfsdword(0); - __writefsdword(0, (unsigned long)frame); - return frame->Next; -} - -static inline EXCEPTION_REGISTRATION_RECORD *__wine_pop_frame( EXCEPTION_REGISTRATION_RECORD *frame ) -{ - __writefsdword(0, (unsigned long)frame->Next); - return frame->Next; -} - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -#endif - -#define __TRY _SEH2_TRY -#define __EXCEPT(func) _SEH2_EXCEPT(func(_SEH2_GetExceptionInformation())) -#define __EXCEPT_PAGE_FAULT _SEH2_EXCEPT(_SEH2_GetExceptionCode() == STATUS_ACCESS_VIOLATION) -#define __EXCEPT_ALL _SEH2_EXCEPT(_SEH_EXECUTE_HANDLER) -#define __ENDTRY _SEH2_END -#define __FINALLY(func) _SEH2_FINALLY { func(!_SEH2_AbnormalTermination()); } - -#define CXX_FRAME_MAGIC 0x19930520 -#define CXX_EXCEPTION 0xe06d7363 - typedef void (*vtable_ptr)(); /* type_info object, see cpp.c for inplementation */ @@ -117,10 +65,10 @@ typedef struct __cxx_exception_frame /* info about a single catch {} block */ typedef struct __catchblock_info { - UINT flags; /* flags (see below) */ - type_info *type_info; /* C++ type caught by this block */ - int offset; /* stack offset to copy exception object to */ - void (*handler)(); /* catch block handler code */ + UINT flags; /* flags (see below) */ + const type_info *type_info; /* C++ type caught by this block */ + int offset; /* stack offset to copy exception object to */ + void (*handler)(void);/* catch block handler code */ } catchblock_info; #define TYPE_FLAG_CONST 1 #define TYPE_FLAG_VOLATILE 2 @@ -129,31 +77,36 @@ typedef struct __catchblock_info /* info about a single try {} block */ typedef struct __tryblock_info { - int start_level; /* start trylevel of that block */ - int end_level; /* end trylevel of that block */ - int catch_level; /* initial trylevel of the catch block */ - int catchblock_count; /* count of catch blocks in array */ - catchblock_info *catchblock; /* array of catch blocks */ + int start_level; /* start trylevel of that block */ + int end_level; /* end trylevel of that block */ + int catch_level; /* initial trylevel of the catch block */ + int catchblock_count; /* count of catch blocks in array */ + const catchblock_info *catchblock; /* array of catch blocks */ } tryblock_info; /* info about the unwind handler for a given trylevel */ typedef struct __unwind_info { int prev; /* prev trylevel unwind handler, to run after this one */ - void (*handler)(); /* unwind handler */ + void (*handler)(void);/* unwind handler */ } unwind_info; /* descriptor of all try blocks of a given function */ typedef struct __cxx_function_descr { - UINT magic; /* must be CXX_FRAME_MAGIC */ - UINT unwind_count; /* number of unwind handlers */ - unwind_info *unwind_table; /* array of unwind handlers */ - UINT tryblock_count; /* number of try blocks */ - tryblock_info *tryblock; /* array of try blocks */ - UINT unknown[3]; + UINT magic; /* must be CXX_FRAME_MAGIC */ + UINT unwind_count; /* number of unwind handlers */ + const unwind_info *unwind_table; /* array of unwind handlers */ + UINT tryblock_count; /* number of try blocks */ + const tryblock_info *tryblock; /* array of try blocks */ + UINT ipmap_count; + const void *ipmap; + const void *expect_list; /* expected exceptions list when magic >= VC7 */ + UINT flags; /* flags when magic >= VC8 */ } cxx_function_descr; +#define FUNC_DESCR_SYNCHRONOUS 1 /* synchronous exceptions only (built with /EHs) */ + typedef void (*cxx_copy_ctor)(void); /* offsets for computing the this pointer */ @@ -192,18 +145,20 @@ typedef DWORD (*cxx_exc_custom_handler)( PEXCEPTION_RECORD, cxx_exception_frame* typedef struct __cxx_exception_type { UINT flags; /* TYPE_FLAG flags */ - void (*destructor)(); /* exception object destructor */ + void (*destructor)(void);/* exception object destructor */ cxx_exc_custom_handler custom_handler; /* custom handler for this exception */ const cxx_type_info_table *type_info_table; /* list of types for this exception object */ } cxx_exception_type; -void _CxxThrowException(exception*,const cxx_exception_type*); +void CDECL _CxxThrowException(exception*,const cxx_exception_type*); +int CDECL _XcptFilter(NTSTATUS, PEXCEPTION_POINTERS); +int CDECL __CppXcptFilter(NTSTATUS, PEXCEPTION_POINTERS); static inline const char *dbgstr_type_info( const type_info *info ) { if (!info) return "{}"; - return "{}";/*sprintf( "{vtable=%p name=%s (%s)}", - info->vtable, info->mangled, info->name ? info->name : "" );*/ + return wine_dbg_sprintf( "{vtable=%p name=%s (%s)}", + info->vtable, info->mangled, info->name ? info->name : "" ); } /* compute the this pointer for a base class of a given type */ diff --git a/reactos/lib/sdk/crt/precomp.h b/reactos/lib/sdk/crt/precomp.h index 580f29d310c..acc6e6d7dec 100644 --- a/reactos/lib/sdk/crt/precomp.h +++ b/reactos/lib/sdk/crt/precomp.h @@ -34,6 +34,7 @@ #endif #include "wine/unicode.h" +#include "wine/config.h" /* kernelmode libcnt should not include Wine-debugging crap */ #ifndef _LIBCNT_ @@ -58,6 +59,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt); #include #include #include +#include #include #include #include