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// ZapMetadata.h
6//
7
8//
9// Metadata zapping
10//
11// ======================================================================================
12
13#ifndef __ZAPMETADATA_H__
14#define __ZAPMETADATA_H__
15
16//-----------------------------------------------------------------------------
17//
18// ZapMetaData is the barebone ZapNode to save metadata scope
19//
20
21class ZapMetaData : public ZapNode
22{
23 DWORD m_dwSize;
24
25protected:
26 IMetaDataEmit * m_pEmit;
27
28public:
29 ZapMetaData()
30 {
31 }
32
33 ~ZapMetaData()
34 {
35 SAFERELEASE(m_pEmit);
36 }
37
38 void SetMetaData(IUnknown * pEmit);
39
40 virtual DWORD GetSize();
41
42 virtual UINT GetAlignment()
43 {
44 return sizeof(DWORD);
45 }
46
47 virtual ZapNodeType GetType()
48 {
49 return ZapNodeType_MetaData;
50 }
51
52 virtual void Save(ZapWriter * pZapWriter);
53};
54
55//-----------------------------------------------------------------------------
56//
57// Helper node to copy RVA data to from IL to the NGEN image.
58//
59
60class ZapRVADataNode : public ZapNode
61{
62 PVOID m_pData;
63 DWORD m_dwSize;
64 DWORD m_dwAlignment;
65
66public:
67 ZapRVADataNode(PVOID pData)
68 {
69 m_pData = pData;
70 m_dwSize = 0;
71 m_dwAlignment = 1;
72 }
73
74 void UpdateSizeAndAlignment(DWORD dwSize, DWORD dwAlignment)
75 {
76 if (dwSize > m_dwSize)
77 m_dwSize = dwSize;
78
79 if (dwAlignment > m_dwAlignment)
80 m_dwAlignment = dwAlignment;
81 }
82
83 PVOID GetData()
84 {
85 return m_pData;
86 }
87
88 virtual DWORD GetSize()
89 {
90 return m_dwSize;
91 }
92
93 virtual UINT GetAlignment()
94 {
95 return m_dwAlignment;
96 }
97
98 virtual ZapNodeType GetType()
99 {
100 return ZapNodeType_RVAFieldData;
101 }
102
103 virtual void Save(ZapWriter * pZapWriter)
104 {
105 pZapWriter->Write(m_pData, m_dwSize);
106 }
107};
108
109
110//-----------------------------------------------------------------------------
111//
112// ZapILMetaData copies both the metadata and IL to the NGEN image.
113//
114
115class ZapILMetaData : public ZapMetaData
116{
117 ZapImage * m_pImage;
118
119 class ILBlob : public ZapBlobPtr
120 {
121 public:
122 ILBlob(PVOID pData, SIZE_T cbSize)
123 : ZapBlobPtr(pData, cbSize)
124 {
125 }
126
127 virtual UINT GetAlignment()
128 {
129 // The tiny header does not have any alignment requirements
130 return ((COR_ILMETHOD_TINY *)GetData())->IsTiny() ? sizeof(BYTE) : sizeof(DWORD);
131 }
132 };
133
134 // Hashtable with all IL method blobs. If two methods have same IL code
135 // we store it just once.
136 SHash< NoRemoveSHashTraits < ZapBlob::SHashTraits > > m_blobs;
137
138 struct ILMethod
139 {
140 mdMethodDef m_md;
141 ZapBlob * m_pIL;
142 };
143
144 class ILMethodTraits : public NoRemoveSHashTraits< DefaultSHashTraits<ILMethod> >
145 {
146 public:
147 typedef const mdMethodDef key_t;
148
149 static key_t GetKey(element_t e)
150 {
151 LIMITED_METHOD_CONTRACT;
152 return e.m_md;
153 }
154 static BOOL Equals(key_t k1, key_t k2)
155 {
156 LIMITED_METHOD_CONTRACT;
157 return k1 == k2;
158 }
159 static count_t Hash(key_t k)
160 {
161 LIMITED_METHOD_CONTRACT;
162 return k;
163 }
164
165 static const element_t Null() { LIMITED_METHOD_CONTRACT; ILMethod e; e.m_md = 0; e.m_pIL = NULL; return e; }
166 static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e.m_md == 0; }
167 };
168
169 SHash< ILMethodTraits > m_ILMethods;
170
171public:
172 ZapILMetaData(ZapImage * pImage)
173 : m_pImage(pImage)
174 {
175 }
176
177 void Preallocate(COUNT_T cbILImage)
178 {
179 PREALLOCATE_HASHTABLE(ZapILMetaData::m_blobs, 0.0040, cbILImage);
180 PREALLOCATE_HASHTABLE(ZapILMetaData::m_ILMethods, 0.0044, cbILImage);
181 }
182
183 void EmitMethodIL(mdMethodDef md);
184
185 void CopyIL();
186 void CopyMetaData();
187 void CopyRVAFields();
188
189 virtual void Save(ZapWriter * pZapWriter);
190
191 ZapRVADataNode * GetRVAField(void * pData);
192
193private:
194 class RVADataTraits : public NoRemoveSHashTraits< DefaultSHashTraits<ZapRVADataNode *> >
195 {
196 public:
197 typedef PVOID key_t;
198
199 static key_t GetKey(element_t e)
200 {
201 LIMITED_METHOD_CONTRACT;
202 return e->GetData();
203 }
204 static BOOL Equals(key_t k1, key_t k2)
205 {
206 LIMITED_METHOD_CONTRACT;
207 return k1 == k2;
208 }
209 static count_t Hash(key_t k)
210 {
211 LIMITED_METHOD_CONTRACT;
212 return (count_t)k;
213 }
214
215 static element_t Null() { LIMITED_METHOD_CONTRACT; return NULL; }
216 static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e == NULL; }
217 };
218
219 SHash< RVADataTraits > m_rvaData;
220};
221
222#endif // __ZAPMETADATA_H__
223