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// DomainFile.h
6//
7
8// --------------------------------------------------------------------------------
9
10
11#ifndef _DOMAINFILE_H_
12#define _DOMAINFILE_H_
13
14// --------------------------------------------------------------------------------
15// Required headers
16// --------------------------------------------------------------------------------
17
18// --------------------------------------------------------------------------------
19// Forward class declarations
20// --------------------------------------------------------------------------------
21class AppDomain;
22class DomainAssembly;
23class DomainModule;
24class Assembly;
25class Module;
26class DynamicMethodTable;
27
28enum FileLoadLevel
29{
30 // These states are tracked by FileLoadLock
31
32 // Note: This enum must match the static array fileLoadLevelName[]
33 // which contains the printable names of the enum values
34
35 // Note that semantics here are description is the LAST step done, not what is
36 // currently being done.
37
38 FILE_LOAD_CREATE,
39 FILE_LOAD_BEGIN,
40 FILE_LOAD_FIND_NATIVE_IMAGE,
41 FILE_LOAD_VERIFY_NATIVE_IMAGE_DEPENDENCIES,
42 FILE_LOAD_ALLOCATE,
43 FILE_LOAD_ADD_DEPENDENCIES,
44 FILE_LOAD_PRE_LOADLIBRARY,
45 FILE_LOAD_LOADLIBRARY,
46 FILE_LOAD_POST_LOADLIBRARY,
47 FILE_LOAD_EAGER_FIXUPS,
48 FILE_LOAD_VTABLE_FIXUPS,
49 FILE_LOAD_DELIVER_EVENTS,
50 FILE_LOADED, // Loaded by not yet active
51 FILE_LOAD_VERIFY_EXECUTION,
52 FILE_ACTIVE // Fully active (constructors run & security checked)
53};
54
55
56enum NotificationStatus
57{
58 NOT_NOTIFIED=0,
59 PROFILER_NOTIFIED=1,
60 DEBUGGER_NEEDNOTIFICATION=2,
61 DEBUGGER_NOTIFIED=4
62};
63
64// --------------------------------------------------------------------------------
65// DomainFile represents a file loaded (or being loaded) into an app domain. It
66// is guranteed to be unique per file per app domain.
67// --------------------------------------------------------------------------------
68
69class DomainFile
70{
71 VPTR_BASE_VTABLE_CLASS(DomainFile);
72
73 public:
74
75 // ------------------------------------------------------------
76 // Public API
77 // ------------------------------------------------------------
78
79#ifndef DACCESS_COMPILE
80 virtual ~DomainFile();
81 DomainFile() {LIMITED_METHOD_CONTRACT;};
82#endif
83
84 virtual LoaderAllocator *GetLoaderAllocator();
85
86 PTR_AppDomain GetAppDomain()
87 {
88 LIMITED_METHOD_CONTRACT;
89 SUPPORTS_DAC;
90 return m_pDomain;
91 }
92
93 PEFile *GetFile()
94 {
95 LIMITED_METHOD_DAC_CONTRACT;
96 return m_pFile;
97 }
98
99 PEFile *GetOriginalFile()
100 {
101 LIMITED_METHOD_DAC_CONTRACT;
102 return m_pOriginalFile!= NULL ? m_pOriginalFile : m_pFile;
103 }
104
105
106 IMDInternalImport *GetMDImport()
107 {
108 WRAPPER_NO_CONTRACT;
109 return m_pFile->GetPersistentMDImport();
110 }
111
112 OBJECTREF GetExposedModuleObjectIfExists()
113 {
114 LIMITED_METHOD_CONTRACT;
115
116 OBJECTREF objRet = NULL;
117 GET_LOADERHANDLE_VALUE_FAST(GetLoaderAllocator(), m_hExposedModuleObject, &objRet);
118 return objRet;
119 }
120
121 OBJECTREF GetExposedModuleObject();
122
123 BOOL IsSystem()
124 {
125 WRAPPER_NO_CONTRACT;
126 return GetFile()->IsSystem();
127 }
128
129 LPCUTF8 GetSimpleName()
130 {
131 WRAPPER_NO_CONTRACT;
132 return GetFile()->GetSimpleName();
133 }
134
135#ifdef LOGGING
136 LPCWSTR GetDebugName()
137 {
138 WRAPPER_NO_CONTRACT;
139 return GetFile()->GetDebugName();
140 }
141#endif
142
143
144 void ReleaseFiles() DAC_EMPTY();
145
146 virtual BOOL IsAssembly() = 0;
147
148 DomainAssembly *GetDomainAssembly();
149
150 // ------------------------------------------------------------
151 // Loading state checks
152 // ------------------------------------------------------------
153
154 // Return the File's load level. Note that this is the last level actually successfully completed.
155 // Note that this is subtly different than the FileLoadLock's level, which is the last level
156 // which was triggered (but potentially skipped if error or inappropriate.)
157 FileLoadLevel GetLoadLevel() { LIMITED_METHOD_DAC_CONTRACT; return m_level; }
158
159 // Error means that a permanent x-appdomain load error has occurred.
160 BOOL IsError()
161 {
162 LIMITED_METHOD_DAC_CONTRACT;
163 DACCOP_IGNORE(FieldAccess, "No marshalling required");
164 return m_pError != NULL;
165 }
166
167 // Loading means that the load is still being tracked by a FileLoadLock.
168 BOOL IsLoading() { LIMITED_METHOD_CONTRACT; return m_loading; }
169
170 // Loaded means that the file can be used passively. This includes loading types, reflection, and
171 // jitting.
172 BOOL IsLoaded() { LIMITED_METHOD_DAC_CONTRACT; return m_level >= FILE_LOAD_DELIVER_EVENTS; }
173
174 // Active means that the file can be used actively in the current app domain. Note that a shared file
175 // may conditionally not be able to be made active on a per app domain basis.
176 BOOL IsActive() { LIMITED_METHOD_CONTRACT; return m_level >= FILE_ACTIVE; }
177
178 // Checks if the load has reached the point where profilers may be notified
179 // about the file. It's important that IF a profiler is notified, THEN this returns
180 // TRUE, otherwise there can be profiler-attach races where the profiler doesn't see
181 // the file via either enumeration or notification. As a result, this begins
182 // returning TRUE just before the profiler is actually notified. See
183 // code:ProfilerFunctionEnum::Init#ProfilerEnumAssemblies
184 BOOL IsAvailableToProfilers()
185 {
186 LIMITED_METHOD_DAC_CONTRACT;
187 return IsProfilerNotified(); // despite the name, this function returns TRUE just before we notify the profiler
188 }
189
190 // CheckLoaded is appropriate for asserts that the assembly can be passively used.
191 CHECK CheckLoaded();
192
193 // CheckActivated is appropriate for asserts that the assembly can be actively used. Note that
194 // it is slightly different from IsActive in that it deals with reentrancy cases properly.
195 CHECK CheckActivated();
196
197 // Ensure that an assembly has reached at least the IsLoaded state. Throw if not.
198 void EnsureLoaded()
199 {
200 WRAPPER_NO_CONTRACT;
201 return EnsureLoadLevel(FILE_LOADED);
202 }
203
204 // Ensure that an assembly has reached at least the IsActive state. Throw if not.
205 void EnsureActive()
206 {
207 WRAPPER_NO_CONTRACT;
208 return EnsureLoadLevel(FILE_ACTIVE);
209 }
210
211 // Ensure that an assembly has reached at least the Allocated state. Throw if not.
212 void EnsureAllocated()
213 {
214 WRAPPER_NO_CONTRACT;
215 return EnsureLoadLevel(FILE_LOAD_ALLOCATE);
216 }
217
218
219 void EnsureLibraryLoaded()
220 {
221 WRAPPER_NO_CONTRACT;
222 return EnsureLoadLevel(FILE_LOAD_LOADLIBRARY);
223 }
224
225 // This wraps EnsureActive, suppressing non-transient exceptions
226 BOOL TryEnsureActive();
227
228 // EnsureLoadLevel is a generic routine used to ensure that the file is not in a delay loaded
229 // state (unless it needs to be.) This should be used when a particular level of loading
230 // is required for an operation. Note that deadlocks are tolerated so the level may be one
231 void EnsureLoadLevel(FileLoadLevel targetLevel) DAC_EMPTY();
232
233 // AttemptLoadLevel is a generic routine used to try to further load the file to a given level.
234 // No guarantee is made about the load level resulting however.
235 void AttemptLoadLevel(FileLoadLevel targetLevel) DAC_EMPTY();
236
237 // CheckLoadLevel is an assert predicate used to verify the load level of an assembly.
238 // deadlockOK indicates that the level is allowed to be one short if we are restricted
239 // by loader reentrancy.
240 CHECK CheckLoadLevel(FileLoadLevel requiredLevel, BOOL deadlockOK = TRUE) DAC_EMPTY_RET(CHECK::OK());
241
242 // RequireLoadLevel throws an exception if the domain file isn't loaded enough. Note
243 // that this is intolerant of deadlock related failures so is only really appropriate for
244 // checks inside the main loading loop.
245 void RequireLoadLevel(FileLoadLevel targetLevel) DAC_EMPTY();
246
247 // Throws if a load error has occurred
248 void ThrowIfError(FileLoadLevel targetLevel) DAC_EMPTY();
249
250 // Checks that a load error has not occurred before the given level
251 CHECK CheckNoError(FileLoadLevel targetLevel) DAC_EMPTY_RET(CHECK::OK());
252
253 // IsNotified means that the profiler API notification has been delivered
254 BOOL IsProfilerNotified() { LIMITED_METHOD_CONTRACT; return m_notifyflags & PROFILER_NOTIFIED; }
255 BOOL IsDebuggerNotified() { LIMITED_METHOD_CONTRACT; return m_notifyflags & DEBUGGER_NOTIFIED; }
256 BOOL ShouldNotifyDebugger() { LIMITED_METHOD_CONTRACT; return m_notifyflags & DEBUGGER_NEEDNOTIFICATION; }
257
258
259 // ------------------------------------------------------------
260 // Other public APIs
261 // ------------------------------------------------------------
262
263#ifndef DACCESS_COMPILE
264 BOOL Equals(DomainFile *pFile) { WRAPPER_NO_CONTRACT; return GetFile()->Equals(pFile->GetFile()); }
265 BOOL Equals(PEFile *pFile) { WRAPPER_NO_CONTRACT; return GetFile()->Equals(pFile); }
266#endif // DACCESS_COMPILE
267
268 Module* GetCurrentModule();
269 Module* GetLoadedModule();
270 Module* GetModule();
271
272#ifdef FEATURE_PREJIT
273 BOOL IsZapRequired(); // Are we absolutely required to use a native image?
274#endif
275 // The format string is intentionally unicode to avoid globalization bugs
276#ifdef FEATURE_PREJIT
277 void ExternalLog(DWORD level, const WCHAR *fmt, ...);
278 void ExternalLog(DWORD level, const char *msg);
279#endif
280#ifdef DACCESS_COMPILE
281 virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
282#endif
283
284#ifndef DACCESS_COMPILE
285 // light code gen. Keep the list of MethodTables needed for creating dynamic methods
286 DynamicMethodTable* GetDynamicMethodTable();
287#endif
288
289 protected:
290 // ------------------------------------------------------------
291 // Loader API
292 // ------------------------------------------------------------
293
294 friend class AppDomain;
295 friend class Assembly;
296 friend class Module;
297 friend class FileLoadLock;
298
299 DomainFile(AppDomain *pDomain, PEFile *pFile);
300
301 BOOL DoIncrementalLoad(FileLoadLevel targetLevel);
302 void ClearLoading() { LIMITED_METHOD_CONTRACT; m_loading = FALSE; }
303 void SetLoadLevel(FileLoadLevel level) { LIMITED_METHOD_CONTRACT; m_level = level; }
304
305#ifndef DACCESS_COMPILE
306 virtual void Begin() = 0;
307 virtual void Allocate() = 0;
308 void AddDependencies();
309 void PreLoadLibrary();
310 void LoadLibrary();
311 void PostLoadLibrary();
312 void EagerFixups();
313 void VtableFixups();
314 virtual void DeliverSyncEvents() = 0;
315 virtual void DeliverAsyncEvents() = 0;
316 void FinishLoad();
317 void VerifyExecution();
318 void Activate();
319#endif
320
321 // This should be used to permanently set the load to fail. Do not use with transient conditions
322 void SetError(Exception *ex);
323
324#ifdef FEATURE_PREJIT
325
326#ifndef DACCESS_COMPILE
327 virtual void FindNativeImage() = 0;
328#endif
329 void VerifyNativeImageDependencies(bool verifyOnly = FALSE);
330
331 // Are we absolutely required to use a native image?
332 void CheckZapRequired();
333
334 void ClearNativeImageStress();
335
336#endif // FEATURE_PREJIT
337
338 void SetProfilerNotified() { LIMITED_METHOD_CONTRACT; m_notifyflags|= PROFILER_NOTIFIED; }
339 void SetDebuggerNotified() { LIMITED_METHOD_CONTRACT; m_notifyflags|=DEBUGGER_NOTIFIED; }
340 void SetShouldNotifyDebugger() { LIMITED_METHOD_CONTRACT; m_notifyflags|=DEBUGGER_NEEDNOTIFICATION; }
341#ifndef DACCESS_COMPILE
342 void UpdatePEFileWorker(PTR_PEFile pFile);
343#endif
344
345 // ------------------------------------------------------------
346 // Instance data
347 // ------------------------------------------------------------
348
349 PTR_AppDomain m_pDomain;
350 PTR_PEFile m_pFile;
351 PTR_PEFile m_pOriginalFile; // keep file alive just in case someone is sitill using it. If this is not NULL then m_pFile contains reused file from the shared assembly
352 PTR_Module m_pModule;
353 FileLoadLevel m_level;
354 LOADERHANDLE m_hExposedModuleObject;
355
356 class ExInfo
357 {
358 enum
359 {
360 ExType_ClrEx,
361 ExType_HR
362 }
363 m_type;
364 union
365 {
366 Exception *m_pEx;
367 HRESULT m_hr;
368 };
369
370 public:
371 void Throw()
372 {
373 CONTRACTL
374 {
375 THROWS;
376 GC_TRIGGERS;
377 MODE_ANY;
378 }
379 CONTRACTL_END;
380 if (m_type==ExType_ClrEx)
381 {
382 PAL_CPP_THROW(Exception *, m_pEx->DomainBoundClone());
383 }
384 if (m_type==ExType_HR)
385 ThrowHR(m_hr);
386 _ASSERTE(!"Bad exception type");
387 ThrowHR(E_UNEXPECTED);
388 };
389 ExInfo(Exception* pEx)
390 {
391 LIMITED_METHOD_CONTRACT;
392 m_type=ExType_ClrEx;
393 m_pEx=pEx;
394 };
395
396 void ConvertToHResult()
397 {
398 LIMITED_METHOD_CONTRACT;
399 if(m_type==ExType_HR)
400 return;
401 _ASSERTE(m_type==ExType_ClrEx);
402 HRESULT hr=m_pEx->GetHR();
403 delete m_pEx;
404 m_hr=hr;
405 m_type=ExType_HR;
406 };
407 ~ExInfo()
408 {
409 LIMITED_METHOD_CONTRACT;
410 if (m_type==ExType_ClrEx)
411 delete m_pEx;
412 }
413 }* m_pError;
414
415 void ReleaseManagedData()
416 {
417 if (m_pError)
418 m_pError->ConvertToHResult();
419 };
420
421#ifdef FEATURE_PREJIT
422 // Lock-free enumeration of DomainFiles in an AppDomain.
423public:
424 DomainFile *FindNextDomainFileWithNativeImage();
425private:
426 void InsertIntoDomainFileWithNativeImageList();
427#endif // FEATURE_PREJIT
428
429 DWORD m_notifyflags;
430 BOOL m_loading;
431 // m_pDynamicMethodTable is used by the light code generation to allow method
432 // generation on the fly. They are lazily created when/if a dynamic method is requested
433 // for this specific module
434 DynamicMethodTable *m_pDynamicMethodTable;
435 class UMThunkHash *m_pUMThunkHash;
436 BOOL m_bDisableActivationCheck;
437
438 // This value is to make it easier to diagnose Assembly Loader "rejected native image" crashes.
439 // See Dev11 bug 358184 for more details
440public:
441 DWORD m_dwReasonForRejectingNativeImage; // See code:g_dwLoaderReasonForNotSharing in Assembly.cpp for a similar variable.
442private:
443
444#ifdef FEATURE_PREJIT
445 // This value is to allow lock-free enumeration of all native images in an AppDomain
446 Volatile<DomainFile *> m_pNextDomainFileWithNativeImage;
447#endif
448};
449
450// These will sometimes result in a crash with error code 0x80131506 COR_E_EXECUTIONENGINE
451// "An internal error happened in the Common Language Runtime's Execution Engine"
452// Cause: Incorrectly committed to using native image for <path to assembly>
453enum ReasonForRejectingNativeImage
454{
455 ReasonForRejectingNativeImage_NoNiForManifestModule = 0x101,
456 ReasonForRejectingNativeImage_DependencyNotNative = 0x102,
457 ReasonForRejectingNativeImage_MscorlibNotNative = 0x103,
458 ReasonForRejectingNativeImage_FailedSecurityCheck = 0x104,
459 ReasonForRejectingNativeImage_DependencyIdentityMismatch = 0x105,
460 ReasonForRejectingNativeImage_CannotShareNiAssemblyNotDomainNeutral = 0x106,
461 ReasonForRejectingNativeImage_NiAlreadyUsedInAnotherSharedAssembly = 0x107,
462};
463
464//---------------------------------------------------------------------------------------
465// One of these values is specified when requesting a module iterator to customize which
466// modules should appear in the enumeration
467enum ModuleIterationOption
468{
469 // include only modules that are already loaded (m_level >= FILE_LOAD_DELIVER_EVENTS)
470 kModIterIncludeLoaded = 1,
471
472 // include all modules, even those that are still in the process of loading (all m_level values)
473 kModIterIncludeLoading = 2,
474
475 // include only modules loaded just enough that profilers are notified of them.
476 // (m_level >= FILE_LOAD_LOADLIBRARY). See comment at code:DomainFile::IsAvailableToProfilers
477 kModIterIncludeAvailableToProfilers = 3,
478};
479
480// --------------------------------------------------------------------------------
481// DomainAssembly is a subclass of DomainFile which specifically represents a assembly.
482// --------------------------------------------------------------------------------
483
484class DomainAssembly : public DomainFile
485{
486 VPTR_VTABLE_CLASS(DomainAssembly, DomainFile);
487
488public:
489 // ------------------------------------------------------------
490 // Public API
491 // ------------------------------------------------------------
492
493 PEAssembly *GetFile()
494 {
495 LIMITED_METHOD_CONTRACT;
496 return PTR_PEAssembly(m_pFile);
497 }
498
499 LoaderAllocator *GetLoaderAllocator()
500 {
501 LIMITED_METHOD_CONTRACT;
502 return m_pLoaderAllocator;
503 }
504
505#ifndef DACCESS_COMPILE
506 void ReleaseFiles();
507#endif // DACCESS_COMPILE
508
509 // Finds only loaded hmods
510 DomainFile *FindIJWModule(HMODULE hMod);
511
512 void SetAssembly(Assembly* pAssembly);
513
514 BOOL IsAssembly()
515 {
516 LIMITED_METHOD_DAC_CONTRACT;
517 return TRUE;
518 }
519
520 OBJECTREF GetExposedAssemblyObjectIfExists()
521 {
522 LIMITED_METHOD_CONTRACT;
523
524 OBJECTREF objRet = NULL;
525 GET_LOADERHANDLE_VALUE_FAST(GetLoaderAllocator(), m_hExposedAssemblyObject, &objRet);
526 return objRet;
527 }
528
529 // Returns managed representation of the assembly (Assembly or AssemblyBuilder).
530 // Returns NULL if the managed scout was already collected (see code:LoaderAllocator#AssemblyPhases).
531 OBJECTREF GetExposedAssemblyObject();
532
533 Assembly* GetCurrentAssembly();
534 Assembly* GetLoadedAssembly();
535 Assembly* GetAssembly();
536
537#ifdef DACCESS_COMPILE
538 virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
539#endif
540
541 // ------------------------------------------------------------
542 // Modules
543 // ------------------------------------------------------------
544 class ModuleIterator
545 {
546 ArrayList::Iterator m_i;
547 ModuleIterationOption m_moduleIterationOption;
548
549 public:
550 BOOL Next()
551 {
552 WRAPPER_NO_CONTRACT;
553 while (m_i.Next())
554 {
555 if (m_i.GetElement() == NULL)
556 {
557 continue;
558 }
559 if (GetDomainFile()->IsError())
560 {
561 continue;
562 }
563 if (m_moduleIterationOption == kModIterIncludeLoading)
564 return TRUE;
565 if ((m_moduleIterationOption == kModIterIncludeLoaded) &&
566 GetDomainFile()->IsLoaded())
567 return TRUE;
568 if ((m_moduleIterationOption == kModIterIncludeAvailableToProfilers) &&
569 GetDomainFile()->IsAvailableToProfilers())
570 return TRUE;
571 }
572 return FALSE;
573 }
574 Module *GetModule()
575 {
576 WRAPPER_NO_CONTRACT;
577 return GetDomainFile()->GetModule();
578 }
579 Module *GetLoadedModule()
580 {
581 WRAPPER_NO_CONTRACT;
582 return GetDomainFile()->GetLoadedModule();
583 }
584 DomainFile *GetDomainFile()
585 {
586 WRAPPER_NO_CONTRACT;
587 return dac_cast<PTR_DomainFile>(m_i.GetElement());
588 }
589 SIZE_T GetIndex()
590 {
591 WRAPPER_NO_CONTRACT;
592 return m_i.GetIndex();
593 }
594
595 private:
596 friend class DomainAssembly;
597 // Cannot have constructor so this iterator can be used inside a union
598 static ModuleIterator Create(DomainAssembly * pDomainAssembly, ModuleIterationOption moduleIterationOption)
599 {
600 WRAPPER_NO_CONTRACT;
601 ModuleIterator i;
602
603 i.m_i = pDomainAssembly->m_Modules.Iterate();
604 i.m_moduleIterationOption = moduleIterationOption;
605
606 return i;
607 }
608 };
609 friend class ModuleIterator;
610
611 ModuleIterator IterateModules(ModuleIterationOption moduleIterationOption)
612 {
613 WRAPPER_NO_CONTRACT;
614 return ModuleIterator::Create(this, moduleIterationOption);
615 }
616
617 DomainFile *LookupDomainFile(DWORD index)
618 {
619 WRAPPER_NO_CONTRACT;
620 if (index >= m_Modules.GetCount())
621 return NULL;
622 else
623 return dac_cast<PTR_DomainFile>(m_Modules.Get(index));
624 }
625
626 Module *LookupModule(DWORD index)
627 {
628 WRAPPER_NO_CONTRACT;
629 DomainFile *pModule = LookupDomainFile(index);
630 if (pModule == NULL)
631 return NULL;
632 else
633 return pModule->GetModule();
634 }
635
636
637 // ------------------------------------------------------------
638 // Resource access
639 // ------------------------------------------------------------
640
641 BOOL GetResource(LPCSTR szName, DWORD *cbResource,
642 PBYTE *pbInMemoryResource, DomainAssembly** pAssemblyRef,
643 LPCSTR *szFileName, DWORD *dwLocation,
644 BOOL fSkipRaiseResolveEvent);
645
646#ifdef FEATURE_PREJIT
647 // ------------------------------------------------------------
648 // Prejitting API
649 // ------------------------------------------------------------
650
651 void GetCurrentVersionInfo(CORCOMPILE_VERSION_INFO *pZapVersionInfo);
652
653 void GetOptimizedIdentitySignature(CORCOMPILE_ASSEMBLY_SIGNATURE *pSignature);
654 BOOL CheckZapDependencyIdentities(PEImage *pNativeImage);
655
656#endif // FEATURE_PREJIT
657
658 // ------------------------------------------------------------
659 // Debugger control API
660 // ------------------------------------------------------------
661
662 DebuggerAssemblyControlFlags GetDebuggerInfoBits(void)
663 {
664 LIMITED_METHOD_CONTRACT;
665 return m_debuggerFlags;
666 }
667
668 void SetDebuggerInfoBits(DebuggerAssemblyControlFlags newBits)
669 {
670 LIMITED_METHOD_CONTRACT;
671 m_debuggerFlags = newBits;
672 }
673
674 void SetupDebuggingConfig(void);
675 DWORD ComputeDebuggingConfig(void);
676
677 bool GetDebuggingOverrides(DWORD *pdwFlags);
678
679 HRESULT GetDebuggingCustomAttributes(DWORD *pdwFlags);
680
681 BOOL IsVisibleToDebugger();
682 BOOL NotifyDebuggerLoad(int flags, BOOL attaching);
683 void NotifyDebuggerUnload();
684
685 inline BOOL IsCollectible();
686 //
687 // GC API
688 //
689 void EnumStaticGCRefs(promote_func* fn, ScanContext* sc);
690
691
692 private:
693
694 // ------------------------------------------------------------
695 // Loader API
696 // ------------------------------------------------------------
697
698 friend class AppDomain;
699 friend class Assembly;
700 friend class AssemblyNameNative;
701
702#ifndef DACCESS_COMPILE
703public:
704 ~DomainAssembly();
705private:
706 DomainAssembly(AppDomain *pDomain, PEFile *pFile, LoaderAllocator *pLoaderAllocator);
707#endif
708
709 // ------------------------------------------------------------
710 // Internal routines
711 // ------------------------------------------------------------
712
713 void SetSecurityError(Exception *ex);
714
715#ifndef DACCESS_COMPILE
716 void Begin();
717 void Allocate();
718 void LoadSharers();
719 void DeliverSyncEvents();
720 void DeliverAsyncEvents();
721#endif
722
723 void UpdatePEFile(PTR_PEFile pFile);
724
725#ifdef FEATURE_PREJIT
726#ifndef DACCESS_COMPILE
727 void FindNativeImage();
728#endif
729#endif // FEATURE_PREJIT
730
731 BOOL IsInstrumented();
732
733 public:
734 ULONG HashIdentity();
735
736 // ------------------------------------------------------------
737 // Instance data
738 // ------------------------------------------------------------
739
740 private:
741 LOADERHANDLE m_hExposedAssemblyObject;
742 PTR_Assembly m_pAssembly;
743 DebuggerAssemblyControlFlags m_debuggerFlags;
744 ArrayList m_Modules;
745 BOOL m_fDebuggerUnloadStarted;
746 BOOL m_fCollectible;
747 Volatile<bool> m_fHostAssemblyPublished;
748 PTR_LoaderAllocator m_pLoaderAllocator;
749 DomainAssembly* m_NextDomainAssemblyInSameALC;
750
751 public:
752 DomainAssembly* GetNextDomainAssemblyInSameALC()
753 {
754 return m_NextDomainAssemblyInSameALC;
755 }
756
757 void SetNextDomainAssemblyInSameALC(DomainAssembly* domainAssembly)
758 {
759 _ASSERTE(m_NextDomainAssemblyInSameALC == NULL);
760 m_NextDomainAssemblyInSameALC = domainAssembly;
761 }
762
763 // Indicates if the assembly can be cached in a binding cache such as AssemblySpecBindingCache.
764 inline bool CanUseWithBindingCache()
765 { STATIC_CONTRACT_WRAPPER; return GetFile()->CanUseWithBindingCache(); }
766};
767
768typedef DomainAssembly::ModuleIterator DomainModuleIterator;
769
770// --------------------------------------------------------------------------------
771// DomainModule is a subclass of DomainFile which specifically represents a module.
772// --------------------------------------------------------------------------------
773#endif // _DOMAINFILE_H_
774