summaryrefslogtreecommitdiff
path: root/src/vm/rtlfunctions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/rtlfunctions.cpp')
-rw-r--r--src/vm/rtlfunctions.cpp132
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
+