From 88c4a462ed964e3bde05cebcdaf53a8602d25156 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Thu, 19 Nov 2020 05:24:37 -0500 Subject: [PATCH] Add AOT support for the EntryPoint property for UnmanagedCallersOnly. (#44809) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * Change mono_reflection_create_custom_attr_data_args_noalloc () so it returns the beginning of the metadata string so its length can be computed. * Add AOT support for the EntryPoint property for UnmanagedCallersOnly. Fixes https://github.com/dotnet/runtime/issues/44803. * Update src/mono/mono/mini/driver.c Co-authored-by: Aleksey Kliger (λgeek) Co-authored-by: Aleksey Kliger (λgeek) --- src/mono/mono/metadata/custom-attrs.c | 11 ++++++++--- src/mono/mono/mini/aot-compiler.c | 34 +++++++++++++++++++++++++++++++++- src/mono/mono/mini/driver.c | 5 +++-- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/mono/mono/metadata/custom-attrs.c b/src/mono/mono/metadata/custom-attrs.c index b521943..fe3165f 100644 --- a/src/mono/mono/metadata/custom-attrs.c +++ b/src/mono/mono/metadata/custom-attrs.c @@ -374,7 +374,9 @@ handle_enum: g_error ("generic valutype %s not handled in custom attr value decoding", m_class_get_name (t->data.klass)); break; - case MONO_TYPE_STRING: + case MONO_TYPE_STRING: { + const char *start = p; + if (!bcheck_blob (p, 0, boundp, error)) return NULL; MONO_DISABLE_WARNING (4310) // cast truncates constant value @@ -389,7 +391,7 @@ MONO_RESTORE_WARNING return NULL; *end = p + slen; if (!out_obj) - return (void*)p; + return (void*)start; // https://bugzilla.xamarin.com/show_bug.cgi?id=60848 // Custom attribute strings are encoded as wtf-8 instead of utf-8. // If we decode using utf-8 like the spec says, we will silently fail @@ -398,6 +400,7 @@ MONO_RESTORE_WARNING // See https://simonsapin.github.io/wtf-8/ for a description of wtf-8. *out_obj = (MonoObject*)mono_string_new_wtf8_len_checked (mono_domain_get (), p, slen, error); return NULL; + } case MONO_TYPE_CLASS: { MonoType *type = load_cattr_type (image, t, TRUE, p, boundp, end, error, &slen); if (out_obj) { @@ -1204,7 +1207,9 @@ fail: * mono_reflection_create_custom_attr_data_args_noalloc: * * Same as mono_reflection_create_custom_attr_data_args but allocate no managed objects, return values - * using C arrays. Only usable for cattrs with primitive/type arguments. + * using C arrays. Only usable for cattrs with primitive/type/string arguments. + * For types, a MonoType* is returned. + * For strings, the address in the metadata blob is returned. * TYPED_ARGS, NAMED_ARGS, and NAMED_ARG_INFO should be freed using g_free (). */ void diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 2eca80f..a07c0e2 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -5060,10 +5060,42 @@ MONO_RESTORE_WARNING if (cattr->attrs [j].ctor && mono_is_corlib_image (m_class_get_image (cattr->attrs [j].ctor->klass)) && !strcmp (m_class_get_name (cattr->attrs [j].ctor->klass), "UnmanagedCallersOnlyAttribute")) break; if (j < cattr->num_attrs) { - MonoMethod *wrapper = mono_marshal_get_managed_wrapper (method, NULL, 0, error); + MonoCustomAttrEntry *e = &cattr->attrs [j]; + const char *named; + int slen; + char *export_name = NULL; + MonoMethod *wrapper; + + if (!(method->flags & METHOD_ATTRIBUTE_STATIC)) { + g_warning ("AOT restriction: Method '%s' must be static since it is decorated with [UnmanagedCallers].", + mono_method_full_name (method, TRUE)); + exit (1); + } + + gpointer *typed_args = NULL; + gpointer *named_args = NULL; + CattrNamedArg *named_arg_info = NULL; + int num_named_args = 0; + mono_reflection_create_custom_attr_data_args_noalloc (acfg->image, e->ctor, e->data, e->data_size, &typed_args, &named_args, &num_named_args, &named_arg_info, error); + mono_error_assert_ok (error); + for (j = 0; j < num_named_args; ++j) { + if (named_arg_info [j].field && !strcmp (named_arg_info [j].field->name, "EntryPoint")) { + named = named_args [j]; + slen = mono_metadata_decode_value (named, &named); + export_name = (char *)g_malloc (slen + 1); + memcpy (export_name, named, slen); + export_name [slen] = 0; + } + } + g_free (named_args); + g_free (named_arg_info); + + wrapper = mono_marshal_get_managed_wrapper (method, NULL, 0, error); mono_error_assert_ok (error); add_method (acfg, wrapper); + if (export_name) + g_hash_table_insert (acfg->export_names, wrapper, export_name); } #endif diff --git a/src/mono/mono/mini/driver.c b/src/mono/mono/mini/driver.c index 5115400..0d01be7 100644 --- a/src/mono/mono/mini/driver.c +++ b/src/mono/mono/mini/driver.c @@ -452,7 +452,9 @@ method_should_be_regression_tested (MonoMethod *method, gboolean interp) if (!is_ok (error)) continue; - char *utf8_str = (char*)(void*)typed_args[0]; //this points into image memory that is constant + const char *arg = (const char*)typed_args [0]; + mono_metadata_decode_value (arg, &arg); + char *utf8_str = (char*)arg; //this points into image memory that is constant g_free (typed_args); g_free (named_args); g_free (arginfo); @@ -3352,4 +3354,3 @@ mono_parse_env_options (int *ref_argc, char **ref_argv []) fprintf (stderr, "%s", ret); exit (1); } - -- 2.7.4