diff options
Diffstat (limited to 'src/vm/rtlfunctions.cpp')
-rw-r--r-- | src/vm/rtlfunctions.cpp | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/src/vm/rtlfunctions.cpp b/src/vm/rtlfunctions.cpp new file mode 100644 index 0000000000..b7cb78761a --- /dev/null +++ b/src/vm/rtlfunctions.cpp @@ -0,0 +1,132 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// +// RtlFunctions.CPP +// + +// +// Various functions for interacting with ntdll. +// +// + +// Precompiled Header + +#include "common.h" + +#include "rtlfunctions.h" + + +#ifdef _TARGET_AMD64_ + +RtlVirtualUnwindFn* RtlVirtualUnwind_Unsafe = NULL; + +HRESULT EnsureRtlFunctions() +{ + CONTRACTL + { + NOTHROW; + GC_TRIGGERS; + MODE_ANY; + } + CONTRACTL_END; + + HMODULE hModuleNtDll = CLRLoadLibrary(W("ntdll")); + + if (hModuleNtDll == NULL) + return E_FAIL; + +#define ENSURE_FUNCTION_RENAME(clrname, ntname) \ + if (NULL == clrname) { clrname = (ntname##Fn*)GetProcAddress(hModuleNtDll, #ntname); } \ + if (NULL == clrname) { return E_FAIL; } \ + { } + + ENSURE_FUNCTION_RENAME(RtlVirtualUnwind_Unsafe, RtlVirtualUnwind ); + + return S_OK; +} + +#else // _TARGET_AMD64_ + +HRESULT EnsureRtlFunctions() +{ + LIMITED_METHOD_CONTRACT; + return S_OK; +} + +#endif // _TARGET_AMD64_ + +#if defined(WIN64EXCEPTIONS) + +VOID InstallEEFunctionTable ( + PVOID pvTableID, + PVOID pvStartRange, + ULONG cbRange, + PGET_RUNTIME_FUNCTION_CALLBACK pfnGetRuntimeFunctionCallback, + PVOID pvContext, + EEDynamicFunctionTableType TableType) +{ + CONTRACTL + { + THROWS; + GC_NOTRIGGER; + MODE_ANY; + PRECONDITION(cbRange <= DYNAMIC_FUNCTION_TABLE_MAX_RANGE); + } + CONTRACTL_END; + + static LPWSTR wszModuleName = NULL; + static WCHAR rgwModuleName[MAX_LONGPATH] = { 0 }; + + if (wszModuleName == NULL) + { + StackSString ssTempName; + DWORD dwTempNameSize; + + // Leaves trailing backslash on path, producing something like "c:\windows\microsoft.net\framework\v4.0.x86dbg\" + LPCWSTR pszSysDir = GetInternalSystemDirectory(&dwTempNameSize); + + //finish creating complete path and copy to buffer if we can + if (pszSysDir == NULL) + { // The CLR should become unavailable in this case. + EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE); + } + + ssTempName.Set(pszSysDir); + ssTempName.Append(MAIN_DAC_MODULE_DLL_NAME_W); + + if (ssTempName.GetCount() < MAX_LONGPATH) + { + wcscpy_s(rgwModuleName, MAX_LONGPATH, ssTempName.GetUnicode()); + + // publish result + InterlockedExchangeT(&wszModuleName, rgwModuleName); + } + else + { + NewArrayHolder<WCHAR> wzTempName(DuplicateStringThrowing(ssTempName.GetUnicode())); + + // publish result + if (InterlockedCompareExchangeT(&wszModuleName, (LPWSTR)wzTempName, nullptr) == nullptr) + { + wzTempName.SuppressRelease(); + } + } + } + + if (!RtlInstallFunctionTableCallback( + ((ULONG_PTR)pvTableID) | 3, // the low 2 bits must be set so NT knows + // it's not really a pointer. See + // DeleteEEFunctionTable. + (ULONG_PTR)pvStartRange, + cbRange, + pfnGetRuntimeFunctionCallback, + EncodeDynamicFunctionTableContext(pvContext, TableType), + wszModuleName)) + { + COMPlusThrowOM(); + } +} + +#endif // WIN64EXCEPTIONS + |