JIT: Fix bug in finally cloning caused by unsound callfinally reordering
[platform/upstream/coreclr.git] / src / zap / zapwrapper.cpp
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
17 void 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
28 class ZapMethodHandle : public ZapWrapper
29 {
30 public:
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
42 ZapNode * ZapWrapperTable::GetMethodHandle(CORINFO_METHOD_HANDLE handle)
43 {
44     return GetPlaceHolder<ZapMethodHandle, ZapNodeType_MethodHandle>(handle);
45 }
46
47 class ZapClassHandle : public ZapWrapper
48 {
49 public:
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
61 ZapNode * ZapWrapperTable::GetClassHandle(CORINFO_CLASS_HANDLE handle)
62 {
63     return GetPlaceHolder<ZapClassHandle, ZapNodeType_ClassHandle>(handle);
64 }
65
66 class ZapFieldHandle : public ZapWrapper
67 {
68 public:
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
80 ZapNode * ZapWrapperTable::GetFieldHandle(CORINFO_FIELD_HANDLE handle)
81 {
82     return GetPlaceHolder<ZapFieldHandle, ZapNodeType_FieldHandle>(handle);
83 }
84
85 class ZapAddrOfPInvokeFixup : public ZapWrapper
86 {
87 public:
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
99 ZapNode * 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
105 class ZapGenericHandle : public ZapWrapper
106 {
107 public:
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
119 ZapNode * ZapWrapperTable::GetGenericHandle(CORINFO_GENERIC_HANDLE handle)
120 {
121     return GetPlaceHolder<ZapGenericHandle, ZapNodeType_GenericHandle>(handle);
122 }
123
124 class ZapModuleIDHandle : public ZapWrapper
125 {
126 public:
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
138 ZapNode * ZapWrapperTable::GetModuleIDHandle(CORINFO_MODULE_HANDLE handle)
139 {
140     return GetPlaceHolder<ZapModuleIDHandle, ZapNodeType_ModuleIDHandle>(handle);
141 }
142
143 class ZapStub : public ZapWrapper
144 {
145     DWORD m_dwStubSize;
146
147 public:
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
183 ZapNode * 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 }