src/vm/ceeload.cpp
Assembly * Module::GetAssemblyIfLoadedFromNativeAssemblyRefWithRefDefMismatch(mdAssemblyRef kAssemblyRef, BOOL *pfDiscoveredAssemblyRefMatchesTargetDefExactly)
{
    CONTRACT(Assembly *)
    {
        INSTANCE_CHECK;
        NOTHROW;
        GC_NOTRIGGER;
        FORBID_FAULT;
        MODE_ANY;
        POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
    }
    CONTRACT_END;

    _ASSERTE(HasNativeImage());

    Assembly *pAssembly = NULL;
    IMDInternalImport *pImportFoundNativeImage = this->GetNativeAssemblyImport(FALSE);

    if (!pImportFoundNativeImage)
    {
        RETURN NULL;
    }

    if (kAssemblyRef != mdAssemblyRefNil)
    {
        // Scan CORCOMPILE_DEPENDENCIES tables
        PEImageLayout* pNativeLayout = this->GetNativeImage();
        COUNT_T dependencyCount;
        CORCOMPILE_DEPENDENCY *pDependencies = pNativeLayout->GetNativeDependencies(&dependencyCount);

        // Find the assemblyDef that defines the exact target
        mdAssemblyRef foundAssemblyDef = mdAssemblyRefNil;

        for (COUNT_T i = 0; i < dependencyCount; ++i)
        {
            CORCOMPILE_DEPENDENCY* pDependency = &(pDependencies[i]);
            if (pDependency->dwAssemblyRef == kAssemblyRef)
            {
                foundAssemblyDef = pDependency->dwAssemblyDef;
                break;
            }
        }

        // In this case we know there is no assembly redirection involved. Skip any additional work.
        if (kAssemblyRef == foundAssemblyDef)
        {
            *pfDiscoveredAssemblyRefMatchesTargetDefExactly = true;
            RETURN NULL;
        }

        if (foundAssemblyDef != mdAssemblyRefNil)
        {
            // Find out if THIS reference is satisfied
            // Specify fDoNotUtilizeExtraChecks to prevent recursion
            Assembly *pAssemblyCandidate = this->GetAssemblyIfLoaded(foundAssemblyDef, NULL, NULL, pImportFoundNativeImage, TRUE /*fDoNotUtilizeExtraChecks*/); 

            // This extended check is designed only to find assemblies loaded via an AssemblySpecBindingCache based binder. Verify that's what we found.
            if(pAssemblyCandidate != NULL)
            {
                if (!pAssemblyCandidate->GetManifestFile()->HasHostAssembly())
                {
                    pAssembly = pAssemblyCandidate;
                }
                else
                {
                    // This should only happen in the generic instantiation case when multiple threads are racing and
                    // the assembly found is one which we will determine is the wrong assembly.
                    //
                    // We can't assert that (as its possible under stress); however it shouldn't happen in the stack walk or GC case, so we assert in those cases.
                    _ASSERTE("Non-AssemblySpecBindingCache based assembly found with extended search" && !(IsStackWalkerThread() || IsGCThread()) && IsGenericInstantiationLookupCompareThread());
                }
            }
        }
    }

    RETURN pAssembly;
}
// This function, given an AssemblyRef into the ngen generated native metadata section, will find the assembly referenced if
// 1. The Assembly is defined with a different name than the AssemblyRef provides
// 2. The Assembly has reached the stage of being loaded.
// This function is used as a helper function to assist GetAssemblyIfLoaded with its tasks in the conditions
// where GetAssemblyIfLoaded must succeed (or we violate various invariants in the system required for
// correct implementation of GC, Stackwalking, and generic type loading.
This function, given an AssemblyRef into the ngen generated native metadata section, will find the assembly referenced if
1. The Assembly is defined with a different name than the AssemblyRef provides
2. The Assembly has reached the stage of being loaded.
This function is used as a helper function to assist GetAssemblyIfLoaded with its tasks in the conditions
where GetAssemblyIfLoaded must succeed (or we violate various invariants in the system required for
correct implementation of GC, Stackwalking, and generic type loading.
This function given an AssemblyRef into the ngen generated native metadata section will find the assembly referenced if 1 . The Assembly is defined with a different name than the AssemblyRef provides 2 . The Assembly has reached the stage of being loaded . This function is used as a helper function to assist GetAssemblyIfLoaded with its tasks in the conditions where GetAssemblyIfLoaded must succeed ( or we violate various invariants in the system required for correct implementation of GC Stackwalking and generic type loading .
Assembly * Module::GetAssemblyIfLoadedFromNativeAssemblyRefWithRefDefMismatch(mdAssemblyRef kAssemblyRef, BOOL *pfDiscoveredAssemblyRefMatchesTargetDefExactly)
{
    CONTRACT(Assembly *)
    {
        INSTANCE_CHECK;
        NOTHROW;
        GC_NOTRIGGER;
        FORBID_FAULT;
        MODE_ANY;
        POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
    }
    CONTRACT_END;
    _ASSERTE(HasNativeImage());
    Assembly *pAssembly = NULL;
    IMDInternalImport *pImportFoundNativeImage = this->GetNativeAssemblyImport(FALSE);
    if (!pImportFoundNativeImage)
    {
        RETURN NULL;
    }
    if (kAssemblyRef != mdAssemblyRefNil)
    {
        PEImageLayout* pNativeLayout = this->GetNativeImage();
        COUNT_T dependencyCount;
        CORCOMPILE_DEPENDENCY *pDependencies = pNativeLayout->GetNativeDependencies(&dependencyCount);
        mdAssemblyRef foundAssemblyDef = mdAssemblyRefNil;
        for (COUNT_T i = 0; i < dependencyCount; ++i)
        {
            CORCOMPILE_DEPENDENCY* pDependency = &(pDependencies[i]);
            if (pDependency->dwAssemblyRef == kAssemblyRef)
            {
                foundAssemblyDef = pDependency->dwAssemblyDef;
                break;
            }
        }
        if (kAssemblyRef == foundAssemblyDef)
        {
            *pfDiscoveredAssemblyRefMatchesTargetDefExactly = true;
            RETURN NULL;
        }
        if (foundAssemblyDef != mdAssemblyRefNil)
        {
            Assembly *pAssemblyCandidate = this->GetAssemblyIfLoaded(foundAssemblyDef, NULL, NULL, pImportFoundNativeImage, TRUE ); 
            if(pAssemblyCandidate != NULL)
            {
                if (!pAssemblyCandidate->GetManifestFile()->HasHostAssembly())
                {
                    pAssembly = pAssemblyCandidate;
                }
                else
                {
                     We can't assert that (as its possible under stress); however it shouldn't happen in the stack walk or GC case, so we assert in those cases.
                    _ASSERTE("Non-AssemblySpecBindingCache based assembly found with extended search" && !(IsStackWalkerThread() || IsGCThread()) && IsGenericInstantiationLookupCompareThread());
                }
            }
        }
    }
    RETURN pAssembly;
}
Assembly * Module :: GetAssemblyIfLoadedFromNativeAssemblyRefWithRefDefMismatch ( mdAssemblyRef kAssemblyRef , BOOL * pfDiscoveredAssemblyRefMatchesTargetDefExactly ) { CONTRACT ( Assembly * ) { INSTANCE_CHECK ; NOTHROW ; GC_NOTRIGGER ; FORBID_FAULT ; MODE_ANY ; POSTCONDITION ( CheckPointer ( RETVAL , NULL_OK ) ) ; } CONTRACT_END ; _ASSERTE ( HasNativeImage ( ) ) ; Assembly * pAssembly = NULL ; IMDInternalImport * pImportFoundNativeImage = this -> GetNativeAssemblyImport ( FALSE ) ; if ( ! pImportFoundNativeImage ) { RETURN NULL ; } if ( kAssemblyRef != mdAssemblyRefNil ) { PEImageLayout * pNativeLayout = this -> GetNativeImage ( ) ; COUNT_T dependencyCount ; CORCOMPILE_DEPENDENCY * pDependencies = pNativeLayout -> GetNativeDependencies ( & dependencyCount ) ; mdAssemblyRef foundAssemblyDef = mdAssemblyRefNil ; for ( COUNT_T i = 0 ; i < dependencyCount ; ++ i ) { CORCOMPILE_DEPENDENCY * pDependency = & ( pDependencies [ i ] ) ; if ( pDependency -> dwAssemblyRef == kAssemblyRef ) { foundAssemblyDef = pDependency -> dwAssemblyDef ; break ; } } if ( kAssemblyRef == foundAssemblyDef ) { * pfDiscoveredAssemblyRefMatchesTargetDefExactly = true ; RETURN NULL ; } if ( foundAssemblyDef != mdAssemblyRefNil ) { Assembly * pAssemblyCandidate = this -> GetAssemblyIfLoaded ( foundAssemblyDef , NULL , NULL , pImportFoundNativeImage , TRUE ) ; if ( pAssemblyCandidate != NULL ) { if ( ! pAssemblyCandidate -> GetManifestFile ( ) -> HasHostAssembly ( ) ) { pAssembly = pAssemblyCandidate ; } else { _ASSERTE ( " " && ! ( IsStackWalkerThread ( ) || IsGCThread ( ) ) && IsGenericInstantiationLookupCompareThread ( ) ) ; } } } } RETURN pAssembly ; }
This function, given an AssemblyRef into the ngen generated native metadata section, will find the assembly referenced if
1.
This function given an AssemblyRef into the ngen generated native metadata section will find the assembly referenced if 1 .
// Scan CORCOMPILE_DEPENDENCIES tables // Find the assemblyDef that defines the exact target // In this case we know there is no assembly redirection involved. Skip any additional work. // Find out if THIS reference is satisfied // Specify fDoNotUtilizeExtraChecks to prevent recursion /*fDoNotUtilizeExtraChecks*/ // This extended check is designed only to find assemblies loaded via an AssemblySpecBindingCache based binder. Verify that's what we found. // This should only happen in the generic instantiation case when multiple threads are racing and // the assembly found is one which we will determine is the wrong assembly. // // We can't assert that (as its possible under stress); however it shouldn't happen in the stack walk or GC case, so we assert in those cases.