This MR implements changes suggested in !2418.
From: Piotr Caban piotr@codeweavers.com
--- dlls/msvcrt/Makefile.in | 1 + .../except_x86_64.c => msvcrt/handler4.c} | 36 +++--- dlls/msvcrt/main.c | 15 +++ dlls/msvcrt/msvcrt.h | 10 ++ dlls/ucrtbase/Makefile.in | 1 + dlls/ucrtbase/ucrtbase.spec | 1 + dlls/vcruntime140_1/Makefile.in | 4 +- dlls/vcruntime140_1/cppexcept.h | 119 ------------------ dlls/vcruntime140_1/main.c | 41 ++++++ 9 files changed, 91 insertions(+), 137 deletions(-) rename dlls/{vcruntime140_1/except_x86_64.c => msvcrt/handler4.c} (98%) delete mode 100644 dlls/vcruntime140_1/cppexcept.h create mode 100644 dlls/vcruntime140_1/main.c
diff --git a/dlls/msvcrt/Makefile.in b/dlls/msvcrt/Makefile.in index 8cd0c4ea7f4..63e6630d7bd 100644 --- a/dlls/msvcrt/Makefile.in +++ b/dlls/msvcrt/Makefile.in @@ -26,6 +26,7 @@ C_SRCS = \ exception_ptr.c \ exit.c \ file.c \ + handler4.c \ heap.c \ iob.c \ locale.c \ diff --git a/dlls/vcruntime140_1/except_x86_64.c b/dlls/msvcrt/handler4.c similarity index 98% rename from dlls/vcruntime140_1/except_x86_64.c rename to dlls/msvcrt/handler4.c index ec6b06c69d6..40cb1a7c3b8 100644 --- a/dlls/vcruntime140_1/except_x86_64.c +++ b/dlls/msvcrt/handler4.c @@ -18,7 +18,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#ifdef __x86_64__ +#include <corecrt.h> + +#if defined(__x86_64__) && _MSVCR_VER>=140
#include <stdarg.h> #include <stdlib.h> @@ -26,6 +28,7 @@ #include "wine/exception.h" #include "wine/debug.h" #include "cppexcept.h" +#include "msvcrt.h"
WINE_DEFAULT_DEBUG_CHANNEL(seh);
@@ -880,24 +883,23 @@ EXCEPTION_DISPOSITION __cdecl __CxxFrameHandler4(EXCEPTION_RECORD *rec, return cxx_frame_handler4(rec, frame, context, dispatch, &descr, trylevel); }
-BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID reserved) +BOOL msvcrt_init_handler4(void) { - switch (fdwReason) - { - case DLL_PROCESS_ATTACH: - fls_index = FlsAlloc(NULL); - if (fls_index == FLS_OUT_OF_INDEXES) - return FALSE; - /* fall through */ - case DLL_THREAD_ATTACH: - FlsSetValue(fls_index, (void*)-2); - break; - case DLL_PROCESS_DETACH: - if (reserved) break; - FlsFree(fls_index); - break; - } + fls_index = FlsAlloc(NULL); + if (fls_index == FLS_OUT_OF_INDEXES) + return FALSE; + msvcrt_attach_handler4(); return TRUE; }
+void msvcrt_attach_handler4(void) +{ + FlsSetValue(fls_index, (void*)-2); +} + +void msvcrt_free_handler4(void) +{ + FlsFree(fls_index); +} + #endif diff --git a/dlls/msvcrt/main.c b/dlls/msvcrt/main.c index db8554668ad..e4bcfe35681 100644 --- a/dlls/msvcrt/main.c +++ b/dlls/msvcrt/main.c @@ -111,6 +111,15 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) msvcrt_destroy_heap(); return FALSE; } +#if defined(__x86_64__) && _MSVCR_VER>=140 + if(!msvcrt_init_handler4()) { + msvcrt_free_locks(); + msvcrt_free_tls_mem(); + msvcrt_destroy_heap(); + _free_locale(MSVCRT_locale); + return FALSE; + } +#endif msvcrt_init_math(hinstDLL); msvcrt_init_io(); msvcrt_init_args(); @@ -128,6 +137,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) TRACE("finished process init\n"); break; case DLL_THREAD_ATTACH: +#if defined(__x86_64__) && _MSVCR_VER>=140 + msvcrt_attach_handler4(); +#endif break; case DLL_PROCESS_DETACH: msvcrt_free_io(); @@ -140,6 +152,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) msvcrt_free_tls_mem(); if (!msvcrt_free_tls()) return FALSE; +#if defined(__x86_64__) && _MSVCR_VER>=140 + msvcrt_free_handler4(); +#endif _free_locale(MSVCRT_locale); #if _MSVCR_VER >= 100 && _MSVCR_VER <= 120 msvcrt_free_scheduler_thread(); diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 1d965ff8ffc..1d2db6a4d87 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -117,6 +117,16 @@ BOOL __cdecl __CxxRegisterExceptionObject(EXCEPTION_POINTERS*, cxx_frame_info*); void __cdecl __CxxUnregisterExceptionObject(cxx_frame_info*, BOOL); void CDECL __DestructExceptionObject(EXCEPTION_RECORD*);
+#if defined(__x86_64__) && _MSVCR_VER>=140 +void** __cdecl __current_exception(void); +int* __cdecl __processing_throw(void); +void __cdecl terminate(void); + +BOOL msvcrt_init_handler4(void); +void msvcrt_attach_handler4(void); +void msvcrt_free_handler4(void); +#endif + /* TLS data */ extern DWORD msvcrt_tls_index DECLSPEC_HIDDEN;
diff --git a/dlls/ucrtbase/Makefile.in b/dlls/ucrtbase/Makefile.in index 4e7cfc03b5c..abab9d4f02c 100644 --- a/dlls/ucrtbase/Makefile.in +++ b/dlls/ucrtbase/Makefile.in @@ -26,6 +26,7 @@ C_SRCS = \ exception_ptr.c \ exit.c \ file.c \ + handler4.c \ heap.c \ locale.c \ lock.c \ diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index c7bff96ee26..bc9dd2bcbc6 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -54,6 +54,7 @@ @ cdecl -arch=i386,x86_64,arm,arm64 -norelay __CxxFrameHandler(ptr ptr ptr ptr) @ cdecl -arch=i386,x86_64,arm,arm64 -norelay __CxxFrameHandler2(ptr ptr ptr ptr) __CxxFrameHandler @ cdecl -arch=i386,x86_64,arm,arm64 -norelay __CxxFrameHandler3(ptr ptr ptr ptr) __CxxFrameHandler +@ cdecl -arch=x86_64 __CxxFrameHandler4(ptr long ptr ptr) @ stdcall -arch=i386 __CxxLongjmpUnwind(ptr) @ cdecl -arch=i386,x86_64,arm,arm64 __CxxQueryExceptionSize() @ cdecl __CxxRegisterExceptionObject(ptr ptr) diff --git a/dlls/vcruntime140_1/Makefile.in b/dlls/vcruntime140_1/Makefile.in index 6b76e4576bc..6e3dd2ec2ff 100644 --- a/dlls/vcruntime140_1/Makefile.in +++ b/dlls/vcruntime140_1/Makefile.in @@ -1,5 +1,7 @@ MODULE = vcruntime140_1.dll IMPORTS = vcruntime140 +PARENTSRC = ../msvcrt
C_SRCS = \ - except_x86_64.c + handler4.c \ + main.c diff --git a/dlls/vcruntime140_1/cppexcept.h b/dlls/vcruntime140_1/cppexcept.h deleted file mode 100644 index 067df35a3de..00000000000 --- a/dlls/vcruntime140_1/cppexcept.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * vcruntime140_1 x86_64 C++ exception handling - * - * Copyright 2002 Alexandre Julliard - * Copyright 2020 Piotr Caban - * - * 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 - */ - -typedef void (*vtable_ptr)(void); - -/* type_info object, see cpp.c for implementation */ -typedef struct __type_info -{ - const vtable_ptr *vtable; - char *name; /* Unmangled name, allocated lazily */ - char mangled[64]; /* Variable length, but we declare it large enough for static RTTI */ -} type_info; - -typedef struct -{ - int this_offset; /* offset of base class this pointer from start of object */ - int vbase_descr; /* offset of virtual base class descriptor */ - int vbase_offset; /* offset of this pointer offset in virtual base class descriptor */ -} this_ptr_offsets; - -/* complete information about a C++ type */ -typedef struct __cxx_type_info -{ - UINT flags; - unsigned int type_info; - this_ptr_offsets offsets; - unsigned int size; - unsigned int copy_ctor; -} cxx_type_info; - -#define CLASS_IS_SIMPLE_TYPE 1 -#define CLASS_HAS_VIRTUAL_BASE_CLASS 4 - -/* table of C++ types that apply for a given object */ -typedef struct __cxx_type_info_table -{ - UINT count; - unsigned int info[3]; -} cxx_type_info_table; - -struct __cxx_exception_frame; -struct __cxx_function_descr; - -/* type information for an exception object */ -typedef struct -{ - UINT flags; - unsigned int destructor; - unsigned int custom_handler; - unsigned int type_info_table; -} cxx_exception_type; - -static inline const char *dbgstr_type_info( const type_info *info ) -{ - if (!info) return "{}"; - 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 */ -static inline void *get_this_pointer( const this_ptr_offsets *off, void *object ) -{ - if (!object) return NULL; - - if (off->vbase_descr >= 0) - { - int *offset_ptr; - - /* move this ptr to vbase descriptor */ - object = (char *)object + off->vbase_descr; - /* and fetch additional offset from vbase descriptor */ - offset_ptr = (int *)(*(char **)object + off->vbase_offset); - object = (char *)object + *offset_ptr; - } - - object = (char *)object + off->this_offset; - return object; -} - -typedef void (__cdecl *_se_translator_function)(unsigned int code, struct _EXCEPTION_POINTERS *info); - -typedef struct _frame_info -{ - void *object; - struct _frame_info *next; -} frame_info; - -typedef struct -{ - frame_info frame_info; - EXCEPTION_RECORD *rec; - CONTEXT *context; -} cxx_frame_info; - -BOOL __cdecl __CxxRegisterExceptionObject(EXCEPTION_POINTERS*, cxx_frame_info*); -void __cdecl __CxxUnregisterExceptionObject(cxx_frame_info*, BOOL); -void __cdecl __DestructExceptionObject(EXCEPTION_RECORD *rec); - -void** __cdecl __current_exception(void); -int* __cdecl __processing_throw(void); -void __cdecl terminate(void); diff --git a/dlls/vcruntime140_1/main.c b/dlls/vcruntime140_1/main.c new file mode 100644 index 00000000000..a0665b9e46f --- /dev/null +++ b/dlls/vcruntime140_1/main.c @@ -0,0 +1,41 @@ +/* + * Copyright 2023 Piotr Caban for CodeWeavers + * + * 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 + */ + +#include <corecrt.h> + +#if defined(__x86_64__) && _MSVCR_VER>=140 + +#include "msvcrt.h" + +BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, VOID *reserved) +{ + switch (reason) + { + case DLL_PROCESS_ATTACH: + return msvcrt_init_handler4(); + case DLL_THREAD_ATTACH: + msvcrt_attach_handler4(); + break; + case DLL_PROCESS_DETACH: + msvcrt_free_handler4(); + break; + } + return TRUE; +} + +#endif