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// PEFile.h
6//
7
8// --------------------------------------------------------------------------------
9
10
11#ifndef PEFILE_H_
12#define PEFILE_H_
13
14// --------------------------------------------------------------------------------
15// Required headers
16// --------------------------------------------------------------------------------
17
18#include <windef.h>
19
20#include "sstring.h"
21#include "peimage.h"
22#include "metadata.h"
23#include "corhlpr.h"
24#include "utilcode.h"
25#include "loaderheap.h"
26#include "sstring.h"
27#include "ex.h"
28#include "assemblyspecbase.h"
29#include "eecontract.h"
30#include "metadatatracker.h"
31#include "stackwalktypes.h"
32#include <specstrings.h>
33#include "slist.h"
34#include "eventtrace.h"
35
36#include "clrprivbinderutil.h"
37
38// --------------------------------------------------------------------------------
39// Forward declared classes
40// --------------------------------------------------------------------------------
41
42class Module;
43class EditAndContinueModule;
44
45class PEFile;
46class PEModule;
47class PEAssembly;
48class SimpleRWLock;
49
50typedef VPTR(PEModule) PTR_PEModule;
51typedef VPTR(PEAssembly) PTR_PEAssembly;
52
53// --------------------------------------------------------------------------------
54// Types
55// --------------------------------------------------------------------------------
56
57// --------------------------------------------------------------------------------
58// A PEFile is an input to the CLR loader. It is produced as a result of
59// binding, usually through fusion (although there are a few less common methods to
60// obtain one which do not go through fusion, e.g. IJW loads)
61//
62// Although a PEFile is usually a disk based PE file (hence the name), it is not
63// always the case. Thus it is a conscious decision to not export access to the PE
64// file directly; rather the specific information required should be provided via
65// individual query API.
66//
67// There are multiple "flavors" of PEFiles:
68//
69// 1. HMODULE - these PE Files are loaded in response to "spontaneous" OS callbacks.
70// These should only occur for .exe main modules and IJW dlls loaded via LoadLibrary
71// or static imports in umnanaged code.
72//
73// 2. Fusion loads - these are the most common case. A path is obtained from fusion and
74// the result is loaded via PEImage.
75// a. Display name loads - these are metadata-based binds
76// b. Path loads - these are loaded from an explicit path
77//
78// 3. Byte arrays - loaded explicitly by user code. These also go through PEImage.
79//
80// 4. Dynamic - these are not actual PE images at all, but are placeholders
81// for reflection-based modules.
82//
83// PEFiles are segmented into two subtypes: PEAssembly and PEModule. The formere
84// is a file to be loaded as an assembly, and the latter is to be loaded as a module.
85//
86// See also file:..\inc\corhdr.h#ManagedHeader for more on the format of managed images.
87// See code:Module for more on modules
88// --------------------------------------------------------------------------------
89
90typedef VPTR(class PEFile) PTR_PEFile;
91
92typedef ReleaseHolder<IMDInternalImport> IMDInternalImportHolder;
93
94class PEFile
95{
96 // ------------------------------------------------------------
97 // SOS support
98 // ------------------------------------------------------------
99 VPTR_BASE_CONCRETE_VTABLE_CLASS(PEFile)
100
101public:
102
103 // ------------------------------------------------------------
104 // Public API
105 // ------------------------------------------------------------
106
107 STDMETHOD_(ULONG, AddRef)();
108 STDMETHOD_(ULONG, Release)();
109
110#ifdef DACCESS_COMPILE
111 virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
112#endif
113
114#if CHECK_INVARIANTS
115 CHECK Invariant();
116#endif
117
118private:
119 // ------------------------------------------------------------
120 // Loader access API
121 // ------------------------------------------------------------
122
123 friend class DomainFile;
124 friend class PEModule;
125#ifdef DACCESS_COMPILE
126 friend class NativeImageDumper;
127#endif
128
129public:
130 void LoadLibrary(BOOL allowNativeSkip = TRUE);
131
132
133private:
134 void CheckForDisallowedInProcSxSLoadWorker();
135 void ValidateImagePlatformNeutrality();
136
137 // For use inside LoadLibrary callback
138 friend HRESULT ExecuteDLLForAttach(HINSTANCE hInst,
139 DWORD dwReason,
140 LPVOID lpReserved,
141 BOOL fFromThunk);
142 void SetLoadedHMODULE(HMODULE hMod);
143
144 // DO NOT USE !!! this is to be removed when we move to new fusion binding API
145 friend class DomainAssembly;
146
147 // Helper for creating metadata for CreateDynamic
148 friend class Assembly;
149 friend class COMDynamicWrite;
150 friend class AssemblyNative;
151 static void DefineEmitScope(
152 GUID iid,
153 void **ppEmit);
154
155protected:
156 IMDInternalImportHolder GetMDImport();
157
158public:
159 // ------------------------------------------------------------
160 // Generic PEFile - can be used to access metadata
161 // ------------------------------------------------------------
162
163 static PEFile *Open(PEImage *image);
164
165 // ------------------------------------------------------------
166 // Identity
167 // ------------------------------------------------------------
168
169#ifndef DACCESS_COMPILE
170 BOOL Equals(PEFile *pFile);
171 BOOL Equals(PEImage *pImage);
172#endif // DACCESS_COMPILE
173
174
175 void GetMVID(GUID *pMvid);
176
177 // ------------------------------------------------------------
178 // Descriptive strings
179 // ------------------------------------------------------------
180
181 // Path is the file path to the file; empty if not a file
182 const SString &GetPath();
183
184#ifdef DACCESS_COMPILE
185 // This is the metadata module name. Used as a hint as file name.
186 const SString &GetModuleFileNameHint();
187#endif // DACCESS_COMPILE
188
189 // Full name is the most descriptive name available (path, codebase, or name as appropriate)
190 void GetCodeBaseOrName(SString &result);
191
192#ifdef LOGGING
193 // This is useful for log messages
194 LPCWSTR GetDebugName();
195#endif
196
197 // ------------------------------------------------------------
198 // Checks
199 // ------------------------------------------------------------
200
201 CHECK CheckLoaded(BOOL allowNativeSkip = TRUE);
202 void ValidateForExecution();
203 BOOL IsMarkedAsNoPlatform();
204 BOOL IsMarkedAsContentTypeWindowsRuntime();
205
206
207 // ------------------------------------------------------------
208 // Classification
209 // ------------------------------------------------------------
210
211 BOOL IsAssembly() const;
212 PTR_PEAssembly AsAssembly();
213 BOOL IsModule() const;
214 PTR_PEModule AsModule();
215 BOOL IsSystem() const;
216 BOOL IsDynamic() const;
217 BOOL IsResource() const;
218 BOOL IsIStream() const;
219 // Returns self (if assembly) or containing assembly (if module)
220 PEAssembly *GetAssembly() const;
221
222 // ------------------------------------------------------------
223 // Metadata access
224 // ------------------------------------------------------------
225
226 BOOL HasMetadata();
227
228 IMDInternalImport *GetPersistentMDImport();
229 IMDInternalImport *GetMDImportWithRef();
230 void MakeMDImportPersistent() {m_bHasPersistentMDImport=TRUE;};
231
232#ifndef DACCESS_COMPILE
233 IMetaDataEmit *GetEmitter();
234 IMetaDataAssemblyEmit *GetAssemblyEmitter();
235 IMetaDataImport2 *GetRWImporter();
236 IMetaDataAssemblyImport *GetAssemblyImporter();
237#else
238 TADDR GetMDInternalRWAddress();
239#endif // DACCESS_COMPILE
240
241 LPCUTF8 GetSimpleName();
242 HRESULT GetScopeName(LPCUTF8 * pszName);
243 BOOL IsStrongNameVerified();
244 BOOL IsStrongNamed();
245 const void *GetPublicKey(DWORD *pcbPK);
246 ULONG GetHashAlgId();
247 HRESULT GetVersion(USHORT *pMajor, USHORT *pMinor, USHORT *pBuild, USHORT *pRevision);
248 LPCSTR GetLocale();
249 DWORD GetFlags();
250 HRESULT GetFlagsNoTrigger(DWORD * pdwFlags);
251 // ------------------------------------------------------------
252 // PE file access
253 // ------------------------------------------------------------
254
255 BOOL IsIbcOptimized();
256 BOOL IsILImageReadyToRun();
257 WORD GetSubsystem();
258 mdToken GetEntryPointToken(
259#ifdef _DEBUG
260 BOOL bAssumeLoaded = FALSE
261#endif //_DEBUG
262 );
263 BOOL IsILOnly();
264 BOOL IsDll();
265
266 TADDR GetIL(RVA il);
267
268 PTR_VOID GetRvaField(RVA field);
269 CHECK CheckRvaField(RVA field);
270 CHECK CheckRvaField(RVA field, COUNT_T size);
271
272 BOOL HasTls();
273 BOOL IsRvaFieldTls(RVA field);
274 UINT32 GetFieldTlsOffset(RVA field);
275 UINT32 GetTlsIndex();
276
277 const void *GetInternalPInvokeTarget(RVA target);
278 CHECK CheckInternalPInvokeTarget(RVA target);
279
280 IMAGE_COR_VTABLEFIXUP *GetVTableFixups(COUNT_T *pCount = NULL);
281 void *GetVTable(RVA rva);
282
283 BOOL GetResource(LPCSTR szName, DWORD *cbResource,
284 PBYTE *pbInMemoryResource, DomainAssembly** pAssemblyRef,
285 LPCSTR *szFileName, DWORD *dwLocation,
286 BOOL fSkipRaiseResolveEvent, DomainAssembly* pDomainAssembly,
287 AppDomain* pAppDomain);
288#ifndef DACCESS_COMPILE
289 PTR_CVOID GetMetadata(COUNT_T *pSize);
290#endif
291 PTR_CVOID GetLoadedMetadata(COUNT_T *pSize);
292
293 void GetPEKindAndMachine(DWORD* pdwKind, DWORD* pdwMachine);
294
295 ULONG GetILImageTimeDateStamp();
296
297
298 // ------------------------------------------------------------
299 // Image memory access
300 //
301 // WARNING: do not abuse these. There are scenarios where the image
302 // is not in memory as an optimization.
303 //
304 // In general, you should add an entry point to get the specific info
305 // you are interested in, rather than using these general purpose
306 // entry points. The info can then be extracted from the native image
307 // in the no-IL image case.
308 // ------------------------------------------------------------
309
310 // For IJW purposes only - this asserts that we have an IJW image.
311 HMODULE GetIJWBase();
312
313 // The debugger can tolerate a null value here for native only loading cases
314 PTR_VOID GetDebuggerContents(COUNT_T *pSize = NULL);
315
316#ifndef DACCESS_COMPILE
317 // Returns the IL image range; may force a LoadLibrary
318 const void *GetManagedFileContents(COUNT_T *pSize = NULL);
319#endif // DACCESS_COMPILE
320
321 PTR_CVOID GetLoadedImageContents(COUNT_T *pSize = NULL);
322
323 // ------------------------------------------------------------
324 // Native image access
325 // ------------------------------------------------------------
326
327 // Does the loader support using a native image for this file?
328 // Some implementation restrictions prevent native images from being used
329 // in some cases.
330#ifdef FEATURE_PREJIT
331 BOOL CanUseNativeImage() { LIMITED_METHOD_CONTRACT; return m_fCanUseNativeImage; }
332 void SetCannotUseNativeImage() { LIMITED_METHOD_CONTRACT; m_fCanUseNativeImage = FALSE; }
333
334 BOOL IsNativeLoaded();
335 PEImage *GetNativeImageWithRef();
336 PEImage *GetPersistentNativeImage();
337#endif
338 BOOL HasNativeOrReadyToRunImage();
339 BOOL HasNativeImage();
340 PTR_PEImageLayout GetLoaded();
341 PTR_PEImageLayout GetLoadedNative();
342 PTR_PEImageLayout GetLoadedIL();
343 PTR_PEImageLayout GetAnyILWithRef(); //AddRefs!
344 IStream * GetPdbStream();
345 void ClearPdbStream();
346 BOOL IsLoaded(BOOL bAllowNativeSkip=TRUE) ;
347 BOOL PassiveDomainOnly();
348 BOOL IsPtrInILImage(PTR_CVOID data);
349
350#ifdef DACCESS_COMPILE
351 PEImage *GetNativeImage()
352 {
353 LIMITED_METHOD_DAC_CONTRACT;
354#ifdef FEATURE_PREJIT
355 return m_nativeImage;
356#else
357 return NULL;
358#endif
359 }
360#endif
361
362#ifdef FEATURE_PREJIT
363 // ------------------------------------------------------------
364 // Native image config utilities
365 // ------------------------------------------------------------
366
367 static CorCompileConfigFlags GetNativeImageConfigFlags(BOOL fForceDebug = FALSE,
368 BOOL fForceProfiling = FALSE,
369 BOOL fForceInstrument = FALSE);
370
371 static CorCompileConfigFlags GetNativeImageConfigFlagsWithOverrides();
372
373#ifdef DEBUGGING_SUPPORTED
374 static void SetNGENDebugFlags(BOOL fAllowOpt);
375 static void GetNGENDebugFlags(BOOL *fAllowOpt);
376#endif
377
378 static BOOL ShouldTreatNIAsMSIL();
379
380#endif // FEATURE_PREJIT
381
382 // ------------------------------------------------------------
383 // Resource access
384 // ------------------------------------------------------------
385
386 void GetEmbeddedResource(DWORD dwOffset, DWORD *cbResource, PBYTE *pbInMemoryResource);
387
388 // ------------------------------------------------------------
389 // File loading
390 // ------------------------------------------------------------
391
392 PEAssembly * LoadAssembly(
393 mdAssemblyRef kAssemblyRef,
394 IMDInternalImport * pImport = NULL,
395 LPCUTF8 szWinRtTypeNamespace = NULL,
396 LPCUTF8 szWinRtTypeClassName = NULL);
397
398 // ------------------------------------------------------------
399 // Logging
400 // ------------------------------------------------------------
401
402 // The format string is intentionally unicode to avoid globalization bugs
403#ifdef FEATURE_PREJIT
404 void ExternalLog(DWORD facility, DWORD level, const WCHAR *fmt, ...) DAC_EMPTY();
405 void ExternalLog(DWORD level, const WCHAR *fmt, ...) DAC_EMPTY();
406 void ExternalLog(DWORD level, const char *msg) DAC_EMPTY();
407 virtual void ExternalVLog(DWORD facility, DWORD level, const WCHAR *fmt, va_list args) DAC_EMPTY();
408 virtual void FlushExternalLog() DAC_EMPTY();
409#endif
410
411protected:
412 // ------------------------------------------------------------
413 // Internal constants
414 // ------------------------------------------------------------
415
416 enum
417 {
418 PEFILE_SYSTEM = 0x01,
419 PEFILE_ASSEMBLY = 0x02,
420 PEFILE_MODULE = 0x04,
421
422#ifdef FEATURE_PREJIT
423 PEFILE_HAS_NATIVE_IMAGE_METADATA = 0x200,
424#endif
425 };
426
427 // ------------------------------------------------------------
428 // Internal routines
429 // ------------------------------------------------------------
430
431#ifndef DACCESS_COMPILE
432 PEFile(PEImage *image, BOOL fCheckAuthenticodeSignature = TRUE);
433 virtual ~PEFile();
434
435 virtual void ReleaseIL();
436#else
437 virtual ~PEFile() {}
438#endif
439
440 void OpenMDImport();
441 void RestoreMDImport(IMDInternalImport* pImport);
442 void OpenMDImport_Unsafe();
443 void OpenImporter();
444 void OpenAssemblyImporter();
445 void OpenEmitter();
446 void OpenAssemblyEmitter();
447
448 void ConvertMDInternalToReadWrite();
449 void ReleaseMetadataInterfaces(BOOL bDestructor, BOOL bKeepNativeData=FALSE);
450
451
452 friend class Module;
453#ifdef FEATURE_PREJIT
454 void SetNativeImage(PEImage *nativeImage);
455#ifndef DACCESS_COMPILE
456 virtual void ClearNativeImage();
457#endif
458#endif
459
460#ifndef DACCESS_COMPILE
461 void EnsureImageOpened();
462#endif // DACCESS_COMPILE
463
464 friend class ClrDataAccess;
465 BOOL HasNativeImageMetadata();
466
467 // ------------------------------------------------------------
468 // Instance fields
469 // ------------------------------------------------------------
470
471#ifdef _DEBUG
472 LPCWSTR m_pDebugName;
473 SString m_debugName;
474#endif
475
476 // Identity image
477 PTR_PEImage m_identity;
478 // IL image, NULL if we didn't need to open the file
479 PTR_PEImage m_openedILimage;
480#ifdef FEATURE_PREJIT
481 // Native image
482 PTR_PEImage m_nativeImage;
483
484 BOOL m_fCanUseNativeImage;
485#endif
486 // This flag is not updated atomically with m_pMDImport. Its fine for debugger usage
487 // but don't rely on it in the runtime. In runtime try QI'ing the m_pMDImport for
488 // IID_IMDInternalImportENC
489 BOOL m_MDImportIsRW_Debugger_Use_Only;
490 Volatile<BOOL> m_bHasPersistentMDImport;
491
492#ifndef DACCESS_COMPILE
493 IMDInternalImport *m_pMDImport;
494#else
495 IMDInternalImport *m_pMDImport_UseAccessor;
496#endif
497 IMetaDataImport2 *m_pImporter;
498 IMetaDataEmit *m_pEmitter;
499 SimpleRWLock *m_pMetadataLock;
500 Volatile<LONG> m_refCount;
501 int m_flags;
502
503#ifdef DEBUGGING_SUPPORTED
504#ifdef FEATURE_PREJIT
505 SVAL_DECL(DWORD, s_NGENDebugFlags);
506#endif
507#endif
508public:
509
510 PTR_PEImage GetILimage()
511 {
512 CONTRACTL
513 {
514 THROWS;
515 MODE_ANY;
516 GC_TRIGGERS;
517 }
518 CONTRACTL_END;
519#ifndef DACCESS_COMPILE
520 if (m_openedILimage == NULL && m_identity != NULL)
521 {
522 PEImage* pOpenedILimage;
523 m_identity->Clone(MDInternalImport_Default,&pOpenedILimage);
524 if (InterlockedCompareExchangeT(&m_openedILimage,pOpenedILimage,NULL) != NULL)
525 pOpenedILimage->Release();
526 }
527#endif
528 return m_openedILimage;
529 }
530
531 PEImage *GetOpenedILimage()
532 {
533 LIMITED_METHOD_DAC_CONTRACT;
534 _ASSERTE(HasOpenedILimage());
535 return m_openedILimage;
536 }
537
538
539 BOOL HasOpenedILimage()
540 {
541 LIMITED_METHOD_DAC_CONTRACT;
542 return m_openedILimage != NULL;
543
544 }
545
546 BOOL HasLoadedIL()
547 {
548 LIMITED_METHOD_DAC_CONTRACT;
549 return HasOpenedILimage() && GetOpenedILimage()->HasLoadedLayout();
550 }
551
552 LPCWSTR GetPathForErrorMessages();
553
554 static PEFile* Dummy();
555 void MarkNativeImageInvalidIfOwned();
556 void ConvertMetadataToRWForEnC();
557
558protected:
559 PTR_ICLRPrivAssembly m_pHostAssembly;
560
561 // For certain assemblies, we do not have m_pHostAssembly since they are not bound using an actual binder.
562 // An example is Ref-Emitted assemblies. Thus, when such assemblies trigger load of their dependencies,
563 // we need to ensure they are loaded in appropriate load context.
564 //
565 // To enable this, we maintain a concept of "Fallback LoadContext", which will be set to the Binder of the
566 // assembly that created the dynamic assembly. If the creator assembly is dynamic itself, then its fallback
567 // load context would be propagated to the assembly being dynamically generated.
568 PTR_ICLRPrivBinder m_pFallbackLoadContextBinder;
569
570protected:
571
572#ifndef DACCESS_COMPILE
573 void SetHostAssembly(ICLRPrivAssembly * pHostAssembly)
574 { LIMITED_METHOD_CONTRACT; m_pHostAssembly = clr::SafeAddRef(pHostAssembly); }
575#endif //DACCESS_COMPILE
576
577public:
578 // Returns a non-AddRef'ed ICLRPrivAssembly*
579 PTR_ICLRPrivAssembly GetHostAssembly()
580 {
581 STATIC_CONTRACT_LIMITED_METHOD;
582 return m_pHostAssembly;
583 }
584
585 // Returns the ICLRPrivBinder* instance associated with the PEFile
586 PTR_ICLRPrivBinder GetBindingContext();
587
588 bool HasHostAssembly()
589 { STATIC_CONTRACT_WRAPPER; return GetHostAssembly() != nullptr; }
590
591 bool CanUseWithBindingCache()
592 { LIMITED_METHOD_CONTRACT; return !HasHostAssembly(); }
593
594 void SetFallbackLoadContextBinder(PTR_ICLRPrivBinder pFallbackLoadContextBinder)
595 {
596 LIMITED_METHOD_CONTRACT;
597 m_pFallbackLoadContextBinder = pFallbackLoadContextBinder;
598 }
599
600 PTR_ICLRPrivBinder GetFallbackLoadContextBinder()
601 {
602 LIMITED_METHOD_CONTRACT;
603
604 return m_pFallbackLoadContextBinder;
605 }
606}; // class PEFile
607
608
609class PEAssembly : public PEFile
610{
611 VPTR_VTABLE_CLASS(PEAssembly, PEFile)
612
613 public:
614 // ------------------------------------------------------------
615 // Statics initialization.
616 // ------------------------------------------------------------
617 static
618 void Attach();
619
620 // ------------------------------------------------------------
621 // Public API
622 // ------------------------------------------------------------
623
624 // CoreCLR's PrivBinder PEAssembly creation entrypoint
625 static PEAssembly * Open(
626 PEAssembly * pParent,
627 PEImage * pPEImageIL,
628 PEImage * pPEImageNI,
629 ICLRPrivAssembly * pHostAssembly);
630
631 // This opens the canonical mscorlib.dll
632 static PEAssembly *OpenSystem(IUnknown *pAppCtx);
633#ifdef DACCESS_COMPILE
634 virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
635#endif
636
637 static PEAssembly *Open(
638 CoreBindResult* pBindResult,
639 BOOL isSystem);
640
641 static PEAssembly *Create(
642 PEAssembly *pParentAssembly,
643 IMetaDataAssemblyEmit *pEmit);
644
645 static PEAssembly *OpenMemory(
646 PEAssembly *pParentAssembly,
647 const void *flat,
648 COUNT_T size);
649
650 static PEAssembly *DoOpenMemory(
651 PEAssembly *pParentAssembly,
652 const void *flat,
653 COUNT_T size);
654
655 private:
656 // Private helpers for crufty exception handling reasons
657 static PEAssembly *DoOpenSystem(IUnknown *pAppCtx);
658
659 public:
660
661 // ------------------------------------------------------------
662 // binding & source
663 // ------------------------------------------------------------
664
665 ULONG HashIdentity();
666
667#ifndef DACCESS_COMPILE
668 virtual void ReleaseIL();
669#endif
670
671 // ------------------------------------------------------------
672 // Hash support
673 // ------------------------------------------------------------
674
675 BOOL HasStrongNameSignature();
676
677 // ------------------------------------------------------------
678 // Descriptive strings
679 // ------------------------------------------------------------
680
681 // This returns a non-empty path representing the source of the assembly; it may
682 // be the parent assembly for dynamic or memory assemblies
683 const SString &GetEffectivePath();
684
685 // Codebase is the fusion codebase or path for the assembly. It is in URL format.
686 // Note this may be obtained from the parent PEFile if we don't have a path or fusion
687 // assembly.
688 //
689 // fCopiedName means to get the "shadow copied" path rather than the original path, if applicable
690 void GetCodeBase(SString &result, BOOL fCopiedName = FALSE);
691 // Get the fully qualified assembly name from its metadata token
692 static void GetFullyQualifiedAssemblyName(IMDInternalImport* pImport, mdAssembly mda, SString &result, DWORD flags = 0);
693
694 // Display name is the fusion binding name for an assembly
695 void GetDisplayName(SString &result, DWORD flags = 0);
696
697 // ------------------------------------------------------------
698 // Metadata access
699 // ------------------------------------------------------------
700
701 LPCUTF8 GetSimpleName();
702
703 // ------------------------------------------------------------
704 // Utility functions
705 // ------------------------------------------------------------
706
707 static void PathToUrl(SString &string);
708 static void UrlToPath(SString &string);
709 static BOOL FindLastPathSeparator(const SString &path, SString::Iterator &i);
710
711 // ------------------------------------------------------------
712 // Logging
713 // ------------------------------------------------------------
714#ifdef FEATURE_PREJIT
715 void ExternalVLog(DWORD facility, DWORD level, const WCHAR *fmt, va_list args) DAC_EMPTY();
716 void FlushExternalLog() DAC_EMPTY();
717#endif
718
719
720 protected:
721
722#ifndef DACCESS_COMPILE
723 PEAssembly(
724 CoreBindResult* pBindResultInfo,
725 IMetaDataEmit *pEmit,
726 PEFile *creator,
727 BOOL system,
728 PEImage * pPEImageIL = NULL,
729 PEImage * pPEImageNI = NULL,
730 ICLRPrivAssembly * pHostAssembly = NULL
731 );
732 virtual ~PEAssembly();
733#endif
734
735 // ------------------------------------------------------------
736 // Loader access API
737 // ------------------------------------------------------------
738
739 friend class DomainAssembly;
740#ifdef FEATURE_PREJIT
741
742 void SetNativeImage(PEImage *image);
743
744 BOOL CheckNativeImageVersion(PEImage *image);
745
746#endif // FEATURE_PREJIT
747
748 private:
749 // ------------------------------------------------------------
750 // Instance fields
751 // ------------------------------------------------------------
752
753 PTR_PEFile m_creator;
754 // Using a separate entry and not m_pHostAssembly because otherwise
755 // HasHostAssembly becomes true that trips various other code paths resulting in bad
756 // things
757 SString m_sTextualIdentity;
758
759 public:
760 PTR_PEFile GetCreator()
761 { LIMITED_METHOD_CONTRACT; return m_creator; }
762
763 // Returns TRUE if the assembly is .winmd file (WinRT assembly)
764 bool IsWindowsRuntime();
765
766 // Used to determine if this assembly has an identity that may be used for
767 // binding purposes. Currently this is true for standard .NET assemblies
768 // and false for WinRT assemblies (where assemblies are identified by their
769 // member types).
770 bool HasBindableIdentity();
771
772 // Indicates if the assembly can be cached in a binding cache such as AssemblySpecBindingCache.
773 inline bool CanUseWithBindingCache()
774 {
775 STATIC_CONTRACT_WRAPPER;
776 return (HasBindableIdentity());
777 }
778};
779
780
781typedef ReleaseHolder<PEFile> PEFileHolder;
782
783typedef ReleaseHolder<PEAssembly> PEAssemblyHolder;
784
785BOOL RuntimeVerifyNativeImageDependency(const CORCOMPILE_DEPENDENCY *pExpected,
786 const CORCOMPILE_VERSION_INFO *pActual,
787 PEAssembly *pLogAsm);
788
789// ================================================================================
790// Inline definitions
791// ================================================================================
792
793
794#endif // PEFILE_H_
795