From 087e2630982070ad207fbfe7a022d0c9571b1799 Mon Sep 17 00:00:00 2001 From: Ryan Lucia Date: Mon, 26 Oct 2020 12:39:03 -0400 Subject: [PATCH 1/2] [mono] Fix LoadAssemblyRaw to not pin or copy Copying of the assembly and symbols happens later, in `mono_alc_load_raw_bytes`, and the pinning is no longer necessary so long as we have the handle. --- src/mono/mono/metadata/appdomain.c | 30 ++++++------------------------ src/mono/mono/metadata/handle.c | 10 ++++++++-- src/mono/mono/metadata/handle.h | 4 ++++ 3 files changed, 18 insertions(+), 26 deletions(-) diff --git a/src/mono/mono/metadata/appdomain.c b/src/mono/mono/metadata/appdomain.c index a14b98dff7183d..e482ddf7fd7781 100644 --- a/src/mono/mono/metadata/appdomain.c +++ b/src/mono/mono/metadata/appdomain.c @@ -2789,33 +2789,15 @@ ves_icall_System_AppDomain_LoadAssemblyRaw (MonoAppDomainHandle ad, { MonoAssembly *ass; MonoReflectionAssemblyHandle refass = MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE); - MonoDomain *domain = MONO_HANDLE_GETVAL(ad, data); - 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 */ - 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; - } - MonoGCHandle gchandle; - mono_byte *raw_data = (mono_byte*) MONO_ARRAY_HANDLE_PIN (raw_assembly, gchar, 0, &gchandle); - memcpy (assembly_data, raw_data, raw_assembly_len); - mono_gchandle_free_internal (gchandle); /* unpin */ - MONO_HANDLE_ASSIGN (raw_assembly, NULL_HANDLE); /* don't reference the data anymore */ - + MonoDomain *domain = MONO_HANDLE_GETVAL (ad, data); MonoAssemblyLoadContext *alc = mono_domain_default_alc (domain); - mono_byte *raw_symbol_data = NULL; - guint32 symbol_len = 0; - MonoGCHandle 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); - } + guint8 *raw_assembly_ptr = (guint8 *)mono_array_handle_addr (raw_assembly, sizeof (guint8), 0); + guint32 raw_assembly_len = mono_array_handle_length (raw_assembly); + guint8 *raw_symbols_ptr = (guint8 *)mono_array_handle_addr (raw_symbol_store, sizeof (guint8), 0); + guint32 raw_symbols_len = mono_array_handle_length (raw_symbol_store); - 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); + ass = mono_alc_load_raw_bytes (alc, raw_assembly_ptr, raw_assembly_len, raw_symbols_ptr, raw_symbols_len, refonly, error); goto_if_nok (error, leave); refass = mono_assembly_get_object_handle (domain, ass, error); diff --git a/src/mono/mono/metadata/handle.c b/src/mono/mono/metadata/handle.c index d552b3fd27b7dc..843e3cb081a429 100644 --- a/src/mono/mono/metadata/handle.c +++ b/src/mono/mono/metadata/handle.c @@ -414,13 +414,19 @@ mono_gchandle_get_target_handle (MonoGCHandle gchandle) return MONO_HANDLE_NEW (MonoObject, mono_gchandle_get_target_internal (gchandle)); } +gpointer +mono_array_handle_addr (MonoArrayHandle handle, int size, uintptr_t index) +{ + MonoArray *raw = MONO_HANDLE_RAW (handle); + return mono_array_addr_with_size_internal (raw, size, index); +} + gpointer mono_array_handle_pin_with_size (MonoArrayHandle handle, int size, uintptr_t idx, MonoGCHandle *gchandle) { g_assert (gchandle != NULL); *gchandle = mono_gchandle_from_handle (MONO_HANDLE_CAST(MonoObject,handle), TRUE); - MonoArray *raw = MONO_HANDLE_RAW (handle); - return mono_array_addr_with_size_internal (raw, size, idx); + return mono_array_handle_addr (handle, size, idx); } gunichar2* diff --git a/src/mono/mono/metadata/handle.h b/src/mono/mono/metadata/handle.h index 0be5c18d206f54..a825f92cee5c08 100644 --- a/src/mono/mono/metadata/handle.h +++ b/src/mono/mono/metadata/handle.h @@ -651,6 +651,10 @@ mono_array_handle_memcpy_refs (MonoArrayHandle dest, uintptr_t dest_idx, MonoArr gpointer mono_array_handle_pin_with_size (MonoArrayHandle handle, int size, uintptr_t index, MonoGCHandle *gchandle); +// Returns a pointer to the element with the given index, but does not pin +gpointer +mono_array_handle_addr (MonoArrayHandle handle, int size, uintptr_t index); + #define MONO_ARRAY_HANDLE_PIN(handle,type,index,gchandle_out) ((type*)mono_array_handle_pin_with_size (MONO_HANDLE_CAST(MonoArray,(handle)), sizeof (type), (index), (gchandle_out))) void From c678f6eedd302d571208a247a7911076a6662fde Mon Sep 17 00:00:00 2001 From: Ryan Lucia Date: Tue, 27 Oct 2020 15:39:55 -0400 Subject: [PATCH 2/2] Handle null symbol store --- src/mono/mono/metadata/appdomain.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/metadata/appdomain.c b/src/mono/mono/metadata/appdomain.c index e482ddf7fd7781..47035b4ab245c3 100644 --- a/src/mono/mono/metadata/appdomain.c +++ b/src/mono/mono/metadata/appdomain.c @@ -2794,8 +2794,13 @@ ves_icall_System_AppDomain_LoadAssemblyRaw (MonoAppDomainHandle ad, guint8 *raw_assembly_ptr = (guint8 *)mono_array_handle_addr (raw_assembly, sizeof (guint8), 0); guint32 raw_assembly_len = mono_array_handle_length (raw_assembly); - guint8 *raw_symbols_ptr = (guint8 *)mono_array_handle_addr (raw_symbol_store, sizeof (guint8), 0); - guint32 raw_symbols_len = mono_array_handle_length (raw_symbol_store); + + guint8 *raw_symbols_ptr = NULL; + guint32 raw_symbols_len = 0; + if (!MONO_HANDLE_IS_NULL (raw_symbol_store)) { + raw_symbols_ptr = (guint8 *)mono_array_handle_addr (raw_symbol_store, sizeof (guint8), 0); + raw_symbols_len = mono_array_handle_length (raw_symbol_store); + } ass = mono_alc_load_raw_bytes (alc, raw_assembly_ptr, raw_assembly_len, raw_symbols_ptr, raw_symbols_len, refonly, error); goto_if_nok (error, leave);