This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/
methoddescbackpatchinfo.h
138 lines (110 loc) · 3.85 KB
/
methoddescbackpatchinfo.h
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
132
133
134
135
136
137
138
// 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.
#pragma once
#include "debugmacrosext.h"
#include "crossloaderallocatorhash.h"
#ifndef CROSSGEN_COMPILE
#define DISABLE_COPY(T) \
T(const T &) = delete; \
T &operator =(const T &) = delete
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// EntryPointSlots
class EntryPointSlots
{
public:
enum SlotType : UINT8
{
SlotType_Normal, // pointer-sized value not in executable code
SlotType_Vtable, // pointer-sized value not in executable code, may be relative based on MethodTable::VTableIndir2_t
SlotType_Executable, // pointer-sized value in executable code
SlotType_ExecutableRel32, // 32-bit value relative to the end of the slot, in executable code
SlotType_Count,
SlotType_Mask = SlotType_Vtable | SlotType_Executable | SlotType_ExecutableRel32
};
#ifndef DACCESS_COMPILE
private:
static SIZE_T GetRequiredSlotAlignment(SlotType slotType)
{
LIMITED_METHOD_CONTRACT;
_ASSERTE(slotType >= SlotType_Normal);
_ASSERTE(slotType < SlotType_Count);
return slotType == SlotType_ExecutableRel32 ? sizeof(INT32) : sizeof(void *);
}
public:
static UINT_PTR ConvertSlotAndTypePairToUINT_PTR(TADDR slot, SlotType slotType)
{
slot |= (TADDR)slotType;
return (UINT_PTR)slot;
}
static void ConvertUINT_PTRToSlotAndTypePair(UINT_PTR storedData, TADDR *pSlot, SlotType *pSlotType)
{
*pSlot = storedData;
*pSlotType = (SlotType)(*pSlot & SlotType_Mask);
*pSlot ^= *pSlotType;
}
static void Backpatch_Locked(TADDR slot, SlotType slotType, PCODE entryPoint);
#endif
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// MethodDescBackpatchInfoTracker
class MethodDescBackpatchInfoTracker
{
private:
static CrstStatic s_lock;
class BackpatchInfoTrackerHashTraits : public NoRemoveDefaultCrossLoaderAllocatorHashTraits<MethodDesc *, UINT_PTR>
{
};
typedef CrossLoaderAllocatorHash<BackpatchInfoTrackerHashTraits> BackpatchInfoTrackerHash;
// Contains information about slots associated with the MethodDesc that were recorded for backpatching. This field and its
// data is protected by s_lock.
BackpatchInfoTrackerHash m_backpatchInfoHash;
#ifndef DACCESS_COMPILE
public:
static void StaticInitialize();
#endif
void Initialize(LoaderAllocator *pLoaderAllocator)
{
WRAPPER_NO_CONTRACT;
m_backpatchInfoHash.Init(pLoaderAllocator);
}
#ifdef _DEBUG
public:
static bool IsLockedByCurrentThread();
#endif
public:
class ConditionalLockHolder : CrstHolderWithState
{
public:
ConditionalLockHolder(bool acquireLock = true)
: CrstHolderWithState(
#ifndef DACCESS_COMPILE
acquireLock ? &MethodDescBackpatchInfoTracker::s_lock : nullptr
#else
nullptr
#endif
)
{
LIMITED_METHOD_CONTRACT;
}
};
public:
MethodDescBackpatchInfoTracker()
{
LIMITED_METHOD_CONTRACT;
}
#ifdef _DEBUG
public:
static bool MayHaveEntryPointSlotsToBackpatch(PTR_MethodDesc methodDesc);
#endif
#ifndef DACCESS_COMPILE
public:
void Backpatch_Locked(MethodDesc *pMethodDesc, PCODE entryPoint);
void AddSlotAndPatch_Locked(MethodDesc *pMethodDesc, LoaderAllocator *pLoaderAllocatorOfSlot, TADDR slot, EntryPointSlots::SlotType slotType, PCODE currentEntryPoint);
public:
#endif
friend class ConditionalLockHolder;
DISABLE_COPY(MethodDescBackpatchInfoTracker);
};
#undef DISABLE_COPY
#endif // !CROSSGEN_COMPILE