diff options
author | Jiyoung Yun <jy910.yun@samsung.com> | 2017-04-13 14:17:19 +0900 |
---|---|---|
committer | Jiyoung Yun <jy910.yun@samsung.com> | 2017-04-13 14:17:19 +0900 |
commit | a56e30c8d33048216567753d9d3fefc2152af8ac (patch) | |
tree | 7e5d979695fc4a431740982eb1cfecc2898b23a5 /src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs | |
parent | 4b11dc566a5bbfa1378d6266525c281b028abcc8 (diff) | |
download | coreclr-a56e30c8d33048216567753d9d3fefc2152af8ac.tar.gz coreclr-a56e30c8d33048216567753d9d3fefc2152af8ac.tar.bz2 coreclr-a56e30c8d33048216567753d9d3fefc2152af8ac.zip |
Imported Upstream version 2.0.0.11353upstream/2.0.0.11353
Diffstat (limited to 'src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs')
-rw-r--r-- | src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs | 161 |
1 files changed, 79 insertions, 82 deletions
diff --git a/src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs b/src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs index 2be8b13274..de8137f1ec 100644 --- a/src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs +++ b/src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs @@ -18,19 +18,18 @@ namespace System.Runtime.Loader { public abstract class AssemblyLoadContext { - [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern bool CanUseAppPathAssemblyLoadContextInCurrentDomain(); - + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern IntPtr InitializeAssemblyLoadContext(IntPtr ptrAssemblyLoadContext, bool fRepresentsTPALoadContext); - + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern IntPtr LoadFromStream(IntPtr ptrNativeAssemblyLoadContext, IntPtr ptrAssemblyArray, int iAssemblyArrayLen, IntPtr ptrSymbols, int iSymbolArrayLen, ObjectHandleOnStack retAssembly); - + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] internal static extern void InternalSetProfileRoot(string directoryPath); @@ -50,8 +49,8 @@ namespace System.Runtime.Loader // Initialize the ALC representing TPA LoadContext InitializeLoadContext(fRepresentsTPALoadContext); } - - void InitializeLoadContext(bool fRepresentsTPALoadContext) + + private void InitializeLoadContext(bool fRepresentsTPALoadContext) { // Initialize the VM side of AssemblyLoadContext if not already done. GCHandle gchALC = GCHandle.Alloc(this); @@ -75,14 +74,14 @@ namespace System.Runtime.Loader [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern void GetLoadedAssembliesInternal(ObjectHandleOnStack assemblies); - + public static Assembly[] GetLoadedAssemblies() { Assembly[] assemblies = null; GetLoadedAssembliesInternal(JitHelpers.GetObjectHandleOnStack(ref assemblies)); return assemblies; } - + // These are helpers that can be used by AssemblyLoadContext derivations. // They are used to load assemblies in DefaultContext. public Assembly LoadFromAssemblyPath(string assemblyPath) @@ -94,14 +93,14 @@ namespace System.Runtime.Loader if (PathInternal.IsPartiallyQualified(assemblyPath)) { - throw new ArgumentException( Environment.GetResourceString("Argument_AbsolutePathRequired"), nameof(assemblyPath)); + throw new ArgumentException(SR.Argument_AbsolutePathRequired, nameof(assemblyPath)); } RuntimeAssembly loadedAssembly = null; LoadFromPath(m_pNativeAssemblyLoadContext, assemblyPath, null, JitHelpers.GetObjectHandleOnStack(ref loadedAssembly)); return loadedAssembly; } - + public Assembly LoadFromNativeImagePath(string nativeImagePath, string assemblyPath) { if (nativeImagePath == null) @@ -111,12 +110,12 @@ namespace System.Runtime.Loader if (PathInternal.IsPartiallyQualified(nativeImagePath)) { - throw new ArgumentException( Environment.GetResourceString("Argument_AbsolutePathRequired"), nameof(nativeImagePath)); + throw new ArgumentException(SR.Argument_AbsolutePathRequired, nameof(nativeImagePath)); } if (assemblyPath != null && PathInternal.IsPartiallyQualified(assemblyPath)) { - throw new ArgumentException(Environment.GetResourceString("Argument_AbsolutePathRequired"), nameof(assemblyPath)); + throw new ArgumentException(SR.Argument_AbsolutePathRequired, nameof(assemblyPath)); } // Basic validation has succeeded - lets try to load the NI image. @@ -125,74 +124,79 @@ namespace System.Runtime.Loader LoadFromPath(m_pNativeAssemblyLoadContext, assemblyPath, nativeImagePath, JitHelpers.GetObjectHandleOnStack(ref loadedAssembly)); return loadedAssembly; } - + public Assembly LoadFromStream(Stream assembly) { return LoadFromStream(assembly, null); } - + public Assembly LoadFromStream(Stream assembly, Stream assemblySymbols) { if (assembly == null) { throw new ArgumentNullException(nameof(assembly)); } - + + if (assembly.Length <= 0) + { + throw new BadImageFormatException(SR.BadImageFormat_BadILFormat); + } + int iAssemblyStreamLength = (int)assembly.Length; int iSymbolLength = 0; - + // Allocate the byte[] to hold the assembly byte[] arrAssembly = new byte[iAssemblyStreamLength]; - + // Copy the assembly to the byte array assembly.Read(arrAssembly, 0, iAssemblyStreamLength); - + // Get the symbol stream in byte[] if provided byte[] arrSymbols = null; if (assemblySymbols != null) { iSymbolLength = (int)assemblySymbols.Length; arrSymbols = new byte[iSymbolLength]; - + assemblySymbols.Read(arrSymbols, 0, iSymbolLength); } - + RuntimeAssembly loadedAssembly = null; - unsafe + unsafe { - fixed(byte *ptrAssembly = arrAssembly, ptrSymbols = arrSymbols) + fixed (byte* ptrAssembly = arrAssembly, ptrSymbols = arrSymbols) { LoadFromStream(m_pNativeAssemblyLoadContext, new IntPtr(ptrAssembly), iAssemblyStreamLength, new IntPtr(ptrSymbols), iSymbolLength, JitHelpers.GetObjectHandleOnStack(ref loadedAssembly)); } } - + return loadedAssembly; } - + // Custom AssemblyLoadContext implementations can override this // method to perform custom processing and use one of the protected // helpers above to load the assembly. protected abstract Assembly Load(AssemblyName assemblyName); - + // This method is invoked by the VM when using the host-provided assembly load context // implementation. private static Assembly Resolve(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName) { AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchManagedAssemblyLoadContext).Target); - + return context.ResolveUsingLoad(assemblyName); } - + // This method is invoked by the VM to resolve an assembly reference using the Resolving event // after trying assembly resolution via Load override and TPA load context without success. private static Assembly ResolveUsingResolvingEvent(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName) { AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchManagedAssemblyLoadContext).Target); - + // Invoke the AssemblyResolve event callbacks if wired up return context.ResolveUsingEvent(assemblyName); } - + private Assembly GetFirstResolvedAssembly(AssemblyName assemblyName) { Assembly resolvedAssembly = null; @@ -202,8 +206,8 @@ namespace System.Runtime.Loader if (assemblyResolveHandler != null) { // Loop through the event subscribers and return the first non-null Assembly instance - Delegate [] arrSubscribers = assemblyResolveHandler.GetInvocationList(); - for(int i = 0; i < arrSubscribers.Length; i++) + Delegate[] arrSubscribers = assemblyResolveHandler.GetInvocationList(); + for (int i = 0; i < arrSubscribers.Length; i++) { resolvedAssembly = ((Func<AssemblyLoadContext, AssemblyName, Assembly>)arrSubscribers[i])(this, assemblyName); if (resolvedAssembly != null) @@ -212,7 +216,7 @@ namespace System.Runtime.Loader } } } - + return resolvedAssembly; } @@ -220,7 +224,7 @@ namespace System.Runtime.Loader { // Get the name of the loaded assembly string loadedSimpleName = null; - + // Derived type's Load implementation is expected to use one of the LoadFrom* methods to get the assembly // which is a RuntimeAssembly instance. However, since Assembly type can be used build any other artifact (e.g. AssemblyBuilder), // we need to check for RuntimeAssembly. @@ -229,49 +233,48 @@ namespace System.Runtime.Loader { loadedSimpleName = rtLoadedAssembly.GetSimpleName(); } - + // The simple names should match at the very least if (String.IsNullOrEmpty(loadedSimpleName) || (!requestedSimpleName.Equals(loadedSimpleName, StringComparison.InvariantCultureIgnoreCase))) - throw new InvalidOperationException(Environment.GetResourceString("Argument_CustomAssemblyLoadContextRequestedNameMismatch")); - + throw new InvalidOperationException(SR.Argument_CustomAssemblyLoadContextRequestedNameMismatch); + return assembly; - } - + private Assembly ResolveUsingLoad(AssemblyName assemblyName) { string simpleName = assemblyName.Name; Assembly assembly = Load(assemblyName); - + if (assembly != null) { assembly = ValidateAssemblyNameWithSimpleName(assembly, simpleName); } - + return assembly; } - + private Assembly ResolveUsingEvent(AssemblyName assemblyName) { string simpleName = assemblyName.Name; - + // Invoke the AssemblyResolve event callbacks if wired up Assembly assembly = GetFirstResolvedAssembly(assemblyName); if (assembly != null) { assembly = ValidateAssemblyNameWithSimpleName(assembly, simpleName); } - + // Since attempt to resolve the assembly via Resolving event is the last option, // throw an exception if we do not find any assembly. if (assembly == null) { - throw new FileNotFoundException(Environment.GetResourceString("IO.FileLoad"), simpleName); + throw new FileNotFoundException(SR.IO_FileLoad, simpleName); } - + return assembly; } - + public Assembly LoadFromAssemblyName(AssemblyName assemblyName) { // Attempt to load the assembly, using the same ordering as static load, in the current load context. @@ -294,23 +297,23 @@ namespace System.Runtime.Loader } if (unmanagedDllPath.Length == 0) { - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"), nameof(unmanagedDllPath)); + throw new ArgumentException(SR.Argument_EmptyPath, nameof(unmanagedDllPath)); } if (PathInternal.IsPartiallyQualified(unmanagedDllPath)) { - throw new ArgumentException(Environment.GetResourceString("Argument_AbsolutePathRequired"), nameof(unmanagedDllPath)); + throw new ArgumentException(SR.Argument_AbsolutePathRequired, nameof(unmanagedDllPath)); } return InternalLoadUnmanagedDllFromPath(unmanagedDllPath); } - + // Custom AssemblyLoadContext implementations can override this // method to perform the load of unmanaged native dll // This function needs to return the HMODULE of the dll it loads protected virtual IntPtr LoadUnmanagedDll(String unmanagedDllName) { //defer to default coreclr policy of loading unmanaged dll - return IntPtr.Zero; + return IntPtr.Zero; } // This method is invoked by the VM when using the host-provided assembly load context @@ -331,7 +334,7 @@ namespace System.Runtime.Loader if (AssemblyLoadContext.CanUseAppPathAssemblyLoadContextInCurrentDomain()) { // Synchronize access to initializing Default ALC - lock(s_initLock) + lock (s_initLock) { if (s_DefaultAssemblyLoadContext == null) { @@ -340,16 +343,11 @@ namespace System.Runtime.Loader } } } - + return s_DefaultAssemblyLoadContext; } } - - // This call opens and closes the file, but does not add the - // assembly to the domain. - [MethodImplAttribute(MethodImplOptions.InternalCall)] - static internal extern AssemblyName nGetFileInformation(String s); - + // Helper to return AssemblyName corresponding to the path of an IL assembly public static AssemblyName GetAssemblyName(string assemblyPath) { @@ -358,14 +356,13 @@ namespace System.Runtime.Loader throw new ArgumentNullException(nameof(assemblyPath)); } - string fullPath = Path.GetFullPath(assemblyPath); - return nGetFileInformation(fullPath); + return AssemblyName.GetAssemblyName(assemblyPath); } - + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern IntPtr GetLoadContextForAssembly(RuntimeAssembly assembly); - + // Returns the load context in which the specified assembly has been loaded public static AssemblyLoadContext GetLoadContext(Assembly assembly) { @@ -373,11 +370,11 @@ namespace System.Runtime.Loader { throw new ArgumentNullException(nameof(assembly)); } - + AssemblyLoadContext loadContextForAssembly = null; RuntimeAssembly rtAsm = assembly as RuntimeAssembly; - + // We only support looking up load context for runtime assemblies. if (rtAsm != null) { @@ -397,7 +394,7 @@ namespace System.Runtime.Loader return loadContextForAssembly; } - + // Set the root directory path for profile optimization. public void SetProfileOptimizationRoot(string directoryPath) { @@ -424,7 +421,7 @@ namespace System.Runtime.Loader // Contains the reference to VM's representation of the AssemblyLoadContext private IntPtr m_pNativeAssemblyLoadContext; - + // Each AppDomain contains the reference to its AssemblyLoadContext instance, if one is // specified by the host. By having the field as a static, we are // making it an AppDomain-wide field. @@ -434,36 +431,36 @@ namespace System.Runtime.Loader private static readonly object s_initLock = new Object(); // Occurs when an Assembly is loaded - public static event AssemblyLoadEventHandler AssemblyLoad - { - add { AppDomain.CurrentDomain.AssemblyLoad += value; } - remove { AppDomain.CurrentDomain.AssemblyLoad -= value; } + public static event AssemblyLoadEventHandler AssemblyLoad + { + add { AppDomain.CurrentDomain.AssemblyLoad += value; } + remove { AppDomain.CurrentDomain.AssemblyLoad -= value; } } // Occurs when resolution of type fails - public static event ResolveEventHandler TypeResolve - { - add { AppDomain.CurrentDomain.TypeResolve += value; } - remove { AppDomain.CurrentDomain.TypeResolve -= value; } + public static event ResolveEventHandler TypeResolve + { + add { AppDomain.CurrentDomain.TypeResolve += value; } + remove { AppDomain.CurrentDomain.TypeResolve -= value; } } // Occurs when resolution of resource fails - public static event ResolveEventHandler ResourceResolve - { - add { AppDomain.CurrentDomain.ResourceResolve += value; } - remove { AppDomain.CurrentDomain.ResourceResolve -= value; } - } + public static event ResolveEventHandler ResourceResolve + { + add { AppDomain.CurrentDomain.ResourceResolve += value; } + remove { AppDomain.CurrentDomain.ResourceResolve -= value; } + } // Occurs when resolution of assembly fails // This event is fired after resolve events of AssemblyLoadContext fails public static event ResolveEventHandler AssemblyResolve { - add { AppDomain.CurrentDomain.AssemblyResolve += value; } - remove { AppDomain.CurrentDomain.AssemblyResolve -= value; } + add { AppDomain.CurrentDomain.AssemblyResolve += value; } + remove { AppDomain.CurrentDomain.AssemblyResolve -= value; } } } - class AppPathAssemblyLoadContext : AssemblyLoadContext + internal class AppPathAssemblyLoadContext : AssemblyLoadContext { internal AppPathAssemblyLoadContext() : base(true) { |