1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4//
5// ZapWrapper.cpp
6//
7
8//
9// ZapNode that wraps EE datastructure for zapping
10//
11// ======================================================================================
12
13#include "common.h"
14
15#include "zapwrapper.h"
16
17void ZapWrapperTable::Resolve()
18{
19 for (WrapperTable::Iterator i = m_entries.Begin(), end = m_entries.End(); i != end; i++)
20 {
21 (*i)->Resolve(m_pImage);
22 }
23}
24
25// ======================================================================================
26// Actual placeholders
27
28class ZapMethodHandle : public ZapWrapper
29{
30public:
31 virtual void Resolve(ZapImage * pImage)
32 {
33 SetRVA(pImage->m_pPreloader->MapMethodHandle(CORINFO_METHOD_HANDLE(GetHandle())));
34 }
35
36 virtual ZapNodeType GetType()
37 {
38 return ZapNodeType_MethodHandle;
39 }
40};
41
42ZapNode * ZapWrapperTable::GetMethodHandle(CORINFO_METHOD_HANDLE handle)
43{
44 return GetPlaceHolder<ZapMethodHandle, ZapNodeType_MethodHandle>(handle);
45}
46
47class ZapClassHandle : public ZapWrapper
48{
49public:
50 virtual void Resolve(ZapImage * pImage)
51 {
52 SetRVA(pImage->m_pPreloader->MapClassHandle(CORINFO_CLASS_HANDLE(GetHandle())));
53 }
54
55 virtual ZapNodeType GetType()
56 {
57 return ZapNodeType_ClassHandle;
58 }
59};
60
61ZapNode * ZapWrapperTable::GetClassHandle(CORINFO_CLASS_HANDLE handle)
62{
63 return GetPlaceHolder<ZapClassHandle, ZapNodeType_ClassHandle>(handle);
64}
65
66class ZapFieldHandle : public ZapWrapper
67{
68public:
69 virtual void Resolve(ZapImage * pImage)
70 {
71 SetRVA(pImage->m_pPreloader->MapFieldHandle(CORINFO_FIELD_HANDLE(GetHandle())));
72 }
73
74 virtual ZapNodeType GetType()
75 {
76 return ZapNodeType_FieldHandle;
77 }
78};
79
80ZapNode * ZapWrapperTable::GetFieldHandle(CORINFO_FIELD_HANDLE handle)
81{
82 return GetPlaceHolder<ZapFieldHandle, ZapNodeType_FieldHandle>(handle);
83}
84
85class ZapAddrOfPInvokeFixup : public ZapWrapper
86{
87public:
88 virtual void Resolve(ZapImage * pImage)
89 {
90 SetRVA(pImage->m_pPreloader->MapAddressOfPInvokeFixup(CORINFO_METHOD_HANDLE((BYTE *)GetHandle() - 1)));
91 }
92
93 virtual ZapNodeType GetType()
94 {
95 return ZapNodeType_AddrOfPInvokeFixup;
96 }
97};
98
99ZapNode * ZapWrapperTable::GetAddrOfPInvokeFixup(CORINFO_METHOD_HANDLE handle)
100{
101 // Disambiguate the normal method handle and address of P/Invoke fixup by adding 1
102 return GetPlaceHolder<ZapAddrOfPInvokeFixup, ZapNodeType_AddrOfPInvokeFixup>((BYTE *)handle + 1);
103}
104
105class ZapGenericHandle : public ZapWrapper
106{
107public:
108 virtual void Resolve(ZapImage * pImage)
109 {
110 SetRVA(pImage->m_pPreloader->MapGenericHandle(CORINFO_GENERIC_HANDLE(GetHandle())));
111 }
112
113 virtual ZapNodeType GetType()
114 {
115 return ZapNodeType_GenericHandle;
116 }
117};
118
119ZapNode * ZapWrapperTable::GetGenericHandle(CORINFO_GENERIC_HANDLE handle)
120{
121 return GetPlaceHolder<ZapGenericHandle, ZapNodeType_GenericHandle>(handle);
122}
123
124class ZapModuleIDHandle : public ZapWrapper
125{
126public:
127 virtual void Resolve(ZapImage * pImage)
128 {
129 SetRVA(pImage->m_pPreloader->MapModuleIDHandle(CORINFO_MODULE_HANDLE(GetHandle())));
130 }
131
132 virtual ZapNodeType GetType()
133 {
134 return ZapNodeType_ModuleIDHandle;
135 }
136};
137
138ZapNode * ZapWrapperTable::GetModuleIDHandle(CORINFO_MODULE_HANDLE handle)
139{
140 return GetPlaceHolder<ZapModuleIDHandle, ZapNodeType_ModuleIDHandle>(handle);
141}
142
143class ZapStub : public ZapWrapper
144{
145 DWORD m_dwStubSize;
146
147public:
148 ZapStub(PVOID pStubData, DWORD dwStubSize)
149 : ZapWrapper(pStubData), m_dwStubSize(dwStubSize)
150 {
151 }
152
153 virtual DWORD GetSize()
154 {
155 return m_dwStubSize;
156 }
157
158 virtual ZapNodeType GetType()
159 {
160 return ZapNodeType_Stub;
161 }
162
163 virtual UINT GetAlignment()
164 {
165 return DEFAULT_CODE_ALIGN;
166 }
167
168 virtual void Save(ZapWriter * pZapWriter)
169 {
170 DWORD dwSize = GetSize();
171 PVOID pStub = GetHandle();
172
173 SBuffer stubClone(dwSize);
174
175 ICorCompileInfo *pCompileInfo = ZapImage::GetImage(pZapWriter)->GetCompileInfo();
176 IfFailThrow(pCompileInfo->GetStubClone(pStub,
177 const_cast<BYTE *>(static_cast<const BYTE *>(stubClone)), dwSize));
178
179 pZapWriter->Write(const_cast<BYTE *>(static_cast<const BYTE *>(stubClone)), dwSize);
180 }
181};
182
183ZapNode * ZapWrapperTable::GetStub(void * pStub)
184{
185 DWORD dwStubSize = 0;
186 void * pStubData = m_pImage->GetCompileInfo()->GetStubSize(pStub, &dwStubSize);
187 _ASSERTE(pStubData < pStub && pStub < (BYTE*)pStubData + dwStubSize);
188
189 ZapStub * pZapStub = (ZapStub *)m_entries.Lookup(pStubData);
190 if (pZapStub == NULL)
191 {
192 // did not find the delegate stub, need to emit the stub in the native image
193 pZapStub = new (m_pImage->GetHeap()) ZapStub(pStubData, dwStubSize);
194
195 m_entries.Add(pZapStub);
196 }
197
198 // Return inner ptr for the entrypoint
199 _ASSERTE(pZapStub->GetType() == ZapNodeType_Stub);
200 return m_pImage->GetInnerPtr(pZapStub, (PBYTE)pStub - (PBYTE)pStubData);
201}
202