Commit 75669ea3 authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

ucrtbase: Add __CxxFrameHandler4 implementation.

parent b8807b99
...@@ -26,6 +26,7 @@ C_SRCS = \ ...@@ -26,6 +26,7 @@ C_SRCS = \
exception_ptr.c \ exception_ptr.c \
exit.c \ exit.c \
file.c \ file.c \
handler4.c \
heap.c \ heap.c \
iob.c \ iob.c \
locale.c \ locale.c \
......
...@@ -18,7 +18,9 @@ ...@@ -18,7 +18,9 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 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 <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -26,6 +28,7 @@ ...@@ -26,6 +28,7 @@
#include "wine/exception.h" #include "wine/exception.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "cppexcept.h" #include "cppexcept.h"
#include "msvcrt.h"
WINE_DEFAULT_DEBUG_CHANNEL(seh); WINE_DEFAULT_DEBUG_CHANNEL(seh);
...@@ -880,24 +883,23 @@ EXCEPTION_DISPOSITION __cdecl __CxxFrameHandler4(EXCEPTION_RECORD *rec, ...@@ -880,24 +883,23 @@ EXCEPTION_DISPOSITION __cdecl __CxxFrameHandler4(EXCEPTION_RECORD *rec,
return cxx_frame_handler4(rec, frame, context, dispatch, &descr, trylevel); 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) fls_index = FlsAlloc(NULL);
{ if (fls_index == FLS_OUT_OF_INDEXES)
case DLL_PROCESS_ATTACH: return FALSE;
fls_index = FlsAlloc(NULL); msvcrt_attach_handler4();
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;
}
return TRUE; return TRUE;
} }
void msvcrt_attach_handler4(void)
{
FlsSetValue(fls_index, (void*)-2);
}
void msvcrt_free_handler4(void)
{
FlsFree(fls_index);
}
#endif #endif
...@@ -111,6 +111,15 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) ...@@ -111,6 +111,15 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
msvcrt_destroy_heap(); msvcrt_destroy_heap();
return FALSE; 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_math(hinstDLL);
msvcrt_init_io(); msvcrt_init_io();
msvcrt_init_args(); msvcrt_init_args();
...@@ -128,6 +137,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) ...@@ -128,6 +137,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
TRACE("finished process init\n"); TRACE("finished process init\n");
break; break;
case DLL_THREAD_ATTACH: case DLL_THREAD_ATTACH:
#if defined(__x86_64__) && _MSVCR_VER>=140
msvcrt_attach_handler4();
#endif
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
msvcrt_free_io(); msvcrt_free_io();
...@@ -140,6 +152,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) ...@@ -140,6 +152,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
msvcrt_free_tls_mem(); msvcrt_free_tls_mem();
if (!msvcrt_free_tls()) if (!msvcrt_free_tls())
return FALSE; return FALSE;
#if defined(__x86_64__) && _MSVCR_VER>=140
msvcrt_free_handler4();
#endif
_free_locale(MSVCRT_locale); _free_locale(MSVCRT_locale);
#if _MSVCR_VER >= 100 && _MSVCR_VER <= 120 #if _MSVCR_VER >= 100 && _MSVCR_VER <= 120
msvcrt_free_scheduler_thread(); msvcrt_free_scheduler_thread();
......
...@@ -117,6 +117,16 @@ BOOL __cdecl __CxxRegisterExceptionObject(EXCEPTION_POINTERS*, cxx_frame_info*); ...@@ -117,6 +117,16 @@ BOOL __cdecl __CxxRegisterExceptionObject(EXCEPTION_POINTERS*, cxx_frame_info*);
void __cdecl __CxxUnregisterExceptionObject(cxx_frame_info*, BOOL); void __cdecl __CxxUnregisterExceptionObject(cxx_frame_info*, BOOL);
void CDECL __DestructExceptionObject(EXCEPTION_RECORD*); 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 */ /* TLS data */
extern DWORD msvcrt_tls_index DECLSPEC_HIDDEN; extern DWORD msvcrt_tls_index DECLSPEC_HIDDEN;
......
...@@ -26,6 +26,7 @@ C_SRCS = \ ...@@ -26,6 +26,7 @@ C_SRCS = \
exception_ptr.c \ exception_ptr.c \
exit.c \ exit.c \
file.c \ file.c \
handler4.c \
heap.c \ heap.c \
locale.c \ locale.c \
lock.c \ lock.c \
......
...@@ -54,6 +54,7 @@ ...@@ -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 __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 __CxxFrameHandler2(ptr ptr ptr ptr) __CxxFrameHandler
@ cdecl -arch=i386,x86_64,arm,arm64 -norelay __CxxFrameHandler3(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) @ stdcall -arch=i386 __CxxLongjmpUnwind(ptr)
@ cdecl -arch=i386,x86_64,arm,arm64 __CxxQueryExceptionSize() @ cdecl -arch=i386,x86_64,arm,arm64 __CxxQueryExceptionSize()
@ cdecl __CxxRegisterExceptionObject(ptr ptr) @ cdecl __CxxRegisterExceptionObject(ptr ptr)
......
MODULE = vcruntime140_1.dll MODULE = vcruntime140_1.dll
IMPORTS = vcruntime140 IMPORTS = vcruntime140
PARENTSRC = ../msvcrt
C_SRCS = \ C_SRCS = \
except_x86_64.c handler4.c \
main.c
/*
* 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);
/*
* 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:
if (reserved) break;
msvcrt_free_handler4();
break;
}
return TRUE;
}
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment