From 1ec935a56a15fa88918918995ba02c0f2b3f7fa3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Aleksey=20Kliger=20=28=CE=BBgeek=29?= Date: Tue, 23 Jul 2019 19:09:27 -0400 Subject: [PATCH] [netcore] Implement AssemblyLoadContext.InternalLoad (mono/mono#15753) Fixes https://github.com/mono/mono/issues/14830 Commit migrated from https://github.com/mono/mono/commit/7467ce4369adecef24a9c65854e7e39228ac9637 --- src/mono/mono/metadata/appdomain.c | 74 ++++++++++++++++------ src/mono/mono/metadata/icall-def-netcore.h | 1 + src/mono/netcore/CoreFX.issues.rsp | 5 -- .../System.Runtime.Loader/AssemblyLoadContext.cs | 12 +++- 4 files changed, 68 insertions(+), 24 deletions(-) diff --git a/src/mono/mono/metadata/appdomain.c b/src/mono/mono/metadata/appdomain.c index 9f51044..106beb2 100644 --- a/src/mono/mono/metadata/appdomain.c +++ b/src/mono/mono/metadata/appdomain.c @@ -2530,6 +2530,25 @@ leave: } #endif +static MonoAssembly* +mono_alc_load_raw_bytes (MonoAssemblyLoadContext *alc, guint8 *raw_assembly, guint32 raw_assembly_len, guint8 *raw_symbol_data, guint32 raw_symbol_len, gboolean refonly, MonoError *error); + +#ifdef ENABLE_NETCORE +MonoReflectionAssemblyHandle +ves_icall_System_Runtime_Loader_AssemblyLoadContext_InternalLoadFromStream (gpointer native_alc, gpointer raw_assembly_ptr, gint32 raw_assembly_len, gpointer raw_symbols_ptr, gint32 raw_symbols_len, MonoError *error) +{ + MonoDomain *domain = mono_domain_get (); + MonoReflectionAssemblyHandle result = MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE); + MonoAssembly *assm = NULL; + assm = mono_alc_load_raw_bytes ((MonoAssemblyLoadContext *)native_alc, (guint8 *)raw_assembly_ptr, raw_assembly_len, (guint8 *)raw_symbols_ptr, raw_symbols_len, FALSE, error); + goto_if_nok (error, leave); + + result = mono_assembly_get_object_handle (domain, assm, error); + +leave: + return result; +} +#else MonoReflectionAssemblyHandle ves_icall_System_AppDomain_LoadAssemblyRaw (MonoAppDomainHandle ad, MonoArrayHandle raw_assembly, @@ -2540,11 +2559,10 @@ ves_icall_System_AppDomain_LoadAssemblyRaw (MonoAppDomainHandle ad, MonoAssembly *ass; MonoReflectionAssemblyHandle refass = MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE); MonoDomain *domain = MONO_HANDLE_GETVAL(ad, data); - MonoImageOpenStatus status; guint32 raw_assembly_len = mono_array_handle_length (raw_assembly); /* Copy the data ourselves to unpin the raw assembly byte array as soon as possible */ - char *assembly_data = (char*) g_try_malloc (raw_assembly_len); + guint8 *assembly_data = (guint8*) g_try_malloc (raw_assembly_len); if (!assembly_data) { mono_error_set_out_of_memory (error, "Could not allocate %ud bytes to copy raw assembly data", raw_assembly_len); return refass; @@ -2556,21 +2574,43 @@ ves_icall_System_AppDomain_LoadAssemblyRaw (MonoAppDomainHandle ad, MONO_HANDLE_ASSIGN (raw_assembly, NULL_HANDLE); /* don't reference the data anymore */ MonoAssemblyLoadContext *alc = mono_domain_default_alc (domain); - MonoImage *image = mono_image_open_from_data_internal (alc, assembly_data, raw_assembly_len, FALSE, NULL, refonly, FALSE, NULL); - if (!image) { - mono_error_set_bad_image_by_name (error, "In memory assembly", "0x%p", raw_data); - return refass; + mono_byte *raw_symbol_data = NULL; + guint32 symbol_len = 0; + uint32_t symbol_gchandle = 0; + if (!MONO_HANDLE_IS_NULL (raw_symbol_store)) { + symbol_len = mono_array_handle_length (raw_symbol_store); + raw_symbol_data = (mono_byte*) MONO_ARRAY_HANDLE_PIN (raw_symbol_store, mono_byte, 0, &symbol_gchandle); } - if (!MONO_HANDLE_IS_NULL(raw_symbol_store)) { - guint32 symbol_len = mono_array_handle_length (raw_symbol_store); - uint32_t symbol_gchandle; - mono_byte *raw_symbol_data = (mono_byte*) MONO_ARRAY_HANDLE_PIN (raw_symbol_store, mono_byte, 0, &symbol_gchandle); - mono_debug_open_image_from_memory (image, raw_symbol_data, symbol_len); - mono_gchandle_free_internal (symbol_gchandle); + ass = mono_alc_load_raw_bytes (alc, assembly_data, raw_assembly_len, raw_symbol_data, symbol_len, refonly, error); + mono_gchandle_free_internal (symbol_gchandle); + goto_if_nok (error, leave); + + refass = mono_assembly_get_object_handle (domain, ass, error); + if (!MONO_HANDLE_IS_NULL (refass)) + MONO_HANDLE_SET (refass, evidence, evidence); + +leave: + return refass; +} +#endif /* ENABLE_NETCORE */ + +static MonoAssembly* +mono_alc_load_raw_bytes (MonoAssemblyLoadContext *alc, guint8 *assembly_data, guint32 raw_assembly_len, guint8 *raw_symbol_data, guint32 raw_symbol_len, gboolean refonly, MonoError *error) +{ + MonoAssembly *ass = NULL; + MonoImageOpenStatus status; + MonoImage *image = mono_image_open_from_data_internal (alc, (char*)assembly_data, raw_assembly_len, FALSE, NULL, refonly, FALSE, NULL); + + if (!image) { + mono_error_set_bad_image_by_name (error, "In memory assembly", "0x%p", assembly_data); + return ass; } + if (raw_symbol_data) + mono_debug_open_image_from_memory (image, raw_symbol_data, raw_symbol_len); + MonoAssembly* redirected_asm = NULL; MonoImageOpenStatus new_status = MONO_IMAGE_OK; if ((redirected_asm = mono_assembly_binding_applies_to_image (image, &new_status))) { @@ -2580,26 +2620,24 @@ ves_icall_System_AppDomain_LoadAssemblyRaw (MonoAppDomainHandle ad, } else if (new_status != MONO_IMAGE_OK) { mono_image_close (image); mono_error_set_bad_image_by_name (error, "In Memory assembly", "0x%p was assembly binding redirected to another assembly that failed to load", assembly_data); - return refass; + return ass; } MonoAssemblyLoadRequest req; mono_assembly_request_prepare (&req, sizeof (req), refonly? MONO_ASMCTX_REFONLY : MONO_ASMCTX_INDIVIDUAL); + req.alc = alc; ass = mono_assembly_request_load_from (image, "", &req, &status); if (!ass) { mono_image_close (image); mono_error_set_bad_image_by_name (error, "In Memory assembly", "0x%p", assembly_data); - return refass; + return ass; } /* Clear the reference added by mono_image_open_from_data_internal above */ mono_image_close (image); - refass = mono_assembly_get_object_handle (domain, ass, error); - if (!MONO_HANDLE_IS_NULL(refass)) - MONO_HANDLE_SET (refass, evidence, evidence); - return refass; + return ass; } MonoReflectionAssemblyHandle diff --git a/src/mono/mono/metadata/icall-def-netcore.h b/src/mono/mono/metadata/icall-def-netcore.h index e9001e7..9d1a876 100644 --- a/src/mono/mono/metadata/icall-def-netcore.h +++ b/src/mono/mono/metadata/icall-def-netcore.h @@ -373,6 +373,7 @@ HANDLES(MARSHAL_42, "copy_to_unmanaged_fixed", ves_icall_System_Runtime_InteropS ICALL_TYPE(ALC, "System.Runtime.Loader.AssemblyLoadContext", ALC_2) HANDLES(ALC_2, "InternalInitializeNativeALC", ves_icall_System_Runtime_Loader_AssemblyLoadContext_InternalInitializeNativeALC, gpointer, 3, (gpointer, MonoBoolean, MonoBoolean)) HANDLES(ALC_1, "InternalLoadFile", ves_icall_System_Runtime_Loader_AssemblyLoadContext_InternalLoadFile, MonoReflectionAssembly, 3, (gpointer, MonoString, MonoStackCrawlMark_ptr)) +HANDLES(ALC_3, "InternalLoadFromStream", ves_icall_System_Runtime_Loader_AssemblyLoadContext_InternalLoadFromStream, MonoReflectionAssembly, 5, (gpointer, gpointer, gint32, gpointer, gint32)) ICALL_TYPE(RUNIMPORT, "System.Runtime.RuntimeImports", RUNIMPORT_1) NOHANDLES(ICALL(RUNIMPORT_1, "RhBulkMoveWithWriteBarrier", ves_icall_System_Runtime_RuntimeImports_RhBulkMoveWithWriteBarrier)) diff --git a/src/mono/netcore/CoreFX.issues.rsp b/src/mono/netcore/CoreFX.issues.rsp index 8988884..4259011 100644 --- a/src/mono/netcore/CoreFX.issues.rsp +++ b/src/mono/netcore/CoreFX.issues.rsp @@ -432,11 +432,6 @@ # https://github.com/mono/mono/issues/15037 -nomethod System.Reflection.Tests.ParameterInfoTests.RawDefaultValueFromAttribute -# AssemblyLoadContext.InternalLoad not implemented -# https://github.com/mono/mono/issues/14830 --nomethod System.Reflection.Tests.AssemblyTests.AssemblyLoadFromBytes --nomethod System.Reflection.Tests.AssemblyTests.AssemblyLoadFromBytesWithSymbols - # Need to set ProcessorArchitecture in AssemblyName # https://github.com/mono/mono/issues/15068 -nomethod System.Reflection.Tests.AssemblyNameTests.Ctor_ValidArchitectureName_Succeeds diff --git a/src/mono/netcore/System.Private.CoreLib/src/System.Runtime.Loader/AssemblyLoadContext.cs b/src/mono/netcore/System.Private.CoreLib/src/System.Runtime.Loader/AssemblyLoadContext.cs index 6e68962..9058559 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System.Runtime.Loader/AssemblyLoadContext.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System.Runtime.Loader/AssemblyLoadContext.cs @@ -43,7 +43,14 @@ namespace System.Runtime.Loader internal Assembly InternalLoad (byte[] arrAssembly, byte[] arrSymbols) { - throw new NotImplementedException (); + unsafe { + int symbolsLength = arrSymbols?.Length ?? 0; + fixed (byte* ptrAssembly = arrAssembly, ptrSymbols = arrSymbols) + { + return InternalLoadFromStream (NativeALC, new IntPtr (ptrAssembly), arrAssembly.Length, + new IntPtr (ptrSymbols), symbolsLength); + } + } } public static Assembly[] GetLoadedAssemblies () @@ -70,6 +77,9 @@ namespace System.Runtime.Loader [MethodImplAttribute (MethodImplOptions.InternalCall)] extern static IntPtr InternalInitializeNativeALC (IntPtr thisHandlePtr, bool representsTPALoadContext, bool isCollectible); + [MethodImplAttribute (MethodImplOptions.InternalCall)] + extern static Assembly InternalLoadFromStream (IntPtr nativeAssemblyLoadContext, IntPtr assm, int assmLength, IntPtr symbols, int symbolsLength); + internal static Assembly DoAssemblyResolve (string name) { return AssemblyResolve (null, new ResolveEventArgs (name)); -- 2.7.4