diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs index a0a0fdfd78bf65..b22f6bc458481b 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs @@ -154,8 +154,7 @@ internal Type LoadTypeForWinRTTypeNameInContext(string typeName) if (ptrAssemblyLoadContext == IntPtr.Zero) { // If the load context is returned null, then the assembly was bound using the TPA binder - // and we shall return reference to the active "Default" binder - which could be the TPA binder - // or an overridden CLRPrivBinderAssemblyLoadContext instance. + // and we shall return reference to the "Default" binder. loadContextForAssembly = AssemblyLoadContext.Default; } else diff --git a/src/coreclr/src/binder/clrprivbinderassemblyloadcontext.cpp b/src/coreclr/src/binder/clrprivbinderassemblyloadcontext.cpp index 657e6c304d1e2d..0881af5c599832 100644 --- a/src/coreclr/src/binder/clrprivbinderassemblyloadcontext.cpp +++ b/src/coreclr/src/binder/clrprivbinderassemblyloadcontext.cpp @@ -165,13 +165,6 @@ Exit:; return hr; } -HRESULT CLRPrivBinderAssemblyLoadContext::GetBinderID( - UINT_PTR *pBinderId) -{ - *pBinderId = reinterpret_cast(this); - return S_OK; -} - HRESULT CLRPrivBinderAssemblyLoadContext::GetLoaderAllocator(LPVOID* pLoaderAllocator) { _ASSERTE(pLoaderAllocator != NULL); diff --git a/src/coreclr/src/binder/clrprivbindercoreclr.cpp b/src/coreclr/src/binder/clrprivbindercoreclr.cpp index f99fe465078c92..62d5f867beea5c 100644 --- a/src/coreclr/src/binder/clrprivbindercoreclr.cpp +++ b/src/coreclr/src/binder/clrprivbindercoreclr.cpp @@ -198,13 +198,6 @@ Exit:; } #endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE) -HRESULT CLRPrivBinderCoreCLR::GetBinderID( - UINT_PTR *pBinderId) -{ - *pBinderId = reinterpret_cast(this); - return S_OK; -} - HRESULT CLRPrivBinderCoreCLR::SetupBindingPaths(SString &sTrustedPlatformAssemblies, SString &sPlatformResourceRoots, SString &sAppPaths, diff --git a/src/coreclr/src/binder/inc/clrprivbinderassemblyloadcontext.h b/src/coreclr/src/binder/inc/clrprivbinderassemblyloadcontext.h index 6d012d9b1c684f..09695b09fc0108 100644 --- a/src/coreclr/src/binder/inc/clrprivbinderassemblyloadcontext.h +++ b/src/coreclr/src/binder/inc/clrprivbinderassemblyloadcontext.h @@ -23,8 +23,7 @@ class Object; class Assembly; class LoaderAllocator; -class CLRPrivBinderAssemblyLoadContext : - public IUnknownCommon +class CLRPrivBinderAssemblyLoadContext : public AssemblyLoadContext { public: @@ -35,9 +34,6 @@ class CLRPrivBinderAssemblyLoadContext : /* [in] */ IAssemblyName *pIAssemblyName, /* [retval][out] */ ICLRPrivAssembly **ppAssembly); - STDMETHOD(GetBinderID)( - /* [retval][out] */ UINT_PTR *pBinderId); - STDMETHOD(GetLoaderAllocator)( /* [retval][out] */ LPVOID *pLoaderAllocator); diff --git a/src/coreclr/src/binder/inc/clrprivbindercoreclr.h b/src/coreclr/src/binder/inc/clrprivbindercoreclr.h index f5fd7d4653ea71..3779e5bd63a213 100644 --- a/src/coreclr/src/binder/inc/clrprivbindercoreclr.h +++ b/src/coreclr/src/binder/inc/clrprivbindercoreclr.h @@ -8,13 +8,14 @@ #include "coreclrbindercommon.h" #include "applicationcontext.hpp" +#include "assemblyloadcontext.h" namespace BINDER_SPACE { class AssemblyIdentityUTF8; }; -class CLRPrivBinderCoreCLR : public IUnknownCommon +class CLRPrivBinderCoreCLR : public AssemblyLoadContext { public: @@ -25,9 +26,6 @@ class CLRPrivBinderCoreCLR : public IUnknownCommon(this); + return S_OK; +} diff --git a/src/coreclr/src/vm/assemblyloadcontext.h b/src/coreclr/src/vm/assemblyloadcontext.h new file mode 100644 index 00000000000000..395e697562ea39 --- /dev/null +++ b/src/coreclr/src/vm/assemblyloadcontext.h @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#ifndef _ASSEMBLYLOADCONTEXT_H +#define _ASSEMBLYLOADCONTEXT_H + +// +// Unmanaged counter-part of System.Runtime.Loader.AssemblyLoadContext +// +class AssemblyLoadContext : public IUnknownCommon +{ +public: + AssemblyLoadContext(); + + STDMETHOD(GetBinderID)( + /* [retval][out] */ UINT_PTR* pBinderId); +}; + +#endif diff --git a/src/coreclr/src/vm/assemblyname.cpp b/src/coreclr/src/vm/assemblyname.cpp index 02f16684843022..f9291158bc384a 100644 --- a/src/coreclr/src/vm/assemblyname.cpp +++ b/src/coreclr/src/vm/assemblyname.cpp @@ -24,10 +24,6 @@ #include "strongnameinternal.h" #include "eeconfig.h" -#ifndef URL_ESCAPE_AS_UTF8 -#define URL_ESCAPE_AS_UTF8 0x00040000 // Percent-encode all non-ASCII characters as their UTF-8 equivalents. -#endif - FCIMPL1(Object*, AssemblyNameNative::GetFileInformation, StringObject* filenameUNSAFE) { FCALL_CONTRACT; diff --git a/src/coreclr/src/vm/assemblynative.cpp b/src/coreclr/src/vm/assemblynative.cpp index 6567cd9dce1ab1..b9cec28e3c5a27 100644 --- a/src/coreclr/src/vm/assemblynative.cpp +++ b/src/coreclr/src/vm/assemblynative.cpp @@ -1280,11 +1280,7 @@ INT_PTR QCALLTYPE AssemblyNative::InitializeAssemblyLoadContext(INT_PTR ptrManag { // We are initializing the managed instance of Assembly Load Context that would represent the TPA binder. // First, confirm we do not have an existing managed ALC attached to the TPA binder. - INT_PTR ptrTPAAssemblyLoadContext = pTPABinderContext->GetManagedAssemblyLoadContext(); - if ((ptrTPAAssemblyLoadContext != NULL) && (ptrTPAAssemblyLoadContext != ptrManagedAssemblyLoadContext)) - { - COMPlusThrow(kInvalidOperationException, IDS_HOST_ASSEMBLY_RESOLVER_INCOMPATIBLE_TPA_BINDING_CONTEXT); - } + _ASSERTE(pTPABinderContext->GetManagedAssemblyLoadContext() == NULL); // Attach the managed TPA binding context with the native one. pTPABinderContext->SetManagedAssemblyLoadContext(ptrManagedAssemblyLoadContext); @@ -1325,55 +1321,13 @@ INT_PTR QCALLTYPE AssemblyNative::GetLoadContextForAssembly(QCall::AssemblyHandl _ASSERTE(pAssembly != NULL); - // Get the PEAssembly for the RuntimeAssembly - PEFile *pPEFile = pAssembly->GetFile(); - PTR_PEAssembly pPEAssembly = pPEFile ? pPEFile->AsAssembly() : NULL; - - // Platform assemblies are semantically bound against the "Default" binder. - // The reference to the same will be returned when this QCall returns. - - // Get the binding context for the assembly. - // - ICLRPrivBinder *pOpaqueBinder = nullptr; - AppDomain *pCurDomain = AppDomain::GetCurrentDomain(); - CLRPrivBinderCoreCLR *pTPABinder = pCurDomain->GetTPABinderContext(); - - // GetBindingContext returns a ICLRPrivAssembly which can be used to get access to the - // actual ICLRPrivBinder instance in which the assembly was loaded. - PTR_ICLRPrivBinder pBindingContext = pPEAssembly->GetBindingContext(); - UINT_PTR assemblyBinderID = 0; - - if (pBindingContext) - { - IfFailThrow(pBindingContext->GetBinderID(&assemblyBinderID)); - - // If the assembly was bound using the TPA binder, - // then we will return the reference to "Default" binder from the managed implementation when this QCall returns. - // - // See earlier comment about "Default" binder for additional context. - pOpaqueBinder = reinterpret_cast(assemblyBinderID); - } - else - { - // GetBindingContext() returns NULL for System.Private.CoreLib - pOpaqueBinder = pTPABinder; - } + AssemblyLoadContext* pAssemblyLoadContext = pAssembly->GetFile()->GetAssemblyLoadContext(); - // We should have a load context binder at this point. - _ASSERTE(pOpaqueBinder != nullptr); - - // the TPA binder uses the default ALC - // WinRT assemblies (bound using the WinRT binder) don't actually have an ALC, - // so treat them the same as if they were loaded into the TPA ALC in this case. -#ifdef FEATURE_COMINTEROP - if (!AreSameBinderInstance(pTPABinder, pOpaqueBinder) && !AreSameBinderInstance(pCurDomain->GetWinRtBinder(), pOpaqueBinder)) -#else - if (!AreSameBinderInstance(pTPABinder, pOpaqueBinder)) -#endif // FEATURE_COMINTEROP + if (pAssemblyLoadContext != AppDomain::GetCurrentDomain()->GetTPABinderContext()) { // Only CLRPrivBinderAssemblyLoadContext instance contains the reference to its // corresponding managed instance. - CLRPrivBinderAssemblyLoadContext *pBinder = (CLRPrivBinderAssemblyLoadContext *)(pOpaqueBinder); + CLRPrivBinderAssemblyLoadContext* pBinder = (CLRPrivBinderAssemblyLoadContext*)(pAssemblyLoadContext); // Fetch the managed binder reference from the native binder instance ptrManagedAssemblyLoadContext = pBinder->GetManagedAssemblyLoadContext(); diff --git a/src/coreclr/src/vm/crossgen/CMakeLists.txt b/src/coreclr/src/vm/crossgen/CMakeLists.txt index dcf43e853eda1f..e89ae13f45ae14 100644 --- a/src/coreclr/src/vm/crossgen/CMakeLists.txt +++ b/src/coreclr/src/vm/crossgen/CMakeLists.txt @@ -2,6 +2,7 @@ set(VM_CROSSGEN_SOURCES ../appdomain.cpp ../array.cpp ../assembly.cpp + ../assemblyloadcontext.cpp ../assemblyspec.cpp ../baseassemblyspec.cpp ../binder.cpp @@ -91,6 +92,7 @@ set(VM_CROSSGEN_HEADERS ../appdomain.inl ../array.h ../assembly.hpp + ../assemblyloadcontext.h ../assemblyspec.hpp ../assemblyspecbase.h ../baseassemblyspec.h diff --git a/src/coreclr/src/vm/pefile.cpp b/src/coreclr/src/vm/pefile.cpp index 6928cc6f98c478..480482bf3b1dd6 100644 --- a/src/coreclr/src/vm/pefile.cpp +++ b/src/coreclr/src/vm/pefile.cpp @@ -2448,7 +2448,6 @@ PTR_ICLRPrivBinder PEFile::GetBindingContext() // CoreLibrary is always bound in context of the TPA Binder. However, since it gets loaded and published // during EEStartup *before* DefaultContext Binder (aka TPAbinder) is initialized, we dont have a binding context to publish against. - // Thus, we will always return NULL for its binding context. if (!IsSystem()) { pBindingContext = dac_cast(GetHostAssembly()); @@ -2466,3 +2465,31 @@ PTR_ICLRPrivBinder PEFile::GetBindingContext() return pBindingContext; } + +#ifndef DACCESS_COMPILE +AssemblyLoadContext* PEFile::GetAssemblyLoadContext() +{ + LIMITED_METHOD_CONTRACT; + + PTR_ICLRPrivBinder pBindingContext = GetBindingContext(); + ICLRPrivBinder* pOpaqueBinder = NULL; + + if (pBindingContext != NULL) + { + UINT_PTR assemblyBinderID = 0; + IfFailThrow(pBindingContext->GetBinderID(&assemblyBinderID)); + + pOpaqueBinder = reinterpret_cast(assemblyBinderID); + +#ifdef FEATURE_COMINTEROP + // Treat WinRT assemblies (bound using the WinRT binder) as if they were loaded into the TPA ALC + if (AreSameBinderInstance(AppDomain::GetCurrentDomain()->GetWinRtBinder(), pOpaqueBinder)) + { + pOpaqueBinder = NULL; + } +#endif + } + + return (pOpaqueBinder != NULL) ? (AssemblyLoadContext*)pOpaqueBinder : AppDomain::GetCurrentDomain()->GetTPABinderContext(); +} +#endif diff --git a/src/coreclr/src/vm/pefile.h b/src/coreclr/src/vm/pefile.h index f21ff7b0654f78..a417c4b881a88d 100644 --- a/src/coreclr/src/vm/pefile.h +++ b/src/coreclr/src/vm/pefile.h @@ -46,6 +46,7 @@ class PEFile; class PEModule; class PEAssembly; class SimpleRWLock; +class AssemblyLoadContext; typedef VPTR(PEModule) PTR_PEModule; typedef VPTR(PEAssembly) PTR_PEAssembly; @@ -568,6 +569,8 @@ class PEFile // Returns the ICLRPrivBinder* instance associated with the PEFile PTR_ICLRPrivBinder GetBindingContext(); + AssemblyLoadContext* GetAssemblyLoadContext(); + bool HasHostAssembly() { STATIC_CONTRACT_WRAPPER; return GetHostAssembly() != nullptr; } @@ -729,8 +732,8 @@ class PEAssembly : public PEFile // Indicates if the assembly can be cached in a binding cache such as AssemblySpecBindingCache. inline bool CanUseWithBindingCache() { - STATIC_CONTRACT_WRAPPER; - return (HasBindableIdentity()); + STATIC_CONTRACT_WRAPPER; + return (HasBindableIdentity()); } };