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 // --------------------------------------------------------------------------------
8 // --------------------------------------------------------------------------------
13 // --------------------------------------------------------------------------------
15 // --------------------------------------------------------------------------------
20 #include "securitymeta.h"
21 #include "invokeutil.h"
23 #include "dynamicmethod.h"
25 #include "dbginterface.h"
26 #include "eventtrace.h"
29 #include <corcompile.h>
31 #endif // FEATURE_PREJIT
33 #include "umthunkhash.h"
34 #include "peimagelayout.inl"
36 #include "winrthelpers.h"
38 #ifdef FEATURE_PERFMAP
40 #endif // FEATURE_PERFMAP
42 BOOL DomainAssembly::IsUnloading()
47 BOOL fIsUnloading = FALSE;
49 fIsUnloading = this->GetAppDomain()->IsUnloading();
53 fIsUnloading = m_fDebuggerUnloadStarted;
60 #ifndef DACCESS_COMPILE
61 DomainFile::DomainFile(AppDomain *pDomain, PEFile *pFile)
64 m_pOriginalFile(NULL),
66 m_level(FILE_LOAD_CREATE),
68 m_notifyflags(NOT_NOTIFIED),
70 m_pDynamicMethodTable(NULL),
72 m_bDisableActivationCheck(FALSE),
73 m_dwReasonForRejectingNativeImage(0)
78 THROWS; // From CreateHandle
85 m_hExposedModuleObject = NULL;
89 DomainFile::~DomainFile()
102 m_pOriginalFile->Release();
103 if (m_pDynamicMethodTable)
104 m_pDynamicMethodTable->Destroy();
105 #if defined(FEATURE_MIXEDMODE) && !defined(CROSSGEN_COMPILE)
107 delete m_pUMThunkHash;
112 #endif //!DACCESS_COMPILE
114 LoaderAllocator * DomainFile::GetLoaderAllocator()
124 Assembly *pAssembly = GetDomainAssembly()->GetAssembly();
125 if ((pAssembly != NULL) && (pAssembly->IsCollectible()))
127 return pAssembly->GetLoaderAllocator();
131 return this->GetAppDomain()->GetLoaderAllocator();
135 #ifndef DACCESS_COMPILE
137 void DomainFile::ReleaseFiles()
140 Module* pModule=GetCurrentModule();
142 pModule->StartUnload();
145 m_pFile->ReleaseIL();
147 m_pOriginalFile->ReleaseIL();
150 pModule->ReleaseILData();
153 BOOL DomainFile::TryEnsureActive()
173 EX_END_CATCH(RethrowTransientExceptions);
178 // Optimization intended for EnsureLoadLevel only
179 #include <optsmallperfcritical.h>
180 void DomainFile::EnsureLoadLevel(FileLoadLevel targetLevel)
193 this->GetAppDomain()->LoadDomainFile(this, targetLevel);
195 // Enforce the loading requirement. Note that we may have a deadlock in which case we
196 // may be off by one which is OK. (At this point if we are short of targetLevel we know
197 // we have done so because of reentrancy contraints.)
199 RequireLoadLevel((FileLoadLevel)(targetLevel-1));
202 ThrowIfError(targetLevel);
206 #include <optdefault.h>
208 void DomainFile::AttemptLoadLevel(FileLoadLevel targetLevel)
219 this->GetAppDomain()->LoadDomainFile(this, targetLevel);
221 ThrowIfError(targetLevel);
227 CHECK DomainFile::CheckLoadLevel(FileLoadLevel requiredLevel, BOOL deadlockOK)
239 #ifndef CROSSGEN_COMPILE
240 // CheckLoading requires waiting on a host-breakable lock.
241 // Since this is only a checked-build assert and we've been
242 // living with it for a while, I'll leave it as is.
243 //@TODO: CHECK statements are *NOT* debug-only!!!
244 CONTRACT_VIOLATION(ThrowsViolation|GCViolation|TakesLockViolation);
245 CHECK(this->GetAppDomain()->CheckLoading(this, requiredLevel));
250 CHECK_MSG(m_level >= requiredLevel,
251 "File not sufficiently loaded");
259 void DomainFile::RequireLoadLevel(FileLoadLevel targetLevel)
269 if (GetLoadLevel() < targetLevel)
271 ThrowIfError(targetLevel);
272 ThrowHR(MSEE_E_ASSEMBLYLOADINPROGRESS); // @todo: better exception
279 void DomainFile::SetError(Exception *ex)
283 PRECONDITION(!IsError());
284 PRECONDITION(ex != NULL);
288 POSTCONDITION(IsError());
292 m_pError = new ExInfo(ex->DomainBoundClone());
294 GetCurrentModule()->NotifyEtwLoadFinished(ex->GetHR());
296 if (!IsProfilerNotified())
298 SetProfilerNotified();
300 #ifdef PROFILING_SUPPORTED
301 if (GetCurrentModule() != NULL
302 && !GetCurrentModule()->GetAssembly()->IsDomainNeutral())
304 // Only send errors for non-shared assemblies; other assemblies might be successfully completed
305 // in another app domain later.
306 GetCurrentModule()->NotifyProfilerLoadFinished(ex->GetHR());
314 void DomainFile::ThrowIfError(FileLoadLevel targetLevel)
325 if (m_level < targetLevel)
334 CHECK DomainFile::CheckNoError(FileLoadLevel targetLevel)
336 LIMITED_METHOD_CONTRACT;
337 CHECK(m_level >= targetLevel
343 CHECK DomainFile::CheckLoaded()
354 CHECK_MSG(CheckNoError(FILE_LOADED), "DomainFile load resulted in an error");
359 // Mscorlib is allowed to run managed code much earlier than other
360 // assemblies for bootstrapping purposes. This is because it has no
361 // dependencies, security checks, and doesn't rely on loader notifications.
363 if (GetFile()->IsSystem())
366 CHECK_MSG(GetFile()->CheckLoaded(), "PEFile has not been loaded");
371 CHECK DomainFile::CheckActivated()
382 CHECK_MSG(CheckNoError(FILE_ACTIVE), "DomainFile load resulted in an error");
387 // Mscorlib is allowed to run managed code much earlier than other
388 // assemblies for bootstrapping purposes. This is because it has no
389 // dependencies, security checks, and doesn't rely on loader notifications.
391 if (GetFile()->IsSystem())
394 CHECK_MSG(GetFile()->CheckLoaded(), "PEFile has not been loaded");
395 CHECK_MSG(IsLoaded(), "DomainFile has not been fully loaded");
396 CHECK_MSG(m_bDisableActivationCheck || CheckLoadLevel(FILE_ACTIVE), "File has not had execution verified");
401 #endif //!DACCESS_COMPILE
403 DomainAssembly *DomainFile::GetDomainAssembly()
414 #ifdef FEATURE_MULTIMODULE_ASSEMBLIES
417 return dac_cast<PTR_DomainAssembly>(this);
421 return dac_cast<PTR_DomainModule>(this)->GetDomainAssembly();
424 _ASSERTE(IsAssembly());
425 return (DomainAssembly *) this;
426 #endif // FEATURE_MULTIMODULE_ASSEMBLIES
429 BOOL DomainFile::IsIntrospectionOnly()
432 return GetFile()->IsIntrospectionOnly();
435 // Return true iff the debugger should get notifications about this assembly.
438 // The debuggee may be stopped while a DomainAssmebly is being initialized. In this time window,
439 // GetAssembly() may be NULL. If that's the case, this function has to return FALSE. Later on, when
440 // the DomainAssembly is fully initialized, this function will return TRUE. This is the only scenario
441 // where this function is mutable. In other words, a DomainAssembly can only change from being invisible
442 // to visible, but NOT vice versa. Once a DomainAssmebly is fully initialized, this function should be
443 // immutable for an instance of a module. That ensures that the debugger gets consistent
444 // notifications about it. It this value mutates, than the debugger may miss relevant notifications.
445 BOOL DomainAssembly::IsVisibleToDebugger()
450 // If you can't run an assembly, then don't send notifications to the debugger.
451 // This check includeds IsIntrospectionOnly().
452 return ((GetAssembly() != NULL) ? GetAssembly()->HasRunAccess() : FALSE);
455 #ifndef DACCESS_COMPILE
456 #ifdef FEATURE_PREJIT
457 void DomainFile::ExternalLog(DWORD level, const WCHAR *fmt, ...)
464 GetOriginalFile()->ExternalVLog(LF_ZAP, level, fmt, args);
469 void DomainFile::ExternalLog(DWORD level, const char *msg)
473 GetOriginalFile()->ExternalLog(level, msg);
477 #ifndef CROSSGEN_COMPILE
478 //---------------------------------------------------------------------------------------
480 // Returns managed representation of the module (Module or ModuleBuilder).
481 // Returns NULL if the managed scout was already collected (see code:LoaderAllocator#AssemblyPhases).
483 OBJECTREF DomainFile::GetExposedModuleObject()
494 LoaderAllocator * pLoaderAllocator = GetLoaderAllocator();
496 if (m_hExposedModuleObject == NULL)
498 // Atomically create a handle
499 LOADERHANDLE handle = pLoaderAllocator->AllocateHandle(NULL);
501 FastInterlockCompareExchangePointer(&m_hExposedModuleObject, handle, static_cast<LOADERHANDLE>(NULL));
504 if (pLoaderAllocator->GetHandleValue(m_hExposedModuleObject) == NULL)
506 REFLECTMODULEBASEREF refClass = NULL;
508 // Will be TRUE only if LoaderAllocator managed object was already collected and therefore we should
510 BOOL fIsLoaderAllocatorCollected = FALSE;
512 GCPROTECT_BEGIN(refClass);
514 if (GetFile()->IsDynamic())
516 refClass = (REFLECTMODULEBASEREF) AllocateObject(MscorlibBinder::GetClass(CLASS__MODULE_BUILDER));
520 refClass = (REFLECTMODULEBASEREF) AllocateObject(MscorlibBinder::GetClass(CLASS__MODULE));
522 refClass->SetModule(m_pModule);
524 // Attach the reference to the assembly to keep the LoaderAllocator for this collectible type
525 // alive as long as a reference to the module is kept alive.
526 if (GetModule()->GetAssembly() != NULL)
528 OBJECTREF refAssembly = GetModule()->GetAssembly()->GetExposedObject();
529 if ((refAssembly == NULL) && GetModule()->GetAssembly()->IsCollectible())
531 fIsLoaderAllocatorCollected = TRUE;
533 refClass->SetAssembly(refAssembly);
536 pLoaderAllocator->CompareExchangeValueInHandle(m_hExposedModuleObject, (OBJECTREF)refClass, NULL);
539 if (fIsLoaderAllocatorCollected)
540 { // The LoaderAllocator managed object was already collected, we cannot re-create it
541 // Note: We did not publish the allocated Module/ModuleBuilder object, it will get collected
547 return pLoaderAllocator->GetHandleValue(m_hExposedModuleObject);
548 } // DomainFile::GetExposedModuleObject
549 #endif // CROSSGEN_COMPILE
551 BOOL DomainFile::DoIncrementalLoad(FileLoadLevel level)
553 STANDARD_VM_CONTRACT;
559 pThread = GetThread();
561 INTERIOR_STACK_PROBE_FOR(pThread, 8);
565 case FILE_LOAD_BEGIN:
569 case FILE_LOAD_FIND_NATIVE_IMAGE:
570 #ifdef FEATURE_PREJIT
575 case FILE_LOAD_VERIFY_NATIVE_IMAGE_DEPENDENCIES:
576 #ifdef FEATURE_PREJIT
577 VerifyNativeImageDependencies();
581 case FILE_LOAD_ALLOCATE:
585 case FILE_LOAD_ADD_DEPENDENCIES:
589 case FILE_LOAD_PRE_LOADLIBRARY:
593 case FILE_LOAD_LOADLIBRARY:
597 case FILE_LOAD_POST_LOADLIBRARY:
601 case FILE_LOAD_EAGER_FIXUPS:
605 case FILE_LOAD_VTABLE_FIXUPS:
609 case FILE_LOAD_DELIVER_EVENTS:
617 case FILE_LOAD_VERIFY_EXECUTION:
629 END_INTERIOR_STACK_PROBE;
631 #ifdef FEATURE_MULTICOREJIT
633 Module * pModule = GetModule();
635 if (pModule != NULL) // Should not triggle assert when module is NULL
637 this->GetAppDomain()->GetMulticoreJitManager().RecordModuleLoad(pModule, level);
645 #ifdef FEATURE_PREJIT
647 void DomainFile::VerifyNativeImageDependencies(bool verifyOnly)
653 PRECONDITION(verifyOnly || (m_pDomain->GetDomainFileLoadLevel(this) ==
654 FILE_LOAD_FIND_NATIVE_IMAGE));
658 // This function gets called multiple times. The first call is the real work.
659 // Subsequent calls are only to verify that everything still looks OK.
661 ClearNativeImageStress();
663 if (!m_pFile->HasNativeImage())
670 // Go through native dependencies & make sure they still have their prejit images after
671 // the security check.
672 // NOTE: we could theoretically do this without loading the dependencies, if we cache the
673 // COR_TRUST structures from the dependencies in the version information.
675 // Verify that all of our hard dependencies are loaded at the right base address.
676 // If not, abandon prejit image (or fix ours up)
677 // Also, if there are any hard dependencies, then our native image also needs to be
678 // loaded at the right base address
680 // Note: we will go through all of our dependencies, call Load on them, and check the base
681 // addresses & identity.
682 // It is important to note that all of those dependencies are also going to do the
683 // same thing, so we might conceivably check a base address as OK, and then have that image
684 // abandoned by that assembly during its VerifyNativeImageDependencies phase.
685 // However, we avoid this problem since the hard depedencies stored are a closure of the
686 // hard dependencies of an image. This effectively means that our check here is a superset
687 // of the check that the dependencies will perform. Even if we hit a dependency loop, we
688 // will still guarantee that we've examined all of our dependencies.
690 ReleaseHolder<PEImage> pNativeImage = m_pFile->GetNativeImageWithRef();
691 if(pNativeImage==NULL)
697 PEImageLayout* pNativeLayout = pNativeImage->GetLoadedLayout();
699 // reuse same codepath for both manifest and non-manifest modules
700 ReleaseHolder<PEImage> pManifestNativeImage(NULL);
702 PEFile* pManifestFile = m_pFile;
703 PEImageLayout* pManifestNativeLayout = pNativeLayout;
707 pManifestFile = GetDomainAssembly()->GetCurrentAssembly()
708 ->GetManifestModule()->GetFile();
710 pManifestNativeImage = pManifestFile->GetNativeImageWithRef();
712 if (pManifestNativeImage == NULL)
714 ExternalLog(LL_ERROR, "Rejecting native image because there is no "
715 "ngen image for manifest module. Check why the manifest module "
716 "does not have an ngen image");
717 m_dwReasonForRejectingNativeImage = ReasonForRejectingNativeImage_NoNiForManifestModule;
718 STRESS_LOG3(LF_ZAP,LL_INFO100,"Rejecting native file %p, because its manifest module %p has no NI - reason 0x%x\n",pNativeImage.GetValue(),pManifestFile,m_dwReasonForRejectingNativeImage);
719 goto NativeImageRejected;
725 COUNT_T cDependencies;
726 CORCOMPILE_DEPENDENCY *pDependencies = pManifestNativeLayout->GetNativeDependencies(&cDependencies);
728 LOG((LF_ZAP, LL_INFO100, "ZAP: Checking native image dependencies for %S.\n",
729 pNativeImage->GetPath().GetUnicode()));
731 for (COUNT_T iDependency = 0; iDependency < cDependencies; iDependency++)
733 CORCOMPILE_DEPENDENCY *pDependency = &(pDependencies[iDependency]);
735 // Later, for domain neutral assemblies, we will also want to verify security policy
736 // in such cases, the prejit image should store the publisher info for the dependencies
739 // If this is not a hard-bound dependency, then skip to the next dependency
740 if (pDependency->signNativeImage == INVALID_NGEN_SIGNATURE)
745 // CoreCLR hard binds to mscorlib.dll only. Avoid going through the full load.
750 name.InitializeSpec(pDependency->dwAssemblyRef,
751 ((pManifestNativeImage != NULL) ? pManifestNativeImage : pNativeImage)->GetNativeMDImport(),
752 GetDomainAssembly());
753 _ASSERTE(name.IsMscorlib());
756 PEAssembly * pDependencyFile = SystemDomain::SystemFile();
759 ReleaseHolder<PEImage> pDependencyNativeImage = pDependencyFile->GetNativeImageWithRef();
760 if (pDependencyNativeImage == NULL)
762 ExternalLog(LL_ERROR, W("Rejecting native image because dependency %s is not native"),
763 pDependencyFile->GetPath().GetUnicode());
764 m_dwReasonForRejectingNativeImage = ReasonForRejectingNativeImage_DependencyNotNative;
765 STRESS_LOG3(LF_ZAP,LL_INFO100,"Rejecting native file %p, because dependency %p is not NI - reason 0x%x\n",pNativeImage.GetValue(),pDependencyFile,m_dwReasonForRejectingNativeImage);
766 goto NativeImageRejected;
769 #ifndef FEATURE_FUSION // Fusion does this verification at native binding time.
770 PTR_PEImageLayout pDependencyNativeLayout = pDependencyNativeImage->GetLoadedLayout();
771 // Assert that the native image signature is as expected
772 // Fusion will ensure this
773 CORCOMPILE_VERSION_INFO * pDependencyNativeVersion =
774 pDependencyNativeLayout->GetNativeVersionInfo();
776 LoggablePEAssembly logAsm(pDependencyFile);
777 if (!RuntimeVerifyNativeImageDependency(pDependency, pDependencyNativeVersion, &logAsm))
778 goto NativeImageRejected;
781 LOG((LF_ZAP, LL_INFO100, "ZAP: Native image dependencies for %S OK.\n",
782 pNativeImage->GetPath().GetUnicode()));
788 m_pFile->ClearNativeImage();
789 m_pFile->SetCannotUseNativeImage();
796 BOOL DomainFile::IsZapRequired()
804 INJECT_FAULT(COMPlusThrowOM(););
808 if (!m_pFile->HasMetadata() || !g_pConfig->RequireZap(GetSimpleName()))
811 #if defined(_DEBUG) && defined(FEATURE_TREAT_NI_AS_MSIL_DURING_DIAGNOSTICS)
812 // If we're intentionally treating NIs as if they were MSIL assemblies, and the test
813 // is flexible enough to accept that (e.g., complus_zaprequired=2), then zaps are not
814 // required (i.e., it's ok for m_pFile->m_nativeImage to be NULL), but only if we
815 // loaded an actual NI to be treated as an IL assembly
816 if (PEFile::ShouldTreatNIAsMSIL())
818 // Since the RequireZap() call above returned true, we know that some level of
819 // zap requiredness was configured
820 _ASSERTE(g_pConfig->RequireZaps() != EEConfig::REQUIRE_ZAPS_NONE);
822 // If config uses this special value (2), zaps are not required, so long as
823 // we're using an actual NI as IL
824 if ((g_pConfig->RequireZaps() == EEConfig::REQUIRE_ZAPS_ALL_JIT_OK) &&
825 m_pFile->HasOpenedILimage() &&
826 m_pFile->GetOpenedILimage()->HasNativeHeader())
831 #endif // defined(_DEBUG) && defined(FEATURE_TREAT_NI_AS_MSIL_DURING_DIAGNOSTICS)
833 // Does this look like a resource-only assembly? We assume an assembly is resource-only
834 // if it contains no TypeDef (other than the <Module> TypeDef) and no MethodDef.
835 // Note that pMD->GetCountWithTokenKind(mdtTypeDef) doesn't count the <Module> type.
836 IMDInternalImportHolder pMD = m_pFile->GetMDImport();
837 if (pMD->GetCountWithTokenKind(mdtTypeDef) == 0 && pMD->GetCountWithTokenKind(mdtMethodDef) == 0)
840 DomainAssembly * pDomainAssembly = GetDomainAssembly();
842 // If the manifest module does not have an ngen image, the non-manifest
843 // modules cannot either
844 if (m_pFile->IsModule() && !pDomainAssembly->GetFile()->CanUseNativeImage())
845 m_pFile->SetCannotUseNativeImage();
847 // Some cases are not supported by design. They can never have a native image.
848 // So ignore such cases
850 if (!m_pFile->CanUseNativeImage() &&
851 g_pConfig->RequireZaps() == EEConfig::REQUIRE_ZAPS_SUPPORTED)
854 #ifdef FEATURE_NATIVE_IMAGE_GENERATION
855 if (IsCompilationProcess())
857 // Ignore the assembly being ngened.
859 bool fileIsBeingNGened = false;
861 if (this->GetAppDomain()->IsCompilationDomain())
863 Assembly * assemblyBeingNGened = this->GetAppDomain()->ToCompilationDomain()->GetTargetAssembly();
864 if (assemblyBeingNGened == NULL || assemblyBeingNGened == pDomainAssembly->GetCurrentAssembly())
865 fileIsBeingNGened = true;
869 // mscorlib gets loaded before the CompilationDomain gets created.
870 // However, we may be ngening mscorlib itself
871 fileIsBeingNGened = true;
874 if (fileIsBeingNGened)
882 void DomainFile::CheckZapRequired()
890 INJECT_FAULT(COMPlusThrowOM(););
894 if (m_pFile->HasNativeImage() || !IsZapRequired())
897 #ifdef FEATURE_READYTORUN
898 if(m_pFile->GetLoaded()->HasReadyToRunHeader())
902 // Flush any log messages
903 GetFile()->FlushExternalLog();
906 ss.Printf("ZapRequire: Could not get native image for %s.\n"
907 "Use FusLogVw.exe to check the reason.",
911 // Assert as some test may not check their error codes well. So throwing an
912 // exception may not cause a test failure (as it should).
913 StackScratchBuffer scratch;
914 DbgAssertDialog(__FILE__, __LINE__, (char*)ss.GetUTF8(scratch));
915 #endif // defined(_DEBUG)
917 COMPlusThrowNonLocalized(kFileNotFoundException, ss.GetUnicode());
920 // Discarding an ngen image can cause problems. For more coverage,
921 // this stress-mode discards ngen images even if not needed.
923 void DomainFile::ClearNativeImageStress()
928 static ConfigDWORD clearNativeImageStress;
929 DWORD stressPercentage = clearNativeImageStress.val(CLRConfig::INTERNAL_clearNativeImageStress);
930 _ASSERTE(stressPercentage <= 100);
931 if (stressPercentage == 0 || !GetFile()->HasNativeImage())
934 // Note that discarding a native image can affect dependencies. So its not enough
935 // to only check DomainFile::IsZapRequired() here.
936 if (g_pConfig->RequireZaps() != EEConfig::REQUIRE_ZAPS_NONE)
939 // Its OK to ClearNativeImage even for a shared assembly, as the current PEFile will
940 // be discarded if we decide to share the assembly. However, we always use the same
941 // PEFile for the system assembly. So discarding the native image in the current
942 // AppDomain will actually affect the system assembly in the shared domain, and other
943 // appdomains may have already committed to using its ngen image.
944 if (GetFile()->IsSystem() && !this->GetAppDomain()->IsDefaultDomain())
947 if (g_IBCLogger.InstrEnabled())
950 ULONG hash = HashStringA(GetSimpleName());
952 // Hash in the FileLoadLevel so that we make a different decision for every level.
953 FileLoadLevel fileLoadLevel = m_pDomain->GetDomainFileLoadLevel(this);
954 hash ^= ULONG(fileLoadLevel);
955 // We do not discard native images after this level
956 _ASSERTE(fileLoadLevel < FILE_LOAD_VERIFY_NATIVE_IMAGE_DEPENDENCIES);
958 // Different app-domains should make different decisions
959 hash ^= HashString(this->GetAppDomain()->GetFriendlyName());
961 #ifdef FEATURE_NATIVE_IMAGE_GENERATION
962 // Since DbgRandomOnHashAndExe() is not so random under ngen.exe, also
963 // factor in the module being compiled
964 if (this->GetAppDomain()->IsCompilationDomain())
966 Module * module = this->GetAppDomain()->ToCompilationDomain()->GetTargetModule();
967 // Has the target module been set yet?
969 hash ^= HashStringA(module->GetSimpleName());
973 if (DbgRandomOnHashAndExe(hash, float(stressPercentage)/100))
975 GetFile()->SetCannotUseNativeImage();
976 GetFile()->ClearNativeImage();
977 ExternalLog(LL_ERROR, "Rejecting native image for **clearNativeImageStress**");
982 #endif // FEATURE_PREJIT
984 void DomainFile::PreLoadLibrary()
993 // Check skip verification for loading if required
994 if (!GetFile()->CanLoadLibrary())
996 DomainAssembly* pDomainAssembly = GetDomainAssembly();
997 if (pDomainAssembly->GetSecurityDescriptor()->IsResolved())
999 if (Security::CanSkipVerification(pDomainAssembly))
1000 GetFile()->SetSkipVerification();
1004 AppDomain *pAppDomain = this->GetAppDomain();
1005 PEFile *pFile = GetFile();
1006 _ASSERTE(pFile != NULL);
1007 PEImage *pImage = pFile->GetILimage();
1008 _ASSERTE(pImage != NULL);
1009 _ASSERTE(!pImage->IsFile());
1010 if (pImage->HasV1Metadata())
1012 // In V1 case, try to derive SkipVerification status from parents
1015 PEAssembly * pAssembly = pFile->GetAssembly();
1016 if (pAssembly == NULL)
1018 pFile = pAssembly->GetCreator();
1021 pAssembly = pFile->GetAssembly();
1022 // Find matching DomainAssembly for the given PEAsssembly
1023 // Perf: This does not scale
1024 AssemblyIterationFlags flags =
1025 (AssemblyIterationFlags) (kIncludeLoaded | kIncludeLoading | kIncludeExecution);
1026 AppDomain::AssemblyIterator i = pAppDomain->IterateAssembliesEx(flags);
1027 CollectibleAssemblyHolder<DomainAssembly *> pDomainAssembly;
1029 while (i.Next(pDomainAssembly.This()))
1031 if ((pDomainAssembly != NULL) && (pDomainAssembly->GetFile() == pAssembly))
1036 if (pDomainAssembly != NULL)
1038 if (pDomainAssembly->GetSecurityDescriptor()->IsResolved())
1040 if (Security::CanSkipVerification(pDomainAssembly))
1042 GetFile()->SetSkipVerification();
1049 // Potential Bug: Unable to find DomainAssembly for given PEAssembly
1050 // In retail build gracefully exit loop
1051 _ASSERTE(pDomainAssembly != NULL);
1056 while (pFile != NULL);
1060 } // DomainFile::PreLoadLibrary
1062 // Note that this is the sole loading function which must be called OUTSIDE THE LOCK, since
1063 // it will potentially involve the OS loader lock.
1064 void DomainFile::LoadLibrary()
1073 Thread::LoadingFileHolder holder(GetThread());
1074 GetThread()->SetLoadingFile(this);
1075 GetFile()->LoadLibrary();
1078 void DomainFile::PostLoadLibrary()
1083 // Note that GetFile()->LoadLibrary must be called before this OUTSIDE OF THE LOCKS
1084 PRECONDITION(GetFile()->CheckLoaded());
1089 #ifdef FEATURE_PREJIT
1090 if (GetFile()->HasNativeImage())
1092 InsertIntoDomainFileWithNativeImageList();
1095 #ifdef PROFILING_SUPPORTED
1096 // After this point, it is possible to load types.
1097 // We need to notify the profiler now because the profiler may need to inject methods into
1098 // the module, and to do so reliably, it must have the chance to do so before
1099 // any types are loaded from the module.
1101 // In the past we only allowed injecting types/methods on non-NGEN images so notifying here
1102 // worked ok, but for NGEN images this is pretty ugly. Rejitting often occurs in this callback,
1103 // but then during fixup the results of LoadedMethodDesc iterator would change and we would
1104 // need to re-iterate everything. Aside from Rejit other code often wasn't designed to handle
1105 // running before Fixup. A concrete example VS recently hit, calling GetClassLayout using
1106 // a MethodTable which doesn't need restore but its parent pointer isn't fixed up yet.
1107 // We've already set the rules so that profilers can't modify the member list of types in NGEN images
1108 // so it doesn't matter if types are pre-loaded. We only need the guarantee that code for the
1109 // loaded types won't execute yet. For NGEN images we deliver the load notification in
1110 // FILE_LOAD_DELIVER_EVENTS.
1111 if (!GetFile()->HasNativeImage())
1113 if (!IsProfilerNotified())
1115 SetProfilerNotified();
1116 GetCurrentModule()->NotifyProfilerLoadFinished(S_OK);
1123 void DomainFile::AddDependencies()
1125 STANDARD_VM_CONTRACT;
1127 #ifdef FEATURE_PREJIT
1130 // CoreCLR hard binds to mscorlib.dll only. No need to track hardbound dependencies.
1133 #endif // FEATURE_PREJIT
1136 void DomainFile::EagerFixups()
1138 WRAPPER_NO_CONTRACT;
1140 #ifdef FEATURE_PREJIT
1141 if (IsIntrospectionOnly())
1144 if (GetCurrentModule()->HasNativeImage())
1146 GetCurrentModule()->RunEagerFixups();
1148 #ifdef FEATURE_READYTORUN
1150 if (GetCurrentModule()->IsReadyToRun())
1152 #ifndef CROSSGEN_COMPILE
1153 GetCurrentModule()->RunEagerFixups();
1156 PEImageLayout * pLayout = GetCurrentModule()->GetReadyToRunInfo()->GetImage();
1158 TADDR base = dac_cast<TADDR>(pLayout->GetBase());
1160 ExecutionManager::AddCodeRange(base, base + (TADDR)pLayout->GetVirtualSize(),
1161 ExecutionManager::GetReadyToRunJitManager(),
1162 RangeSection::RANGE_SECTION_READYTORUN,
1163 GetCurrentModule() /* (void *)pLayout */);
1165 #endif // FEATURE_READYTORUN
1167 #endif // FEATURE_PREJIT
1170 void DomainFile::VtableFixups()
1172 WRAPPER_NO_CONTRACT;
1174 #if defined(FEATURE_MIXEDMODE) && !defined(CROSSGEN_COMPILE)
1175 if (!GetCurrentModule()->IsResource())
1176 GetCurrentModule()->FixupVTables();
1180 void DomainFile::FinishLoad()
1189 #ifdef FEATURE_PREJIT
1191 if (m_pFile->HasNativeImage())
1193 #ifdef FEATURE_FUSION
1194 // <REVISIT_TODO>Because of bug 112034, we may commit to a native image even though
1195 // we should not have.</REVISIT_TODO>
1199 // Verify that the native image dependencies are still valid
1200 // Since we had already committed to using a native image, they cannot
1202 VerifyNativeImageDependencies(true);
1203 _ASSERTE(m_pFile->HasNativeImage());
1205 if (!m_pFile->HasNativeImage())
1207 STRESS_LOG1(LF_CODESHARING, LL_FATALERROR, "Incorrectly committed to using native image for %S",
1208 m_pFile->GetPath().GetUnicode());
1209 EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE);
1213 #endif // FEATURE_FUSION
1215 LOG((LF_ZAP, LL_INFO10, "Using native image %S.\n", m_pFile->GetPersistentNativeImage()->GetPath().GetUnicode()));
1216 ExternalLog(LL_INFO10, "Native image successfully used.");
1218 // Inform metadata that it has been loaded from a native image
1219 // (and so there was an opportunity to check for or fix inconsistencies in the original IL metadata)
1220 m_pFile->GetMDImport()->SetVerifiedByTrustedSource(TRUE);
1223 // Are we absolutely required to use a native image?
1226 #if defined(FEATURE_COMINTEROP)
1227 // If this is a winmd file, ensure that the ngen reference namespace is loadable.
1228 // This is necessary as on the phone we don't check ngen image dependencies, and thus we can get in a situation
1229 // where a winmd is loaded as a dependency of an ngen image, but the type used to build cross module references
1230 // in winmd files isn't loaded.
1231 if (GetFile()->AsAssembly()->IsWindowsRuntime() && GetFile()->HasHostAssembly())
1233 IMDInternalImport *pImport = GetFile()->GetPersistentMDImport();
1236 // It does not make sense to pass the file name to recieve fake type name for empty WinMDs, because we would use the name
1237 // for binding in next call to BindAssemblySpec which would fail for fake WinRT type name
1238 // We will throw/return the error instead and the caller will recognize it and react to it by not creating the ngen image -
1239 // see code:Zapper::ComputeDependenciesInCurrentDomain
1240 if (SUCCEEDED(::GetFirstWinRTTypeDef(pImport, &szNameSpace, &szTypeName, NULL, NULL)))
1242 // Build assembly spec to describe binding to that WinRT type.
1244 IfFailThrow(spec.Init("WindowsRuntimeAssemblyName, ContentType=WindowsRuntime"));
1245 spec.SetWindowsRuntimeType(szNameSpace, szTypeName);
1247 // Bind to assembly using the CLRPriv binder infrastructure. (All WinRT loads are done through CLRPriv binders
1248 ReleaseHolder<IAssemblyName> pAssemblyName;
1249 IfFailThrow(spec.CreateFusionName(&pAssemblyName, FALSE, TRUE));
1250 ReleaseHolder<ICLRPrivAssembly> pPrivAssembly;
1251 IfFailThrow(GetFile()->GetHostAssembly()->BindAssemblyByName(pAssemblyName, &pPrivAssembly));
1253 // Verify that we found this. If this invariant doesn't hold, then the ngen images that reference this winmd are be invalid.
1254 // ALSO, this winmd file is invalid as it doesn't follow spec about how it is distributed.
1255 if (GetAppDomain()->FindAssembly(pPrivAssembly) != this)
1257 ThrowHR(COR_E_BADIMAGEFORMAT);
1261 #endif // defined(FEATURE_CORECLR) && defined(FEATURE_COMINTEROP)
1262 #endif // FEATURE_PREJIT
1264 // Flush any log messages
1265 #ifdef FEATURE_PREJIT
1266 GetFile()->FlushExternalLog();
1268 // Must set this a bit prematurely for the DAC stuff to work
1269 m_level = FILE_LOADED;
1271 // Now the DAC can find this module by enumerating assemblies in a domain.
1272 DACNotify::DoModuleLoadNotification(m_pModule);
1274 #if defined(DEBUGGING_SUPPORTED) && !defined(DACCESS_COMPILE)
1275 if (IsDebuggerNotified() && (g_pDebugInterface != NULL))
1277 // We already notified dbgapi that this module was loading (via LoadModule()).
1278 // Now let the dbgapi know the module has reached FILE_LOADED, so it can do any
1279 // processing that needs to wait until this stage (e.g., binding breakpoints in
1281 g_pDebugInterface->LoadModuleFinished(m_pModule, m_pDomain);
1283 #endif // defined(DEBUGGING_SUPPORTED) && !defined(DACCESS_COMPILE)
1285 // Set a bit to indicate that the module has been loaded in some domain, and therefore
1286 // typeloads can involve types from this module. (Used for candidate instantiations.)
1287 GetModule()->SetIsReadyForTypeLoad();
1289 #ifdef FEATURE_PERFMAP
1290 // Notify the perfmap of the IL image load.
1291 PerfMap::LogImageLoad(m_pFile);
1295 void DomainFile::VerifyExecution()
1300 PRECONDITION(IsLoaded());
1305 if (GetModule()->IsIntrospectionOnly())
1307 // Throw an exception
1308 COMPlusThrow(kInvalidOperationException, IDS_EE_CODEEXECUTION_IN_INTROSPECTIVE_ASSEMBLY);
1311 if (GetModule()->GetAssembly()->IsSIMDVectorAssembly() &&
1312 !GetModule()->GetAssembly()->GetSecurityDescriptor()->IsFullyTrusted())
1314 COMPlusThrow(kFileLoadException, IDS_EE_SIMD_PARTIAL_TRUST_DISALLOWED);
1317 if(GetFile()->PassiveDomainOnly())
1319 // Remove path - location must be hidden for security purposes
1320 LPCWSTR path=GetFile()->GetPath();
1321 LPCWSTR pStart = wcsrchr(path, '\\');
1326 COMPlusThrow(kInvalidOperationException, IDS_EE_CODEEXECUTION_ASSEMBLY_FOR_PASSIVE_DOMAIN_ONLY,pStart);
1332 void DomainFile::Activate()
1337 PRECONDITION(IsLoaded());
1342 // If we are a module, ensure we've activated the assembly first.
1346 GetDomainAssembly()->EnsureActive();
1350 // We cannot execute any code in this assembly until we know what exception plan it is on.
1351 // At the point of an exception's stack-crawl it is too late because we cannot tolerate a GC.
1352 // See PossiblyUnwrapThrowable and its callers.
1353 _ASSERTE(GetLoadedModule() == GetDomainAssembly()->GetLoadedAssembly()->GetManifestModule());
1354 GetLoadedModule()->IsRuntimeWrapExceptions();
1357 // Now activate any dependencies.
1358 // This will typically cause reentrancy of course.
1360 if (!IsSingleAppDomain())
1362 // increment the counter (see the comment in Module::AddActiveDependency)
1363 GetModule()->IncrementNumberOfActivations();
1365 #ifdef FEATURE_LOADER_OPTIMIZATION
1366 AppDomain *pDomain = this->GetAppDomain();
1367 Module::DependencyIterator i = GetCurrentModule()->IterateActiveDependencies();
1368 STRESS_LOG2(LF_LOADER, LL_INFO100,"Activating module %p in AD %i",GetCurrentModule(),pDomain->GetId().m_dwId);
1372 Module *pModule = i.GetDependency();
1373 DomainFile *pDomainFile = pModule->FindDomainFile(pDomain);
1374 if (pDomainFile == NULL)
1375 pDomainFile = pDomain->LoadDomainNeutralModuleDependency(pModule, FILE_LOADED);
1377 STRESS_LOG3(LF_LOADER, LL_INFO100,"Activating dependency %p -> %p, unconditional=%i",GetCurrentModule(),pModule,i.IsUnconditional());
1379 if (i.IsUnconditional())
1381 // Let any failures propagate
1382 pDomainFile->EnsureActive();
1386 // Enable triggers if we fail here
1387 if (!pDomainFile->TryEnsureActive())
1388 GetCurrentModule()->EnableModuleFailureTriggers(pModule, this->GetAppDomain());
1390 STRESS_LOG3(LF_LOADER, LL_INFO100,"Activated dependency %p -> %p, unconditional=%i",GetCurrentModule(),pModule,i.IsUnconditional());
1395 #ifndef CROSSGEN_COMPILE
1396 if (m_pModule->CanExecuteCode())
1399 // Now call the module constructor. Note that this might cause reentrancy;
1400 // this is fine and will be handled by the class cctor mechanism.
1403 MethodTable *pMT = m_pModule->GetGlobalMethodTable();
1406 pMT->CheckRestore();
1407 m_bDisableActivationCheck=TRUE;
1408 pMT->CheckRunClassInitThrowing();
1410 if (g_pConfig->VerifyModulesOnLoad())
1412 m_pModule->VerifyAllMethods();
1415 if (g_pConfig->ExpandModulesOnLoad())
1417 m_pModule->ExpandAll();
1423 // This exception does not need to be localized as it can only happen in
1424 // NGen and PEVerify, and we are not localizing those tools.
1425 _ASSERTE(this->GetAppDomain()->IsPassiveDomain());
1426 // This assert will fire if we attempt to run non-mscorlib code from within ngen
1427 // Current audits of the system indicate that this will never occur, but if it does
1428 // the exception below will prevent actual non-mscorlib code execution.
1429 _ASSERTE(!this->GetAppDomain()->IsCompilationDomain());
1431 LPCWSTR message = W("You may be trying to evaluate a permission from an assembly ")
1432 W("without FullTrust, or which cannot execute code for other reasons.");
1433 COMPlusThrowNonLocalized(kFileLoadException, message);
1435 #endif // CROSSGEN_COMPILE
1440 #ifdef FEATURE_LOADER_OPTIMIZATION
1441 BOOL DomainFile::PropagateActivationInAppDomain(Module *pModuleFrom, Module *pModuleTo, AppDomain* pDomain)
1445 PRECONDITION(CheckPointer(pModuleFrom));
1446 PRECONDITION(CheckPointer(pModuleTo));
1447 THROWS; // should only throw transient failures
1448 DISABLED(GC_TRIGGERS);
1453 #ifdef FEATURE_MULTICOREJIT
1454 // Reset the flag to allow managed code to be called in multicore JIT background thread from this routine
1455 ThreadStateNCStackHolder holder(-1, Thread::TSNC_CallingManagedCodeDisabled);
1458 BOOL completed=true;
1463 ENTER_DOMAIN_PTR(pDomain,ADV_ITERATOR); //iterator
1464 DomainFile *pDomainFileFrom = pModuleFrom->FindDomainFile(pDomain);
1465 if (pDomainFileFrom != NULL && pDomain->IsLoading(pDomainFileFrom, FILE_ACTIVE))
1467 STRESS_LOG3(LF_LOADER, LL_INFO100,"Found DomainFile %p for module %p in AppDomain %i\n",pDomainFileFrom,pModuleFrom,pDomain->GetId().m_dwId);
1468 DomainFile *pDomainFileTo = pModuleTo->FindDomainFile(pDomain);
1469 if (pDomainFileTo == NULL)
1470 pDomainFileTo = pDomain->LoadDomainNeutralModuleDependency(pModuleTo, FILE_LOADED);
1472 if (!pDomainFileTo->TryEnsureActive())
1473 pModuleFrom->EnableModuleFailureTriggers(pModuleTo, pDomain);
1474 else if (!pDomainFileTo->IsActive())
1476 // We are in a reentrant case
1480 END_DOMAIN_TRANSITION;
1484 if (!IsExceptionOfType(kAppDomainUnloadedException, GET_EXCEPTION()))
1487 EX_END_CATCH(SwallowAllExceptions)
1492 // Returns TRUE if activation is completed for all app domains
1494 BOOL DomainFile::PropagateNewActivation(Module *pModuleFrom, Module *pModuleTo)
1498 PRECONDITION(CheckPointer(pModuleFrom));
1499 PRECONDITION(CheckPointer(pModuleTo));
1500 THROWS; // should only throw transient failures
1506 BOOL completed = TRUE;
1507 #ifdef FEATURE_LOADER_OPTIMIZATION
1508 if (pModuleFrom->GetAssembly()->IsDomainNeutral())
1510 AppDomainIterator ai(TRUE);
1511 Thread *pThread = GetThread();
1515 STRESS_LOG3(LF_LOADER, LL_INFO100,"Attempting to propagate domain-neutral conditional module dependency %p -> %p to AppDomain %i\n",pModuleFrom,pModuleTo,ai.GetDomain()->GetId().m_dwId);
1516 // This is to minimize the chances of trying to run code in an appdomain that's shutting down.
1517 if (ai.GetDomain()->CanThreadEnter(pThread))
1519 completed &= PropagateActivationInAppDomain(pModuleFrom,pModuleTo,ai.GetDomain());
1526 AppDomain *pDomain = pModuleFrom->GetDomain()->AsAppDomain();
1527 DomainFile *pDomainFileFrom = pModuleFrom->GetDomainFile(pDomain);
1528 if (pDomain->IsLoading(pDomainFileFrom, FILE_ACTIVE))
1530 // The dependency should already be loaded
1531 DomainFile *pDomainFileTo = pModuleTo->GetDomainFile(pDomain);
1532 if (!pDomainFileTo->TryEnsureActive())
1533 pModuleFrom->EnableModuleFailureTriggers(pModuleTo, pDomain);
1534 else if (!pDomainFileTo->IsActive())
1545 // Checks that module has not been activated in any domain
1546 CHECK DomainFile::CheckUnactivatedInAllDomains(Module *pModule)
1550 PRECONDITION(CheckPointer(pModule));
1557 if (pModule->GetAssembly()->IsDomainNeutral())
1559 AppDomainIterator ai(TRUE);
1563 AppDomain *pDomain = ai.GetDomain();
1564 DomainFile *pDomainFile = pModule->FindDomainFile(pDomain);
1565 if (pDomainFile != NULL)
1566 CHECK(!pDomainFile->IsActive());
1571 DomainFile *pDomainFile = pModule->FindDomainFile(pModule->GetDomain()->AsAppDomain());
1572 if (pDomainFile != NULL)
1573 CHECK(!pDomainFile->IsActive());
1579 #ifdef FEATURE_PREJIT
1580 DomainFile *DomainFile::FindNextDomainFileWithNativeImage()
1582 LIMITED_METHOD_CONTRACT;
1583 return m_pNextDomainFileWithNativeImage;
1586 void DomainFile::InsertIntoDomainFileWithNativeImageList()
1588 LIMITED_METHOD_CONTRACT;
1592 DomainFile *pLastDomainFileFoundWithNativeImage = m_pDomain->m_pDomainFileWithNativeImageList;
1593 m_pNextDomainFileWithNativeImage = pLastDomainFileFoundWithNativeImage;
1594 if (pLastDomainFileFoundWithNativeImage == InterlockedCompareExchangeT(&m_pDomain->m_pDomainFileWithNativeImageList, this, pLastDomainFileFoundWithNativeImage))
1600 //--------------------------------------------------------------------------------
1602 //--------------------------------------------------------------------------------
1604 DomainAssembly::DomainAssembly(AppDomain *pDomain, PEFile *pFile, AssemblyLoadSecurity *pLoadSecurity, LoaderAllocator *pLoaderAllocator)
1605 : DomainFile(pDomain, pFile),
1607 m_debuggerFlags(DACF_NONE),
1608 #ifdef FEATURE_FUSION
1609 m_pAssemblyBindingClosure(NULL),
1611 m_MissingDependenciesCheckStatus(CMD_Unknown),
1612 m_fSkipPolicyResolution(pLoadSecurity != NULL && !pLoadSecurity->ShouldResolvePolicy()),
1613 m_fDebuggerUnloadStarted(FALSE),
1614 m_fCollectible(pLoaderAllocator->IsCollectible()),
1615 m_fHostAssemblyPublished(false),
1616 m_fCalculatedShouldLoadDomainNeutral(false),
1617 m_fShouldLoadDomainNeutral(false)
1623 INJECT_FAULT(COMPlusThrowOM(););
1627 pFile->ValidateForExecution();
1629 #ifndef CROSSGEN_COMPILE
1632 ((AssemblyLoaderAllocator *)pLoaderAllocator)->SetDomainAssembly(this);
1638 m_hExposedAssemblyObject = NULL;
1640 NewHolder<IAssemblySecurityDescriptor> pSecurityDescriptorHolder(Security::CreateAssemblySecurityDescriptor(pDomain, this, pLoaderAllocator));
1642 if (pLoadSecurity != NULL)
1644 #ifdef FEATURE_CAS_POLICY
1645 // If this assembly had a file name specified, we aren't allowed to load from remote sources and we
1646 // aren't in CAS policy mode (which sandboxes remote assemblies automatically), then we need to do a
1647 // check on this assembly's zone of origin when creating it.
1648 if (pLoadSecurity->m_fCheckLoadFromRemoteSource &&
1649 !pLoadSecurity->m_fSuppressSecurityChecks &&
1650 !m_pDomain->GetSecurityDescriptor()->AllowsLoadsFromRemoteSources() &&
1651 !pFile->IsIntrospectionOnly())
1653 SString strCodeBase;
1654 BYTE pbUniqueID[MAX_SIZE_SECURITY_ID];
1655 DWORD cbUniqueID = COUNTOF(pbUniqueID);
1656 SecZone dwZone = NoZone;
1658 GetSecurityIdentity(strCodeBase,
1664 // Since loads from remote sources are not enabled for this assembly, we only want to allow the
1665 // load if any of the following conditions apply:
1667 // * The load is coming off the local machine
1668 // * The load is coming from the intranet or a trusted site, and the code base is UNC. (ie,
1669 // don't allow HTTP loads off the local intranet
1671 bool safeLoad = false;
1672 if (dwZone == LocalMachine)
1676 else if (dwZone == Intranet || dwZone == Trusted)
1678 if (UrlIsFileUrl(strCodeBase.GetUnicode()))
1682 else if (PathIsUNC(strCodeBase.GetUnicode()))
1690 // We've tried to load an assembly from a location where it would have been sandboxed in legacy
1691 // CAS situations, but the application hasn't indicated that this is a safe thing to do. In
1692 // order to prevent accidental security holes by silently loading assemblies in full trust that
1693 // an application expected to be sandboxed, we'll throw an exception instead.
1695 // Since this exception can commonly occur with if the file is physically located on the
1696 // hard drive, but has the mark of the web on it we'll also try to detect this mark and
1697 // provide a customized error message if we find it. We do that by re-evaluating the
1698 // assembly's zone with the NOSAVEDFILECHECK flag, which ignores the mark of the web, and if
1699 // that comes back as MyComputer we flag the assembly as having the mark of the web on it.
1700 SecZone dwNoMotwZone = NoZone;
1701 GetSecurityIdentity(strCodeBase, &dwNoMotwZone, MUTZ_NOSAVEDFILECHECK, pbUniqueID, &cbUniqueID);
1703 if (dwNoMotwZone == LocalMachine)
1705 COMPlusThrow(kNotSupportedException, IDS_E_LOADFROM_REMOTE_SOURCE_MOTW);
1709 COMPlusThrow(kNotSupportedException, IDS_E_LOADFROM_REMOTE_SOURCE);
1713 #endif // FEATURE_CAS_POLICY
1715 if (GetFile()->IsSourceGAC())
1717 // Assemblies in the GAC are not allowed to
1718 // specify additional evidence. They must always follow default machine policy rules.
1720 // So, we just ignore the evidence. (Ideally we would throw an error, but it would introduce app
1725 #ifdef FEATURE_FUSION
1726 // We do not support sharing behavior of ALWAYS when using evidence to load assemblies
1727 if (pDomain->GetSharePolicy() == AppDomain::SHARE_POLICY_ALWAYS
1728 && ShouldLoadDomainNeutral())
1730 // Just because we have information about the loaded assembly's security doesn't mean that
1731 // we're trying to override evidence, make sure we're not just trying to push a grant set
1732 if (((pLoadSecurity->m_pEvidence != NULL) && (*pLoadSecurity->m_pEvidence != NULL)) ||
1733 ((pLoadSecurity->m_pAdditionalEvidence != NULL) && (*pLoadSecurity->m_pAdditionalEvidence != NULL)))
1735 // We may not be able to reduce sharing policy at this point, if we have already loaded
1736 // some non-GAC assemblies as domain neutral. For this case we must regrettably fail
1737 // the whole operation.
1738 if (!pDomain->ReduceSharePolicyFromAlways())
1740 ThrowHR(COR_E_CANNOT_SPECIFY_EVIDENCE);
1748 #ifdef FEATURE_CAS_POLICY
1749 if (pLoadSecurity->m_pAdditionalEvidence != NULL)
1751 if(*pLoadSecurity->m_pAdditionalEvidence != NULL)
1753 pSecurityDescriptorHolder->SetAdditionalEvidence(*pLoadSecurity->m_pAdditionalEvidence);
1756 else if (pLoadSecurity->m_pEvidence != NULL)
1758 if (*pLoadSecurity->m_pEvidence != NULL)
1760 pSecurityDescriptorHolder->SetEvidence(*pLoadSecurity->m_pEvidence);
1763 #endif // FEATURE_CAS_POLICY
1765 // If the assembly being loaded already knows its grant set (for instnace, it's being pushed
1766 // from the loading assembly), then we can set that up now as well
1767 if (!pLoadSecurity->ShouldResolvePolicy())
1769 _ASSERTE(pLoadSecurity->m_pGrantSet != NULL);
1771 #ifdef FEATURE_CAS_POLICY
1772 // The permissions from an anonymously hosted dynamic method are fulltrust/transparent,
1773 // so ensure we have full trust to pass that on to the new assembly
1774 if(pLoadSecurity->m_fPropagatingAnonymouslyHostedDynamicMethodGrant &&
1775 !CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_Security_DisableAnonymouslyHostedDynamicMethodCreatorSecurityCheck))
1777 Security::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, SECURITY_FULL_TRUST);
1779 #endif // FEATURE_CAS_POLICY
1781 pSecurityDescriptorHolder->PropagatePermissionSet(
1782 *pLoadSecurity->m_pGrantSet,
1783 pLoadSecurity->m_pRefusedSet == NULL ? NULL : *pLoadSecurity->m_pRefusedSet,
1784 pLoadSecurity->m_dwSpecialFlags);
1790 SetupDebuggingConfig();
1792 // Add a Module iterator entry for this assembly.
1793 IfFailThrow(m_Modules.Append(this));
1795 m_pSecurityDescriptor = pSecurityDescriptorHolder.Extract();
1798 DomainAssembly::~DomainAssembly()
1806 INJECT_FAULT(COMPlusThrowOM(););
1810 if (m_fHostAssemblyPublished)
1812 // Remove association first.
1813 GetAppDomain()->UnPublishHostedAssembly(this);
1816 ModuleIterator i = IterateModules(kModIterIncludeLoading);
1819 if (i.GetDomainFile() != this)
1820 delete i.GetDomainFile();
1823 if (m_pAssembly != NULL && !m_pAssembly->IsDomainNeutral())
1828 delete m_pSecurityDescriptor;
1831 void DomainAssembly::ReleaseFiles()
1833 STANDARD_VM_CONTRACT;
1836 m_pAssembly->StartUnload();
1837 #ifdef FEATURE_FUSION
1838 // release the old closure from the holder
1839 m_pAssemblyBindingClosure=NULL;
1841 ModuleIterator i = IterateModules(kModIterIncludeLoading);
1844 if (i.GetDomainFile() != this)
1845 i.GetDomainFile()->ReleaseFiles();
1848 DomainFile::ReleaseFiles();
1851 void DomainAssembly::SetAssembly(Assembly* pAssembly)
1853 STANDARD_VM_CONTRACT;
1855 UpdatePEFile(pAssembly->GetManifestFile());
1856 _ASSERTE(pAssembly->GetManifestModule()->GetFile()==m_pFile);
1857 m_pAssembly = pAssembly;
1858 m_pModule = pAssembly->GetManifestModule();
1860 pAssembly->SetDomainAssembly(this);
1863 #ifdef FEATURE_MULTIMODULE_ASSEMBLIES
1864 void DomainAssembly::AddModule(DomainModule *pModule)
1875 DWORD index = RidFromToken(pModule->GetToken());
1877 while (index >= m_Modules.GetCount())
1878 IfFailThrow(m_Modules.Append(NULL));
1880 m_Modules.Set(index, pModule);
1882 #endif // FEATURE_MULTIMODULE_ASSEMBLIES
1884 #ifndef CROSSGEN_COMPILE
1885 //---------------------------------------------------------------------------------------
1887 // Returns managed representation of the assembly (Assembly or AssemblyBuilder).
1888 // Returns NULL if the managed scout was already collected (see code:LoaderAllocator#AssemblyPhases).
1890 OBJECTREF DomainAssembly::GetExposedAssemblyObject()
1901 LoaderAllocator * pLoaderAllocator = GetLoaderAllocator();
1903 if (!pLoaderAllocator->IsManagedScoutAlive())
1904 { // We already collected the managed scout, so we cannot re-create any managed objects
1905 // Note: This is an optimization, as the managed scout can be collected right after this check
1909 if (m_hExposedAssemblyObject == NULL)
1911 // Atomically create a handle
1913 LOADERHANDLE handle = pLoaderAllocator->AllocateHandle(NULL);
1915 FastInterlockCompareExchangePointer(&m_hExposedAssemblyObject, handle, static_cast<LOADERHANDLE>(NULL));
1918 if (pLoaderAllocator->GetHandleValue(m_hExposedAssemblyObject) == NULL)
1920 ASSEMBLYREF assemblyObj = NULL;
1922 if (GetFile()->IsDynamic())
1924 // This is unnecessary because the managed InternalAssemblyBuilder object
1925 // should have already been created at the time of DefineDynamicAssembly
1926 OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOADED);
1927 pMT = MscorlibBinder::GetClass(CLASS__INTERNAL_ASSEMBLY_BUILDER);
1931 OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOADED);
1932 pMT = MscorlibBinder::GetClass(CLASS__ASSEMBLY);
1935 // Will be TRUE only if LoaderAllocator managed object was already collected and therefore we should
1937 BOOL fIsLoaderAllocatorCollected = FALSE;
1939 // Create the assembly object
1940 GCPROTECT_BEGIN(assemblyObj);
1941 assemblyObj = (ASSEMBLYREF)AllocateObject(pMT);
1943 assemblyObj->SetAssembly(this);
1945 // Attach the reference to the assembly to keep the LoaderAllocator for this collectible type
1946 // alive as long as a reference to the assembly is kept alive.
1947 // Currently we overload the sync root field of the assembly to do so, but the overload is not necessary.
1948 if (GetAssembly() != NULL)
1950 OBJECTREF refLA = GetAssembly()->GetLoaderAllocator()->GetExposedObject();
1951 if ((refLA == NULL) && GetAssembly()->GetLoaderAllocator()->IsCollectible())
1952 { // The managed LoaderAllocator object was collected
1953 fIsLoaderAllocatorCollected = TRUE;
1955 assemblyObj->SetSyncRoot(refLA);
1958 if (!fIsLoaderAllocatorCollected)
1959 { // We should not expose this value in case the LoaderAllocator managed object was already
1961 pLoaderAllocator->CompareExchangeValueInHandle(m_hExposedAssemblyObject, (OBJECTREF)assemblyObj, NULL);
1965 if (fIsLoaderAllocatorCollected)
1966 { // The LoaderAllocator managed object was already collected, we cannot re-create it
1967 // Note: We did not publish the allocated Assembly/AssmeblyBuilder object, it will get collected
1973 return pLoaderAllocator->GetHandleValue(m_hExposedAssemblyObject);
1974 } // DomainAssembly::GetExposedAssemblyObject
1975 #endif // CROSSGEN_COMPILE
1977 #ifdef FEATURE_LOADER_OPTIMIZATION
1979 #ifdef FEATURE_FUSION
1980 // This inner method exists to avoid EX_TRY calling _alloca repeatedly in the for loop below.
1981 DomainAssembly::CMDI_Result DomainAssembly::CheckMissingDependencyInner(IAssemblyBindingClosure* pClosure, DWORD idx)
1989 SafeComHolder<IAssemblyName> pAssemblyName;
1990 HRESULT hrBindFailure = S_OK;
1991 HRESULT hr = pClosure->GetNextFailureAssembly(idx, &pAssemblyName, &hrBindFailure);
1992 if (hr == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS))
1999 CMDI_Result ret = CMDI_AssemblyResolveFailed;
2001 PEAssemblyHolder result;
2005 spec.InitializeSpec(pAssemblyName, this, FALSE);
2006 result = this->GetAppDomain()->TryResolveAssembly(&spec,FALSE);
2008 if (result && result->CanUseWithBindingCache())
2010 this->GetAppDomain()->AddFileToCache(&spec, result);
2011 ret = CMDI_AssemblyResolveSucceeded;
2015 _ASSERTE(FAILED(hrBindFailure));
2018 spec.GetFileOrDisplayName(0, name);
2019 NewHolder<EEFileLoadException> pEx(new EEFileLoadException(name, hrBindFailure));
2020 this->GetAppDomain()->AddExceptionToCache(&spec, pEx);
2025 // For compat reasons, we don't want to throw right now but make sure that we
2026 // cache the exception so that it can be thrown if/when we try to load the
2027 // further down the road. See VSW 528532 for more details.
2029 EX_END_CATCH(RethrowTransientExceptions);
2035 // CheckMissingDependencies returns FALSE if any missing dependency would
2036 // successfully bind with an AssemblyResolve event. When this is the case, we
2037 // want to avoid sharing this assembly, since AssemblyResolve events are not
2038 // under our control, and therefore not predictable.
2039 CMD_State DomainAssembly::CheckMissingDependencies()
2047 if (MissingDependenciesCheckDone())
2048 return m_MissingDependenciesCheckStatus;
2050 if (this->GetAppDomain()->IsCompilationDomain())
2052 // Compilation domains will never have resolve events. Plus, this path
2053 // will sidestep the compilation domain's bind override, which will make
2054 // us skip over some dependencies.
2055 m_MissingDependenciesCheckStatus = CMD_NotNeeded;
2056 return m_MissingDependenciesCheckStatus;
2061 m_MissingDependenciesCheckStatus = CMD_NotNeeded;
2062 return m_MissingDependenciesCheckStatus;
2066 IAssemblyBindingClosure * pClosure = GetAssemblyBindingClosure(LEVEL_COMPLETE);
2068 if(pClosure == NULL)
2070 // If the closure is empty, no need to iterate them.
2071 m_MissingDependenciesCheckStatus = CMD_NotNeeded;
2072 return m_MissingDependenciesCheckStatus;
2075 for (DWORD idx = 0;;idx++)
2077 switch (CheckMissingDependencyInner(pClosure, idx))
2079 case CMDI_AssemblyResolveSucceeded:
2081 STRESS_LOG1(LF_CODESHARING,LL_INFO100,"Missing dependencies check FAILED, DomainAssembly=%p",this);
2082 m_MissingDependenciesCheckStatus = CMD_Resolved;
2083 return m_MissingDependenciesCheckStatus;
2089 STRESS_LOG1(LF_CODESHARING,LL_INFO100,"Missing dependencies check SUCCESSFUL, DomainAssembly=%p",this);
2090 m_MissingDependenciesCheckStatus = CMD_IndeedMissing;
2091 return m_MissingDependenciesCheckStatus;
2095 case CMDI_AssemblyResolveFailed:
2097 // Don't take any action, just continue the loop.
2103 #endif // FEATURE_FUSION
2105 BOOL DomainAssembly::MissingDependenciesCheckDone()
2107 return m_MissingDependenciesCheckStatus != CMD_Unknown;
2110 CMD_State DomainAssembly::CheckMissingDependencies()
2112 //CoreCLR simply doesn't share if dependencies are missing
2113 return CMD_NotNeeded;
2116 #endif // FEATURE_LOADER_OPTIMIZATION
2118 #ifdef FEATURE_MULTIMODULE_ASSEMBLIES
2119 DomainFile* DomainAssembly::FindModule(PEFile *pFile, BOOL includeLoading)
2121 CONTRACT (DomainFile*)
2127 POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
2131 ModuleIterator i = IterateModules(includeLoading ? kModIterIncludeLoading : kModIterIncludeLoaded);
2134 if (i.GetDomainFile()->Equals(pFile))
2135 RETURN i.GetDomainFile();
2139 #endif // FEATURE_MULTIMODULE_ASSEMBLIES
2141 DomainFile* DomainAssembly::FindIJWModule(HMODULE hMod)
2143 CONTRACT (DomainFile*)
2149 POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
2153 ModuleIterator i = IterateModules(kModIterIncludeLoaded);
2156 PEFile *pFile = i.GetDomainFile()->GetFile();
2158 if ( !pFile->IsResource()
2159 && !pFile->IsDynamic()
2160 && !pFile->IsILOnly()
2161 && pFile->GetIJWBase() == hMod)
2163 RETURN i.GetDomainFile();
2170 void DomainAssembly::Begin()
2172 STANDARD_VM_CONTRACT;
2175 AppDomain::LoadLockHolder lock(m_pDomain);
2176 m_pDomain->AddAssembly(this);
2178 // Make it possible to find this DomainAssembly object from associated ICLRPrivAssembly.
2179 GetAppDomain()->PublishHostedAssembly(this);
2180 m_fHostAssemblyPublished = true;
2183 #ifdef FEATURE_PREJIT
2184 void DomainAssembly::FindNativeImage()
2193 // For non-Apollo builds (i.e., when FEATURE_TREAT_NI_AS_MSIL_DURING_DIAGNOSTICS is
2194 // NOT defined), this is how we avoid use of NGEN when diagnostics requests it: By
2195 // clearing it out and forcing a load of the MSIL assembly. For Apollo builds
2196 // (FEATURE_TREAT_NI_AS_MSIL_DURING_DIAGNOSTICS), though, this doesn't work, as we
2197 // don't have MSIL assemblies handy (particularly for Fx Assemblies), so we need to
2198 // keep the NGENd image loaded, but to treat it as if it were an MSIL assembly. See
2199 // code:PEFile::SetNativeImage.
2200 #ifndef FEATURE_TREAT_NI_AS_MSIL_DURING_DIAGNOSTICS
2201 if (!NGENImagesAllowed())
2203 GetFile()->SetCannotUseNativeImage();
2205 if (GetFile()->HasNativeImage())
2206 GetFile()->ClearNativeImage();
2210 #endif // FEATURE_TREAT_NI_AS_MSIL_DURING_DIAGNOSTICS
2213 #ifdef FEATURE_FUSION
2214 DomainAssembly * pDomainAssembly = GetDomainAssembly();
2215 if (pDomainAssembly->GetSecurityDescriptor()->HasAdditionalEvidence() ||
2216 !(pDomainAssembly->GetFile()->IsContextLoad() ||
2217 pDomainAssembly->GetFile()->HasHostAssembly()))
2219 m_pFile->SetCannotUseNativeImage();
2221 #endif //FEATURE_FUSION
2223 ClearNativeImageStress();
2225 // We already have an image - we just need to do a few more checks
2227 if (GetFile()->HasNativeImage())
2230 if (g_pConfig->ForbidZap(GetSimpleName()))
2233 StackScratchBuffer scratch;
2234 sbuf.Printf("COMPlus_NgenBind_ZapForbid violation: %s.", GetSimpleName());
2235 DbgAssertDialog(__FILE__, __LINE__, sbuf.GetUTF8(scratch));
2239 ReleaseHolder<PEImage> pNativeImage = GetFile()->GetNativeImageWithRef();
2241 if(!IsSystem() && !SystemDomain::System()->SystemFile()->HasNativeImage() && !CLRConfig::GetConfigValue(CLRConfig::INTERNAL_NgenAllowMscorlibSoftbind))
2243 m_dwReasonForRejectingNativeImage = ReasonForRejectingNativeImage_MscorlibNotNative;
2244 STRESS_LOG2(LF_ZAP,LL_INFO100,"Rejecting native file %p, because mscolib has not NI - reason 0x%x\n",pNativeImage.GetValue(),m_dwReasonForRejectingNativeImage);
2245 ExternalLog(LL_ERROR, "Rejecting native image because mscorlib does not have native image");
2246 #ifdef FEATURE_FUSION
2248 GetFile()->ETWTraceLogMessage(ETW::BinderLog::BinderStructs::NGEN_BIND_SYSTEM_ASSEMBLY_NATIVEIMAGE_NOT_AVAILABLE, NULL);
2250 GetFile()->ClearNativeImage();
2252 #ifdef FEATURE_WINDOWSPHONE
2253 // On Phone, always through exceptions when we throw the NI out
2254 ThrowHR(CLR_E_BIND_SYS_ASM_NI_MISSING);
2258 if (!CheckZapSecurity(pNativeImage))
2260 m_dwReasonForRejectingNativeImage = ReasonForRejectingNativeImage_FailedSecurityCheck;
2261 STRESS_LOG2(LF_ZAP,LL_INFO100,"Rejecting native file %p, because security check failed - reason 0x%x\n",pNativeImage.GetValue(),m_dwReasonForRejectingNativeImage);
2262 ExternalLog(LL_ERROR, "Rejecting native image because it failed the security check. "
2263 "The assembly's permissions must have changed since the time it was ngenned, "
2264 "or it is running with a different security context.");
2266 #ifdef FEATURE_FUSION
2268 GetFile()->ETWTraceLogMessage(ETW::BinderLog::BinderStructs::NGEN_BIND_ASSEMBLY_HAS_DIFFERENT_GRANT, NULL);
2270 GetFile()->ClearNativeImage();
2272 #ifdef FEATURE_WINDOWSPHONE
2273 // On Phone, always through exceptions when we throw the NI out
2274 ThrowHR(CLR_E_BIND_NI_SECURITY_FAILURE);
2278 else if (!CheckZapDependencyIdentities(pNativeImage))
2280 m_dwReasonForRejectingNativeImage = ReasonForRejectingNativeImage_DependencyIdentityMismatch;
2281 STRESS_LOG2(LF_ZAP,LL_INFO100,"Rejecting native file %p, because dependency identity mismatch - reason 0x%x\n",pNativeImage.GetValue(),m_dwReasonForRejectingNativeImage);
2282 ExternalLog(LL_ERROR, "Rejecting native image because of identity mismatch "
2283 "with one or more of its assembly dependencies. The assembly needs "
2284 "to be ngenned again");
2286 #ifdef FEATURE_FUSION
2288 GetFile()->ETWTraceLogMessage(ETW::BinderLog::BinderStructs::NGEN_BIND_DEPENDENCY_HAS_DIFFERENT_IDENTITY, NULL);
2290 GetFile()->ClearNativeImage();
2292 #ifdef FEATURE_WINDOWSPHONE
2293 // On Phone, always through exceptions when we throw the NI out
2294 ThrowHR(CLR_E_BIND_NI_DEP_IDENTITY_MISMATCH);
2300 // We can only use a native image for a single Module. If this is a domain-bound
2301 // load, we know that this means only a single load will use this image, so we can just
2302 // flag it as in use.
2304 // If on the other hand, we are going to be domain neutral, we may have many loads use
2305 // the same native image. Still, we only want to allow the native image to be used
2306 // by loads which are going to end up with the same Module. So, we have to effectively
2307 // eagerly compute whether that will be the case eagerly, now. To enable this computation,
2308 // we store the binding closure in the image.
2310 Module * pNativeModule = pNativeImage->GetLoadedLayout()->GetPersistedModuleImage();
2311 EnsureWritablePages(pNativeModule);
2312 PEFile ** ppNativeFile = (PEFile **) (PBYTE(pNativeModule) + Module::GetFileOffset());
2313 BOOL bExpectedToBeShared= ShouldLoadDomainNeutral();
2314 if (!bExpectedToBeShared)
2316 GetFile()->SetNativeImageUsedExclusively();
2318 #ifdef FEATURE_FUSION
2323 GetFile()->SetNativeImageClosure(GetAssemblyBindingClosure(LEVEL_STARTING));
2326 #endif //FEATURE_FUSION
2328 PEAssembly * pFile = (PEAssembly *)FastInterlockCompareExchangePointer((void **)ppNativeFile, (void *)GetFile(), (void *)NULL);
2329 STRESS_LOG3(LF_ZAP,LL_INFO100,"Attempted to set new native file %p, old file was %p, location in the image=%p\n",GetFile(),pFile,ppNativeFile);
2330 if (pFile!=NULL && !IsSystem() &&
2332 ( !bExpectedToBeShared ||
2333 pFile == PEFile::Dummy() ||
2334 pFile->IsNativeImageUsedExclusively() ||
2335 #ifdef FEATURE_FUSION
2336 !pFile->HasEqualNativeClosure(this) ||
2337 #endif //FEATURE_FUSION
2338 !(GetFile()->GetPath().Equals(pFile->GetPath())))
2342 // The non-shareable native image has already been used in this process by another Module.
2343 // We have to abandon the native image. (Note that it isn't enough to
2344 // just abandon the preload image, since the code in the file will
2345 // reference the image directly).
2346 m_dwReasonForRejectingNativeImage = ReasonForRejectingNativeImage_CannotShareNiAssemblyNotDomainNeutral;
2347 STRESS_LOG3(LF_ZAP,LL_INFO100,"Rejecting native file %p, because it is already used by file %p - reason 0x%x\n",GetFile(),pFile,m_dwReasonForRejectingNativeImage);
2349 ExternalLog(LL_WARNING, "ZAP: An ngen image of an assembly which "
2350 "is not loaded as domain-neutral cannot be used in multiple appdomains "
2351 "- abandoning ngen image. The assembly will be JIT-compiled in "
2352 "the second appdomain. See System.LoaderOptimization.MultiDomain "
2353 "for information about domain-neutral loading.");
2354 #ifdef FEATURE_FUSION
2356 GetFile()->ETWTraceLogMessage(ETW::BinderLog::BinderStructs::NGEN_BIND_ASSEMBLY_NOT_DOMAIN_NEUTRAL, NULL);
2358 GetFile()->ClearNativeImage();
2360 // We only support a (non-shared) native image to be used from a single
2361 // AppDomain. Its not obvious if this is an implementation restriction,
2362 // or if this should fail DomainFile::CheckZapRequired().
2363 // We err on the side of conservativeness, so that multi-domain tests
2364 // do not blow up in CheckZapRequired()
2365 GetFile()->SetCannotUseNativeImage();
2369 //If we are the first and others can reuse us, we cannot go away
2370 if ((pFile == NULL) && (!GetFile()->IsNativeImageUsedExclusively()))
2371 GetFile()->AddRef();
2373 LOG((LF_ZAP, LL_INFO100, "ZAP: Found a candidate native image for %s\n", GetSimpleName()));
2378 if (!GetFile()->HasNativeImage())
2381 // Verify that the IL image is consistent with the NGen images loaded into appdomain
2385 spec.InitializeSpec(GetFile());
2388 GetFile()->GetMVID(&mvid);
2390 GetAppDomain()->CheckForMismatchedNativeImages(&spec, &mvid);
2395 #endif // FEATURE_PREJIT
2397 BOOL DomainAssembly::ShouldLoadDomainNeutral()
2399 STANDARD_VM_CONTRACT;
2401 if (m_fCalculatedShouldLoadDomainNeutral)
2402 return m_fShouldLoadDomainNeutral;
2404 m_fShouldLoadDomainNeutral = !!ShouldLoadDomainNeutralHelper();
2405 m_fCalculatedShouldLoadDomainNeutral = true;
2407 return m_fShouldLoadDomainNeutral;
2410 BOOL DomainAssembly::ShouldLoadDomainNeutralHelper()
2412 STANDARD_VM_CONTRACT;
2414 #ifdef FEATURE_LOADER_OPTIMIZATION
2420 if (IsSingleAppDomain())
2423 if (GetFile()->IsDynamic())
2426 #ifdef FEATURE_COMINTEROP
2427 if (GetFile()->IsWindowsRuntime())
2431 switch(this->GetAppDomain()->GetSharePolicy()) {
2432 case AppDomain::SHARE_POLICY_ALWAYS:
2435 case AppDomain::SHARE_POLICY_GAC:
2438 case AppDomain::SHARE_POLICY_NEVER:
2441 case AppDomain::SHARE_POLICY_UNSPECIFIED:
2442 case AppDomain::SHARE_POLICY_COUNT:
2446 return FALSE; // No meaning in doing costly closure walk for CoreCLR.
2449 #else // FEATURE_LOADER_OPTIMIZATION
2451 #endif // FEATURE_LOADER_OPTIMIZATION
2454 BOOL DomainAssembly::ShouldSkipPolicyResolution()
2456 LIMITED_METHOD_CONTRACT;
2457 return m_fSkipPolicyResolution;
2461 #if defined(FEATURE_LOADER_OPTIMIZATION) && defined(FEATURE_FUSION)
2463 // Returns TRUE if the attempt to steal ownership of the native image succeeded, or if there are other
2464 // reasons for retrying load of the native image in the current appdomain.
2466 // Returns FALSE if the native image should be rejected in the current appdomain.
2468 static BOOL TryToStealSharedNativeImageOwnership(PEFile ** ppNativeImage, PEFile * pNativeFile, PEFile * pFile)
2470 STANDARD_VM_CONTRACT;
2472 if (pNativeFile == PEFile::Dummy())
2474 // Nothing to steal anymore. Loading of the native image failed elsewhere.
2478 _ASSERTE(!pNativeFile->IsNativeImageUsedExclusively());
2479 _ASSERTE(!pFile->IsNativeImageUsedExclusively());
2481 SharedDomain * pSharedDomain = SharedDomain::GetDomain();
2483 // Take the lock so that nobody steals or creates Assembly object for this native image while we are stealing it
2484 SharedFileLockHolder pNativeFileLock(pSharedDomain, pNativeFile, TRUE);
2486 if (pNativeFile != VolatileLoad(ppNativeImage))
2488 // The ownership changed before we got a chance. Retry.
2492 SharedAssemblyLocator locator(pNativeFile->AsAssembly(), SharedAssemblyLocator::PEASSEMBLYEXACT);
2493 if (pSharedDomain->FindShareableAssembly(&locator))
2495 // Another shared assembly (with different binding closure) uses this image, therefore we cannot use it
2499 BOOL success = InterlockedCompareExchangeT(ppNativeImage, pFile, pNativeFile) == pNativeFile;
2501 // If others can reuse us, we cannot go away
2505 STRESS_LOG3(LF_ZAP,LL_INFO100,"Attempt to steal ownership from native file %p by %p success %d\n", pNativeFile, pFile, success);
2509 #endif // FEATURE_LOADER_OPTIMIZATION && FEATURE_FUSION
2511 // This is where the decision whether an assembly is DomainNeutral (shared) nor not is made.
2512 void DomainAssembly::Allocate()
2518 INJECT_FAULT(COMPlusThrowOM(););
2522 // Make sure the security system is happy with this assembly being loaded into the domain
2523 GetSecurityDescriptor()->CheckAllowAssemblyLoad();
2525 AllocMemTracker amTracker;
2526 AllocMemTracker * pamTracker = &amTracker;
2528 Assembly * pAssembly = m_pAssembly;
2530 if (pAssembly==NULL)
2532 //! If you decide to remove "if" do not remove this brace: order is important here - in the case of an exception,
2533 //! the Assembly holder must destruct before the AllocMemTracker declared above.
2535 NewHolder<Assembly> assemblyHolder(NULL);
2537 // Determine whether we are supposed to load the assembly as a shared
2538 // assembly or into the app domain.
2539 if (ShouldLoadDomainNeutral())
2542 #ifdef FEATURE_LOADER_OPTIMIZATION
2544 #ifdef FEATURE_FUSION
2548 // Try to find an existing shared version of the assembly which
2549 // is compatible with our domain.
2551 SharedDomain * pSharedDomain = SharedDomain::GetDomain();
2553 SIZE_T nInitialShareableAssemblyCount = pSharedDomain->GetShareableAssemblyCount();
2554 DWORD dwSwitchCount = 0;
2556 SharedFileLockHolder pFileLock(pSharedDomain, GetFile(), FALSE);
2560 pAssembly=SystemDomain::SystemAssembly();
2564 SharedAssemblyLocator locator(this);
2565 pAssembly = pSharedDomain->FindShareableAssembly(&locator);
2567 if (pAssembly == NULL)
2569 pFileLock.Acquire();
2570 pAssembly = pSharedDomain->FindShareableAssembly(&locator);
2574 if (pAssembly == NULL)
2576 #ifdef FEATURE_FUSION
2577 // Final verification that we can use the ngen image.
2579 // code:DomainAssembly::FindNativeImage checks the binding closures before declaring the native image as shareable candidate,
2580 // but the ultimate decisions about sharing happens inside code:Assembly::CanBeShared called from FindShareableAssembly above.
2581 // code:Assembly::CanBeShared checks more conditions than just binding closures. In particular, it also checks whether AssemblyResolve
2582 // event resolves any missing dependencies found in the binding closure - the assembly cannot be shared if it is the case.
2583 // The end result is that same ngen image can get here in multiple domains in parallel, but it may not be shareable between all of them.
2585 // We reconcile this conflict by checking whether there is somebody else conflicting with us. If it is, we will try to steal
2586 // the ownership of the native image from the other guy and retry. The retry logic is required to prevent a perfectly valid
2587 // native image being dropped on the floor just because of multiple appdomains raced to load it.
2589 ReleaseHolder<PEImage> pNativeImage = GetFile()->GetNativeImageWithRef();
2590 if ((pNativeImage != NULL) && (pNativeImage->GetLoadedLayout() != NULL))
2592 Module * pNativeModule = pNativeImage->GetLoadedLayout()->GetPersistedModuleImage();
2593 if (pNativeModule != NULL)
2595 // The owner of the native module was set thread-safe in code:DomainAssembly::FindNativeImage
2596 // However the final decision if we can share the native image is done in this function (see usage of code:FindShareableAssembly above)
2597 PEFile ** ppNativeFile = (PEFile **) (PBYTE(pNativeModule) + Module::GetFileOffset());
2598 PEFile * pNativeFile = VolatileLoad(ppNativeFile);
2599 if (pNativeFile != GetFile())
2601 pFileLock.Release();
2603 // Ensures that multiple threads won't fight with each other indefinitely
2604 __SwitchToThread(0, ++dwSwitchCount);
2606 if (!TryToStealSharedNativeImageOwnership(ppNativeFile, pNativeFile, GetFile()))
2608 // If a shared assembly got loaded in the mean time, retry all lookups again
2609 if (pSharedDomain->GetShareableAssemblyCount() != nInitialShareableAssemblyCount)
2612 m_dwReasonForRejectingNativeImage = ReasonForRejectingNativeImage_NiAlreadyUsedInAnotherSharedAssembly;
2613 STRESS_LOG3(LF_ZAP,LL_INFO100,"Rejecting native file %p, because it is already used by shared file %p - reason 0x%x\n",GetFile(),pNativeFile,m_dwReasonForRejectingNativeImage);
2614 GetFile()->ClearNativeImage();
2615 GetFile()->SetCannotUseNativeImage();
2623 #endif // FEATURE_FUSION
2625 // We can now rely on the fact that our MDImport will not change so we can stop refcounting it.
2626 GetFile()->MakeMDImportPersistent();
2628 // Go ahead and create new shared version of the assembly if possible
2629 // <TODO> We will need to pass a valid OBJECREF* here in the future when we implement SCU </TODO>
2630 assemblyHolder = pAssembly = Assembly::Create(pSharedDomain, GetFile(), GetDebuggerInfoBits(), FALSE, pamTracker, NULL);
2632 if (MissingDependenciesCheckDone())
2633 pAssembly->SetMissingDependenciesCheckDone();
2635 // Compute the closure assembly dependencies
2636 // of the code & layout of given assembly.
2638 // An assembly has direct dependencies listed in its manifest.
2640 // We do not in general also have all of those dependencies' dependencies in the manifest.
2641 // After all, we may be only using a small portion of the assembly.
2643 // However, since all dependent assemblies must also be shared (so that
2644 // the shared data in this assembly can refer to it), we are in
2645 // effect forced to behave as though we do have all of their dependencies.
2646 // This is because the resulting shared assembly that we will depend on
2647 // DOES have those dependencies, but we won't be able to validly share that
2648 // assembly unless we match all of ITS dependencies, too.
2649 #ifdef FEATURE_FUSION
2650 if ((this->GetAppDomain()->GetFusionContext() != NULL) && !IsSystem())
2652 IAssemblyBindingClosure* pClosure = GetAssemblyBindingClosure(LEVEL_STARTING);
2653 pAssembly->SetBindingClosure(pClosure);
2655 #endif // FEATURE_FUSION
2656 // Sets the tenured bit atomically with the hash insert.
2657 pSharedDomain->AddShareableAssembly(pAssembly);
2659 #else // FEATURE_LOADER_OPTIMIZATION
2660 _ASSERTE(IsSystem());
2661 if (SystemDomain::SystemAssembly())
2663 pAssembly = SystemDomain::SystemAssembly();
2667 // We can now rely on the fact that our MDImport will not change so we can stop refcounting it.
2668 GetFile()->MakeMDImportPersistent();
2670 // <TODO> We will need to pass a valid OBJECTREF* here in the future when we implement SCU </TODO>
2671 SharedDomain * pSharedDomain = SharedDomain::GetDomain();
2672 assemblyHolder = pAssembly = Assembly::Create(pSharedDomain, GetFile(), GetDebuggerInfoBits(), FALSE, pamTracker, NULL);
2673 pAssembly->SetIsTenured();
2675 #endif // FEATURE_LOADER_OPTIMIZATION
2679 // We can now rely on the fact that our MDImport will not change so we can stop refcounting it.
2680 GetFile()->MakeMDImportPersistent();
2682 // <TODO> We will need to pass a valid OBJECTREF* here in the future when we implement SCU </TODO>
2683 assemblyHolder = pAssembly = Assembly::Create(m_pDomain, GetFile(), GetDebuggerInfoBits(), FALSE, pamTracker, NULL);
2684 assemblyHolder->SetIsTenured();
2688 //@todo! This is too early to be calling SuppressRelease. The right place to call it is below after
2689 // the CANNOTTHROWCOMPLUSEXCEPTION. Right now, we have to do this to unblock OOM injection testing quickly
2690 // as doing the right thing is nontrivial.
2691 pamTracker->SuppressRelease();
2692 assemblyHolder.SuppressRelease();
2695 #ifdef FEATURE_COMINTEROP
2696 // If we are in an AppX process we should prevent loading of PIA in the AppDomain.
2697 // This will ensure that we do not run into any compatibility issues in case a type has both a co-Class and a Winrt Class
2698 if (AppX::IsAppXProcess() && pAssembly->IsPIA())
2700 COMPlusThrow(kNotSupportedException, W("NotSupported_PIAInAppxProcess"));
2704 SetAssembly(pAssembly);
2706 #ifdef FEATURE_PREJIT
2707 BOOL fInsertIntoAssemblySpecBindingCache = TRUE;
2709 // Insert AssemblyDef details into AssemblySpecBindingCache if appropriate
2711 #ifdef FEATURE_FUSION
2712 fInsertIntoAssemblySpecBindingCache = GetFile()->GetLoadContext() == LOADCTX_TYPE_DEFAULT;
2715 #if defined(FEATURE_APPX_BINDER)
2716 fInsertIntoAssemblySpecBindingCache = fInsertIntoAssemblySpecBindingCache && !GetFile()->HasHostAssembly();
2718 fInsertIntoAssemblySpecBindingCache = fInsertIntoAssemblySpecBindingCache && GetFile()->CanUseWithBindingCache();
2721 if (fInsertIntoAssemblySpecBindingCache)
2723 AssemblySpec specAssemblyDef;
2724 specAssemblyDef.InitializeSpec(GetFile());
2725 if (specAssemblyDef.IsStrongNamed() && specAssemblyDef.HasPublicKey())
2727 specAssemblyDef.ConvertPublicKeyToToken();
2729 m_pDomain->AddAssemblyToCache(&specAssemblyDef, this);
2732 } // DomainAssembly::Allocate
2734 void DomainAssembly::DeliverAsyncEvents()
2746 OVERRIDE_LOAD_LEVEL_LIMIT(FILE_ACTIVE);
2747 m_pDomain->RaiseLoadingAssemblyEvent(this);
2752 void DomainAssembly::DeliverSyncEvents()
2761 GetCurrentModule()->NotifyEtwLoadFinished(S_OK);
2763 // We may be notified from inside the loader lock if we are delivering IJW events, so keep track.
2764 #ifdef PROFILING_SUPPORTED
2765 if (!IsProfilerNotified())
2767 SetProfilerNotified();
2768 GetCurrentModule()->NotifyProfilerLoadFinished(S_OK);
2772 #ifdef DEBUGGING_SUPPORTED
2774 if (!IsDebuggerNotified())
2776 SetShouldNotifyDebugger();
2778 if (m_pDomain->IsDebuggerAttached())
2780 // If this is the first assembly in the AppDomain, it may be possible to get a better name than the
2782 CollectibleAssemblyHolder<DomainAssembly *> pDomainAssembly;
2783 m_pDomain->m_Assemblies.Get(m_pDomain, 0, pDomainAssembly.This());
2784 if ((pDomainAssembly == this) && !m_pDomain->IsUserCreatedDomain())
2785 m_pDomain->ResetFriendlyName();
2788 // Still work to do even if no debugger is attached.
2789 NotifyDebuggerLoad(ATTACH_ASSEMBLY_LOAD, FALSE);
2792 #endif // DEBUGGING_SUPPORTED
2793 } // DomainAssembly::DeliverSyncEvents
2796 // The enum for dwLocation from managed code:
2797 public enum ResourceLocation
2800 ContainedInAnotherAssembly = 2,
2801 ContainedInManifestFile = 4
2805 BOOL DomainAssembly::GetResource(LPCSTR szName, DWORD *cbResource,
2806 PBYTE *pbInMemoryResource, DomainAssembly** pAssemblyRef,
2807 LPCSTR *szFileName, DWORD *dwLocation,
2808 StackCrawlMark *pStackMark, BOOL fSkipSecurityCheck,
2809 BOOL fSkipRaiseResolveEvent)
2816 INJECT_FAULT(COMPlusThrowOM(););
2820 return GetFile()->GetResource( szName,
2828 fSkipRaiseResolveEvent,
2833 #ifdef FEATURE_MULTIMODULE_ASSEMBLIES
2834 BOOL DomainAssembly::GetModuleResource(mdFile mdResFile, LPCSTR szResName,
2835 DWORD *cbResource, PBYTE *pbInMemoryResource,
2836 LPCSTR *szFileName, DWORD *dwLocation,
2837 BOOL fIsPublic, StackCrawlMark *pStackMark,
2838 BOOL fSkipSecurityCheck)
2845 INJECT_FAULT(COMPlusThrowOM(););
2851 DomainFile *pModule = NULL;
2854 if (! ((TypeFromToken(mdResFile) == mdtFile) &&
2855 GetMDImport()->IsValidToken(mdResFile)) )
2857 ThrowHR(COR_E_BADIMAGEFORMAT, BFA_INVALID_FILE_TOKEN);
2860 IfFailThrow(GetMDImport()->GetFileProps(
2867 if (IsFfContainsMetaData(dwFlags))
2869 // The resource is embedded in a manifest-containing file.
2870 mdManifestResource mdResource;
2872 DWORD dwResourceFlags;
2874 Module *pContainerModule = GetCurrentModule();
2875 // Use the real assembly with a rid map if possible
2876 if (pContainerModule != NULL)
2877 pModule = pContainerModule->LoadModule(m_pDomain, mdResFile, FALSE);
2880 PEModuleHolder pFile(GetAssembly()->LoadModule_AddRef(mdResFile, FALSE));
2881 pModule = m_pDomain->LoadDomainModule(this, pFile, FILE_LOADED);
2884 if (FAILED(pModule->GetMDImport()->FindManifestResourceByName(szResName,
2888 IfFailThrow(pModule->GetMDImport()->GetManifestResourceProps(
2895 if (mdLinkRef != mdFileNil)
2897 ThrowHR(COR_E_BADIMAGEFORMAT, BFA_CANT_GET_LINKREF);
2899 fIsPublic = IsMrPublic(dwResourceFlags);
2902 #ifndef CROSSGEN_COMPILE
2903 if (!fIsPublic && pStackMark && !fSkipSecurityCheck)
2905 Assembly *pCallersAssembly = SystemDomain::GetCallersAssembly(pStackMark);
2906 if (pCallersAssembly && // full trust for interop
2907 (!pCallersAssembly->GetManifestFile()->Equals(GetFile())))
2909 RefSecContext sCtx(AccessCheckOptions::kMemberAccess);
2911 AccessCheckOptions accessCheckOptions(
2912 AccessCheckOptions::kMemberAccess, /*accessCheckType*/
2913 NULL, /*pAccessContext*/
2914 FALSE, /*throwIfTargetIsInaccessible*/
2915 (MethodTable *) NULL /*pTargetMT*/
2918 // SL: return TRUE only if the caller is critical
2919 // Desktop: return TRUE only if demanding MemberAccess succeeds
2920 if (!accessCheckOptions.DemandMemberAccessOrFail(&sCtx, NULL, TRUE /*visibilityCheck*/))
2924 #endif // CROSSGEN_COMPILE
2926 if (IsFfContainsMetaData(dwFlags)) {
2928 *dwLocation = *dwLocation | 1; // ResourceLocation.embedded
2929 *szFileName = szName;
2933 pModule->GetFile()->GetEmbeddedResource(dwOffset, cbResource,
2934 pbInMemoryResource);
2939 // The resource is linked (it's in its own file)
2941 *szFileName = szName;
2945 Module *pContainerModule = GetCurrentModule();
2947 // Use the real assembly with a rid map if possible
2948 if (pContainerModule != NULL)
2949 pModule = pContainerModule->LoadModule(m_pDomain, mdResFile);
2952 PEModuleHolder pFile(GetAssembly()->LoadModule_AddRef(mdResFile, TRUE));
2953 pModule = m_pDomain->LoadDomainModule(this, pFile, FILE_LOADED);
2957 const void *contents = pModule->GetFile()->GetManagedFileContents(&size);
2959 *pbInMemoryResource = (BYTE *) contents;
2964 #endif // FEATURE_MULTIMODULE_ASSEMBLIES
2966 #ifdef FEATURE_PREJIT
2968 // --------------------------------------------------------------------------------
2969 // Remember the timestamp of the CLR DLLs used to compile the ngen image.
2970 // These will be checked at runtime by PEFile::CheckNativeImageTimeStamp().
2973 void GetTimeStampsForNativeImage(CORCOMPILE_VERSION_INFO * pNativeVersionInfo)
2978 PRECONDITION(::GetAppDomain()->IsCompilationDomain());
2982 // Do not store runtime timestamps into NGen image for cross-platform NGen determinism
2986 // Which processor should ngen target?
2987 // This is needed when ngen wants to target for "reach" if the ngen images will be
2988 // used on other machines (the Operating System or the OEM build lab can do this).
2989 // It can also be used to reduce the testing matrix
2991 void GetNGenCpuInfo(CORINFO_CPU * cpuInfo)
2993 LIMITED_METHOD_CONTRACT;
2997 static CORINFO_CPU ngenCpuInfo =
2999 (CPU_X86_PENTIUM_PRO << 8), // dwCPUType
3000 0x00000000, // dwFeatures
3001 0 // dwExtendedFeatures
3004 // We always generate P3-compatible code on CoreCLR
3005 *cpuInfo = ngenCpuInfo;
3007 #else // _TARGET_X86_
3008 cpuInfo->dwCPUType = 0;
3009 cpuInfo->dwFeatures = 0;
3010 cpuInfo->dwExtendedFeatures = 0;
3011 #endif // _TARGET_X86_
3014 // --------------------------------------------------------------------------------
3016 void DomainAssembly::GetCurrentVersionInfo(CORCOMPILE_VERSION_INFO *pNativeVersionInfo)
3025 // Clear memory so that we won't write random data into the zapped file
3026 ZeroMemory(pNativeVersionInfo, sizeof(CORCOMPILE_VERSION_INFO));
3028 // Pick up any compilation directives for code flavor
3030 BOOL fForceDebug, fForceProfiling, fForceInstrument;
3031 SystemDomain::GetCompilationOverrides(&fForceDebug,
3035 OSVERSIONINFOW osInfo;
3036 osInfo.dwOSVersionInfoSize = sizeof(osInfo);
3037 if (!GetOSVersion(&osInfo))
3038 _ASSERTE(!"GetOSVersion failed");
3040 _ASSERTE(osInfo.dwMajorVersion < 999);
3041 _ASSERTE(osInfo.dwMinorVersion < 999);
3042 pNativeVersionInfo->wOSPlatformID = (WORD) osInfo.dwPlatformId;
3044 // The native images should be OS-version agnostic. Do not store the actual OS version for determinism.
3045 // pNativeVersionInfo->wOSMajorVersion = (WORD) osInfo.dwMajorVersion;
3046 pNativeVersionInfo->wOSMajorVersion = 4;
3048 pNativeVersionInfo->wMachine = IMAGE_FILE_MACHINE_NATIVE_NI;
3050 pNativeVersionInfo->wVersionMajor = VER_MAJORVERSION;
3051 pNativeVersionInfo->wVersionMinor = VER_MINORVERSION;
3052 pNativeVersionInfo->wVersionBuildNumber = VER_PRODUCTBUILD;
3053 pNativeVersionInfo->wVersionPrivateBuildNumber = VER_PRODUCTBUILD_QFE;
3055 GetNGenCpuInfo(&pNativeVersionInfo->cpuInfo);
3058 pNativeVersionInfo->wBuild = CORCOMPILE_BUILD_CHECKED;
3060 pNativeVersionInfo->wBuild = CORCOMPILE_BUILD_FREE;
3063 #ifdef DEBUGGING_SUPPORTED
3064 if (fForceDebug || !CORDebuggerAllowJITOpts(GetDebuggerInfoBits()))
3066 pNativeVersionInfo->wCodegenFlags |= CORCOMPILE_CODEGEN_DEBUGGING;
3067 pNativeVersionInfo->wConfigFlags |= CORCOMPILE_CONFIG_DEBUG;
3070 #endif // DEBUGGING_SUPPORTED
3072 pNativeVersionInfo->wConfigFlags |= CORCOMPILE_CONFIG_DEBUG_NONE;
3075 #if defined (PROFILING_SUPPORTED_DATA) || defined(PROFILING_SUPPORTED)
3076 if (fForceProfiling || CORProfilerUseProfileImages())
3078 pNativeVersionInfo->wCodegenFlags |= CORCOMPILE_CODEGEN_PROFILING;
3079 pNativeVersionInfo->wConfigFlags |= CORCOMPILE_CONFIG_PROFILING;
3080 #ifdef DEBUGGING_SUPPORTED
3081 // Note that we have hardwired profiling to also imply optimized debugging
3082 // info. This cuts down on one permutation of prejit files.
3083 pNativeVersionInfo->wCodegenFlags &= ~CORCOMPILE_CODEGEN_DEBUGGING;
3084 pNativeVersionInfo->wConfigFlags &= ~(CORCOMPILE_CONFIG_DEBUG|
3085 CORCOMPILE_CONFIG_DEBUG_DEFAULT);
3086 pNativeVersionInfo->wConfigFlags |= CORCOMPILE_CONFIG_DEBUG_NONE;
3087 #endif // DEBUGGING_SUPPORTED
3090 #endif // PROFILING_SUPPORTED_DATA || PROFILING_SUPPORTED
3092 pNativeVersionInfo->wConfigFlags |= CORCOMPILE_CONFIG_PROFILING_NONE;
3095 #ifdef DEBUGGING_SUPPORTED
3097 // Note the default assembly flags (from the custom attributes & INI file) , so we can
3098 // set determine whether or not the current settings
3099 // match the "default" setting or not.
3101 // Note that the INI file settings are considered a part of the
3102 // assembly, even though they could theoretically change between
3103 // ngen time and runtime. It is just too expensive and awkward to
3104 // look up the INI file before binding to the native image at
3105 // runtime, so we effectively snapshot it at ngen time.
3107 DWORD defaultFlags = ComputeDebuggingConfig();
3109 if (CORDebuggerAllowJITOpts(defaultFlags))
3111 // Default is optimized code
3112 if ((pNativeVersionInfo->wCodegenFlags & CORCOMPILE_CODEGEN_DEBUGGING) == 0)
3113 pNativeVersionInfo->wConfigFlags |= CORCOMPILE_CONFIG_DEBUG_DEFAULT;
3117 // Default is non-optimized debuggable code
3118 if ((pNativeVersionInfo->wCodegenFlags & CORCOMPILE_CODEGEN_DEBUGGING) != 0)
3119 pNativeVersionInfo->wConfigFlags |= CORCOMPILE_CONFIG_DEBUG_DEFAULT;
3122 #endif // DEBUGGING_SUPPORTED
3124 if (fForceInstrument || GetAssembly()->IsInstrumented())
3126 pNativeVersionInfo->wCodegenFlags |= CORCOMPILE_CODEGEN_PROF_INSTRUMENTING;
3127 pNativeVersionInfo->wConfigFlags |= CORCOMPILE_CONFIG_INSTRUMENTATION;
3131 pNativeVersionInfo->wConfigFlags |= CORCOMPILE_CONFIG_INSTRUMENTATION_NONE;
3135 GetTimeStampsForNativeImage(pNativeVersionInfo);
3137 // Store signature of source assembly.
3138 GetOptimizedIdentitySignature(&pNativeVersionInfo->sourceAssembly);
3140 // signature will is hash of the whole file. It is written by zapper.
3141 // IfFailThrow(CoCreateGuid(&pNativeVersionInfo->signature));
3144 void DomainAssembly::GetOptimizedIdentitySignature(CORCOMPILE_ASSEMBLY_SIGNATURE *pSignature)
3152 INJECT_FAULT(COMPlusThrowOM(););
3157 // Write the MVID into the version header.
3161 // If this assembly has skip verification permission, then we store its
3162 // mvid. If at load time the assembly still has skip verification
3163 // permission, then we can base the matches purely on mvid values and
3164 // skip the perf-heavy hashing of the file.
3168 // The reason that we tell IsFullyTrusted to do a quick check
3169 // only is because that allows us make a determination for the most
3170 // common full trust scenarios (local machine) without actually
3171 // resolving policy and bringing in a whole list of assembly
3174 ReleaseHolder<IMDInternalImport> scope (GetFile()->GetMDImportWithRef());
3175 IfFailThrow(scope->GetScopeProps(NULL, &pSignature->mvid));
3177 // Use the NGen image if posssible. IL image does not even have to be present on CoreCLR.
3178 if (GetFile()->HasNativeImage())
3180 PEImageHolder pNativeImage(GetFile()->GetNativeImageWithRef());
3182 CORCOMPILE_VERSION_INFO* pVersionInfo = pNativeImage->GetLoadedLayout()->GetNativeVersionInfo();
3183 pSignature->timeStamp = pVersionInfo->sourceAssembly.timeStamp;
3184 pSignature->ilImageSize = pVersionInfo->sourceAssembly.ilImageSize;
3189 // Write the time stamp
3190 PEImageLayoutHolder ilLayout(GetFile()->GetAnyILWithRef());
3191 pSignature->timeStamp = ilLayout->GetTimeDateStamp();
3192 pSignature->ilImageSize = ilLayout->GetVirtualSize();
3195 BOOL DomainAssembly::CheckZapDependencyIdentities(PEImage *pNativeImage)
3205 spec.InitializeSpec(this->GetFile());
3207 // The assembly spec should have the binding context associated with it
3208 _ASSERTE(spec.GetBindingContext() || spec.IsAssemblySpecForMscorlib());
3210 CORCOMPILE_VERSION_INFO *pVersionInfo = pNativeImage->GetLoadedLayout()->GetNativeVersionInfo();
3212 // Check our own assembly first
3213 GetAppDomain()->CheckForMismatchedNativeImages(&spec, &pVersionInfo->sourceAssembly.mvid);
3215 // Check MVID in metadata against MVID in CORCOMPILE_VERSION_INFO - important when metadata is loaded from IL instead of NI
3216 ReleaseHolder<IMDInternalImport> pImport(this->GetFile()->GetMDImportWithRef());
3218 IfFailThrow(pImport->GetScopeProps(NULL, &mvid));
3219 GetAppDomain()->CheckForMismatchedNativeImages(&spec, &mvid);
3221 // Now Check dependencies
3222 COUNT_T cDependencies;
3223 CORCOMPILE_DEPENDENCY *pDependencies = pNativeImage->GetLoadedLayout()->GetNativeDependencies(&cDependencies);
3224 CORCOMPILE_DEPENDENCY *pDependenciesEnd = pDependencies + cDependencies;
3226 while (pDependencies < pDependenciesEnd)
3228 if (pDependencies->dwAssemblyDef != mdAssemblyRefNil)
3231 name.InitializeSpec(pDependencies->dwAssemblyDef, pNativeImage->GetNativeMDImport(), this);
3233 #if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
3234 if (!name.IsAssemblySpecForMscorlib())
3236 // We just initialized the assembly spec for the NI dependency. This will not have binding context
3237 // associated with it, so set it from that of the parent.
3238 _ASSERTE(!name.GetBindingContext());
3239 ICLRPrivBinder *pParentAssemblyBindingContext = name.GetBindingContextFromParentAssembly(name.GetAppDomain());
3240 _ASSERTE(pParentAssemblyBindingContext);
3241 name.SetBindingContext(pParentAssemblyBindingContext);
3243 #endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
3245 GetAppDomain()->CheckForMismatchedNativeImages(&name, &pDependencies->signAssemblyDef.mvid);
3254 BOOL DomainAssembly::CheckZapSecurity(PEImage *pNativeImage)
3265 #endif // FEATURE_PREJIT
3267 #ifdef FEATURE_CAS_POLICY
3268 void DomainAssembly::InitializeSecurityManager()
3276 INJECT_FAULT(COMPlusThrowOM(););
3280 GetFile()->InitializeSecurityManager();
3282 #endif // FEATURE_CAS_POLICY
3284 #ifdef FEATURE_CAS_POLICY
3285 // Returns security information for the assembly based on the codebase
3286 void DomainAssembly::GetSecurityIdentity(SString &codebase,
3297 PRECONDITION(CheckPointer(pdwZone));
3298 PRECONDITION(CheckPointer(pbUniqueID));
3299 PRECONDITION(CheckPointer(pcbUniqueID));
3303 GetFile()->GetSecurityIdentity(codebase, pdwZone, dwFlags, pbUniqueID, pcbUniqueID);
3305 #endif // FEATURE_CAS_POLICY
3307 #ifdef FEATURE_FUSION
3308 IAssemblyBindingClosure* DomainAssembly::GetAssemblyBindingClosure(WALK_LEVEL level)
3310 CONTRACT(IAssemblyBindingClosure *)
3313 POSTCONDITION(CheckPointer(RETVAL,NULL_OK));
3314 //we could return NULL instead of asserting but hitting code paths that call this for mscorlib is just wasting of cycles anyhow
3315 PRECONDITION(!IsSystem());
3319 INJECT_FAULT(COMPlusThrowOM(););
3323 if (m_pAssemblyBindingClosure == NULL || m_pAssemblyBindingClosure->HasBeenWalked(level) == S_FALSE)
3325 SafeComHolder<IAssemblyBindingClosure> pClosure;
3326 if (this->GetAppDomain()->GetFusionContext() == NULL)
3328 _ASSERTE(IsSystem());
3334 ReleaseHolder<IBindResult> pWinRTBindResult;
3337 if (GetFile()->IsIStream())
3339 pUnk = GetFile()->GetIHostAssembly();
3341 else if (GetFile()->IsWindowsRuntime())
3342 { // It is .winmd file (WinRT assembly)
3343 IfFailThrow(CLRPrivAssemblyWinRT::GetIBindResult(GetFile()->GetHostAssembly(), &pWinRTBindResult));
3344 pUnk = pWinRTBindResult;
3348 pUnk = GetFile()->GetFusionAssembly();
3351 if (m_pAssemblyBindingClosure == NULL)
3353 IfFailThrow(this->GetAppDomain()->GetFusionContext()->GetAssemblyBindingClosure(pUnk, NULL, &pClosure));
3354 if (FastInterlockCompareExchangePointer<IAssemblyBindingClosure*>(&m_pAssemblyBindingClosure, pClosure.GetValue(), NULL) == NULL)
3356 pClosure.SuppressRelease();
3359 IfFailThrow(m_pAssemblyBindingClosure->EnsureWalked(pUnk, this->GetAppDomain()->GetFusionContext(), level));
3361 RETURN m_pAssemblyBindingClosure;
3364 // This is used to determine if the binding closure of the assembly in question is in the GAC. Amongst other uses,
3365 // this is the MULTI_DOMAIN_HOST scenario.
3366 BOOL DomainAssembly::IsClosedInGAC()
3374 INJECT_FAULT(COMPlusThrowOM(););
3381 BOOL fIsWindowsRuntime = GetFile()->IsWindowsRuntime();
3383 if (!GetFile()->IsSourceGAC() && !fIsWindowsRuntime)
3386 // Do a binding closure that will help us determine if all the dependencies are in the GAC or not.
3387 IAssemblyBindingClosure * pClosure = GetAssemblyBindingClosure(LEVEL_GACCHECK);
3388 if (pClosure == NULL)
3391 // Once the closure is complete, determine if the dependencies are closed in the GAC (or not).
3392 HRESULT hr = pClosure->IsAllAssembliesInGAC();
3395 return (hr == S_OK);
3398 BOOL DomainAssembly::MayHaveUnknownDependencies()
3406 INJECT_FAULT(COMPlusThrowOM(););
3413 // Perform the binding closure walk to initialize state that will help us
3414 // determine if we have dependencies that could prevent code-sharing.
3415 IAssemblyBindingClosure * pClosure = GetAssemblyBindingClosure(LEVEL_WINRTCHECK);
3416 if (pClosure == NULL)
3419 HRESULT hr = pClosure->MayHaveUnknownDependencies();
3422 return (hr == S_OK);
3425 #endif // FEATURE_FUSION
3428 // <TODO>@todo Find a better place for these</TODO>
3429 #define DE_CUSTOM_VALUE_NAMESPACE "System.Diagnostics"
3430 #define DE_DEBUGGABLE_ATTRIBUTE_NAME "DebuggableAttribute"
3432 // <TODO>@todo .INI file is a temporary workaround for Beta 1</TODO>
3433 #define DE_INI_FILE_SECTION_NAME W(".NET Framework Debugging Control")
3434 #define DE_INI_FILE_KEY_TRACK_INFO W("GenerateTrackingInfo")
3435 #define DE_INI_FILE_KEY_ALLOW_JIT_OPTS W("AllowOptimize")
3437 DWORD DomainAssembly::ComputeDebuggingConfig()
3443 WRAPPER(GC_TRIGGERS);
3445 INJECT_FAULT(COMPlusThrowOM(););
3449 #ifdef DEBUGGING_SUPPORTED
3450 DWORD dacfFlags = DACF_ALLOW_JIT_OPTS;
3452 if (GetDebuggingOverrides(&dacfFlags))
3454 dacfFlags |= DACF_USER_OVERRIDE;
3458 IfFailThrow(GetDebuggingCustomAttributes(&dacfFlags));
3462 #else // !DEBUGGING_SUPPORTED
3464 #endif // DEBUGGING_SUPPORTED
3467 void DomainAssembly::SetupDebuggingConfig(void)
3473 WRAPPER(GC_TRIGGERS);
3475 INJECT_FAULT(COMPlusThrowOM(););
3479 #ifdef DEBUGGING_SUPPORTED
3480 DWORD dacfFlags = ComputeDebuggingConfig();
3482 SetDebuggerInfoBits((DebuggerAssemblyControlFlags)dacfFlags);
3484 LOG((LF_CORDB, LL_INFO10, "Assembly %S: bits=0x%x\n", GetDebugName(), GetDebuggerInfoBits()));
3485 #endif // DEBUGGING_SUPPORTED
3488 // The format for the (temporary) .INI file is:
3490 // [.NET Framework Debugging Control]
3491 // GenerateTrackingInfo=<n> where n is 0 or 1
3492 // AllowOptimize=<n> where n is 0 or 1
3494 // Where neither x nor y equal INVALID_INI_INT:
3495 #define INVALID_INI_INT (0xFFFF)
3497 bool DomainAssembly::GetDebuggingOverrides(DWORD *pdwFlags)
3505 INJECT_FAULT(COMPlusThrowOM(););
3513 // For right now, we only check to see if the DebuggableAttribute is present - later may add fields/properties to the
3515 HRESULT DomainAssembly::GetDebuggingCustomAttributes(DWORD *pdwFlags)
3521 WRAPPER(GC_TRIGGERS);
3524 PRECONDITION(CheckPointer(pdwFlags));
3530 #ifdef FEATURE_PREJIT
3531 ReleaseHolder<PEImage> pNativeImage=GetFile()->GetNativeImageWithRef();
3534 CORCOMPILE_VERSION_INFO * pVersion = pNativeImage->GetLoadedLayout()->GetNativeVersionInfo();
3535 PREFIX_ASSUME(pVersion != NULL);
3537 WORD codegen = pVersion->wCodegenFlags;
3539 if (codegen & CORCOMPILE_CODEGEN_DEBUGGING)
3541 *pdwFlags &= (~DACF_ALLOW_JIT_OPTS);
3545 *pdwFlags |= DACF_ALLOW_JIT_OPTS;
3550 #endif // FEATURE_PREJIT
3555 ReleaseHolder<IMDInternalImport> mdImport(GetFile()->GetMDImportWithRef());
3556 mdMod = mdImport->GetModuleFromScope();
3557 mdAssembly asTK = TokenFromRid(mdtAssembly, 1);
3559 hr = mdImport->GetCustomAttributeByName(asTK,
3560 DE_CUSTOM_VALUE_NAMESPACE
3561 NAMESPACE_SEPARATOR_STR
3562 DE_DEBUGGABLE_ATTRIBUTE_NAME,
3563 (const void**)&blob,
3566 // If there is no custom value, then there is no entrypoint defined.
3567 if (!(FAILED(hr) || hr == S_FALSE))
3569 // We're expecting a 6 or 8 byte blob:
3571 // 1, 0, enable tracking, disable opts, 0, 0
3572 if ((size == 6) || (size == 8))
3574 if (!((blob[0] == 1) && (blob[1] == 0)))
3576 BAD_FORMAT_NOTHROW_ASSERT(!"Invalid blob format for custom attribute");
3577 return COR_E_BADIMAGEFORMAT;
3582 *pdwFlags |= DACF_OBSOLETE_TRACK_JIT_INFO;
3586 *pdwFlags &= (~DACF_OBSOLETE_TRACK_JIT_INFO);
3591 *pdwFlags |= DACF_IGNORE_PDBS;
3595 *pdwFlags &= (~DACF_IGNORE_PDBS);
3599 // For compatibility, we enable optimizations if the tracking byte is zero,
3600 // even if disable opts is nonzero
3601 if (((blob[2] & 0x1) == 0) || (blob[3] == 0))
3603 *pdwFlags |= DACF_ALLOW_JIT_OPTS;
3607 *pdwFlags &= (~DACF_ALLOW_JIT_OPTS);
3610 LOG((LF_CORDB, LL_INFO10, "Assembly %S: has %s=%d,%d bits = 0x%x\n", GetDebugName(),
3611 DE_DEBUGGABLE_ATTRIBUTE_NAME,
3612 blob[2], blob[3], *pdwFlags));
3620 BOOL DomainAssembly::NotifyDebuggerLoad(int flags, BOOL attaching)
3622 WRAPPER_NO_CONTRACT;
3624 BOOL result = FALSE;
3626 if (!IsVisibleToDebugger())
3629 // Debugger Attach is done totally out-of-process. Does not call code in-proc.
3630 _ASSERTE(!attaching);
3632 // Make sure the debugger has been initialized. See code:Debugger::Startup.
3633 if (g_pDebugInterface == NULL)
3635 _ASSERTE(!CORDebuggerAttached());
3639 // There is still work we need to do even when no debugger is attached.
3641 if (flags & ATTACH_ASSEMBLY_LOAD)
3643 if (ShouldNotifyDebugger())
3645 g_pDebugInterface->LoadAssembly(this);
3650 DomainModuleIterator i = IterateModules(kModIterIncludeLoading);
3653 DomainFile * pDomainFile = i.GetDomainFile();
3654 if(pDomainFile->ShouldNotifyDebugger())
3657 pDomainFile->GetModule()->NotifyDebuggerLoad(this->GetAppDomain(), pDomainFile, flags, attaching);
3660 if( ShouldNotifyDebugger())
3662 result|=m_pModule->NotifyDebuggerLoad(m_pDomain, this, ATTACH_MODULE_LOAD, attaching);
3663 SetDebuggerNotified();
3671 void DomainAssembly::NotifyDebuggerUnload()
3673 LIMITED_METHOD_CONTRACT;
3675 if (!IsVisibleToDebugger())
3678 if (!this->GetAppDomain()->IsDebuggerAttached())
3681 m_fDebuggerUnloadStarted = TRUE;
3683 // Dispatch module unloads for all modules. Debugger is resilient in case we haven't dispatched
3684 // a previous load event (such as if debugger attached after the modules was loaded).
3685 DomainModuleIterator i = IterateModules(kModIterIncludeLoading);
3688 i.GetDomainFile()->GetModule()->NotifyDebuggerUnload(this->GetAppDomain());
3691 g_pDebugInterface->UnloadAssembly(this);
3695 // This will enumerate for static GC refs (but not thread static GC refs)
3697 void DomainAssembly::EnumStaticGCRefs(promote_func* fn, ScanContext* sc)
3706 _ASSERTE(GCHeapUtilities::IsGCInProgress() &&
3707 GCHeapUtilities::IsServerHeap() &&
3708 IsGCSpecialThread());
3710 DomainModuleIterator i = IterateModules(kModIterIncludeLoaded);
3713 DomainFile* pDomainFile = i.GetDomainFile();
3715 if (pDomainFile->IsActive())
3717 // We guarantee that at this point the module has it's DomainLocalModule set up
3718 // , as we create it while we load the module
3719 _ASSERTE(pDomainFile->GetLoadedModule()->GetDomainLocalModule(this->GetAppDomain()));
3720 pDomainFile->GetLoadedModule()->EnumRegularStaticGCRefs(this->GetAppDomain(), fn, sc);
3722 // We current to do not iterate over the ThreadLocalModules that correspond
3723 // to this Module. The GC discovers thread statics through the handle table.
3732 #ifdef FEATURE_MULTIMODULE_ASSEMBLIES
3733 //--------------------------------------------------------------------------------
3735 //--------------------------------------------------------------------------------
3737 DomainModule::DomainModule(AppDomain *pDomain, DomainAssembly *pAssembly, PEFile *pFile)
3738 : DomainFile(pDomain, pFile),
3739 m_pDomainAssembly(pAssembly)
3741 STANDARD_VM_CONTRACT;
3744 DomainModule::~DomainModule()
3746 WRAPPER_NO_CONTRACT;
3749 void DomainModule::SetModule(Module* pModule)
3751 STANDARD_VM_CONTRACT;
3753 UpdatePEFile(pModule->GetFile());
3754 pModule->SetDomainFile(this);
3755 // SetDomainFile can throw and will unwind to DomainModule::Allocate at which
3756 // point pModule->Destruct will be called in the catch handler. if we set
3757 // m_pModule = pModule before the call to SetDomainFile then we can end up with
3758 // a bad m_pModule pointer when SetDomainFile throws. so we set m_pModule IIF
3759 // the call to SetDomainFile succeeds.
3760 m_pModule = pModule;
3763 void DomainModule::Begin()
3765 STANDARD_VM_CONTRACT;
3766 m_pDomainAssembly->AddModule(this);
3769 #ifdef FEATURE_PREJIT
3771 void DomainModule::FindNativeImage()
3773 LIMITED_METHOD_CONTRACT;
3775 // Resource files are never prejitted.
3778 #endif // FEATURE_PREJIT
3781 void DomainModule::Allocate()
3790 // We can now rely on the fact that our MDImport will not change so we can stop refcounting it.
3791 GetFile()->MakeMDImportPersistent();
3793 AllocMemTracker amTracker;
3794 AllocMemTracker *pamTracker = &amTracker;
3796 Assembly *pAssembly = m_pDomainAssembly->GetCurrentAssembly();
3797 Module *pModule = NULL;
3799 if (pAssembly->IsDomainNeutral())
3801 // For shared assemblies, the module may be already in the assembly list, even
3802 // though we haven't loaded it here yet.
3804 pModule = pAssembly->GetManifestModule()->GetModuleIfLoaded(GetToken(),FALSE, TRUE);
3805 if (pModule != NULL)
3812 #ifdef FEATURE_LOADER_OPTIMIZATION
3813 SharedDomain *pSharedDomain = SharedDomain::GetDomain();
3814 SharedFileLockHolder pFileLock(pSharedDomain, GetFile());
3815 #else // FEATURE_LOADER_OPTIMIZATION
3816 _ASSERTE(IsSystem());
3817 #endif // FEATURE_LOADER_OPTIMIZATION
3819 pModule = pAssembly->GetManifestModule()->GetModuleIfLoaded(GetToken(), FALSE, TRUE);
3820 if (pModule != NULL)
3827 pModule = Module::Create(pAssembly, GetToken(), m_pFile, pamTracker);
3831 pAssembly->PrepareModuleForAssembly(pModule, pamTracker);
3832 SetModule(pModule); //@todo: This innocent-looking call looks like a mixture of allocations and publishing code - it probably needs to be split.
3836 //! It's critical we destruct the manifest Module prior to the AllocMemTracker used to initialize it.
3837 //! Otherwise, we will leave dangling pointers inside the Module that Module::Destruct will attempt
3839 pModule->Destruct();
3844 CANNOTTHROWCOMPLUSEXCEPTION();
3847 //Cannot fail after this point.
3848 pamTracker->SuppressRelease();
3849 pModule->SetIsTenured();
3851 pAssembly->PublishModuleIntoAssembly(pModule);
3855 return; // Explicit return to let you know you are NOT welcome to add code after the CANNOTTHROW/FAULT_FORBID expires
3866 pModule = Module::Create(pAssembly, GetToken(), m_pFile, pamTracker);
3869 pAssembly->PrepareModuleForAssembly(pModule, pamTracker);
3870 SetModule(pModule); //@todo: This innocent-looking call looks like a mixture of allocations and publishing code - it probably needs to be split.
3874 //! It's critical we destruct the manifest Module prior to the AllocMemTracker used to initialize it.
3875 //! Otherwise, we will leave dangling pointers inside the Module that Module::Destruct will attempt
3877 pModule->Destruct();
3883 CANNOTTHROWCOMPLUSEXCEPTION();
3886 //Cannot fail after this point.
3887 pamTracker->SuppressRelease();
3888 pModule->SetIsTenured();
3889 pAssembly->PublishModuleIntoAssembly(pModule);
3892 return; // Explicit return to let you know you are NOT welcome to add code after the CANNOTTHROW/FAULT_FORBID expires
3902 void DomainModule::DeliverAsyncEvents()
3904 LIMITED_METHOD_CONTRACT;
3908 void DomainModule::DeliverSyncEvents()
3916 INJECT_FAULT(COMPlusThrowOM(););
3921 GetCurrentModule()->NotifyEtwLoadFinished(S_OK);
3923 #ifdef PROFILING_SUPPORTED
3924 if (!IsProfilerNotified())
3926 SetProfilerNotified();
3927 GetCurrentModule()->NotifyProfilerLoadFinished(S_OK);
3931 #ifdef DEBUGGING_SUPPORTED
3933 if(!IsDebuggerNotified())
3935 SetShouldNotifyDebugger();
3937 // Always give the module a chance to notify the debugger. If no debugger is attached, the
3938 // module can skip out on the notification.
3939 m_pModule->NotifyDebuggerLoad(m_pDomain, this, ATTACH_MODULE_LOAD, FALSE);
3940 SetDebuggerNotified();
3945 #endif // FEATURE_MULTIMODULE_ASSEMBLIES
3947 #endif // #ifndef DACCESS_COMPILE
3949 #ifdef DACCESS_COMPILE
3952 DomainFile::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
3956 //sizeof(DomainFile) == 0x60
3959 // Modules are needed for all minidumps, but they are enumerated elsewhere
3960 // so we don't need to duplicate effort; thus we do noting with m_pModule.
3962 // For MiniDumpNormal, we only want the file name.
3963 if (m_pFile.IsValid())
3965 m_pFile->EnumMemoryRegions(flags);
3968 if (flags != CLRDATA_ENUM_MEM_MINI && flags != CLRDATA_ENUM_MEM_TRIAGE
3969 && m_pDomain.IsValid())
3971 m_pDomain->EnumMemoryRegions(flags, true);
3976 DomainAssembly::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
3980 //sizeof(DomainAssembly) == 0xe0
3982 DomainFile::EnumMemoryRegions(flags);
3984 // For minidumps without full memory, we need to always be able to iterate over m_Modules.
3985 m_Modules.EnumMemoryRegions(flags);
3987 if (flags != CLRDATA_ENUM_MEM_MINI && flags != CLRDATA_ENUM_MEM_TRIAGE)
3989 if (m_pAssembly.IsValid())
3991 m_pAssembly->EnumMemoryRegions(flags);
3996 #ifdef FEATURE_MULTIMODULE_ASSEMBLIES
3998 DomainModule::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
4001 DomainFile::EnumMemoryRegions(flags);
4002 if (m_pDomainAssembly.IsValid())
4004 m_pDomainAssembly->EnumMemoryRegions(flags);
4007 #endif // FEATURE_MULTIMODULE_ASSEMBLIES
4009 #endif // #ifdef DACCESS_COMPILE
4011 #if defined(FEATURE_MIXEDMODE) && !defined(CROSSGEN_COMPILE)
4012 LPVOID DomainFile::GetUMThunk(LPVOID pManagedIp, PCCOR_SIGNATURE pSig, ULONG cSig)
4020 INJECT_FAULT(COMPlusThrowOM());
4021 POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
4026 if (m_pUMThunkHash == NULL)
4028 UMThunkHash *pUMThunkHash = new UMThunkHash(GetModule(), this->GetAppDomain());
4029 if (FastInterlockCompareExchangePointer(&m_pUMThunkHash, pUMThunkHash, NULL) != NULL)
4031 delete pUMThunkHash;
4034 RETURN m_pUMThunkHash->GetUMThunk(pManagedIp, pSig, cSig);
4036 #endif // FEATURE_MIXEDMODE && !CROSSGEN_COMPILE