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 | |
42 | class Module; |
43 | class EditAndContinueModule; |
44 | |
45 | class PEFile; |
46 | class PEModule; |
47 | class PEAssembly; |
48 | class SimpleRWLock; |
49 | |
50 | typedef VPTR(PEModule) PTR_PEModule; |
51 | typedef 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 | |
90 | typedef VPTR(class PEFile) PTR_PEFile; |
91 | |
92 | typedef ReleaseHolder<IMDInternalImport> IMDInternalImportHolder; |
93 | |
94 | class PEFile |
95 | { |
96 | // ------------------------------------------------------------ |
97 | // SOS support |
98 | // ------------------------------------------------------------ |
99 | VPTR_BASE_CONCRETE_VTABLE_CLASS(PEFile) |
100 | |
101 | public: |
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 | |
118 | private: |
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 | |
129 | public: |
130 | void LoadLibrary(BOOL allowNativeSkip = TRUE); |
131 | |
132 | |
133 | private: |
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 | |
155 | protected: |
156 | IMDInternalImportHolder GetMDImport(); |
157 | |
158 | public: |
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 | |
411 | protected: |
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 |
508 | public: |
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 | |
558 | protected: |
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 | |
570 | protected: |
571 | |
572 | #ifndef DACCESS_COMPILE |
573 | void SetHostAssembly(ICLRPrivAssembly * pHostAssembly) |
574 | { LIMITED_METHOD_CONTRACT; m_pHostAssembly = clr::SafeAddRef(pHostAssembly); } |
575 | #endif //DACCESS_COMPILE |
576 | |
577 | public: |
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 | |
609 | class 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 | |
781 | typedef ReleaseHolder<PEFile> PEFileHolder; |
782 | |
783 | typedef ReleaseHolder<PEAssembly> PEAssemblyHolder; |
784 | |
785 | BOOL 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 | |