1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//
// 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(FEATURE_EH_FUNCLETS)
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 // FEATURE_EH_FUNCLETS
|