summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs')
-rw-r--r--src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs161
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)
{