Remove superfluous 'const' qualifier from trivial return types (#20652)
[platform/upstream/coreclr.git] / src / zap / zapimport.h
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 // ZapImport.h
6 //
7
8 //
9 // Import is soft bound references to elements outside the current module
10 // 
11 // ======================================================================================
12
13 #ifndef __ZAPIMPORT_H__
14 #define __ZAPIMPORT_H__
15
16 class ZapImportTable;
17 class ZapGCRefMapTable;
18 class NibbleWriter;
19
20 //---------------------------------------------------------------------------------------
21 //
22 // ZapImport is the import cell itself
23 //
24 // Every import cell is uniquely identified by its ZapNodeType and two handles 
25 // (the second handle is optional and is often NULL)
26 //
27 // Actual implementations inherits from this abstract base class.
28 //
29 class ZapImport : public ZapNode
30 {
31     COUNT_T m_index;
32     DWORD m_offset;
33
34     PVOID m_handle;
35     PVOID m_handle2;
36
37     ZapBlob * m_pBlob;
38
39 public:
40     void SetHandle(PVOID handle)
41     {
42         _ASSERTE(m_handle == NULL);
43         m_handle = handle;
44     }
45
46     void SetHandle2(PVOID handle2)
47     {
48         _ASSERTE(m_handle2 == NULL);
49         m_handle2 = handle2;
50     }
51
52     PVOID GetHandle()
53     {
54         return m_handle;
55     }
56
57     PVOID GetHandle2()
58     {
59         return m_handle2;
60     }
61
62     void SetBlob(ZapBlob * pBlob)
63     {
64         _ASSERTE(m_pBlob == NULL);
65         m_pBlob = pBlob;
66     }
67
68     ZapBlob * GetBlob()
69     {
70         _ASSERTE(m_pBlob != NULL);
71         return m_pBlob;
72     }
73
74     BOOL HasBlob()
75     {
76         return m_pBlob != NULL;
77     }
78
79     virtual ZapImportSectionType ComputePlacement(ZapImage * pImage, BOOL * pfIsEager, BOOL * pfNeedsSignature)
80     {
81         *pfIsEager = FALSE;
82         *pfNeedsSignature = TRUE;
83         return ZapImportSectionType_Handle;
84     }
85
86     // All subtypes have to override
87     virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder) = 0;
88
89     virtual DWORD GetSize()
90     {
91         return TARGET_POINTER_SIZE;
92     }
93
94     virtual UINT GetAlignment()
95     {
96         return TARGET_POINTER_SIZE;
97     }
98
99     virtual void Save(ZapWriter * pZapWriter);
100     
101     //
102     // Offset of the fixup cell within its section
103     //
104
105     void SetSectionIndexAndOffset(COUNT_T index, DWORD offset)
106     {
107         m_index = index;
108         m_offset = offset;
109     }
110
111     DWORD GetSectionIndex()
112     {
113         return m_index;
114     }
115
116     DWORD GetOffset()
117     {
118         return m_offset;
119     }
120 };
121
122 //---------------------------------------------------------------------------------------
123 //
124 // ZapGenericSignature is signature of generic dictionary entry.
125 //
126 class ZapGenericSignature : public ZapBlob
127 {
128 public:
129     ZapGenericSignature(SIZE_T cbSize)
130         : ZapBlob(cbSize)
131     {
132     }
133
134     virtual ZapNodeType GetType()
135     {
136         return ZapNodeType_GenericSignature;
137     }
138 };
139
140 //---------------------------------------------------------------------------------------
141 //
142 // ZapImportTable is the main class that keeps track of all ZapImports.
143 //
144 // There is a single instance of it per image.
145 //
146 class ZapImportTable : public ZapNode
147 {
148     //
149     // Hashtable key of the import
150     // The same key is used for both ZapImport and ZapImportBlob
151     //
152     struct ImportKey
153     {
154         FORCEINLINE ImportKey(PVOID handle, ZapNodeType type)
155             : m_handle(handle), m_handle2(NULL), m_type(type)
156         {
157         }
158
159         FORCEINLINE ImportKey(PVOID handle, PVOID handle2, ZapNodeType type)
160             : m_handle(handle), m_handle2(handle2), m_type(type)
161         {
162         }
163
164         PVOID m_handle;
165         PVOID m_handle2;
166         ZapNodeType m_type;
167     };
168
169     //
170     // Hashtable of ZapImports
171     //
172     class ImportTraits : public NoRemoveSHashTraits< DefaultSHashTraits<ZapImport *> >
173     {
174     public:
175         typedef ImportKey key_t;
176
177         static FORCEINLINE key_t GetKey(element_t e)
178         { 
179             LIMITED_METHOD_CONTRACT;
180             return ImportKey(e->GetHandle(), e->GetHandle2(), e->GetType());
181         }
182         static FORCEINLINE BOOL Equals(key_t k1, key_t k2)
183         { 
184             LIMITED_METHOD_CONTRACT;
185             return (k1.m_handle == k2.m_handle) && (k1.m_handle2 == k2.m_handle2) && (k1.m_type == k2.m_type);
186         }
187         static FORCEINLINE count_t Hash(key_t k) 
188         {
189             LIMITED_METHOD_CONTRACT;
190             return (count_t)(size_t)k.m_handle ^ ((count_t)(size_t)k.m_handle2 << 1) ^ k.m_type;
191         }
192
193         static element_t Null() { LIMITED_METHOD_CONTRACT; return NULL; }
194         static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e == NULL; }
195     };
196
197     typedef SHash< ImportTraits > ImportTable;
198
199     //
200     // Hashtable of module indices
201     //
202     struct ModuleReferenceEntry
203     {
204         CORINFO_MODULE_HANDLE m_module;
205         DWORD m_index;
206
207         USHORT m_wAssemblyRid;
208         USHORT m_wModuleRid;
209     };
210
211     class ModuleReferenceTraits : public NoRemoveSHashTraits< DefaultSHashTraits<ModuleReferenceEntry *> >
212     {
213     public:
214         typedef CORINFO_MODULE_HANDLE key_t;
215
216         static key_t GetKey(element_t e)
217         { 
218             LIMITED_METHOD_CONTRACT;
219             return e->m_module;
220         }
221         static BOOL Equals(key_t k1, key_t k2) 
222         { 
223             LIMITED_METHOD_CONTRACT;
224             return (k1 == k2);
225         }
226         static count_t Hash(key_t k) 
227         {
228             LIMITED_METHOD_CONTRACT;
229             return (count_t)(size_t)k;
230         }
231
232         static element_t Null() { LIMITED_METHOD_CONTRACT; return NULL; }
233         static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e == NULL; }
234     };
235
236     typedef SHash< ModuleReferenceTraits > ModuleReferenceTable;
237
238     //
239     // Helpers for inserting actual implementations of ZapImports into hashtable
240     //
241     template < typename impl, ZapNodeType type >
242     ZapImport * GetImport(PVOID handle)
243     {
244         ZapImport * pImport = m_imports.Lookup(ImportKey(handle, type));
245
246         if (pImport != NULL)
247         {
248             return pImport;
249         }
250
251         pImport = new (m_pImage->GetHeap()) impl();
252         _ASSERTE(pImport->GetType() == type);
253         pImport->SetHandle(handle);
254         m_imports.Add(pImport);
255         return pImport;
256     }
257
258     template < typename impl, ZapNodeType type >
259     ZapImport * GetImport(PVOID handle, PVOID handle2)
260     {
261         ZapImport * pImport = m_imports.Lookup(ImportKey(handle, handle2, type));
262
263         if (pImport != NULL)
264         {
265             return pImport;
266         }
267
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);
273         return pImport;
274     }
275
276     template < typename impl, ZapNodeType type >
277     ZapImport * GetImportForSignature(PVOID handle, SigBuilder * pSigBuilder)
278     {
279         ZapBlob * pBlob = GetBlob(pSigBuilder);
280
281         ZapImport * pImport = m_imports.Lookup(ImportKey(handle, pBlob, type));
282
283         if (pImport != NULL)
284         {
285             return pImport;
286         }
287
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);
294         return pImport;
295     }
296
297     ZapImport * GetExistingImport(ZapNodeType type, PVOID handle)
298     {
299         return m_imports.Lookup(ImportKey(handle, type));
300     }
301
302     ModuleReferenceEntry * GetModuleReference(CORINFO_MODULE_HANDLE handle);
303
304     static DWORD EncodeModuleHelper(LPVOID referencingModule, CORINFO_MODULE_HANDLE referencedModule);
305
306     ImportTable m_imports;          // Interned ZapImport *
307     SHash< NoRemoveSHashTraits < ZapBlob::SHashTraits > > m_blobs; // Interned ZapBlos for signatures and fixups
308
309     ModuleReferenceTable m_moduleReferences;
310     SArray<ModuleReferenceEntry *> m_modules;   // Secondary table of ModuleReferences to allow fast index based lookup
311
312     SHash< NoRemoveSHashTraits < ZapBlob::SHashTraits > > m_genericSignatures;
313
314     DWORD   m_nImportSectionSizes[ZapImportSectionType_Total];
315     COUNT_T m_nImportSectionIndices[ZapImportSectionType_Total];
316
317     ZapImage * m_pImage;
318
319 public:
320     ZapImportTable(ZapImage * pImage)
321         : m_pImage(pImage)
322     {
323          // Everything else is zero initialized by the allocator
324     }
325
326     void Preallocate(COUNT_T cbILImage)
327     {
328         PREALLOCATE_HASHTABLE(ZapImportTable::m_imports, 0.0030, cbILImage);
329         PREALLOCATE_HASHTABLE(ZapImportTable::m_blobs, 0.0025, cbILImage);
330
331         PREALLOCATE_HASHTABLE_NOT_NEEDED(ZapImportTable::m_moduleReferences, cbILImage);
332     }
333
334     //
335     // Helpers for encoding import blobs
336     //
337
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, BOOL fEncodeUsingResolvedTokenSpecStreams = FALSE);
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,
345             BOOL fEncodeUsingResolvedTokenSpecStreams = FALSE);
346
347     // Encode module if the reference is within current version bubble. If not, return a suitable module within current version bubble.
348     CORINFO_MODULE_HANDLE TryEncodeModule(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_MODULE_HANDLE module, SigBuilder * pSigBuilder);
349
350     ICorDynamicInfo * GetJitInfo()
351     {
352         return m_pImage->GetJitInfo();
353     }
354
355     ICorCompileInfo * GetCompileInfo()
356     {
357         return m_pImage->GetCompileInfo();
358     }
359
360     ZapImage * GetImage()
361     {
362         return m_pImage;
363     }
364
365     // Returns index of module in the import table for encoding module fixups in EE datastructures.
366     DWORD GetIndexOfModule(CORINFO_MODULE_HANDLE handle)
367     {
368         ZapImportTable::ModuleReferenceEntry * pModuleReference = GetModuleReference(handle);
369         _ASSERTE(pModuleReference != NULL);
370         return pModuleReference->m_index;
371     }
372
373     // Get the import blob for given signature
374     ZapBlob * GetBlob(SigBuilder * pSigBuilder, BOOL fEager = FALSE);
375
376     // Place give import blob
377     void PlaceBlob(ZapBlob * pBlob, BOOL fEager = FALSE);
378
379     // Encodes the import blob and places it into the image
380     ZapBlob * PlaceImportBlob(ZapImport * pImport, BOOL fEager = FALSE);
381
382     // Places import cell into the image.
383     // This also encoded and places all the import blobs if they are not placed yet.
384     void PlaceImport(ZapImport * pImport);
385
386     // Encodes list of fixups and places it into the image. 
387     // This also places all the import cells if they are not placed yet.
388     ZapFixupInfo * PlaceFixups(ZapImport ** pImports);
389     void PlaceFixups(ZapImport ** pImports, NibbleWriter& writer);
390
391     ZapGenericSignature * GetGenericSignature(PVOID signature, BOOL fMethod);
392
393     //
394     // The actual implementations of import cells
395     //
396     ZapImport * GetFunctionEntryImport(CORINFO_METHOD_HANDLE handle);
397     ZapImport * GetModuleHandleImport(CORINFO_MODULE_HANDLE handle);
398     ZapImport * GetClassHandleImport(CORINFO_CLASS_HANDLE handle, PVOID pUniqueId = NULL);
399     ZapImport * GetMethodHandleImport(CORINFO_METHOD_HANDLE handle);
400     ZapImport * GetFieldHandleImport(CORINFO_FIELD_HANDLE handle);
401     ZapImport * GetStringHandleImport(CORINFO_MODULE_HANDLE tokenScope, mdString metaTok);
402     ZapImport * GetStaticFieldAddressImport(CORINFO_FIELD_HANDLE handle);
403     ZapImport * GetClassDomainIdImport(CORINFO_CLASS_HANDLE handle);
404     ZapImport * GetModuleDomainIdImport(CORINFO_MODULE_HANDLE handleToModule, CORINFO_CLASS_HANDLE handleToClass);
405     ZapImport * GetSyncLockImport(CORINFO_CLASS_HANDLE handle); 
406     ZapImport * GetIndirectPInvokeTargetImport(CORINFO_METHOD_HANDLE handle);
407     ZapImport * GetProfilingHandleImport(CORINFO_METHOD_HANDLE handle);
408     ZapImport * GetVarArgImport(CORINFO_MODULE_HANDLE handle, mdToken sigOrMemberRefOrDef);
409     ZapImport * GetActiveDependencyImport(CORINFO_MODULE_HANDLE moduleFrom, CORINFO_MODULE_HANDLE moduleTo);
410
411     ZapImport * GetExistingClassHandleImport(CORINFO_CLASS_HANDLE handle);
412     ZapImport * GetExistingMethodHandleImport(CORINFO_METHOD_HANDLE handle);
413     ZapImport * GetExistingFieldHandleImport(CORINFO_FIELD_HANDLE handle);
414
415     ZapImport * GetVirtualImportThunk(CORINFO_METHOD_HANDLE handle, int slot);
416     void        PlaceVirtualImportThunk(ZapImport * pImportThunk);
417
418     ZapImport * GetExternalMethodThunk(CORINFO_METHOD_HANDLE handle);
419     ZapImport * GetExternalMethodCell(CORINFO_METHOD_HANDLE handle);
420     ZapImport * GetStubDispatchCell(CORINFO_CLASS_HANDLE typeHnd, CORINFO_METHOD_HANDLE methHnd);
421
422     //
423     // Ready-to-run imports
424     //
425     ZapImport * GetClassImport(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_RESOLVED_TOKEN * pResolvedToken);
426     ZapImport * GetMethodImport(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken = NULL);
427     ZapImport * GetFieldImport(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_FIELD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken);
428
429     ZapImport * GetCheckTypeLayoutImport(CORINFO_CLASS_HANDLE handle);
430     ZapImport * GetCheckFieldOffsetImport(CORINFO_FIELD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken, DWORD offset);
431
432     ZapImport * GetStubDispatchCell(CORINFO_RESOLVED_TOKEN * pResolvedToken);
433     ZapImport * GetExternalMethodCell(CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken);
434
435     ZapImport * GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_CLASS_HANDLE handle);
436     ZapImport * GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_CLASS_HANDLE delegateType = NULL);
437     ZapImport * GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_FIELD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken);
438
439     ZapImport * GetDictionaryLookupCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_LOOKUP_KIND * pLookup);
440
441 #ifdef FEATURE_READYTORUN_COMPILER
442     ZapNode * GetPlacedIndirectHelperThunk(ReadyToRunHelper helperNum, PVOID pArg = NULL, ZapNode * pCell = NULL);
443     ZapNode * GetIndirectHelperThunk(ReadyToRunHelper helperNum, PVOID pArg = NULL);
444     void PlaceIndirectHelperThunk(ZapNode * pImport);
445
446     ZapImport * GetPlacedHelperImport(ReadyToRunHelper helperNum);
447     ZapImport * GetHelperImport(ReadyToRunHelper helperNum);
448 #endif
449
450     virtual DWORD GetSize()
451     {
452         return m_modules.GetCount() * sizeof(CORCOMPILE_IMPORT_TABLE_ENTRY);
453     }
454
455     virtual UINT GetAlignment()
456     {
457         return sizeof(DWORD);
458     }
459
460     virtual ZapNodeType GetType()
461     {
462         return ZapNodeType_ImportTable;
463     }
464
465     virtual void Save(ZapWriter * pZapWriter);
466 };
467
468 //
469 // CORCOMPILE_CODE_IMPORT_SECTION
470 //
471 class ZapImportSectionsTable : public ZapNode
472 {
473     struct ImportSection
474     {
475         ZapVirtualSection * m_pSection;
476         ZapNode * m_pSignatures;
477         ZapNode * m_pAuxiliaryData;
478         USHORT    m_Flags;
479         BYTE      m_Type;
480         BYTE      m_EntrySize;
481     };
482
483     SArray<ImportSection> m_ImportSectionsTable;
484
485 public:
486     ZapImportSectionsTable(ZapImage * pImage)
487     {
488     }
489
490     COUNT_T Append(BYTE Type, USHORT Flags, BYTE EntrySize, ZapVirtualSection * pSection, ZapNode * pSignatures = NULL, ZapNode * pAuxiliaryData = NULL);
491
492     virtual UINT GetAlignment()
493     {
494         return sizeof(DWORD);
495     }
496
497     virtual DWORD GetSize();
498
499     virtual ZapNodeType GetType()
500     {
501         return ZapNodeType_ImportSectionsTable;
502     }
503
504     virtual void Save(ZapWriter * pZapWriter);
505 };
506
507 //
508 // ZapImportSectionSignatures contains an array of signature RVAs for given import section.
509 //
510 class ZapImportSectionSignatures : public ZapNode
511 {
512     ZapVirtualSection * m_pImportSection;
513     ZapGCRefMapTable * m_pGCRefMapTable;
514
515     DWORD m_dwIndex;
516
517     ZapImage * m_pImage;
518
519 public:
520     ZapImportSectionSignatures(ZapImage * pImage, ZapVirtualSection * pImportSection, ZapVirtualSection * pGCSection = NULL);
521     ~ZapImportSectionSignatures();
522
523     void PlaceExternalMethodThunk(ZapImport * pImport);
524     void PlaceExternalMethodCell(ZapImport * pImport);
525     void PlaceStubDispatchCell(ZapImport * pImport);
526     void PlaceDynamicHelperCell(ZapImport * pImport);
527
528     virtual DWORD GetSize();
529
530     virtual UINT GetAlignment()
531     {
532         return sizeof(DWORD);
533     }
534
535     virtual ZapNodeType GetType()
536     {
537         return ZapNodeType_ImportSectionSignatures;
538     }
539
540     virtual void Save(ZapWriter * pZapWriter);
541 };
542
543 #include "gcrefmap.h"
544
545 class ZapGCRefMapTable : public ZapNode
546 {
547     ZapImage * m_pImage;
548     GCRefMapBuilder m_GCRefMapBuilder;
549     COUNT_T m_nCount;
550
551 public:
552     ZapGCRefMapTable(ZapImage * pImage)
553         : m_pImage(pImage)
554     {
555     }
556
557     void Append(CORINFO_METHOD_HANDLE handle);
558
559     virtual DWORD GetSize();
560
561     virtual UINT GetAlignment()
562     {
563         return sizeof(DWORD);
564     }
565
566     virtual ZapNodeType GetType()
567     {
568         return ZapNodeType_GCRefMapTable;
569     }
570
571     virtual void Save(ZapWriter * pZapWriter);
572 };
573
574 #endif // __ZAPIMPORT_H__