Add a fourth parameter to the DEFINE_DACVAR macro that is the actual fully qualified...
[platform/upstream/coreclr.git] / src / vm / pefile.h
1 //
2 // Copyright (c) Microsoft. All rights reserved.
3 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
4 //
5 // --------------------------------------------------------------------------------
6 // PEFile.h
7 // 
8
9 // --------------------------------------------------------------------------------
10
11
12 #ifndef PEFILE_H_
13 #define PEFILE_H_
14
15 // --------------------------------------------------------------------------------
16 // Required headers
17 // --------------------------------------------------------------------------------
18
19 #include <windef.h>
20
21 #include <corpolicy.h>
22 #include "sstring.h"
23 #include "peimage.h"
24 #include "metadata.h"
25 #include "corhlpr.h"
26 #include "utilcode.h"
27 #include "loaderheap.h"
28 #include "sstring.h"
29 #include "ex.h"
30 #ifdef FEATURE_FUSION
31 #include <fusion.h>
32 #include <fusionbind.h>
33 #include "binderngen.h"
34 #endif
35 #include "assemblyspecbase.h"
36 #include "eecontract.h"
37 #include "metadatatracker.h"
38 #include "stackwalktypes.h"
39 #include <specstrings.h>
40 #include "slist.h"
41 #include "corperm.h"
42 #include "eventtrace.h"
43
44 #ifdef FEATURE_HOSTED_BINDER
45 #include "clrprivbinderutil.h"
46 #endif
47
48 // --------------------------------------------------------------------------------
49 // Forward declared classes
50 // --------------------------------------------------------------------------------
51
52 class Module;
53 class EditAndContinueModule;
54
55 class PEFile;
56 class PEModule;
57 class PEAssembly;
58 class SimpleRWLock;
59
60 class CLRPrivBinderLoadFile;
61
62 typedef VPTR(PEModule) PTR_PEModule;
63 typedef VPTR(PEAssembly) PTR_PEAssembly;
64
65 // --------------------------------------------------------------------------------
66 // Types
67 // --------------------------------------------------------------------------------
68
69 // --------------------------------------------------------------------------------
70 // A PEFile is an input to the CLR loader.  It is produced as a result of 
71 // binding, usually through fusion (although there are a few less common methods to 
72 // obtain one which do not go through fusion, e.g. IJW loads)
73 //
74 // Although a PEFile is usually a disk based PE file (hence the name), it is not 
75 // always the case. Thus it is a conscious decision to not export access to the PE
76 // file directly; rather the specific information required should be provided via
77 // individual query API.
78 //
79 // There are multiple "flavors" of PEFiles:
80 //
81 // 1. HMODULE - these PE Files are loaded in response to "spontaneous" OS callbacks.
82 //    These should only occur for .exe main modules and IJW dlls loaded via LoadLibrary
83 //    or static imports in umnanaged code.
84 //
85 // 2. Fusion loads - these are the most common case.  A path is obtained from fusion and
86 //    the result is loaded via PEImage.
87 //      a. Display name loads - these are metadata-based binds
88 //      b. Path loads - these are loaded from an explicit path
89 //
90 // 3. Byte arrays - loaded explicitly by user code.  These also go through PEImage.
91 //
92 // 4. Dynamic - these are not actual PE images at all, but are placeholders
93 //    for reflection-based modules.
94 //
95 // PEFiles are segmented into two subtypes: PEAssembly and PEModule.  The formere
96 // is a file to be loaded as an assembly, and the latter is to be loaded as a module.
97 // 
98 // See also file:..\inc\corhdr.h#ManagedHeader for more on the format of managed images.
99 // See code:Module for more on modules 
100 // --------------------------------------------------------------------------------
101
102 typedef VPTR(class PEFile) PTR_PEFile;
103
104 typedef ReleaseHolder<IMDInternalImport> IMDInternalImportHolder;
105
106 class PEFile
107 {
108     // ------------------------------------------------------------
109     // SOS support
110     // ------------------------------------------------------------
111     VPTR_BASE_CONCRETE_VTABLE_CLASS(PEFile)
112
113 public:
114
115     // ------------------------------------------------------------
116     // Public API
117     // ------------------------------------------------------------
118
119     STDMETHOD_(ULONG, AddRef)();
120     STDMETHOD_(ULONG, Release)();
121
122 #ifdef DACCESS_COMPILE
123     virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
124 #endif
125
126 #if CHECK_INVARIANTS
127     CHECK Invariant();
128 #endif
129
130 private:
131     // ------------------------------------------------------------
132     // Loader access API
133     // ------------------------------------------------------------
134
135     friend class DomainFile;
136     friend class PEModule;
137 #ifdef DACCESS_COMPILE
138     friend class NativeImageDumper;
139 #endif
140
141     // Load actually triggers loading side effects of the module.  This should ONLY
142     // be done after validation has been passed
143     BOOL CanLoadLibrary();
144 public:
145     void LoadLibrary(BOOL allowNativeSkip = TRUE);
146
147 #ifdef FEATURE_MIXEDMODE
148 protected:
149     // Returns TRUE if this file references managed CRT (msvcmNN*).
150     BOOL ReferencesManagedCRT();
151     
152     // Checks for unsupported loads of C++/CLI assemblies into multiple runtimes in this process.
153     void CheckForDisallowedInProcSxSLoad();
154 #endif // FEATURE_MIXEDMODE
155
156 private:
157     void CheckForDisallowedInProcSxSLoadWorker();
158     void ValidateImagePlatformNeutrality();
159
160     // For use inside LoadLibrary callback
161     friend HRESULT ExecuteDLLForAttach(HINSTANCE hInst,
162                                        DWORD dwReason,
163                                        LPVOID lpReserved,
164                                        BOOL fFromThunk);
165     void SetLoadedHMODULE(HMODULE hMod);
166
167     BOOL HasSkipVerification();
168     void SetSkipVerification();
169
170     // DO NOT USE !!! this is to be removed when we move to new fusion binding API
171     friend class DomainAssembly;
172
173     // Helper for creating metadata for CreateDynamic
174     friend class Assembly;
175     friend class COMDynamicWrite;
176     friend class AssemblyNative;
177     static void DefineEmitScope(
178         GUID   iid, 
179         void **ppEmit);
180
181 protected:
182     IMDInternalImportHolder GetMDImport();
183
184 public:
185     // ------------------------------------------------------------
186     // Generic PEFile - can be used to access metadata
187     // ------------------------------------------------------------
188     
189     static PEFile *Open(PEImage *image);
190
191     // ------------------------------------------------------------
192     // Identity
193     // ------------------------------------------------------------
194
195 #ifndef DACCESS_COMPILE
196     BOOL Equals(PEFile *pFile);
197     BOOL Equals(PEImage *pImage);
198 #endif // DACCESS_COMPILE
199
200 #ifndef FEATURE_CORECLR
201     BOOL  IsShareable();
202 #endif
203
204     void GetMVID(GUID *pMvid);
205
206     // ------------------------------------------------------------
207     // Descriptive strings
208     // ------------------------------------------------------------
209
210     // Path is the file path to the file; empty if not a file
211     const SString &GetPath();
212
213 #ifdef DACCESS_COMPILE
214     // This is the metadata module name. Used as a hint as file name. 
215     const SString &GetModuleFileNameHint();
216 #endif // DACCESS_COMPILE
217
218     // Full name is the most descriptive name available (path, codebase, or name as appropriate)
219     void GetCodeBaseOrName(SString &result);
220     
221     // Returns security information for the assembly based on the codebase
222     void GetSecurityIdentity(SString &codebase, SecZone *pdwZone, DWORD dwFlags, BYTE *pbUniqueID, DWORD *pcbUniqueID);
223     void InitializeSecurityManager();
224
225 #ifdef LOGGING
226     // This is useful for log messages
227     LPCWSTR GetDebugName();
228 #endif
229
230     // ------------------------------------------------------------
231     // Checks
232     // ------------------------------------------------------------
233
234     CHECK CheckLoaded(BOOL allowNativeSkip = TRUE);
235     void ValidateForExecution();
236     BOOL IsMarkedAsNoPlatform();
237     BOOL IsMarkedAsContentTypeWindowsRuntime();
238
239
240     // ------------------------------------------------------------
241     // Classification
242     // ------------------------------------------------------------
243
244     BOOL IsAssembly() const;
245     PTR_PEAssembly AsAssembly();
246     BOOL IsModule() const;
247     PTR_PEModule AsModule();
248     BOOL IsSystem() const;
249     BOOL IsDynamic() const;
250     BOOL IsResource() const;
251     BOOL IsIStream() const;
252     BOOL IsIntrospectionOnly() const;
253     // Returns self (if assembly) or containing assembly (if module)
254     PEAssembly *GetAssembly() const;
255
256     // ------------------------------------------------------------
257     // Hash support
258     // ------------------------------------------------------------
259
260 #ifndef DACCESS_COMPILE
261     void GetImageBits(SBuffer &result);
262     void GetHash(ALG_ID algorithm, SBuffer &result);
263 #endif // DACCESS_COMPILE
264
265     void GetSHA1Hash(SBuffer &result);
266     CHECK CheckHash(ALG_ID algorithm, const void *hash, COUNT_T size);
267
268     // ------------------------------------------------------------
269     // Metadata access
270     // ------------------------------------------------------------
271
272     BOOL HasMetadata();
273
274     IMDInternalImport *GetPersistentMDImport();
275     IMDInternalImport *GetMDImportWithRef();    
276     void MakeMDImportPersistent() {m_bHasPersistentMDImport=TRUE;};
277
278 #ifndef DACCESS_COMPILE
279     IMetaDataEmit *GetEmitter();
280     IMetaDataAssemblyEmit *GetAssemblyEmitter();
281     IMetaDataImport2 *GetRWImporter();
282     IMetaDataAssemblyImport *GetAssemblyImporter();
283 #else
284     TADDR GetMDInternalRWAddress();
285 #endif // DACCESS_COMPILE
286
287     LPCUTF8 GetSimpleName();
288     HRESULT GetScopeName(LPCUTF8 * pszName);
289     BOOL IsStrongNameVerified();
290     BOOL IsStrongNamed();
291     const void *GetPublicKey(DWORD *pcbPK);
292     ULONG GetHashAlgId();
293     HRESULT GetVersion(USHORT *pMajor, USHORT *pMinor, USHORT *pBuild, USHORT *pRevision);
294     LPCSTR GetLocale();
295     DWORD GetFlags();
296     HRESULT GetFlagsNoTrigger(DWORD * pdwFlags);
297 #ifdef FEATURE_CAS_POLICY
298     COR_TRUST *GetAuthenticodeSignature();
299 #endif
300     // ------------------------------------------------------------
301     // PE file access
302     // ------------------------------------------------------------
303
304     BOOL HasSecurityDirectory();
305     BOOL IsIbcOptimized();
306     WORD GetSubsystem();
307     mdToken GetEntryPointToken(
308 #ifdef _DEBUG        
309         BOOL bAssumeLoaded = FALSE
310 #endif //_DEBUG               
311         );
312     BOOL IsILOnly();
313     BOOL IsDll();
314
315     TADDR GetIL(RVA il);
316
317     PTR_VOID GetRvaField(RVA field);
318     CHECK CheckRvaField(RVA field);
319     CHECK CheckRvaField(RVA field, COUNT_T size);
320
321     PCCOR_SIGNATURE GetSignature(RVA signature);
322     RVA GetSignatureRva(PCCOR_SIGNATURE signature);
323     CHECK CheckSignature(PCCOR_SIGNATURE signature);
324     CHECK CheckSignatureRva(RVA signature);
325
326     BOOL HasTls();
327     BOOL IsRvaFieldTls(RVA field);
328     UINT32 GetFieldTlsOffset(RVA field);
329     UINT32 GetTlsIndex();
330
331     const void *GetInternalPInvokeTarget(RVA target);
332     CHECK CheckInternalPInvokeTarget(RVA target);
333
334     IMAGE_COR_VTABLEFIXUP *GetVTableFixups(COUNT_T *pCount = NULL);
335     void *GetVTable(RVA rva);
336
337     BOOL GetResource(LPCSTR szName, DWORD *cbResource,
338                      PBYTE *pbInMemoryResource, DomainAssembly** pAssemblyRef,
339                      LPCSTR *szFileName, DWORD *dwLocation, 
340                      StackCrawlMark *pStackMark, BOOL fSkipSecurityCheck,
341                      BOOL fSkipRaiseResolveEvent, DomainAssembly* pDomainAssembly,
342                      AppDomain* pAppDomain);
343 #ifndef DACCESS_COMPILE
344     PTR_CVOID GetMetadata(COUNT_T *pSize);
345 #endif
346     PTR_CVOID GetLoadedMetadata(COUNT_T *pSize);
347
348     void GetPEKindAndMachine(DWORD* pdwKind, DWORD* pdwMachine);
349
350     ULONG GetILImageTimeDateStamp();
351
352 #ifdef FEATURE_CAS_POLICY
353     SAFEHANDLE GetSafeHandle();
354 #endif // FEATURE_CAS_POLICY
355
356     // ------------------------------------------------------------
357     // Image memory access
358     //
359     // WARNING: do not abuse these.  There are scenarios where the image
360     // is not in memory as an optimization.  
361     //
362     // In general, you should add an entry point to get the specific info 
363     // you are interested in, rather than using these general purpose 
364     // entry points.  The info can then be extracted from the native image
365     // in the no-IL image case.
366     // ------------------------------------------------------------
367
368     // For IJW purposes only - this asserts that we have an IJW image.
369     HMODULE GetIJWBase();
370
371     // The debugger can tolerate a null value here for native only loading cases
372     PTR_VOID GetDebuggerContents(COUNT_T *pSize = NULL);
373
374 #ifndef DACCESS_COMPILE
375     // Returns the IL image range; may force a LoadLibrary
376     const void *GetManagedFileContents(COUNT_T *pSize = NULL);
377 #endif // DACCESS_COMPILE
378
379     PTR_CVOID GetLoadedImageContents(COUNT_T *pSize = NULL);
380     
381     // SetInProcSxSLoadVerified can run concurrently as we don't hold locks during LoadLibrary but
382     // it is the only flag that can be set during this phase so no mutual exclusion is necessary.
383     void SetInProcSxSLoadVerified() { LIMITED_METHOD_CONTRACT; m_flags |= PEFILE_SXS_LOAD_VERIFIED; }
384     BOOL IsInProcSxSLoadVerified() { LIMITED_METHOD_CONTRACT; return m_flags & PEFILE_SXS_LOAD_VERIFIED; }
385
386     // ------------------------------------------------------------
387     // Native image access
388     // ------------------------------------------------------------
389
390     // Does the loader support using a native image for this file?
391     // Some implementation restrictions prevent native images from being used
392     // in some cases.
393 #ifdef FEATURE_PREJIT 
394     BOOL CanUseNativeImage() { LIMITED_METHOD_CONTRACT; return m_fCanUseNativeImage; }
395     void SetCannotUseNativeImage() { LIMITED_METHOD_CONTRACT; m_fCanUseNativeImage = FALSE; }
396     void SetNativeImageUsedExclusively() { LIMITED_METHOD_CONTRACT; m_flags|=PEFILE_NATIVE_IMAGE_USED_EXCLUSIVELY; }
397     BOOL IsNativeImageUsedExclusively() { LIMITED_METHOD_CONTRACT; return m_flags&PEFILE_NATIVE_IMAGE_USED_EXCLUSIVELY; }
398     void SetSafeToHardBindTo() { LIMITED_METHOD_CONTRACT; m_flags|=PEFILE_SAFE_TO_HARDBINDTO; }
399     BOOL IsSafeToHardBindTo() { LIMITED_METHOD_CONTRACT; return m_flags&PEFILE_SAFE_TO_HARDBINDTO; }
400
401     BOOL IsNativeLoaded();
402     PEImage *GetNativeImageWithRef();
403     PEImage *GetPersistentNativeImage();
404 #endif
405     BOOL HasNativeImage();
406     PTR_PEImageLayout GetLoaded();
407     PTR_PEImageLayout GetLoadedNative();
408     PTR_PEImageLayout GetLoadedIL();    
409     PTR_PEImageLayout GetAnyILWithRef();        //AddRefs!
410     IStream * GetPdbStream();       
411     void ClearPdbStream();
412     BOOL IsLoaded(BOOL bAllowNativeSkip=TRUE) ;
413     BOOL PassiveDomainOnly();
414     BOOL IsPtrInILImage(PTR_CVOID data);
415
416 #ifdef DACCESS_COMPILE    
417     PEImage *GetNativeImage()
418     {
419         LIMITED_METHOD_DAC_CONTRACT;
420 #ifdef FEATURE_PREJIT 
421         return m_nativeImage;
422 #else
423         return NULL;
424 #endif
425     }
426 #endif
427
428 #ifdef FEATURE_PREJIT 
429     // ------------------------------------------------------------
430     // Native image config utilities
431     // ------------------------------------------------------------
432
433     static CorCompileConfigFlags GetNativeImageConfigFlags(BOOL fForceDebug = FALSE,
434                                                            BOOL fForceProfiling = FALSE,
435                                                            BOOL fForceInstrument = FALSE);
436     
437     static CorCompileConfigFlags GetNativeImageConfigFlagsWithOverrides();
438
439 #ifdef DEBUGGING_SUPPORTED
440     static void SetNGENDebugFlags(BOOL fAllowOpt);
441     static void GetNGENDebugFlags(BOOL *fAllowOpt);
442 #endif
443
444 #ifdef FEATURE_TREAT_NI_AS_MSIL_DURING_DIAGNOSTICS
445     static BOOL ShouldTreatNIAsMSIL();
446 #endif // FEATURE_TREAT_NI_AS_MSIL_DURING_DIAGNOSTICS
447             
448 #endif  // FEATURE_PREJIT
449
450     // ------------------------------------------------------------
451     // Resource access
452     // ------------------------------------------------------------
453
454     void GetEmbeddedResource(DWORD dwOffset, DWORD *cbResource, PBYTE *pbInMemoryResource);
455
456     // ------------------------------------------------------------
457     // File loading
458     // ------------------------------------------------------------
459
460     PEAssembly * LoadAssembly(
461             mdAssemblyRef       kAssemblyRef, 
462             IMDInternalImport * pImport = NULL, 
463             LPCUTF8             szWinRtTypeNamespace = NULL, 
464             LPCUTF8             szWinRtTypeClassName = NULL);
465
466     // ------------------------------------------------------------
467     // Logging
468     // ------------------------------------------------------------
469
470     // The format string is intentionally unicode to avoid globalization bugs
471 #ifdef FEATURE_PREJIT
472     void ExternalLog(DWORD facility, DWORD level, const WCHAR *fmt, ...) DAC_EMPTY();
473     void ExternalLog(DWORD level, const WCHAR *fmt, ...) DAC_EMPTY();
474     void ExternalLog(DWORD level, const char *msg) DAC_EMPTY();
475     virtual void ExternalVLog(DWORD facility, DWORD level, const WCHAR *fmt, va_list args) DAC_EMPTY();
476     virtual void FlushExternalLog() DAC_EMPTY();
477 #endif
478
479 protected:
480     // ------------------------------------------------------------
481     // Internal constants
482     // ------------------------------------------------------------
483
484     enum
485     { 
486         PEFILE_SYSTEM                 = 0x01,
487         PEFILE_ASSEMBLY               = 0x02,
488         PEFILE_MODULE                 = 0x04,
489         PEFILE_SKIP_VERIFICATION      = 0x08,
490         PEFILE_SKIP_MODULE_HASH_CHECKS= 0x10,
491         PEFILE_ISTREAM                = 0x100,
492 #ifdef FEATURE_PREJIT        
493         PEFILE_HAS_NATIVE_IMAGE_METADATA = 0x200,
494         PEFILE_NATIVE_IMAGE_USED_EXCLUSIVELY =0x1000,
495         PEFILE_SAFE_TO_HARDBINDTO     = 0x4000, // NGEN-only flag
496 #endif        
497         PEFILE_INTROSPECTIONONLY      = 0x400,
498         PEFILE_SXS_LOAD_VERIFIED      = 0x2000
499     };
500
501     // ------------------------------------------------------------
502     // Internal routines
503     // ------------------------------------------------------------
504
505 #ifndef DACCESS_COMPILE
506     PEFile(PEImage *image, BOOL fCheckAuthenticodeSignature = TRUE);
507     virtual ~PEFile();
508
509     virtual void ReleaseIL();
510 #endif
511
512     void OpenMDImport();
513     void RestoreMDImport(IMDInternalImport* pImport);
514     void OpenMDImport_Unsafe();
515     void OpenImporter();
516     void OpenAssemblyImporter();
517     void OpenEmitter();
518     void OpenAssemblyEmitter();
519
520     void ConvertMDInternalToReadWrite();
521     void ReleaseMetadataInterfaces(BOOL bDestructor, BOOL bKeepNativeData=FALSE);
522
523 #ifdef FEATURE_CAS_POLICY
524     // Check the Authenticode signature of a PE file
525     void CheckAuthenticodeSignature();
526 #endif // FEATURE_CAS_POLICY
527
528     friend class Module;
529 #ifdef FEATURE_PREJIT
530     void SetNativeImage(PEImage *nativeImage);
531 #ifndef DACCESS_COMPILE
532     virtual void ClearNativeImage();
533 #endif
534 #endif
535
536 #ifndef DACCESS_COMPILE
537     void EnsureImageOpened();
538 #endif // DACCESS_COMPILE
539
540     friend class ClrDataAccess;
541     BOOL HasNativeImageMetadata();
542
543     // ------------------------------------------------------------
544     // Instance fields
545     // ------------------------------------------------------------
546     
547 #ifdef _DEBUG
548     LPCWSTR                 m_pDebugName;
549     SString                 m_debugName;
550 #endif
551     
552     // Identity image
553     PTR_PEImage              m_identity;
554     // IL image, NULL if we didn't need to open the file
555     PTR_PEImage              m_openedILimage;
556 #ifdef FEATURE_PREJIT
557     // Native image
558     PTR_PEImage              m_nativeImage;
559
560     BOOL                     m_fCanUseNativeImage;
561 #endif
562     // This flag is not updated atomically with m_pMDImport. Its fine for debugger usage
563     // but don't rely on it in the runtime. In runtime try QI'ing the m_pMDImport for 
564     // IID_IMDInternalImportENC
565     BOOL                     m_MDImportIsRW_Debugger_Use_Only;
566     Volatile<BOOL>           m_bHasPersistentMDImport;
567     
568 #ifndef DACCESS_COMPILE
569     IMDInternalImport       *m_pMDImport;
570 #else
571     IMDInternalImport       *m_pMDImport_UseAccessor;
572 #endif
573     IMetaDataImport2        *m_pImporter;
574     IMetaDataEmit           *m_pEmitter;
575 #ifndef FEATURE_CORECLR
576     IMetaDataAssemblyImport *m_pAssemblyImporter;
577     IMetaDataAssemblyEmit   *m_pAssemblyEmitter;
578 #endif
579     SimpleRWLock            *m_pMetadataLock;
580     Volatile<LONG>           m_refCount;
581     SBuffer                 *m_hash;                   // cached SHA1 hash value
582     int                     m_flags;
583     BOOL                    m_fStrongNameVerified;
584 #ifdef FEATURE_CAS_POLICY
585     COR_TRUST               *m_certificate;
586     BOOL                    m_fCheckedCertificate;
587     IInternetSecurityManager    *m_pSecurityManager;
588     Crst                         m_securityManagerLock;
589 #endif // FEATURE_CAS_POLICY
590
591 #ifdef DEBUGGING_SUPPORTED
592 #ifdef FEATURE_PREJIT
593     SVAL_DECL(DWORD, s_NGENDebugFlags);
594 #endif
595 #endif
596 public:
597
598     PTR_PEImage GetILimage()
599     {
600         CONTRACTL
601         {
602             THROWS;
603             MODE_ANY;
604             GC_TRIGGERS;
605         }
606         CONTRACTL_END;
607 #ifndef DACCESS_COMPILE
608         if (m_openedILimage == NULL && m_identity != NULL)
609         {
610             PEImage* pOpenedILimage;
611             m_identity->Clone(MDInternalImport_Default,&pOpenedILimage);
612             if (InterlockedCompareExchangeT(&m_openedILimage,pOpenedILimage,NULL) != NULL)
613                 pOpenedILimage->Release();
614         }
615 #endif
616         return m_openedILimage;
617     }
618
619     PEImage *GetOpenedILimage()
620     {
621         LIMITED_METHOD_DAC_CONTRACT;
622         _ASSERTE(HasOpenedILimage());
623         return m_openedILimage;
624     }
625
626
627     BOOL HasOpenedILimage()
628     {
629         LIMITED_METHOD_DAC_CONTRACT;
630         return m_openedILimage != NULL;
631
632     }
633
634     BOOL HasLoadedIL()
635     {
636         LIMITED_METHOD_DAC_CONTRACT;
637         return HasOpenedILimage() &&  GetOpenedILimage()->HasLoadedLayout();
638     }
639
640     BOOL IsDesignerBindingContext()
641     {
642         LIMITED_METHOD_CONTRACT;
643
644 #ifdef FEATURE_HOSTED_BINDER
645         DWORD binderFlags = BINDER_NONE;
646
647         HRESULT hr = E_FAIL;
648         if (HasHostAssembly())
649             hr = GetHostAssembly()->GetBinderFlags(&binderFlags);
650
651         return hr == S_OK ? binderFlags & BINDER_DESIGNER_BINDING_CONTEXT : FALSE;
652 #else
653         return FALSE;
654 #endif
655     }
656
657     LPCWSTR GetPathForErrorMessages();
658
659     static PEFile* Dummy();
660     void MarkNativeImageInvalidIfOwned();
661     void ConvertMetadataToRWForEnC();
662
663 #if defined(FEATURE_VERSIONING) || defined(FEATURE_HOSTED_BINDER)
664 protected:
665     PTR_ICLRPrivAssembly m_pHostAssembly;
666 #endif
667
668 #ifdef FEATURE_HOSTED_BINDER
669 protected:
670
671     friend class CLRPrivBinderFusion;
672 #ifndef DACCESS_COMPILE
673     // CLRPrivBinderFusion calls this for Fusion-bound assemblies in AppX processes.
674     void SetHostAssembly(ICLRPrivAssembly * pHostAssembly)
675     { LIMITED_METHOD_CONTRACT; m_pHostAssembly = clr::SafeAddRef(pHostAssembly); }
676 #endif //DACCESS_COMPILE
677
678 public:
679     // Returns a non-AddRef'ed ICLRPrivAssembly*
680     PTR_ICLRPrivAssembly GetHostAssembly()
681     { 
682         STATIC_CONTRACT_LIMITED_METHOD; 
683         return m_pHostAssembly; 
684     }
685
686     // Returns the ICLRPrivBinder* instance associated with the PEFile
687     PTR_ICLRPrivBinder GetBindingContext();
688     
689     bool HasHostAssembly()
690     { STATIC_CONTRACT_WRAPPER; return GetHostAssembly() != nullptr; }
691
692     bool CanUseWithBindingCache()
693     { LIMITED_METHOD_CONTRACT; return !HasHostAssembly(); }
694 #endif // FEATURE_HOSTED_BINDER
695 };  // class PEFile
696
697
698 class PEAssembly : public PEFile
699
700     VPTR_VTABLE_CLASS(PEAssembly, PEFile)
701
702   public:
703     // ------------------------------------------------------------
704     // Statics initialization.
705     // ------------------------------------------------------------
706     static
707     void Attach();
708
709     // ------------------------------------------------------------
710     // Public API
711     // ------------------------------------------------------------
712
713 #if defined(FEATURE_HOSTED_BINDER)
714 #if !defined(FEATURE_CORECLR)
715     static PEAssembly * Open(
716         PEAssembly *       pParentAssembly,
717         PEImage *          pPEImageIL, 
718         PEImage *          pPEImageNI, 
719         ICLRPrivAssembly * pHostAssembly, 
720         BOOL               fIsIntrospectionOnly);
721     
722     static PEAssembly * Open(
723         PEAssembly * pParentAssembly, 
724         PEImage *    pPEImageIL, 
725         BOOL         isIntrospectionOnly = FALSE);
726 #else //!FEATURE_CORECLR
727     // CoreCLR's PrivBinder PEAssembly creation entrypoint
728     static PEAssembly * Open(
729         PEAssembly *       pParent,
730         PEImage *          pPEImageIL, 
731         PEImage *          pPEImageNI, 
732         ICLRPrivAssembly * pHostAssembly, 
733         BOOL               fIsIntrospectionOnly = FALSE);
734 #endif //!FEATURE_CORECLR
735 #endif //FEATURE_HOSTED_BINDER
736
737     // This opens the canonical mscorlib.dll
738 #ifdef FEATURE_FUSION
739     static PEAssembly *OpenSystem(IApplicationContext *pAppCtx);
740 #else
741     static PEAssembly *OpenSystem(IUnknown *pAppCtx);
742 #endif
743 #ifdef DACCESS_COMPILE
744     virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
745 #endif
746
747 #ifdef FEATURE_FUSION
748     static PEAssembly *Open(
749         IAssembly *pIAssembly,
750         IBindResult *pNativeFusionAssembly,
751         IFusionBindLog *pFusionLog = NULL,
752         BOOL isSystemAssembly = FALSE,
753         BOOL isIntrospectionOnly = FALSE);
754
755     static PEAssembly *Open(
756         IHostAssembly *pIHostAssembly,
757         BOOL isSystemAssembly = FALSE,
758         BOOL isIntrospectionOnly = FALSE);
759
760 #ifdef FEATURE_MIXEDMODE
761     // Use for main exe loading
762     // NOTE: This may also be used for "spontaneous" (IJW) dll loading where
763     //      we need to deliver DllMain callbacks, but we should eliminate this case
764
765     static PEAssembly *OpenHMODULE(
766         HMODULE hMod,
767         IAssembly *pFusionAssembly,
768         IBindResult *pNativeFusionAssembly,
769         IFusionBindLog *pFusionLog = NULL,
770         BOOL isIntrospectionOnly = FALSE);
771 #endif // FEATURE_MIXEDMODE
772
773     static PEAssembly *DoOpen(
774         IAssembly *pIAssembly,
775         IBindResult *pNativeFusionAssembly,
776         IFusionBindLog *pFusionLog,
777         BOOL isSystemAssembly,
778         BOOL isIntrospectionOnly = FALSE);
779
780     static PEAssembly *DoOpen(
781         IHostAssembly *pIHostAssembly,
782         BOOL isSystemAssembly,
783         BOOL isIntrospectionOnly = FALSE);
784 #ifdef FEATURE_MIXEDMODE
785     static PEAssembly *DoOpenHMODULE(
786         HMODULE hMod,
787         IAssembly *pFusionAssembly,
788         IBindResult *pNativeFusionAssembly,
789         IFusionBindLog *pFusionLog,
790         BOOL isIntrospectionOnly = FALSE);
791 #endif // FEATURE_MIXEDMODE
792 #else
793     static PEAssembly *Open(
794         CoreBindResult* pBindResult,
795         BOOL isSystem,
796         BOOL isIntrospectionOnly);
797 #endif // FEATURE_FUSION
798
799     static PEAssembly *Create(
800         PEAssembly *pParentAssembly,
801         IMetaDataAssemblyEmit *pEmit,
802         BOOL isIntrospectionOnly);
803
804     static PEAssembly *OpenMemory(
805         PEAssembly *pParentAssembly,
806         const void *flat,
807         COUNT_T size, 
808         BOOL isIntrospectionOnly = FALSE,
809         CLRPrivBinderLoadFile* pBinderToUse = NULL);
810
811     static PEAssembly *DoOpenMemory(
812         PEAssembly *pParentAssembly,
813         const void *flat,
814         COUNT_T size,
815         BOOL isIntrospectionOnly,
816         CLRPrivBinderLoadFile* pBinderToUse);
817
818   private:
819     // Private helpers for crufty exception handling reasons
820 #ifdef FEATURE_FUSION
821     static PEAssembly *DoOpenSystem(IApplicationContext *pAppCtx);
822 #else
823     static PEAssembly *DoOpenSystem(IUnknown *pAppCtx);
824 #endif
825
826   public:
827
828     // ------------------------------------------------------------
829     // binding & source
830     // ------------------------------------------------------------
831
832     BOOL IsSourceGAC();
833 #ifdef FEATURE_CORECLR
834     BOOL IsProfileAssembly();
835     BOOL IsSilverlightPlatformStrongNameSignature();
836     BOOL IsProfileTestAssembly();
837     BOOL IsTestKeySignature();
838 #endif // FEATURE_CORECLR
839
840     ULONG HashIdentity();
841 #ifdef FEATURE_FUSION
842
843     BOOL FusionLoggingEnabled() 
844     {
845         LIMITED_METHOD_CONTRACT;
846         return m_bFusionLogEnabled && (m_pFusionLog != NULL);
847     };
848     void DisableFusionLogging()
849     {
850         m_bFusionLogEnabled = FALSE;
851     };
852
853     IFusionBindLog *GetFusionBindLog()
854     {
855         LIMITED_METHOD_CONTRACT;
856 #ifdef FEATURE_FUSION
857         return (m_bFusionLogEnabled && (m_pFusionLog != NULL)) ? m_pFusionLog : NULL;
858 #else
859         return NULL;
860 #endif 
861     }
862
863
864     BOOL IsBindingCodeBase();
865
866     BOOL IsSourceDownloadCache();
867
868     LOADCTX_TYPE GetLoadContext();
869     BOOL IsContextLoad();
870
871     // Can we avoid exposing these?
872     IAssembly *GetFusionAssembly(); 
873     IHostAssembly *GetIHostAssembly(); 
874     IAssemblyName *GetFusionAssemblyName();
875     IAssemblyName *GetFusionAssemblyNameNoCreate();
876     IAssemblyLocation* GetNativeAssemblyLocation();
877     DWORD GetLocationFlags();
878     PEKIND GetFusionProcessorArchitecture();
879 #endif
880
881 #ifndef  DACCESS_COMPILE
882     virtual void ReleaseIL();
883 #endif
884
885     // ------------------------------------------------------------
886     // Hash support
887     // ------------------------------------------------------------
888
889     BOOL NeedsModuleHashChecks();
890
891     BOOL HasStrongNameSignature();
892     BOOL IsFullySigned();
893
894     void SetStrongNameBypassed();
895     void VerifyStrongName();
896
897     // ------------------------------------------------------------
898     // Descriptive strings
899     // ------------------------------------------------------------
900
901     // This returns a non-empty path representing the source of the assembly; it may 
902     // be the parent assembly for dynamic or memory assemblies
903     const SString &GetEffectivePath();
904
905     // Codebase is the fusion codebase or path for the assembly.  It is in URL format.
906     // Note this may be obtained from the parent PEFile if we don't have a path or fusion
907     // assembly.
908     //
909     // fCopiedName means to get the "shadow copied" path rather than the original path, if applicable
910     void GetCodeBase(SString &result, BOOL fCopiedName = FALSE);
911     // Get the fully qualified assembly name from its metadata token 
912     static void GetFullyQualifiedAssemblyName(IMDInternalImport* pImport, mdAssembly mda, SString &result, DWORD flags = 0); 
913     
914     // Display name is the fusion binding name for an assembly
915     void GetDisplayName(SString &result, DWORD flags = 0);
916
917     // ------------------------------------------------------------
918     // Metadata access
919     // ------------------------------------------------------------
920
921     LPCUTF8 GetSimpleName();
922
923     // ------------------------------------------------------------
924     // Utility functions
925     // ------------------------------------------------------------
926
927     static void PathToUrl(SString &string);
928     static void UrlToPath(SString &string);
929     static BOOL FindLastPathSeparator(const SString &path, SString::Iterator &i);
930
931     // ------------------------------------------------------------
932     // Logging
933     // ------------------------------------------------------------
934 #ifdef FEATURE_PREJIT
935     void ExternalVLog(DWORD facility, DWORD level, const WCHAR *fmt, va_list args) DAC_EMPTY();
936     void FlushExternalLog() DAC_EMPTY();
937 #ifdef FEATURE_FUSION
938     void ETWTraceLogMessage(DWORD dwETWLogCategory, PEAssembly *pAsm)
939     {
940         LIMITED_METHOD_CONTRACT
941         if (FusionLoggingEnabled() && 
942             (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEFUSION_KEYWORD)))
943         { 
944             m_pFusionLog->ETWTraceLogMessage(dwETWLogCategory, (pAsm?pAsm->m_pFusionAssemblyName:NULL));
945         }
946     }
947     ULONGLONG GetBindingID()
948     {
949         LIMITED_METHOD_CONTRACT;
950         ULONGLONG ullBindingID = 0;
951         if (FusionLoggingEnabled())
952             m_pFusionLog->GetBindingID(&ullBindingID);
953         return ullBindingID;
954     }
955 #endif
956 #endif
957
958 #ifndef FEATURE_CORECLR
959     BOOL IsReportedToUsageLog();
960     void SetReportedToUsageLog();
961 #endif // !FEATURE_CORECLR
962
963   protected:
964
965 #ifndef DACCESS_COMPILE
966 #ifdef FEATURE_FUSION
967     PEAssembly(
968         PEImage *image,
969         IMetaDataEmit *pEmit,
970         IAssembly *pIAssembly,
971         IBindResult *pNativeFusionAssembly,
972         PEImage *pNIImage,
973         IFusionBindLog *pFusionLog,
974         IHostAssembly *pIHostAssembly,
975         PEFile *creator,
976         BOOL system,
977         BOOL introspectionOnly = FALSE,
978         ICLRPrivAssembly * pHostAssembly = NULL);
979 #else
980     PEAssembly(
981         CoreBindResult* pBindResultInfo, 
982         IMetaDataEmit *pEmit,
983         PEFile *creator, 
984         BOOL system, 
985         BOOL introspectionOnly = FALSE
986 #ifdef FEATURE_HOSTED_BINDER
987         ,
988         PEImage * pPEImageIL = NULL,
989         PEImage * pPEImageNI = NULL,
990         ICLRPrivAssembly * pHostAssembly = NULL
991 #endif
992         );
993 #endif
994     virtual ~PEAssembly();
995 #endif
996
997     // ------------------------------------------------------------
998     // Loader access API
999     // ------------------------------------------------------------
1000
1001     friend class DomainAssembly;
1002 #ifdef FEATURE_PREJIT
1003
1004 #ifdef FEATURE_FUSION
1005     void SetNativeImage(IBindResult *pNativeFusionAssembly);
1006 #else
1007     void SetNativeImage(PEImage *image);
1008 #endif
1009
1010     BOOL CheckNativeImageVersion(PEImage *image);
1011
1012
1013 #ifdef FEATURE_FUSION
1014     void ClearNativeImage();    
1015     void SetNativeImageClosure(IAssemblyBindingClosure *pClosure)
1016     {
1017         LIMITED_METHOD_CONTRACT;
1018         if (m_pNativeImageClosure!=NULL)
1019             m_pNativeImageClosure->Release();
1020         if (pClosure)
1021             pClosure->AddRef();
1022         m_pNativeImageClosure=pClosure;
1023     };
1024     BOOL HasEqualNativeClosure(DomainAssembly* pDomainAssembly);
1025 #endif //FEATURE_FUSION
1026
1027 #endif  // FEATURE_PREJIT
1028
1029   private:
1030     // Check both the StrongName and Authenticode signature of an assembly. If the application is using
1031     // strong name bypass, then this call may not result in a strong name verificaiton. VerifyStrongName
1032     // should be called if a strong name must be forced to verify.
1033     void DoLoadSignatureChecks();
1034
1035
1036   private:
1037     // ------------------------------------------------------------
1038     // Instance fields
1039     // ------------------------------------------------------------
1040
1041     PTR_PEFile               m_creator;
1042 #ifdef FEATURE_FUSION
1043     IAssemblyName           *m_pFusionAssemblyName;
1044     IAssembly               *m_pFusionAssembly;
1045     IFusionBindLog          *m_pFusionLog;
1046     BOOL                     m_bFusionLogEnabled;
1047     IHostAssembly           *m_pIHostAssembly;
1048     IAssemblyLocation       *m_pNativeAssemblyLocation;
1049     IAssemblyBindingClosure *m_pNativeImageClosure; //present only for shared 
1050     LOADCTX_TYPE             m_loadContext;
1051     DWORD                    m_dwLocationFlags;
1052 #else
1053     BOOL m_bIsFromGAC;
1054     BOOL m_bIsOnTpaList;
1055     // Using a separate entry and not m_pHostAssembly because otherwise
1056     // HasHostAssembly becomes true that trips various other code paths resulting in bad
1057     // things
1058     SString                  m_sTextualIdentity;
1059 #endif
1060 #ifdef FEATURE_CORECLR
1061     int                      m_fProfileAssembly; // Tri-state cache
1062 #else
1063     BOOL                     m_fStrongNameBypassed;
1064 #endif
1065
1066   public:
1067     PTR_PEFile GetCreator()
1068     { LIMITED_METHOD_CONTRACT; return m_creator; }
1069
1070     // Returns TRUE if the assembly is .winmd file (WinRT assembly)
1071     bool IsWindowsRuntime();
1072     
1073     // Used to determine if this assembly has an identity that may be used for
1074     // binding purposes. Currently this is true for standard .NET assemblies
1075     // and false for WinRT assemblies (where assemblies are identified by their
1076     // member types).
1077     bool HasBindableIdentity();
1078
1079     // Indicates if the assembly can be cached in a binding cache such as AssemblySpecBindingCache.
1080     inline bool CanUseWithBindingCache()
1081     {
1082 #if defined(FEATURE_HOSTED_BINDER)
1083             STATIC_CONTRACT_WRAPPER;
1084 #if !defined(FEATURE_APPX_BINDER)
1085             return (HasBindableIdentity());
1086 #else
1087             return (PEFile::CanUseWithBindingCache() && HasBindableIdentity());
1088 #endif // FEATURE_CORECLR
1089 #else
1090             STATIC_CONTRACT_LIMITED_METHOD;
1091             return true;
1092 #endif // FEATURE_HOSTED_BINDER
1093     }
1094 };
1095
1096 #ifdef FEATURE_MULTIMODULE_ASSEMBLIES
1097
1098 class PEModule : public PEFile
1099 {
1100     VPTR_VTABLE_CLASS(PEModule, PEFile)
1101     
1102   public:
1103
1104     // ------------------------------------------------------------
1105     // Public API
1106     // ------------------------------------------------------------
1107
1108     static PEModule *Open(PEAssembly *assembly, mdFile token,
1109                           const SString &fileName);
1110
1111     static PEModule *OpenMemory(PEAssembly *assembly, mdFile kToken,
1112                                 const void *flat, COUNT_T size); 
1113
1114     static PEModule *Create(PEAssembly *assembly, mdFile kToken, IMetaDataEmit *pEmit);
1115
1116 #ifdef DACCESS_COMPILE
1117     virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
1118 #endif
1119
1120   private:
1121     // Private helpers for crufty exception handling reasons
1122     static PEModule *DoOpen(PEAssembly *assembly, mdFile token,
1123                             const SString &fileName);
1124
1125     static PEModule *DoOpenMemory(PEAssembly *assembly, mdFile kToken,
1126                                   const void *flat, COUNT_T size); 
1127   public:
1128
1129     // ------------------------------------------------------------
1130     // Metadata access
1131     // ------------------------------------------------------------
1132
1133     PEAssembly *GetAssembly();
1134     mdFile GetToken();
1135     BOOL IsResource();
1136     BOOL IsIStream();
1137     LPCUTF8 GetSimpleName();
1138
1139     // ------------------------------------------------------------
1140     // Logging
1141     // ------------------------------------------------------------
1142 #ifdef FEATURE_PREJIT
1143     void ExternalVLog(DWORD facility, DWORD level, const WCHAR *fmt, va_list args) DAC_EMPTY();
1144     void FlushExternalLog() DAC_EMPTY();
1145 #endif
1146 private:
1147     // ------------------------------------------------------------
1148     // Loader access API
1149     // ------------------------------------------------------------
1150
1151     friend class DomainModule;
1152 #ifdef FEATURE_PREJIT
1153     void SetNativeImage(const SString &fullPath);
1154 #endif  // FEATURE_PREJIT
1155
1156 private:
1157
1158 #ifndef DACCESS_COMPILE
1159     PEModule(PEImage *image, PEAssembly *assembly, mdFile token, IMetaDataEmit *pEmit);
1160     virtual ~PEModule();
1161 #endif
1162
1163     // ------------------------------------------------------------
1164     // Instance fields
1165     // ------------------------------------------------------------
1166
1167     PTR_PEAssembly          m_assembly;
1168     mdFile                  m_token;
1169     BOOL                    m_bIsResource;
1170 };
1171 #endif // FEATURE_MULTIMODULE_ASSEMBLIES
1172
1173 typedef ReleaseHolder<PEFile> PEFileHolder;
1174
1175 typedef ReleaseHolder<PEAssembly> PEAssemblyHolder;
1176
1177 #ifdef FEATURE_MULTIMODULE_ASSEMBLIES
1178 typedef ReleaseHolder<PEModule> PEModuleHolder;
1179 #endif // FEATURE_MULTIMODULE_ASSEMBLIES
1180
1181
1182 // A small shim around PEAssemblies/IBindResult that allow us to write Fusion/CLR-agnostic
1183 // for logging native bind failures to the Fusion log/CLR log.
1184 //
1185 // These structures are stack-based, non-thread-safe and created for the duration of a single RuntimeVerify call.
1186 // The methods are expected to compute their data lazily as they are only used in bind failures or in checked builds.
1187 class LoggablePEAssembly : public LoggableAssembly
1188 {
1189   public:
1190     virtual SString DisplayString()
1191     {
1192         STANDARD_VM_CONTRACT;
1193
1194         return m_peAssembly->GetPath();
1195     }
1196
1197 #ifdef FEATURE_FUSION
1198     virtual IAssemblyName* FusionAssemblyName()
1199     {
1200         STANDARD_VM_CONTRACT;
1201
1202         return m_peAssembly->GetFusionAssemblyName();
1203     }
1204
1205     virtual IFusionBindLog* FusionBindLog()
1206     {
1207         STANDARD_VM_CONTRACT;
1208
1209         return m_peAssembly->GetFusionBindLog();
1210     }
1211 #endif // FEATURE_FUSION
1212
1213     LoggablePEAssembly(PEAssembly *peAssembly)
1214     {
1215         LIMITED_METHOD_CONTRACT;
1216
1217         m_peAssembly = peAssembly;
1218         peAssembly->AddRef();
1219     }
1220
1221     ~LoggablePEAssembly()
1222     {
1223         LIMITED_METHOD_CONTRACT;
1224
1225         m_peAssembly->Release();
1226     }
1227
1228   private:
1229     PEAssembly  *m_peAssembly;
1230 };
1231
1232
1233 // ================================================================================
1234 // Inline definitions
1235 // ================================================================================
1236
1237
1238 #endif  // PEFILE_H_