From d3e03ba2105f5c0d54ab0aa209f0b24229cc28b1 Mon Sep 17 00:00:00 2001 From: mingkuang Date: Wed, 25 Jan 2023 01:48:02 +0800 Subject: [PATCH] =?UTF-8?q?Fea=EF=BC=8Cvcruntime=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E5=88=B014.34.31933?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/crt/i386/trnsctrl.cpp | 29 ++- Sources/crt/vcruntime/c11_atomic_support.c | 24 +++ Sources/crt/vcruntime/ehhelpers.h | 17 +- Sources/crt/vcruntime/ehstate.cpp | 36 ++-- Sources/crt/vcruntime/frame.cpp | 55 +++++- Sources/crt/vcruntime/risctrnsctrl.cpp | 182 ++++++++++++++++-- Sources/crt/vcruntime/std_type_info.cpp | 82 +++++++- Sources/crt/vcruntime/uncaught_exceptions.cpp | 38 ++-- UnitTest/UnitTest.cpp | 7 + vcruntime.msvcrt/vcruntime.msvcrt.vcxproj | 9 +- .../vcruntime.msvcrt.vcxproj.filters | 3 + vcruntime.ucrtbase/vcruntime.ucrtbase.vcxproj | 1 + .../vcruntime.ucrtbase.vcxproj.filters | 3 + 13 files changed, 400 insertions(+), 86 deletions(-) create mode 100644 Sources/crt/vcruntime/c11_atomic_support.c diff --git a/Sources/crt/i386/trnsctrl.cpp b/Sources/crt/i386/trnsctrl.cpp index 4e7b671..3c504af 100644 --- a/Sources/crt/i386/trnsctrl.cpp +++ b/Sources/crt/i386/trnsctrl.cpp @@ -17,7 +17,11 @@ #include #include +#if 0 +#include "../ehhelpers.h" +#else #include "ehhelpers.h" +#endif #include @@ -43,12 +47,12 @@ #define IS_DISPATCHING(Flag) ((Flag & EXCEPTION_UNWIND) == 0) #define IS_TARGET_UNWIND(Flag) (Flag & EXCEPTION_TARGET_UNWIND) -#ifndef pFrameInfoChain - -#if _CRT_NTDDI_MIN >= NTDDI_WIN6 +#ifdef pFrameInfoChain +#elif WindowsTargetPlatformMinVersion >= __MakeVersion(10, 0, 10240) +#define pFrameInfoChain (*((FRAMEINFO **) &(RENAME_BASE_PTD(__vcrt_getptd)()->_pFrameInfoChain))) +#elif WindowsTargetPlatformMinVersion >= WindowsTargetPlatformWindows6 #define pFrameInfoChain (*((FRAMEINFO **) &(((_ptd_msvcrt_win6_shared*)__acrt_getptd())->_pFrameInfoChain))) #else - static __inline void* __fastcall pFrameInfoChain_fun() { auto ptd = __acrt_getptd(); @@ -67,12 +71,9 @@ static __inline void* __fastcall pFrameInfoChain_fun() return &(((_ptd_msvcrt_win6_shared*)ptd)->_pFrameInfoChain); } - #define pFrameInfoChain (*((FRAMEINFO **) pFrameInfoChain_fun())) #endif -#endif - #if 0 ///////////////////////////////////////////////////////////////////////////// // @@ -240,7 +241,7 @@ extern "C" _VCRTIMP __declspec(naked) DECLSPEC_GUARD_SUPPRESS EXCEPTION_DISPOSIT EHTRACE_FMT1("pRN = 0x%p", pRN); - result = __InternalCxxFrameHandler( pExcept, pRN, (PCONTEXT)pContext, pDC, pFuncInfo, 0, nullptr, FALSE ); + result = __InternalCxxFrameHandlerWrapper( pExcept, pRN, (PCONTEXT)pContext, pDC, pFuncInfo, 0, nullptr, FALSE ); EHTRACE_HANDLER_EXIT(result); @@ -294,7 +295,7 @@ extern "C" _VCRTIMP __declspec(naked) DECLSPEC_GUARD_SUPPRESS EXCEPTION_DISPOSIT EHTRACE_FMT1("pRN = 0x%p", pRN); - result = __InternalCxxFrameHandler( pExcept, pRN, (PCONTEXT)pContext, pDC, pFuncInfo, 0, nullptr, FALSE ); + result = __InternalCxxFrameHandlerWrapper( pExcept, pRN, (PCONTEXT)pContext, pDC, pFuncInfo, 0, nullptr, FALSE ); EHTRACE_HANDLER_EXIT(result); @@ -344,7 +345,7 @@ extern "C" _VCRTIMP __declspec(naked) DECLSPEC_GUARD_SUPPRESS EXCEPTION_DISPOSIT EHTRACE_FMT1("pRN = 0x%p", pRN); - result = __InternalCxxFrameHandler( pExcept, pRN, (PCONTEXT)pContext, pDC, pFuncInfo, 0, nullptr, FALSE ); + result = __InternalCxxFrameHandlerWrapper( pExcept, pRN, (PCONTEXT)pContext, pDC, pFuncInfo, 0, nullptr, FALSE ); EHTRACE_HANDLER_EXIT(result); @@ -473,7 +474,7 @@ extern "C" EXCEPTION_DISPOSITION __cdecl _CatchGuardHandler( __security_check_cookie(pRN->RandomCookie ^ (UINT_PTR)pRN); EXCEPTION_DISPOSITION result = - __InternalCxxFrameHandler( pExcept, + __InternalCxxFrameHandlerWrapper( pExcept, pRN->pRN, (PCONTEXT)pContext, nullptr, @@ -697,7 +698,7 @@ extern "C" EXCEPTION_DISPOSITION __cdecl _TranslatorGuardHandler( // // Check for a handler: // - __InternalCxxFrameHandler( pExcept, pRN->pRN, (PCONTEXT)pContext, nullptr, pRN->pFuncInfo, pRN->CatchDepth, pRN->pMarkerRN, TRUE ); + __InternalCxxFrameHandlerWrapper( pExcept, pRN->pRN, (PCONTEXT)pContext, nullptr, pRN->pFuncInfo, pRN->CatchDepth, pRN->pMarkerRN, TRUE ); if (!pRN->DidUnwind) { // @@ -797,7 +798,6 @@ extern "C" _VCRTIMP FRAMEINFO * __cdecl _CreateFrameInfo( _LCRT_DEFINE_IAT_SYMBOL(_CreateFrameInfo); #endif - ///////////////////////////////////////////////////////////////////////////// // // _FindAndUnlinkFrame - Remove the frame information for this scope that was @@ -828,5 +828,4 @@ extern "C" _VCRTIMP void __cdecl _FindAndUnlinkFrame( } _LCRT_DEFINE_IAT_SYMBOL(_FindAndUnlinkFrame); - -#endif \ No newline at end of file +#endif diff --git a/Sources/crt/vcruntime/c11_atomic_support.c b/Sources/crt/vcruntime/c11_atomic_support.c new file mode 100644 index 0000000..8185815 --- /dev/null +++ b/Sources/crt/vcruntime/c11_atomic_support.c @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// C11 atomic support routines: extern inline defitions +#include + +extern inline void _Check_memory_order(const unsigned int _Order); +extern inline void _Atomic_thread_fence(const unsigned int _Order); + +extern inline void _Atomic_store8(volatile char* _Ptr, char _Desired, int _Order); +extern inline void _Atomic_store16(volatile short* _Ptr, short _Desired, int _Order); +extern inline void _Atomic_store32(volatile int* _Ptr, int _Desired, int _Order); +extern inline void _Atomic_store64(volatile long long* _Ptr, long long _Desired, int _Order); + +extern inline char _Atomic_load8(const volatile char* _Ptr, int _Order); +extern inline short _Atomic_load16(const volatile short* _Ptr, int _Order); +extern inline int _Atomic_load32(const volatile int* _Ptr, int _Order); +extern inline long long _Atomic_load64(const volatile long long* _Ptr, int _Order); + +extern inline _Bool _Atomic_compare_exchange_strong8(volatile char* _Ptr, char* _Expected, char _Desired, int _Order); +extern inline _Bool _Atomic_compare_exchange_strong16( + volatile short* _Ptr, short* _Expected, short _Desired, int _Order); +extern inline _Bool _Atomic_compare_exchange_strong32(volatile int* _Ptr, int* _Expected, int _Desired, int _Order); +extern inline _Bool _Atomic_compare_exchange_strong64( + volatile long long* _Ptr, long long* _Expected, long long _Desired, int _Order); diff --git a/Sources/crt/vcruntime/ehhelpers.h b/Sources/crt/vcruntime/ehhelpers.h index b6d094e..fd0f620 100644 --- a/Sources/crt/vcruntime/ehhelpers.h +++ b/Sources/crt/vcruntime/ehhelpers.h @@ -13,11 +13,9 @@ #define _pForeignExcept (*((EHExceptionRecord **)&(((_ptd_msvcrt_win6_shared*)RENAME_BASE_PTD(__vcrt_getptd)())->_pForeignException))) #else #include - #define _pForeignExceptWin6 (*((EHExceptionRecord **)&(((_ptd_msvcrt_win6_shared*)RENAME_BASE_PTD(__vcrt_getptd)())->_pForeignException))) #define _pForeignExceptdownlevel (*((EHExceptionRecord **)&(__LTL_get_ptd_downlevel(TRUE)->_pForeignException))) #define _pForeignExcept (__LTL_GetOsMinVersion() >= MakeMiniVersion(6, 0) ? _pForeignExceptWin6 : _pForeignExceptdownlevel) - #endif #endif @@ -27,11 +25,9 @@ #elif WindowsTargetPlatformMinVersion >= WindowsTargetPlatformWindows6 #define pFrameInfoChain (*((FRAMEINFO **) &(((_ptd_msvcrt_win6_shared*)RENAME_BASE_PTD(__vcrt_getptd)())->_pFrameInfoChain))) #elif WindowsTargetPlatformMinVersion >= WindowsTargetPlatformWindowsXP - #define pFrameInfoChainWin6 (*((FRAMEINFO **) &(((_ptd_msvcrt_win6_shared*)RENAME_BASE_PTD(__vcrt_getptd)())->_pFrameInfoChain))) #define pFrameInfoChainWinXP (*((FRAMEINFO **) &(((_ptd_msvcrt_winxp*)RENAME_BASE_PTD(__vcrt_getptd)())->_pFrameInfoChain))) #define pFrameInfoChain (__LTL_GetOsMinVersion() >= MakeMiniVersion(6, 0) ? pFrameInfoChainWin6 : pFrameInfoChainWinXP) - #endif // Pre-V4 managed exception code @@ -40,12 +36,15 @@ // V4 and later managed exception code #define MANAGED_EXCEPTION_CODE_V4 0XE0434352 -//extern "C" void -//__except_validate_context_record( -// _In_ PCONTEXT ContextRecord -// ); +#if 0 +extern "C" void +__except_validate_context_record( + _In_ PCONTEXT ContextRecord + ); +#else //这个函数仅仅是验证内存是否在堆栈中,而且要开启 guard ICall才行,所以直接砍掉吧 #define __except_validate_context_record(ContextRecord) +#endif extern "C" _VCRTIMP void * __AdjustPointer( void *, @@ -95,7 +94,7 @@ extern "C" _VCRTIMP int __cdecl RENAME_EH_EXTERN(__TypeMatch)( // template -EXCEPTION_DISPOSITION __InternalCxxFrameHandler( +EXCEPTION_DISPOSITION __InternalCxxFrameHandlerWrapper( EHExceptionRecord *pExcept, EHRegistrationNode *pRN, CONTEXT *pContext, diff --git a/Sources/crt/vcruntime/ehstate.cpp b/Sources/crt/vcruntime/ehstate.cpp index fc48bcd..744d676 100644 --- a/Sources/crt/vcruntime/ehstate.cpp +++ b/Sources/crt/vcruntime/ehstate.cpp @@ -16,19 +16,30 @@ #include #include #include "ehhelpers.h" +#include #if _EH_RELATIVE_FUNCINFO -#if defined(_M_ARM_NT) || defined(_M_ARM64) || defined(_CHPE_X86_ARM64_EH_) +#if defined(_M_ARM_NT) || defined(_M_ARM64) || defined(_CHPE_X86_ARM64_EH_) || defined(_M_ARM64EC) static uintptr_t adjustIp(DispatcherContext *pDC, uintptr_t Ip) { - // - // If this context came from an unwind to a call, then the ControlPc points - // to a return address, which could put us at the start of a neighboring - // scope. To correct for this, back the PC up by the minimum instruction - // size to ensure we are in the same scope as the original call opcode. - // +#if defined(_M_ARM64EC) + if(RtlIsEcCode(Ip)) { + PDISPATCHER_CONTEXT_ARM64EC pECDC; + pECDC = (PDISPATCHER_CONTEXT_ARM64EC) pDC; - if (pDC->ControlPcIsUnwound) { + if(pECDC->ControlPcIsUnwound != FALSE) { + Ip -= 4; + } + } +#else + + // + // If this context came from an unwind to a call, then the ControlPc points + // to a return address, which could put us at the start of a neighboring + // scope. To correct for this, back the PC up by the minimum instruction + // size to ensure we are in the same scope as the original call opcode. + // + if (pDC->ControlPcIsUnwound) { #if defined(_M_ARM_NT) @@ -38,10 +49,11 @@ static uintptr_t adjustIp(DispatcherContext *pDC, uintptr_t Ip) Ip -= 4; -#endif +#endif // _M_ARM_NT } +#endif // _M_ARM64EC return Ip; } @@ -50,7 +62,7 @@ static uintptr_t adjustIp(DispatcherContext* /*pDC*/, uintptr_t Ip) { return Ip; } -#endif +#endif // (_M_ARM_NT) || defined(_M_ARM64) || defined(_CHPE_X86_ARM64_EH_) || defined(_M_ARM64EC) __ehstate_t RENAME_EH_EXTERN(__FrameHandler4)::StateFromIp( FuncInfo *pFuncInfo, @@ -209,6 +221,7 @@ void RENAME_EH_EXTERN(__FrameHandler3)::SetState( } #endif +#else #if 0 __ehstate_t RENAME_EH_EXTERN(__FrameHandler3)::GetCurrentState( EHRegistrationNode *pRN, @@ -237,6 +250,5 @@ void RENAME_EH_EXTERN(__FrameHandler3)::SetState( { pRN->state = newState; } -#endif - +#endif // 0 #endif diff --git a/Sources/crt/vcruntime/frame.cpp b/Sources/crt/vcruntime/frame.cpp index 4edad5d..85deee9 100644 --- a/Sources/crt/vcruntime/frame.cpp +++ b/Sources/crt/vcruntime/frame.cpp @@ -215,11 +215,9 @@ static BOOLEAN Is_bad_exception_allowed(ESTypeList *pExceptionSpec); #elif WindowsTargetPlatformMinVersion >= WindowsTargetPlatformWindows6 #define _pCurrentFuncInfo (*((ESTypeList **)&(((_ptd_msvcrt_win6_shared*)RENAME_BASE_PTD(__vcrt_getptd)())->_curexcspec))) #elif WindowsTargetPlatformMinVersion >= WindowsTargetPlatformWindowsXP - #define _pCurrentFuncInfoWin6 (*((ESTypeList **)&(((_ptd_msvcrt_win6_shared*)RENAME_BASE_PTD(__vcrt_getptd)())->_curexcspec))) #define _pCurrentFuncInfoWinXP (*((ESTypeList **)&(((_ptd_msvcrt_winxp*)RENAME_BASE_PTD(__vcrt_getptd)())->_curexcspec))) #define _pCurrentFuncInfo (__LTL_GetOsMinVersion() >= MakeMiniVersion(6,0) ? _pCurrentFuncInfoWin6 : _pCurrentFuncInfoWinXP) - #endif inline ESTypeList* RENAME_EH_EXTERN(__FrameHandler3)::getESTypes(FuncInfo* pFuncInfo) @@ -227,6 +225,49 @@ inline ESTypeList* RENAME_EH_EXTERN(__FrameHandler3)::getESTypes(FuncInfo* pFunc return FUNC_PESTYPES(pFuncInfo); } +//////////////////////////////////////////////////////////////////////////////// +// +// __InternalCxxFrameHandlerWrapper - Wraps the frame handler so we have a place +// to apply cleanup on this function + +template +EXCEPTION_DISPOSITION __InternalCxxFrameHandlerWrapper( + EHExceptionRecord* pExcept, // Information for this exception + EHRegistrationNode* pRN, // Dynamic information for this frame + CONTEXT* pContext, // Context info + DispatcherContext* pDC, // Context within subject frame + typename T::FuncInfo* pFuncInfo, // Static information for this frame + int CatchDepth, // How deeply nested are we? + EHRegistrationNode* pMarkerRN, // Marker node for when checking inside catch block + BOOLEAN recursive // Are we handling a translation? +) { + +#if defined(_M_HYBRID_X86_ARM64) && !defined(_CHPE_X86_ARM64_EH_) + _HybridGenerateThunks(__InternalCxxFrameHandlerWrapper, 1); +#endif + + if constexpr (std::is_same_v) + { + __try + { + return __InternalCxxFrameHandler(pExcept, pRN, pContext, pDC, pFuncInfo, CatchDepth, pMarkerRN, recursive); + } + __finally + { +#if _VCRT_BUILD_FH4 + // For FrameHandler4, this value should always be invalid past an invocation of this function. + CatchStateInParent = INVALID_CATCH_SPECIFIC_STATE; +#endif + } + } + else + { + // Compile-time disable the __try/__finally unless we need it. On x86 even a no-op finally triggers a call + // to local_unwind and can change behavior of the handler. + return __InternalCxxFrameHandler(pExcept, pRN, pContext, pDC, pFuncInfo, CatchDepth, pMarkerRN, recursive); + } +} + //////////////////////////////////////////////////////////////////////////////// // // __InternalCxxFrameHandler - the frame handler for all functions with C++ EH @@ -252,8 +293,7 @@ EXCEPTION_DISPOSITION __InternalCxxFrameHandler( DispatcherContext *pDC, // Context within subject frame typename T::FuncInfo *pFuncInfo, // Static information for this frame int CatchDepth, // How deeply nested are we? - EHRegistrationNode *pMarkerRN, // Marker node for when checking inside - // catch block + EHRegistrationNode *pMarkerRN, // Marker node for when checking inside catch block BOOLEAN recursive // Are we handling a translation? ) { @@ -378,7 +418,7 @@ EXCEPTION_DISPOSITION __InternalCxxFrameHandler( } // __InternalCxxFrameHandler #if 0 -template EXCEPTION_DISPOSITION __InternalCxxFrameHandler( +template EXCEPTION_DISPOSITION __InternalCxxFrameHandlerWrapper( EHExceptionRecord *pExcept, EHRegistrationNode *pRN, CONTEXT *pContext, @@ -391,7 +431,7 @@ template EXCEPTION_DISPOSITION __InternalCxxFrameHandler( +template EXCEPTION_DISPOSITION __InternalCxxFrameHandlerWrapper( EHExceptionRecord *pExcept, EHRegistrationNode *pRN, CONTEXT *pContext, @@ -1000,7 +1040,6 @@ extern "C" _VCRTIMP int __cdecl RENAME_EH_EXTERN(__TypeMatch)( } _LCRT_DEFINE_IAT_SYMBOL(__TypeMatch); - #endif #if 0 @@ -1915,7 +1954,6 @@ extern "C" _VCRTIMP int __cdecl RENAME_EH_EXTERN(__BuildCatchObjectHelper)( } _LCRT_DEFINE_IAT_SYMBOL(__BuildCatchObjectHelper); - #endif #if 0 @@ -2029,7 +2067,6 @@ extern "C" _VCRTIMP void __cdecl RENAME_EH_EXTERN(__BuildCatchObject)( } _LCRT_DEFINE_IAT_SYMBOL(__BuildCatchObject); - #endif #if 0 diff --git a/Sources/crt/vcruntime/risctrnsctrl.cpp b/Sources/crt/vcruntime/risctrnsctrl.cpp index b488fb9..f1c502a 100644 --- a/Sources/crt/vcruntime/risctrnsctrl.cpp +++ b/Sources/crt/vcruntime/risctrnsctrl.cpp @@ -8,7 +8,9 @@ * EH. ****/ -//#include +#if 0 +#include +#endif #include #include #include @@ -17,8 +19,9 @@ #include #include "ehhelpers.h" #include - +#if 1 #include "framework.h" +#endif #if !defined(RENAME_EH_EXTERN_HYBRID) #define RENAME_EH_EXTERN_HYBRID(x) x @@ -32,16 +35,13 @@ #define _ImageBase (((_ptd_msvcrt_win6_shared*)__vcrt_getptd())->_ImageBase) #else #include - #define _ImageBaseWin6 (((_ptd_msvcrt_win6_shared*)__vcrt_getptd())->_ImageBase) #define _ImageBasedownlevel (__LTL_get_ptd_downlevel(TRUE)->_ImageBase) #define _ImageBase (__LTL_GetOsMinVersion() >= MakeMiniVersion(6,0) ? _ImageBaseWin6 : _ImageBasedownlevel) - #endif - extern "C" uintptr_t __cdecl _GetImageBase() { - return _ImageBase; + return _ImageBase; } extern "C" void __cdecl _SetImageBase(uintptr_t ImageBaseToRestore) @@ -59,10 +59,8 @@ extern "C" void __cdecl _SetImageBase(uintptr_t ImageBaseToRestore) #define _ThrowImageBase (((_ptd_msvcrt_win6_shared*)__vcrt_getptd())->_ThrowImageBase) #else #include - #define _ThrowImageBaseWin6 (((_ptd_msvcrt_win6_shared*)__vcrt_getptd())->_ThrowImageBase) #define _ThrowImageBasedownlevel (__LTL_get_ptd_downlevel(TRUE)->_ThrowImageBase) - #define _ThrowImageBase (__LTL_GetOsMinVersion() >= MakeMiniVersion(6,0) ? _ThrowImageBaseWin6 : _ThrowImageBasedownlevel) #endif @@ -78,13 +76,11 @@ extern "C" void __cdecl _SetThrowImageBase(uintptr_t NewThrowImageBase) #endif -#if _VCRT_BUILD_FH4 - -#if WindowsTargetPlatformMinVersion >= WindowsTargetPlatformWindows6 +#if 1 +#if _VCRT_BUILD_FH4 && WindowsTargetPlatformMinVersion >= WindowsTargetPlatformWindows6 thread_local int VC_LTL_UCRT_CatchStateInParent = INVALID_CATCH_SPECIFIC_STATE; -#endif - -#endif +#endif // _VCRT_BUILD_FH4 && WindowsTargetPlatformMinVersion >= WindowsTargetPlatformWindows6 +#endif // 1 #if _EH_RELATIVE_FUNCINFO #if _VCRT_BUILD_FH4 @@ -296,6 +292,34 @@ void RENAME_EH_EXTERN(__FrameHandler3)::FrameUnwindToEmptyState( } #endif +#if 0 +// +// __CxxFrameHandler3 - Real entry point to the runtime +// __CxxFrameHandler2 is an alias for __CxxFrameHandler3 +// since they are compatible in VC version of CRT +// These functions should be separated out if a change makes +// __CxxFrameHandler3 incompatible with __CxxFrameHandler2 +// +extern "C" DECLSPEC_GUARD_SUPPRESS EXCEPTION_DISPOSITION __cdecl RENAME_EH_EXTERN_HYBRID(__CxxFrameHandler3)( + EHExceptionRecord *pExcept, // Information for this exception + EHRegistrationNode RN, // Dynamic information for this frame + CONTEXT *pContext, // Context info + DispatcherContext *pDC // More dynamic info for this frame +) { + FuncInfo *pFuncInfo; + EXCEPTION_DISPOSITION result; + EHRegistrationNode EstablisherFrame = RN; + + _ImageBase = pDC->ImageBase; +#ifdef _ThrowImageBase + _ThrowImageBase = (uintptr_t)pExcept->params.pThrowImageBase; +#endif + pFuncInfo = (FuncInfo*)(_ImageBase +*(PULONG)pDC->HandlerData); + result = __InternalCxxFrameHandlerWrapper(pExcept, &EstablisherFrame, pContext, pDC, pFuncInfo, 0, nullptr, FALSE); + return result; +} +#endif // 0 + #if _VCRT_BUILD_FH4 && WindowsTargetPlatformMinVersion < __MakeVersion(10, 0, 19041) extern "C" DECLSPEC_GUARD_SUPPRESS EXCEPTION_DISPOSITION __cdecl RENAME_EH_EXTERN_HYBRID(__CxxFrameHandler4)( EHExceptionRecord *pExcept, // Information for this exception @@ -315,14 +339,44 @@ extern "C" DECLSPEC_GUARD_SUPPRESS EXCEPTION_DISPOSITION __cdecl RENAME_EH_EXTER FH4::DecompFuncInfo(buffer, FuncInfo, pDC->ImageBase, pDC->FunctionEntry->BeginAddress); - result = __InternalCxxFrameHandler(pExcept, &EstablisherFrame, pContext, pDC, &FuncInfo, 0, nullptr, FALSE); + result = __InternalCxxFrameHandlerWrapper(pExcept, &EstablisherFrame, pContext, pDC, &FuncInfo, 0, nullptr, FALSE); return result; } _LCRT_DEFINE_IAT_SYMBOL(RENAME_EH_EXTERN_HYBRID(__CxxFrameHandler4)); - #endif // _VCRT_BUILD_FH4 +#if !defined(_CHPE_X86_ARM64_EH_) + +#if 0 +// +// __CxxFrameHandler2 - Remove after compiler is updated +// +extern "C" DECLSPEC_GUARD_SUPPRESS EXCEPTION_DISPOSITION __cdecl __CxxFrameHandler2( + EHExceptionRecord *pExcept, // Information for this exception + EHRegistrationNode RN, // Dynamic information for this frame + CONTEXT *pContext, // Context info + DispatcherContext *pDC // More dynamic info for this frame +) +{ + return __CxxFrameHandler3(pExcept, RN, pContext, pDC); +} +#endif + +#if 0 +extern "C" DECLSPEC_GUARD_SUPPRESS EXCEPTION_DISPOSITION __cdecl __CxxFrameHandler( + EHExceptionRecord *pExcept, // Information for this exception + EHRegistrationNode RN, // Dynamic information for this frame + CONTEXT *pContext, // Context info + DispatcherContext *pDC // More dynamic info for this frame +) +{ + return __CxxFrameHandler3(pExcept, RN, pContext, pDC); +} +#endif // 0 + +#endif + // Call the SEH to EH translator. template static int SehTransFilter( @@ -338,6 +392,7 @@ static int SehTransFilter( UNREFERENCED_PARAMETER(curState); _pForeignExcept = pExcept; + _ImageBase = pDC->ImageBase; #ifdef _ThrowImageBase _ThrowImageBase = (uintptr_t)((EHExceptionRecord *)ExPtrs->ExceptionRecord)->params.pThrowImageBase; #endif @@ -345,13 +400,13 @@ static int SehTransFilter( #if _VCRT_BUILD_FH4 if constexpr (std::is_same_v) { - // For FH4, the catch state from rethrow is transient and only readable one time before being reset. + // For FH4, the catch state from rethrow is transient and only readable one time before being reset. // This path reprocesses a throw which means the transient state needs to be set again so the correct state is used. CatchStateInParent = curState; } #endif - __InternalCxxFrameHandler((EHExceptionRecord *)ExPtrs->ExceptionRecord, + __InternalCxxFrameHandlerWrapper((EHExceptionRecord *)ExPtrs->ExceptionRecord, pRN, pContext, pDC, @@ -422,6 +477,19 @@ BOOL _CallSETranslator( ); #endif // _VCRT_BUILD_FH4 +#if 0 +template +BOOL _CallSETranslator( + EHExceptionRecord *pExcept, // The exception to be translated + EHRegistrationNode *pRN, // Dynamic info of function with catch + CONTEXT *pContext, // Context info + DispatcherContext *pDC, // More dynamic info of function with catch (ignored) + RENAME_EH_EXTERN(__FrameHandler3)::FuncInfo *pFuncInfo, // Static info of function with catch + ULONG CatchDepth, // How deeply nested in catch blocks are we? + EHRegistrationNode *pMarkerRN, // Marker for parent context + __ehstate_t curState // Current state +); +#endif ///////////////////////////////////////////////////////////////////////////// // @@ -636,7 +704,7 @@ void RENAME_EH_EXTERN(__FrameHandler4)::UnwindNestedFrames( ExceptionRecord.ExceptionInformation[7] = (ULONG_PTR)recursive; // Used for translated Exceptions ExceptionRecord.ExceptionInformation[8] = EH_MAGIC_NUMBER1; - // Used in __InternalCxxFrameHandler to detected if it's being + // Used in __InternalCxxFrameHandler to detect if it's being // called from _UnwindNestedFrames. // TODO: make these contiguous @@ -673,4 +741,80 @@ void RENAME_EH_EXTERN(__FrameHandler4)::UnwindNestedFrames( } #endif // _VCRT_BUILD_FH4 +#if 0 +void RENAME_EH_EXTERN(__FrameHandler3)::UnwindNestedFrames( + EHRegistrationNode *pFrame, // Unwind up to (but not including) this frame + EHExceptionRecord *pExcept, // The exception that initiated this unwind + CONTEXT *pContext, // Context info for current exception + EHRegistrationNode *pEstablisher, + void *Handler, + FuncInfo *pFuncInfo, + __ehstate_t TargetUnwindState, + __ehstate_t /*CatchState*/, + HandlerType* /*pCatch*/, + DispatcherContext *pDC, + BOOLEAN recursive + ) +{ + static const EXCEPTION_RECORD ExceptionTemplate = // A generic exception record + { + STATUS_UNWIND_CONSOLIDATE, // STATUS_UNWIND_CONSOLIDATE + EXCEPTION_NONCONTINUABLE, // Exception flags (we don't do resume) + nullptr, // Additional record (none) + nullptr, // Address of exception (OS fills in) + 15, // Number of parameters + { EH_MAGIC_NUMBER1, // Our version control magic number + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 + } // pThrowInfo + }; + + EXCEPTION_RECORD ExceptionRecord = ExceptionTemplate; + ExceptionRecord.ExceptionInformation[0] = (ULONG_PTR)CxxCallCatchBlock; + // Address of call back function + ExceptionRecord.ExceptionInformation[1] = (ULONG_PTR)pEstablisher; + // Used by callback function + ExceptionRecord.ExceptionInformation[2] = (ULONG_PTR)Handler; + // Used by callback function to call catch block + ExceptionRecord.ExceptionInformation[3] = (ULONG_PTR)TargetUnwindState; + // Used by CxxFrameHandler to unwind to target_state + ExceptionRecord.ExceptionInformation[4] = (ULONG_PTR)pContext; + // used to set pCurrentExContext in callback function + ExceptionRecord.ExceptionInformation[5] = (ULONG_PTR)pFuncInfo; + // Used in callback function to set state on stack to -2 + ExceptionRecord.ExceptionInformation[6] = (ULONG_PTR)pExcept; + // Used for passing current Exception + ExceptionRecord.ExceptionInformation[7] = (ULONG_PTR)recursive; + // Used for translated Exceptions + ExceptionRecord.ExceptionInformation[8] = EH_MAGIC_NUMBER1; + // Used in __InternalCxxFrameHandler to detect if it's being + // called from _UnwindNestedFrames. + +#if defined(_M_ARM64EC) + + if (RtlIsEcCode(pDC->ControlPc)) { + ExceptionRecord.ExceptionInformation[10] = static_cast(-1); + } + +#elif defined(_M_ARM_NT) || defined(_M_ARM64) || defined(_CHPE_X86_ARM64_EH_) + + ExceptionRecord.ExceptionInformation[10] = static_cast(-1); + // ARM/ARM64-specific: used to hold a pointer to the non-volatile + // registers + +#elif !defined(_M_X64) + +#error Unknown processor architecture. + +#endif + + RtlUnwindEx((void *)*pFrame, + (void *)pDC->ControlPc, // Address where control left function + &ExceptionRecord, + nullptr, + pDC->ContextRecord, + (PUNWIND_HISTORY_TABLE)pDC->HistoryTable); +} +#endif // 0 + #endif // _EH_RELATIVE_FUNCINFO diff --git a/Sources/crt/vcruntime/std_type_info.cpp b/Sources/crt/vcruntime/std_type_info.cpp index bc65692..fa19fab 100644 --- a/Sources/crt/vcruntime/std_type_info.cpp +++ b/Sources/crt/vcruntime/std_type_info.cpp @@ -8,11 +8,14 @@ // #include #include -//#include -//#include +#if 0 +#include +#include +#else #include +#endif - +#if 1 struct __std_type_info_data { const char* _UndecoratedName; @@ -24,6 +27,7 @@ struct __std_type_info_data __std_type_info_data& operator=(const __std_type_info_data&) = delete; __std_type_info_data& operator=(__std_type_info_data&&) = delete; }; +#endif #if WindowsTargetPlatformMinVersion < __MakeVersion(10, 0, 10240) extern "C" int __cdecl __std_type_info_compare( @@ -40,7 +44,6 @@ extern "C" int __cdecl __std_type_info_compare( } _LCRT_DEFINE_IAT_SYMBOL(__std_type_info_compare); - #endif #if WindowsTargetPlatformMinVersion < __MakeVersion(10, 0, 10240) @@ -78,9 +81,9 @@ extern "C" size_t __cdecl __std_type_info_hash( } _LCRT_DEFINE_IAT_SYMBOL(__std_type_info_hash); - #endif +#if 1 //重新声明出msvcrt 的名称 class __declspec(dllimport) type_info { public: @@ -90,6 +93,7 @@ class __declspec(dllimport) type_info { void* _m_data; char _m_d_name[1]; }; +#endif #if WindowsTargetPlatformMinVersion < __MakeVersion(10, 0, 10240) extern "C" char const* __cdecl __std_type_info_name( @@ -97,15 +101,80 @@ extern "C" char const* __cdecl __std_type_info_name( __type_info_node* const root_node ) { +#if 0 + // First check to see if we've already cached the undecorated name; if we + // have, we can just return it: + { + char const* const cached_undecorated_name = __crt_interlocked_read_pointer(&data->_UndecoratedName); + if (cached_undecorated_name) + { + return cached_undecorated_name; + } + } + + __crt_unique_heap_ptr undecorated_name(__unDName( + nullptr, + data->_DecoratedName + 1, + 0, + [](size_t const n) { return _malloc_crt(n); }, + [](void* const p) { return _free_crt(p); }, + UNDNAME_32_BIT_DECODE | UNDNAME_TYPE_ONLY)); + + if (!undecorated_name) + { + return nullptr; // CRT_REFACTOR TODO This is nonconforming + } + + size_t undecorated_name_length = strlen(undecorated_name.get()); + while (undecorated_name_length != 0 && undecorated_name.get()[undecorated_name_length - 1] == ' ') + { + undecorated_name.get()[undecorated_name_length - 1] = '\0'; + --undecorated_name_length; + } + + size_t const undecorated_name_count = undecorated_name_length + 1; + size_t const node_size = sizeof(SLIST_ENTRY) + undecorated_name_count; + + __crt_unique_heap_ptr node_block(_malloc_crt(node_size)); + if (!node_block) + { + return nullptr; // CRT_REFACTOR TODO This is nonconforming + } + + PSLIST_ENTRY const node_header = static_cast(node_block.get()); + char* const node_string = reinterpret_cast(node_header + 1); + + *node_header = SLIST_ENTRY{}; + strcpy_s(node_string, undecorated_name_count, undecorated_name.get()); + + char const* const cached_undecorated_name = __crt_interlocked_compare_exchange_pointer( + &data->_UndecoratedName, + node_string, + nullptr); + + // If the cache already contained an undecorated name pointer, another + // thread must have cached it while we were computing the undecorated + // name. Discard the string we created and return the cached string: + if (cached_undecorated_name) + { + return cached_undecorated_name; + } + + // Otherwise, we've successfully cached our string; link it into the list + // and return it: + node_block.detach(); + InterlockedPushEntrySList(&root_node->_Header, node_header); + return node_string; +#else //调用 msvcrt中的 type_info::name() 即可 auto pMsvcrtTypeInfo = (::type_info*)((char*)data - (unsigned)&((type_info*)NULL)->_m_data); return pMsvcrtTypeInfo->name(); +#endif } _LCRT_DEFINE_IAT_SYMBOL(__std_type_info_name); - #endif // This function is called during module unload to clean up all of the undecorated @@ -125,5 +194,4 @@ extern "C" void __cdecl __std_type_info_destroy_list( } _LCRT_DEFINE_IAT_SYMBOL(__std_type_info_destroy_list); - #endif diff --git a/Sources/crt/vcruntime/uncaught_exceptions.cpp b/Sources/crt/vcruntime/uncaught_exceptions.cpp index 1c50d6a..64edf00 100644 --- a/Sources/crt/vcruntime/uncaught_exceptions.cpp +++ b/Sources/crt/vcruntime/uncaught_exceptions.cpp @@ -1,22 +1,38 @@ - +/*** +*uncaught_exceptions.cpp - Some target-independent helper routines used by the EH frame handler. +* +* Copyright (c) Microsoft Corporation. All rights reserved. +* +****/ + +#if 1 #include "framework.h" -#include "vcruntime_internal.h" +#endif +#include +#if 1 extern "C" int* __cdecl __processing_throw(); +#endif -#if WindowsTargetPlatformMinVersion < __MakeVersion(10, 0, 14393) +/////////////////////////////////////////////////////////////////////////////// +// +// __uncaught_exceptions() - Returns the number of exceptions that have been +// thrown but not yet caught. +// +// If a thread/fiber does not yet have thread/fiber locals, these functions +// just return false/0, without trying to allocate/initialize thread/fiber locals. +// +#if WindowsTargetPlatformMinVersion < __MakeVersion(10, 0, 14393) extern "C" int __cdecl __uncaught_exceptions() { -#ifdef __BuildWithMSVCRT - return *__processing_throw(); +#if WindowsTargetPlatformMinVersion >= __MakeVersion(10, 0, 10240) + RENAME_BASE_PTD(__vcrt_ptd)* const ptd = RENAME_BASE_PTD(__vcrt_getptd_noinit)(); + return ptd ? ptd->_ProcessingThrow : 0; #else - auto ptd = __vcrt_getptd_noinit(); - - return ptd ? ptd->_ProcessingThrow : 0; -#endif + return *__processing_throw(); +#endif // WindowsTargetPlatformMinVersion >= __MakeVersion(10, 0, 10240) } _LCRT_DEFINE_IAT_SYMBOL(__uncaught_exceptions); - -#endif +#endif // WindowsTargetPlatformMinVersion < __MakeVersion(10, 0, 14393) diff --git a/UnitTest/UnitTest.cpp b/UnitTest/UnitTest.cpp index 0fb1684..db5e372 100644 --- a/UnitTest/UnitTest.cpp +++ b/UnitTest/UnitTest.cpp @@ -746,6 +746,13 @@ namespace UnitTest if (Symbol.GetLength() == 0) continue; + // 内部私有符号全部忽略 + if (Symbol.GetLength() > 2 + && Symbol[0]== '?' && Symbol[1] == '?') + { + continue; + } + //_NULL_THUNK_DATA 之类的全部跳过 if (Symbol[0] == 127 || stricmp(Symbol, "__NULL_IMPORT_DESCRIPTOR") == 0 diff --git a/vcruntime.msvcrt/vcruntime.msvcrt.vcxproj b/vcruntime.msvcrt/vcruntime.msvcrt.vcxproj index e344004..c1e5521 100644 --- a/vcruntime.msvcrt/vcruntime.msvcrt.vcxproj +++ b/vcruntime.msvcrt/vcruntime.msvcrt.vcxproj @@ -676,6 +676,7 @@ true true + true true @@ -724,12 +725,12 @@ true - true + true - true - true - + true + true + diff --git a/vcruntime.msvcrt/vcruntime.msvcrt.vcxproj.filters b/vcruntime.msvcrt/vcruntime.msvcrt.vcxproj.filters index 8630f15..a32a202 100644 --- a/vcruntime.msvcrt/vcruntime.msvcrt.vcxproj.filters +++ b/vcruntime.msvcrt/vcruntime.msvcrt.vcxproj.filters @@ -98,6 +98,9 @@ 源文件\ltl + + 源文件 + diff --git a/vcruntime.ucrtbase/vcruntime.ucrtbase.vcxproj b/vcruntime.ucrtbase/vcruntime.ucrtbase.vcxproj index be39135..c18d174 100644 --- a/vcruntime.ucrtbase/vcruntime.ucrtbase.vcxproj +++ b/vcruntime.ucrtbase/vcruntime.ucrtbase.vcxproj @@ -822,6 +822,7 @@ true + true true diff --git a/vcruntime.ucrtbase/vcruntime.ucrtbase.vcxproj.filters b/vcruntime.ucrtbase/vcruntime.ucrtbase.vcxproj.filters index 92b824b..f8c49ba 100644 --- a/vcruntime.ucrtbase/vcruntime.ucrtbase.vcxproj.filters +++ b/vcruntime.ucrtbase/vcruntime.ucrtbase.vcxproj.filters @@ -59,5 +59,8 @@ 源文件\ltl + + 源文件 + \ No newline at end of file