[Tizen] Unify dnetmemoryenumlib terms to match the codebase (#291)
[platform/upstream/coreclr.git] / src / vm / peimage.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 // PEImage.h
6 // 
7
8 // --------------------------------------------------------------------------------
9
10
11 #ifndef PEIMAGE_H_
12 #define PEIMAGE_H_
13
14 // --------------------------------------------------------------------------------
15 // Required headers
16 // --------------------------------------------------------------------------------
17
18 #include "clrtypes.h"
19 #include "peimagelayout.h"
20 #include "sstring.h"
21 #include "holder.h"
22
23 class SimpleRWLock;
24 // --------------------------------------------------------------------------------
25 // Forward declarations
26 // --------------------------------------------------------------------------------
27
28 class Crst;
29 class Thread;
30
31 Thread* GetThreadNULLOk();
32
33 // --------------------------------------------------------------------------------
34 // PEImage is a PE file loaded by our "simulated LoadLibrary" mechanism.  A PEImage 
35 // can be loaded either FLAT (same layout as on disk) or MAPPED (PE sections 
36 // mapped into virtual addresses.)
37 // 
38 // The MAPPED format is currently limited to "IL only" images - this can be checked
39 // for via PEDecoder::IsILOnlyImage.
40 //
41 // NOTE: PEImage will NEVER call LoadLibrary.
42 // --------------------------------------------------------------------------------
43
44
45
46 #define CV_SIGNATURE_RSDS   0x53445352
47
48 // CodeView RSDS debug information -> PDB 7.00
49 struct CV_INFO_PDB70 
50 {
51     DWORD      magic; 
52     GUID       signature;       // unique identifier 
53     DWORD      age;             // an always-incrementing value 
54     char       path[MAX_LONGPATH];  // zero terminated string with the name of the PDB file 
55 };
56
57 typedef DPTR(class PEImage)                PTR_PEImage;
58
59 class PEImage 
60 {
61     friend class PEModule;
62 public:
63     // ------------------------------------------------------------
64     // Public constants
65     // ------------------------------------------------------------
66
67     enum
68     {
69         LAYOUT_CREATEIFNEEDED=1
70     };
71     PTR_PEImageLayout GetLayout(DWORD imageLayoutMask,DWORD flags); //with ref
72     PTR_PEImageLayout GetLoadedLayout(); //no ref
73     BOOL IsOpened();
74     BOOL HasLoadedLayout();
75
76 public:
77     // ------------------------------------------------------------
78     // Public API
79     // ------------------------------------------------------------
80
81     static void Startup();
82
83     // Normal constructed PEImages do NOT share images between calls and
84     // cannot be accessed by Get methods.
85     //
86     // DO NOT USE these unless you want a private copy-on-write mapping of
87     // the file.
88
89
90
91 public:
92     ~PEImage();
93     PEImage();
94
95 #ifndef DACCESS_COMPILE
96     static PTR_PEImage LoadFlat(
97         const void *flat,
98         COUNT_T size);
99 #ifndef FEATURE_PAL
100     static PTR_PEImage LoadImage(
101         HMODULE hMod);
102 #endif // !FEATURE_PAL        
103     static PTR_PEImage OpenImage(
104         LPCWSTR pPath,
105         MDInternalImportFlags flags = MDInternalImport_Default);
106
107
108     // clones the image with new flags (this is pretty much about cached / noncached difference)
109     void Clone(MDInternalImportFlags flags, PTR_PEImage* ppImage)
110     {
111         if (GetPath().IsEmpty())
112         {
113             AddRef();
114             *ppImage = this;
115         }
116         else
117             *ppImage = PEImage::OpenImage(GetPath(), flags);
118
119     };
120
121     // pUnkResource must be one of the ICLRPrivResource* interfaces defined in CLRPrivBinding.IDL.
122     // pUnkResource will be queried for each of these to find a match and 
123     static PEImage * OpenImage(
124         ICLRPrivResource * pIResource,
125         MDInternalImportFlags flags = MDInternalImport_Default);
126
127     static PTR_PEImage FindById(UINT64 uStreamAsmId, DWORD dwModuleId);
128     static PTR_PEImage FindByPath(LPCWSTR pPath);    
129     static PTR_PEImage FindByShortPath(LPCWSTR pPath);
130     static PTR_PEImage FindByLongPath(LPCWSTR pPath);
131     void AddToHashMap();
132
133     void   Load();
134     void   SetLoadedHMODULE(HMODULE hMod);
135     void   LoadNoMetaData();
136     void   LoadNoFile();
137     void   LoadFromMapped();
138
139     void AllocateLazyCOWPages();
140 #endif
141     
142     BOOL   HasID();
143     ULONG GetIDHash();
144     
145     PTR_CVOID GetStrongNameSignature(COUNT_T *pSize = NULL);
146     
147
148     // Refcount above images.
149     ULONG AddRef();
150     ULONG Release();
151
152     // Accessors
153     const SString &GetPath();
154     BOOL IsFile();
155     HANDLE GetFileHandle();
156     void SetFileHandle(HANDLE hFile);
157     HRESULT TryOpenFile();    
158
159     LPCWSTR GetPathForErrorMessages();
160
161     // Equality
162     BOOL Equals(PEImage *pImage);
163
164     void GetMVID(GUID *pMvid);
165     BOOL HasV1Metadata();
166     IMDInternalImport* GetMDImport();
167     BOOL MDImportLoaded();
168     IMDInternalImport* GetNativeMDImport(BOOL loadAllowed = TRUE);    
169
170     BOOL HasContents() ;
171     BOOL HasNativeHeader() ;
172     BOOL IsPtrInImage(PTR_CVOID data);
173     CHECK CheckFormat();
174
175     // Check utilites
176     CHECK CheckILFormat();
177 #ifdef FEATURE_PREJIT    
178     CHECK CheckNativeFormat();    
179 #endif // FEATURE_PREJIT
180     static CHECK CheckCanonicalFullPath(const SString &path);
181     static CHECK CheckStartup();
182     PTR_CVOID GetMetadata(COUNT_T *pSize = NULL);
183     void GetHashedStrongNameSignature(SBuffer &result);
184
185 #ifndef FEATURE_PAL
186     static void GetPathFromDll(HINSTANCE hMod, SString &result);
187 #endif // !FEATURE_PAL
188     static BOOL PathEquals(const SString &p1, const SString &p2);
189     BOOL IsTrustedNativeImage(){LIMITED_METHOD_CONTRACT; return m_bIsTrustedNativeImage;};
190     void SetIsTrustedNativeImage(){LIMITED_METHOD_CONTRACT; m_bIsTrustedNativeImage=TRUE;};
191
192     void SetModuleFileNameHintForDAC();
193 #ifdef DACCESS_COMPILE
194     void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
195     const SString &GetModuleFileNameHintForDAC();
196 #endif
197
198     BOOL HasNTHeaders();
199     BOOL HasCorHeader();
200     BOOL HasReadyToRunHeader();
201     void SetPassiveDomainOnly();
202     BOOL PassiveDomainOnly();
203     BOOL IsReferenceAssembly();
204 #ifdef FEATURE_PREJIT
205     BOOL IsNativeILILOnly();
206     BOOL IsNativeILDll();
207     void GetNativeILPEKindAndMachine(DWORD* pdwKind, DWORD* pdwMachine);
208 #endif
209     PTR_CVOID GetNativeManifestMetadata(COUNT_T *pSize = NULL);
210     BOOL HasDirectoryEntry(int entry);
211     mdToken GetEntryPointToken();
212     DWORD GetCorHeaderFlags();
213     BOOL IsILOnly();
214     BOOL IsDll();
215     WORD GetSubsystem();
216     BOOL  IsFileLocked();
217     BOOL HasStrongNameSignature();
218
219     BOOL IsIbcOptimized();
220     BOOL Has32BitNTHeaders();
221
222     void VerifyIsAssembly();
223     void VerifyIsNIAssembly();
224
225
226     static void GetAll(SArray<PEImage*> &images);
227
228 private:
229 #ifndef DACCESS_COMPILE
230     // Get or create the layout corresponding to the mask, with an AddRef
231     PTR_PEImageLayout GetLayoutInternal(DWORD imageLayoutMask, DWORD flags); 
232
233     // Create the mapped layout
234     PTR_PEImageLayout CreateLayoutMapped();
235
236     // Create the flat layout
237     PTR_PEImageLayout CreateLayoutFlat(BOOL bPermitWriteableSections);
238 #endif
239     // Get an existing layout corresponding to the mask, no AddRef
240     PTR_PEImageLayout GetExistingLayoutInternal(DWORD imageLayoutMask);
241
242     void OpenMDImport();
243     void OpenNativeMDImport();    
244     // ------------------------------------------------------------
245     // Private routines
246     // ------------------------------------------------------------
247
248     void  Init(LPCWSTR pPath);
249     void  Init(IStream* pStream, UINT64 uStreamAsmId,
250                DWORD dwModuleId, BOOL resourceFile);
251
252     void VerifyIsILOrNIAssembly(BOOL fIL);
253
254     struct PEImageLocator
255     {
256
257         LPCWSTR m_pPath;
258
259         PEImageLocator(LPCWSTR pPath)
260             : m_pPath(pPath)
261         {
262         }
263
264         PEImageLocator(PEImage * pImage)
265             : m_pPath(pImage->m_path.GetUnicode())
266         {
267         }
268     };
269
270     static BOOL CompareImage(UPTR image1, UPTR image2);
271     static BOOL CompareIJWDataBase(UPTR base, UPTR mapping);
272
273     void DECLSPEC_NORETURN ThrowFormat(HRESULT hr);
274
275     static CHECK CheckLayoutFormat(PEDecoder *pe);
276
277     // ------------------------------------------------------------
278     // Instance members
279     // ------------------------------------------------------------
280
281     SString     m_path;
282     LONG        m_refCount;
283
284     // This variable will have the data of module name. 
285     // It is only used by DAC to remap fusion loaded modules back to 
286     // disk IL. This really is a workaround. The real fix is for fusion loader
287     // hook (public API on hosting) to take an additional file name hint.
288     // We are piggy backing on the fact that module name is the same as file name!!!
289     //
290     SString     m_sModuleFileNameHintUsedByDac; // This is only used by DAC
291 private:
292     BOOL        m_bIsTrustedNativeImage;
293     BOOL        m_bPassiveDomainOnly;
294 #ifdef FEATURE_LAZY_COW_PAGES
295     BOOL        m_bAllocatedLazyCOWPages;
296 #endif // FEATURE_LAZY_COW_PAGES
297
298 protected:
299
300     enum 
301     {
302         IMAGE_FLAT=0,
303         IMAGE_MAPPED=1,
304         IMAGE_LOADED=2,
305         IMAGE_COUNT=3
306     };
307     
308     SimpleRWLock *m_pLayoutLock;
309     PTR_PEImageLayout m_pLayouts[IMAGE_COUNT] ;
310     BOOL      m_bInHashMap;
311 #ifndef DACCESS_COMPILE    
312     void   SetLayout(DWORD dwLayout, PTR_PEImageLayout pLayout);
313 #endif // DACCESS_COMPILE
314
315
316 #ifdef METADATATRACKER_DATA
317     class MetaDataTracker   *m_pMDTracker;
318 #endif // METADATATRACKER_DATA
319
320     IMDInternalImport* m_pMDImport;
321     IMDInternalImport* m_pNativeMDImport;
322
323
324 private:
325
326
327     // ------------------------------------------------------------
328     // Static members
329     // ------------------------------------------------------------
330
331     static CrstStatic   s_hashLock;
332
333     static PtrHashMap   *s_Images;
334
335     HANDLE m_hFile;
336     bool   m_bOwnHandle;
337
338     BOOL        m_bSignatureInfoCached;
339     HRESULT   m_hrSignatureInfoStatus;
340     DWORD        m_dwSignatureInfo;    
341
342     //@TODO:workaround: Remove this when we have one PEImage per mapped image,
343     //@TODO:workaround: and move the lock there
344     // This is for IJW thunk initialization, as it is no longer guaranteed
345     // that the initialization will occur under the loader lock.
346     static CrstStatic   s_ijwHashLock;
347     static PtrHashMap   *s_ijwFixupDataHash;
348
349 public:
350         class IJWFixupData
351         {
352         private:
353             Crst            m_lock;
354             void           *m_base;
355             DWORD           m_flags;
356             PTR_LoaderHeap  m_DllThunkHeap;
357
358             // the fixup for the next iteration in FixupVTables
359             // we use it to make sure that we do not try to fix up the same entry twice
360             // if there was a pass that was aborted in the middle
361             COUNT_T         m_iNextFixup;
362             COUNT_T         m_iNextMethod;
363
364             enum {
365                 e_FIXED_UP = 0x1
366             };
367
368         public:
369             IJWFixupData(void *pBase);
370             ~IJWFixupData();
371             void *GetBase() { LIMITED_METHOD_CONTRACT; return m_base; }
372             Crst *GetLock() { LIMITED_METHOD_CONTRACT; return &m_lock; }
373             BOOL IsFixedUp() { LIMITED_METHOD_CONTRACT; return m_flags & e_FIXED_UP; }
374             void SetIsFixedUp() { LIMITED_METHOD_CONTRACT; m_flags |= e_FIXED_UP; }
375             PTR_LoaderHeap  GetThunkHeap();
376             void MarkMethodFixedUp(COUNT_T iFixup, COUNT_T iMethod);
377             BOOL IsMethodFixedUp(COUNT_T iFixup, COUNT_T iMethod);
378         };
379
380         static IJWFixupData *GetIJWData(void *pBase);
381         static PTR_LoaderHeap GetDllThunkHeap(void *pBase);
382         static void UnloadIJWModule(void *pBase);
383
384 private:
385     DWORD m_dwPEKind;
386     DWORD m_dwMachine;
387     BOOL  m_fCachedKindAndMachine;
388
389
390
391 public:
392     void CachePEKindAndMachine();
393     void GetPEKindAndMachine(DWORD* pdwKind, DWORD* pdwMachine);
394
395 };
396
397 FORCEINLINE void PEImageRelease(PEImage *i)
398 {
399     WRAPPER_NO_CONTRACT;
400     i->Release();
401 }
402
403 typedef Wrapper<PEImage *, DoNothing, PEImageRelease> PEImageHolder;
404
405 // ================================================================================
406 // Inline definitions
407 // ================================================================================
408
409 #include "peimage.inl"
410
411 #endif  // PEIMAGE_H_