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.
9 // Import is soft bound references to elements outside the current module
11 // ======================================================================================
13 #ifndef __ZAPIMPORT_H__
14 #define __ZAPIMPORT_H__
17 class ZapGCRefMapTable;
20 //---------------------------------------------------------------------------------------
22 // ZapImport is the import cell itself
24 // Every import cell is uniquely identified by its ZapNodeType and two handles
25 // (the second handle is optional and is often NULL)
27 // Actual implementations inherits from this abstract base class.
29 class ZapImport : public ZapNode
40 void SetHandle(PVOID handle)
42 _ASSERTE(m_handle == NULL);
46 void SetHandle2(PVOID handle2)
48 _ASSERTE(m_handle2 == NULL);
62 void SetBlob(ZapBlob * pBlob)
64 _ASSERTE(m_pBlob == NULL);
70 _ASSERTE(m_pBlob != NULL);
76 return m_pBlob != NULL;
79 virtual ZapImportSectionType ComputePlacement(ZapImage * pImage, BOOL * pfIsEager, BOOL * pfNeedsSignature)
82 *pfNeedsSignature = TRUE;
83 return ZapImportSectionType_Handle;
86 // All subtypes have to override
87 virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder) = 0;
89 virtual DWORD GetSize()
94 virtual UINT GetAlignment()
99 virtual void Save(ZapWriter * pZapWriter);
102 // Offset of the fixup cell within its section
105 void SetSectionIndexAndOffset(COUNT_T index, DWORD offset)
111 DWORD GetSectionIndex()
122 //---------------------------------------------------------------------------------------
124 // ZapGenericSignature is signature of generic dictionary entry.
126 class ZapGenericSignature : public ZapBlob
129 ZapGenericSignature(SIZE_T cbSize)
134 virtual ZapNodeType GetType()
136 return ZapNodeType_GenericSignature;
140 //---------------------------------------------------------------------------------------
142 // ZapImportTable is the main class that keeps track of all ZapImports.
144 // There is a single instance of it per image.
146 class ZapImportTable : public ZapNode
149 // Hashtable key of the import
150 // The same key is used for both ZapImport and ZapImportBlob
154 FORCEINLINE ImportKey(PVOID handle, ZapNodeType type)
155 : m_handle(handle), m_handle2(NULL), m_type(type)
159 FORCEINLINE ImportKey(PVOID handle, PVOID handle2, ZapNodeType type)
160 : m_handle(handle), m_handle2(handle2), m_type(type)
170 // Hashtable of ZapImports
172 class ImportTraits : public NoRemoveSHashTraits< DefaultSHashTraits<ZapImport *> >
175 typedef ImportKey key_t;
177 static FORCEINLINE key_t GetKey(element_t e)
179 LIMITED_METHOD_CONTRACT;
180 return ImportKey(e->GetHandle(), e->GetHandle2(), e->GetType());
182 static FORCEINLINE BOOL Equals(key_t k1, key_t k2)
184 LIMITED_METHOD_CONTRACT;
185 return (k1.m_handle == k2.m_handle) && (k1.m_handle2 == k2.m_handle2) && (k1.m_type == k2.m_type);
187 static FORCEINLINE count_t Hash(key_t k)
189 LIMITED_METHOD_CONTRACT;
190 return (count_t)(size_t)k.m_handle ^ ((count_t)(size_t)k.m_handle2 << 1) ^ k.m_type;
193 static const element_t Null() { LIMITED_METHOD_CONTRACT; return NULL; }
194 static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e == NULL; }
197 typedef SHash< ImportTraits > ImportTable;
200 // Hashtable of module indices
202 struct ModuleReferenceEntry
204 CORINFO_MODULE_HANDLE m_module;
207 USHORT m_wAssemblyRid;
211 class ModuleReferenceTraits : public NoRemoveSHashTraits< DefaultSHashTraits<ModuleReferenceEntry *> >
214 typedef CORINFO_MODULE_HANDLE key_t;
216 static key_t GetKey(element_t e)
218 LIMITED_METHOD_CONTRACT;
221 static BOOL Equals(key_t k1, key_t k2)
223 LIMITED_METHOD_CONTRACT;
226 static count_t Hash(key_t k)
228 LIMITED_METHOD_CONTRACT;
229 return (count_t)(size_t)k;
232 static const element_t Null() { LIMITED_METHOD_CONTRACT; return NULL; }
233 static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e == NULL; }
236 typedef SHash< ModuleReferenceTraits > ModuleReferenceTable;
239 // Helpers for inserting actual implementations of ZapImports into hashtable
241 template < typename impl, ZapNodeType type >
242 ZapImport * GetImport(PVOID handle)
244 ZapImport * pImport = m_imports.Lookup(ImportKey(handle, type));
251 pImport = new (m_pImage->GetHeap()) impl();
252 _ASSERTE(pImport->GetType() == type);
253 pImport->SetHandle(handle);
254 m_imports.Add(pImport);
258 template < typename impl, ZapNodeType type >
259 ZapImport * GetImport(PVOID handle, PVOID handle2)
261 ZapImport * pImport = m_imports.Lookup(ImportKey(handle, handle2, type));
268 pImport = new (m_pImage->GetHeap()) impl();
269 _ASSERTE(pImport->GetType() == type);
270 pImport->SetHandle(handle);
271 pImport->SetHandle2(handle2);
272 m_imports.Add(pImport);
276 template < typename impl, ZapNodeType type >
277 ZapImport * GetImportForSignature(PVOID handle, SigBuilder * pSigBuilder)
279 ZapBlob * pBlob = GetBlob(pSigBuilder);
281 ZapImport * pImport = m_imports.Lookup(ImportKey(handle, pBlob, type));
288 pImport = new (m_pImage->GetHeap()) impl();
289 _ASSERTE(pImport->GetType() == type);
290 pImport->SetHandle(handle);
291 pImport->SetHandle2(pBlob);
292 pImport->SetBlob(pBlob);
293 m_imports.Add(pImport);
297 ZapImport * GetExistingImport(ZapNodeType type, PVOID handle)
299 return m_imports.Lookup(ImportKey(handle, type));
302 ModuleReferenceEntry * GetModuleReference(CORINFO_MODULE_HANDLE handle);
304 static DWORD __stdcall EncodeModuleHelper(LPVOID referencingModule, CORINFO_MODULE_HANDLE referencedModule);
306 ImportTable m_imports; // Interned ZapImport *
307 SHash< NoRemoveSHashTraits < ZapBlob::SHashTraits > > m_blobs; // Interned ZapBlos for signatures and fixups
309 ModuleReferenceTable m_moduleReferences;
310 SArray<ModuleReferenceEntry *> m_modules; // Secondary table of ModuleReferences to allow fast index based lookup
312 SHash< NoRemoveSHashTraits < ZapBlob::SHashTraits > > m_genericSignatures;
314 DWORD m_nImportSectionSizes[ZapImportSectionType_Total];
315 COUNT_T m_nImportSectionIndices[ZapImportSectionType_Total];
320 ZapImportTable(ZapImage * pImage)
323 // Everything else is zero initialized by the allocator
326 void Preallocate(COUNT_T cbILImage)
328 PREALLOCATE_HASHTABLE(ZapImportTable::m_imports, 0.0030, cbILImage);
329 PREALLOCATE_HASHTABLE(ZapImportTable::m_blobs, 0.0025, cbILImage);
331 PREALLOCATE_HASHTABLE_NOT_NEEDED(ZapImportTable::m_moduleReferences, cbILImage);
335 // Helpers for encoding import blobs
338 void EncodeModule(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_MODULE_HANDLE module, SigBuilder * pSigBuilder);
339 void EncodeClass(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_CLASS_HANDLE handle, SigBuilder * pSigBuilder);
340 void EncodeClassInContext(CORINFO_MODULE_HANDLE context, CORINFO_CLASS_HANDLE handle, SigBuilder * pSigBuilder);
341 void EncodeField(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_FIELD_HANDLE handle, SigBuilder * pSigBuilder,
342 CORINFO_RESOLVED_TOKEN * pResolvedToken = NULL);
343 void EncodeMethod(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_METHOD_HANDLE handle, SigBuilder * pSigBuilder,
344 CORINFO_RESOLVED_TOKEN * pResolvedToken = NULL, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken = NULL);
346 // Encode module if the reference is within current version bubble. If not, return a suitable module within current version bubble.
347 CORINFO_MODULE_HANDLE TryEncodeModule(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_MODULE_HANDLE module, SigBuilder * pSigBuilder);
349 ICorDynamicInfo * GetJitInfo()
351 return m_pImage->GetJitInfo();
354 ICorCompileInfo * GetCompileInfo()
356 return m_pImage->GetCompileInfo();
359 ZapImage * GetImage()
364 // Returns index of module in the import table for encoding module fixups in EE datastructures.
365 DWORD GetIndexOfModule(CORINFO_MODULE_HANDLE handle)
367 ZapImportTable::ModuleReferenceEntry * pModuleReference = GetModuleReference(handle);
368 _ASSERTE(pModuleReference != NULL);
369 return pModuleReference->m_index;
372 // Get the import blob for given signature
373 ZapBlob * GetBlob(SigBuilder * pSigBuilder, BOOL fEager = FALSE);
375 // Place give import blob
376 void PlaceBlob(ZapBlob * pBlob, BOOL fEager = FALSE);
378 // Encodes the import blob and places it into the image
379 ZapBlob * PlaceImportBlob(ZapImport * pImport, BOOL fEager = FALSE);
381 // Places import cell into the image.
382 // This also encoded and places all the import blobs if they are not placed yet.
383 void PlaceImport(ZapImport * pImport);
385 // Encodes list of fixups and places it into the image.
386 // This also places all the import cells if they are not placed yet.
387 ZapFixupInfo * PlaceFixups(ZapImport ** pImports);
388 void PlaceFixups(ZapImport ** pImports, NibbleWriter& writer);
390 ZapGenericSignature * GetGenericSignature(PVOID signature, BOOL fMethod);
393 // The actual implementations of import cells
395 ZapImport * GetFunctionEntryImport(CORINFO_METHOD_HANDLE handle);
396 ZapImport * GetModuleHandleImport(CORINFO_MODULE_HANDLE handle);
397 ZapImport * GetClassHandleImport(CORINFO_CLASS_HANDLE handle, PVOID pUniqueId = NULL);
398 ZapImport * GetMethodHandleImport(CORINFO_METHOD_HANDLE handle);
399 ZapImport * GetFieldHandleImport(CORINFO_FIELD_HANDLE handle);
400 ZapImport * GetStringHandleImport(CORINFO_MODULE_HANDLE tokenScope, mdString metaTok);
401 ZapImport * GetStaticFieldAddressImport(CORINFO_FIELD_HANDLE handle);
402 ZapImport * GetClassDomainIdImport(CORINFO_CLASS_HANDLE handle);
403 ZapImport * GetModuleDomainIdImport(CORINFO_MODULE_HANDLE handleToModule, CORINFO_CLASS_HANDLE handleToClass);
404 ZapImport * GetSyncLockImport(CORINFO_CLASS_HANDLE handle);
405 ZapImport * GetIndirectPInvokeTargetImport(CORINFO_METHOD_HANDLE handle);
406 ZapImport * GetProfilingHandleImport(CORINFO_METHOD_HANDLE handle);
407 ZapImport * GetVarArgImport(CORINFO_MODULE_HANDLE handle, mdToken sigOrMemberRefOrDef);
408 ZapImport * GetActiveDependencyImport(CORINFO_MODULE_HANDLE moduleFrom, CORINFO_MODULE_HANDLE moduleTo);
410 ZapImport * GetExistingClassHandleImport(CORINFO_CLASS_HANDLE handle);
411 ZapImport * GetExistingMethodHandleImport(CORINFO_METHOD_HANDLE handle);
412 ZapImport * GetExistingFieldHandleImport(CORINFO_FIELD_HANDLE handle);
414 ZapImport * GetVirtualImportThunk(CORINFO_METHOD_HANDLE handle, int slot);
415 void PlaceVirtualImportThunk(ZapImport * pImportThunk);
417 ZapImport * GetExternalMethodThunk(CORINFO_METHOD_HANDLE handle);
418 ZapImport * GetExternalMethodCell(CORINFO_METHOD_HANDLE handle);
419 ZapImport * GetStubDispatchCell(CORINFO_CLASS_HANDLE typeHnd, CORINFO_METHOD_HANDLE methHnd);
422 // Ready-to-run imports
424 ZapImport * GetClassImport(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_RESOLVED_TOKEN * pResolvedToken);
425 ZapImport * GetMethodImport(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken = NULL);
426 ZapImport * GetFieldImport(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_FIELD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken);
428 ZapImport * GetCheckTypeLayoutImport(CORINFO_CLASS_HANDLE handle);
429 ZapImport * GetCheckFieldOffsetImport(CORINFO_FIELD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken, DWORD offset);
431 ZapImport * GetStubDispatchCell(CORINFO_RESOLVED_TOKEN * pResolvedToken);
432 ZapImport * GetExternalMethodCell(CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken);
434 ZapImport * GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_CLASS_HANDLE handle);
435 ZapImport * GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken,
436 CORINFO_CLASS_HANDLE delegateType = NULL);
437 ZapImport * GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_FIELD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken);
439 #ifdef FEATURE_READYTORUN_COMPILER
440 ZapNode * GetPlacedIndirectHelperThunk(ReadyToRunHelper helperNum, PVOID pArg = NULL, ZapNode * pCell = NULL);
441 ZapNode * GetIndirectHelperThunk(ReadyToRunHelper helperNum, PVOID pArg = NULL);
442 void PlaceIndirectHelperThunk(ZapNode * pImport);
444 ZapImport * GetPlacedHelperImport(ReadyToRunHelper helperNum);
445 ZapImport * GetHelperImport(ReadyToRunHelper helperNum);
448 virtual DWORD GetSize()
450 return m_modules.GetCount() * sizeof(CORCOMPILE_IMPORT_TABLE_ENTRY);
453 virtual UINT GetAlignment()
455 return sizeof(DWORD);
458 virtual ZapNodeType GetType()
460 return ZapNodeType_ImportTable;
463 virtual void Save(ZapWriter * pZapWriter);
467 // CORCOMPILE_CODE_IMPORT_SECTION
469 class ZapImportSectionsTable : public ZapNode
473 ZapVirtualSection * m_pSection;
474 ZapNode * m_pSignatures;
475 ZapNode * m_pAuxiliaryData;
481 SArray<ImportSection> m_ImportSectionsTable;
484 ZapImportSectionsTable(ZapImage * pImage)
488 COUNT_T Append(BYTE Type, USHORT Flags, BYTE EntrySize, ZapVirtualSection * pSection, ZapNode * pSignatures = NULL, ZapNode * pAuxiliaryData = NULL);
490 virtual UINT GetAlignment()
492 return sizeof(DWORD);
495 virtual DWORD GetSize();
497 virtual ZapNodeType GetType()
499 return ZapNodeType_ImportSectionsTable;
502 virtual void Save(ZapWriter * pZapWriter);
506 // ZapImportSectionSignatures contains an array of signature RVAs for given import section.
508 class ZapImportSectionSignatures : public ZapNode
510 ZapVirtualSection * m_pImportSection;
511 ZapGCRefMapTable * m_pGCRefMapTable;
518 ZapImportSectionSignatures(ZapImage * pImage, ZapVirtualSection * pImportSection, ZapVirtualSection * pGCSection = NULL);
519 ~ZapImportSectionSignatures();
521 void PlaceExternalMethodThunk(ZapImport * pImport);
522 void PlaceExternalMethodCell(ZapImport * pImport);
523 void PlaceStubDispatchCell(ZapImport * pImport);
524 void PlaceDynamicHelperCell(ZapImport * pImport);
526 virtual DWORD GetSize();
528 virtual UINT GetAlignment()
530 return sizeof(DWORD);
533 virtual ZapNodeType GetType()
535 return ZapNodeType_ImportSectionSignatures;
538 virtual void Save(ZapWriter * pZapWriter);
541 #include "gcrefmap.h"
543 class ZapGCRefMapTable : public ZapNode
546 GCRefMapBuilder m_GCRefMapBuilder;
550 ZapGCRefMapTable(ZapImage * pImage)
555 void Append(CORINFO_METHOD_HANDLE handle);
557 virtual DWORD GetSize();
559 virtual UINT GetAlignment()
561 return sizeof(DWORD);
564 virtual ZapNodeType GetType()
566 return ZapNodeType_GCRefMapTable;
569 virtual void Save(ZapWriter * pZapWriter);
572 #endif // __ZAPIMPORT_H__