From 7add6cb87c4802129c35244d43828ab605cde5ef Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Fri, 13 May 2022 12:34:07 +0200 Subject: [PATCH 01/24] Initial noalloc variant of load_cattr_value function --- src/mono/mono/metadata/custom-attrs.c | 359 +++++++++++++++++++++++++- 1 file changed, 356 insertions(+), 3 deletions(-) diff --git a/src/mono/mono/metadata/custom-attrs.c b/src/mono/mono/metadata/custom-attrs.c index 8e61a6aa095bb7..70ab6988f75010 100644 --- a/src/mono/mono/metadata/custom-attrs.c +++ b/src/mono/mono/metadata/custom-attrs.c @@ -626,6 +626,359 @@ MONO_RESTORE_WARNING return NULL; } +/* + * Load custrom attribute without mono allocation - invoked from AOT compiler + */ +static void* +load_cattr_value_noalloc (MonoImage *image, MonoType *t, MonoObject **out_obj, const char *p, const char *boundp, const char **end, MonoError *error) +{ + int type = t->type; + guint32 slen; + MonoClass *tklass = t->data.klass; + + if (out_obj) + *out_obj = NULL; + g_assert (boundp); + error_init (error); + + if (type == MONO_TYPE_GENERICINST) { + MonoGenericClass * mgc = t->data.generic_class; + MonoClass * cc = mgc->container_class; + if (m_class_is_enumtype (cc)) { + tklass = m_class_get_element_class (cc); + t = m_class_get_byval_arg (tklass); + type = t->type; + } else { + g_error ("Unhandled type of generic instance in load_cattr_value_noalloc: %s", m_class_get_name (cc)); + } + } + +handle_enum: + switch (type) { + case MONO_TYPE_U1: + case MONO_TYPE_I1: + case MONO_TYPE_BOOLEAN: { + MonoBoolean *bval = (MonoBoolean *)g_malloc (sizeof (MonoBoolean)); + if (!bcheck_blob (p, 0, boundp, error)) + return NULL; + *bval = *p; + *end = p + 1; + return bval; + } + case MONO_TYPE_CHAR: + case MONO_TYPE_U2: + case MONO_TYPE_I2: { + guint16 *val = (guint16 *)g_malloc (sizeof (guint16)); + if (!bcheck_blob (p, 1, boundp, error)) + return NULL; + *val = read16 (p); + *end = p + 2; + return val; + } +#if SIZEOF_VOID_P == 4 + case MONO_TYPE_U: + case MONO_TYPE_I: +#endif + case MONO_TYPE_R4: + case MONO_TYPE_U4: + case MONO_TYPE_I4: { + guint32 *val = (guint32 *)g_malloc (sizeof (guint32)); + if (!bcheck_blob (p, 3, boundp, error)) + return NULL; + *val = read32 (p); + *end = p + 4; + return val; + } +#if SIZEOF_VOID_P == 8 + case MONO_TYPE_U: /* error out instead? this should probably not happen */ + case MONO_TYPE_I: +#endif + case MONO_TYPE_U8: + case MONO_TYPE_I8: { + guint64 *val = (guint64 *)g_malloc (sizeof (guint64)); + if (!bcheck_blob (p, 7, boundp, error)) + return NULL; + *val = read64 (p); + *end = p + 8; + return val; + } + case MONO_TYPE_R8: { + double *val = (double *)g_malloc (sizeof (double)); + if (!bcheck_blob (p, 7, boundp, error)) + return NULL; + readr8 (p, val); + *end = p + 8; + return val; + } + case MONO_TYPE_VALUETYPE: + if (m_class_is_enumtype (t->data.klass)) { + type = mono_class_enum_basetype_internal (t->data.klass)->type; + goto handle_enum; + } else { + MonoClass *k = t->data.klass; + + if (mono_is_corlib_image (m_class_get_image (k)) && strcmp (m_class_get_name_space (k), "System") == 0 && strcmp (m_class_get_name (k), "DateTime") == 0){ + guint64 *val = (guint64 *)g_malloc (sizeof (guint64)); + if (!bcheck_blob (p, 7, boundp, error)) + return NULL; + *val = read64 (p); + *end = p + 8; + return val; + } + } + g_error ("generic valutype %s not handled in custom attr value decoding", m_class_get_name (t->data.klass)); + break; + + 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 + if (*p == (char)0xFF) { + *end = p + 1; + return NULL; + } +MONO_RESTORE_WARNING + if (!decode_blob_value_checked (p, boundp, &slen, &p, error)) + return NULL; + if (slen > 0 && !bcheck_blob (p, slen - 1, boundp, error)) + return NULL; + *end = p + slen; + if (!out_obj) + 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 + // to decode some attributes in assemblies that Windows .NET Framework + // and CoreCLR both manage to decode. + // See https://simonsapin.github.io/wtf-8/ for a description of wtf-8. + // Always use string.Empty for empty strings + if (slen == 0) + *out_obj = (MonoObject*)mono_string_empty_internal (mono_domain_get ()); + else + *out_obj = (MonoObject*)mono_string_new_wtf8_len_checked (p, slen, error); + return NULL; + } + case MONO_TYPE_CLASS: { + MonoType *cattr_type = load_cattr_type (image, t, TRUE, p, boundp, end, error, &slen); + if (out_obj) { + if (!cattr_type ) + return NULL; + *out_obj = (MonoObject*)mono_type_get_object_checked (cattr_type , error); + return NULL; + } else { + return cattr_type; + } + } + case MONO_TYPE_OBJECT: { + if (!bcheck_blob (p, 0, boundp, error)) + return NULL; + char subt = *p++; + MonoObject *obj; + MonoClass *subc = NULL; + void *val; + + if (subt == CATTR_TYPE_SYSTEM_TYPE) { + MonoType *cattr_type = load_cattr_type (image, t, FALSE, p, boundp, end, error, &slen); + if (out_obj) { + if (!cattr_type) + return NULL; + *out_obj = (MonoObject*)mono_type_get_object_checked (cattr_type, error); + return NULL; + } else { + return cattr_type; + } + } else if (subt == 0x0E) { + type = MONO_TYPE_STRING; + goto handle_enum; + } else if (subt == 0x1D) { + MonoType simple_type = {{0}}; + if (!bcheck_blob (p, 0, boundp, error)) + return NULL; + int etype = *p; + p ++; + + type = MONO_TYPE_SZARRAY; + if (etype == CATTR_TYPE_SYSTEM_TYPE) { + tklass = mono_defaults.systemtype_class; + } else if (etype == MONO_TYPE_ENUM) { + tklass = load_cattr_enum_type (image, p, boundp, &p, error); + if (!is_ok (error)) + return NULL; + } else { + if (etype == CATTR_BOXED_VALUETYPE_PREFIX) + /* See Partition II, Appendix B3 */ + etype = MONO_TYPE_OBJECT; + simple_type.type = (MonoTypeEnum)etype; + tklass = mono_class_from_mono_type_internal (&simple_type); + } + goto handle_enum; + } else if (subt == MONO_TYPE_ENUM) { + char *n; + MonoType *enum_type; + if (!decode_blob_value_checked (p, boundp, &slen, &p, error)) + return NULL; + if (slen > 0 && !bcheck_blob (p, slen - 1, boundp, error)) + return NULL; + n = (char *)g_memdup (p, slen + 1); + n [slen] = 0; + enum_type = cattr_type_from_name (n, image, FALSE, error); + g_free (n); + return_val_if_nok (error, NULL); + p += slen; + subc = mono_class_from_mono_type_internal (enum_type); + } else if (subt >= MONO_TYPE_BOOLEAN && subt <= MONO_TYPE_R8) { + MonoType simple_type = {{0}}; + simple_type.type = (MonoTypeEnum)subt; + subc = mono_class_from_mono_type_internal (&simple_type); + } else { + g_error ("Unknown type 0x%02x for object type encoding in custom attr", subt); + } + val = load_cattr_value_noalloc (image, m_class_get_byval_arg (subc), NULL, p, boundp, end, error); + if (is_ok (error)) { + obj = mono_object_new_checked (subc, error); + g_assert (!m_class_has_references (subc)); + if (is_ok (error)) + mono_gc_memmove_atomic (mono_object_get_data (obj), val, mono_class_value_size (subc, NULL)); + g_assert (out_obj); + *out_obj = obj; + } + + g_free (val); + return NULL; + } + case MONO_TYPE_SZARRAY: { + MonoArray *arr = NULL; + guint32 i, alen, basetype; + + if (!bcheck_blob (p, 3, boundp, error)) + return NULL; + alen = read32 (p); + p += 4; + if (alen == 0xffffffff) { + *end = p; + return NULL; + } + + if (out_obj) { + arr = mono_array_new_checked (tklass, alen, error); + return_val_if_nok (error, NULL); + } + + basetype = m_class_get_byval_arg (tklass)->type; + if (basetype == MONO_TYPE_VALUETYPE && m_class_is_enumtype (tklass)) + basetype = mono_class_enum_basetype_internal (tklass)->type; + + if (basetype == MONO_TYPE_GENERICINST) { + MonoGenericClass * mgc = m_class_get_byval_arg (tklass)->data.generic_class; + MonoClass * cc = mgc->container_class; + if (m_class_is_enumtype (cc)) { + basetype = m_class_get_byval_arg (m_class_get_element_class (cc))->type; + } else { + g_error ("Unhandled type of generic instance in load_cattr_value_noalloc: %s[]", m_class_get_name (cc)); + } + } + + switch (basetype) { + case MONO_TYPE_U1: + case MONO_TYPE_I1: + case MONO_TYPE_BOOLEAN: + for (i = 0; i < alen; i++) { + if (!bcheck_blob (p, 0, boundp, error)) + return NULL; + MonoBoolean val = *p++; + if (arr) + mono_array_set_internal (arr, MonoBoolean, i, val); + } + break; + case MONO_TYPE_CHAR: + case MONO_TYPE_U2: + case MONO_TYPE_I2: + for (i = 0; i < alen; i++) { + if (!bcheck_blob (p, 1, boundp, error)) + return NULL; + guint16 val = read16 (p); + if (arr) + mono_array_set_internal (arr, guint16, i, val); + p += 2; + } + break; + case MONO_TYPE_R4: + case MONO_TYPE_U4: + case MONO_TYPE_I4: + for (i = 0; i < alen; i++) { + if (!bcheck_blob (p, 3, boundp, error)) + return NULL; + guint32 val = read32 (p); + if (arr) + mono_array_set_internal (arr, guint32, i, val); + p += 4; + } + break; + case MONO_TYPE_R8: + for (i = 0; i < alen; i++) { + if (!bcheck_blob (p, 7, boundp, error)) + return NULL; + double val; + readr8 (p, &val); + if (arr) + mono_array_set_internal (arr, double, i, val); + p += 8; + } + break; + case MONO_TYPE_U8: + case MONO_TYPE_I8: + for (i = 0; i < alen; i++) { + if (!bcheck_blob (p, 7, boundp, error)) + return NULL; + guint64 val = read64 (p); + if (arr) + mono_array_set_internal (arr, guint64, i, val); + p += 8; + } + break; + case MONO_TYPE_CLASS: + case MONO_TYPE_OBJECT: + case MONO_TYPE_STRING: + case MONO_TYPE_SZARRAY: { + if (arr) { + HANDLE_FUNCTION_ENTER (); + MONO_HANDLE_NEW (MonoArray, arr); + + for (i = 0; i < alen; i++) { + MonoObject *item = NULL; + load_cattr_value_noalloc (image, m_class_get_byval_arg (tklass), &item, p, boundp, &p, error); + if (!is_ok (error)) + return NULL; + mono_array_setref_internal (arr, i, item); + } + HANDLE_FUNCTION_RETURN (); + } else { + for (i = 0; i < alen; i++) { + MonoObject *item = NULL; + load_cattr_value_noalloc (image, m_class_get_byval_arg (tklass), &item, p, boundp, &p, error); + if (!is_ok (error)) + return NULL; + } + } + break; + } + default: + g_error ("Type 0x%02x not handled in custom attr array decoding", basetype); + } + *end = p; + + if (out_obj) + *out_obj = (MonoObject*)arr; + return NULL; + } + default: + g_error ("Type 0x%02x not handled in custom attr value decoding", type); + } + return NULL; +} + static MonoObject* load_cattr_value_boxed (MonoDomain *domain, MonoImage *image, MonoType *t, const char* p, const char *boundp, const char** end, MonoError *error) { @@ -1263,7 +1616,7 @@ mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMeth typed_args = g_new0 (gpointer, sig->param_count); for (i = 0; i < sig->param_count; ++i) { - typed_args [i] = load_cattr_value (image, sig->params [i], NULL, p, data_end, &p, error); + typed_args [i] = load_cattr_value_noalloc (image, sig->params [i], NULL, p, data_end, &p, error); return_if_nok (error); } @@ -1332,7 +1685,7 @@ mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMeth arginfo [j].type = field->type; arginfo [j].field = field; - named_args [j] = load_cattr_value (image, field->type, NULL, named, data_end, &named, error); + named_args [j] = load_cattr_value_noalloc (image, field->type, NULL, named, data_end, &named, error); if (!is_ok (error)) { g_free (name); goto fail; @@ -1353,7 +1706,7 @@ mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMeth arginfo [j].type = prop_type; arginfo [j].prop = prop; - named_args [j] = load_cattr_value (image, prop_type, NULL, named, data_end, &named, error); + named_args [j] = load_cattr_value_noalloc (image, prop_type, NULL, named, data_end, &named, error); if (!is_ok (error)) { g_free (name); goto fail; From 2bf15b130a6c2ea2a0bcfcbf117145e75fb1152c Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Fri, 13 May 2022 12:56:27 +0200 Subject: [PATCH 02/24] Removing redundant parameter and some of managed objects handling --- src/mono/mono/metadata/custom-attrs.c | 121 ++++++++------------------ 1 file changed, 34 insertions(+), 87 deletions(-) diff --git a/src/mono/mono/metadata/custom-attrs.c b/src/mono/mono/metadata/custom-attrs.c index 70ab6988f75010..15655e449c5fc9 100644 --- a/src/mono/mono/metadata/custom-attrs.c +++ b/src/mono/mono/metadata/custom-attrs.c @@ -630,14 +630,12 @@ MONO_RESTORE_WARNING * Load custrom attribute without mono allocation - invoked from AOT compiler */ static void* -load_cattr_value_noalloc (MonoImage *image, MonoType *t, MonoObject **out_obj, const char *p, const char *boundp, const char **end, MonoError *error) +load_cattr_value_noalloc (MonoImage *image, MonoType *t, const char *p, const char *boundp, const char **end, MonoError *error) { int type = t->type; guint32 slen; MonoClass *tklass = t->data.klass; - if (out_obj) - *out_obj = NULL; g_assert (boundp); error_init (error); @@ -745,31 +743,10 @@ MONO_RESTORE_WARNING if (slen > 0 && !bcheck_blob (p, slen - 1, boundp, error)) return NULL; *end = p + slen; - if (!out_obj) - 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 - // to decode some attributes in assemblies that Windows .NET Framework - // and CoreCLR both manage to decode. - // See https://simonsapin.github.io/wtf-8/ for a description of wtf-8. - // Always use string.Empty for empty strings - if (slen == 0) - *out_obj = (MonoObject*)mono_string_empty_internal (mono_domain_get ()); - else - *out_obj = (MonoObject*)mono_string_new_wtf8_len_checked (p, slen, error); - return NULL; + return (void*)start; } case MONO_TYPE_CLASS: { - MonoType *cattr_type = load_cattr_type (image, t, TRUE, p, boundp, end, error, &slen); - if (out_obj) { - if (!cattr_type ) - return NULL; - *out_obj = (MonoObject*)mono_type_get_object_checked (cattr_type , error); - return NULL; - } else { - return cattr_type; - } + return load_cattr_type (image, t, TRUE, p, boundp, end, error, &slen); } case MONO_TYPE_OBJECT: { if (!bcheck_blob (p, 0, boundp, error)) @@ -780,15 +757,7 @@ MONO_RESTORE_WARNING void *val; if (subt == CATTR_TYPE_SYSTEM_TYPE) { - MonoType *cattr_type = load_cattr_type (image, t, FALSE, p, boundp, end, error, &slen); - if (out_obj) { - if (!cattr_type) - return NULL; - *out_obj = (MonoObject*)mono_type_get_object_checked (cattr_type, error); - return NULL; - } else { - return cattr_type; - } + return load_cattr_type (image, t, FALSE, p, boundp, end, error, &slen); } else if (subt == 0x0E) { type = MONO_TYPE_STRING; goto handle_enum; @@ -835,21 +804,24 @@ MONO_RESTORE_WARNING } else { g_error ("Unknown type 0x%02x for object type encoding in custom attr", subt); } - val = load_cattr_value_noalloc (image, m_class_get_byval_arg (subc), NULL, p, boundp, end, error); - if (is_ok (error)) { - obj = mono_object_new_checked (subc, error); - g_assert (!m_class_has_references (subc)); - if (is_ok (error)) - mono_gc_memmove_atomic (mono_object_get_data (obj), val, mono_class_value_size (subc, NULL)); - g_assert (out_obj); - *out_obj = obj; - } - - g_free (val); + val = load_cattr_value_noalloc (image, m_class_get_byval_arg (subc), p, boundp, end, error); + + // TODO: check this below, for now just assert + g_assert(FALSE); + + // if (is_ok (error)) { + // obj = mono_object_new_checked (subc, error); + // g_assert (!m_class_has_references (subc)); + // if (is_ok (error)) + // mono_gc_memmove_atomic (mono_object_get_data (obj), val, mono_class_value_size (subc, NULL)); + // g_assert (out_obj); + // *out_obj = obj; + // } + + // g_free (val); return NULL; } case MONO_TYPE_SZARRAY: { - MonoArray *arr = NULL; guint32 i, alen, basetype; if (!bcheck_blob (p, 3, boundp, error)) @@ -861,11 +833,6 @@ MONO_RESTORE_WARNING return NULL; } - if (out_obj) { - arr = mono_array_new_checked (tklass, alen, error); - return_val_if_nok (error, NULL); - } - basetype = m_class_get_byval_arg (tklass)->type; if (basetype == MONO_TYPE_VALUETYPE && m_class_is_enumtype (tklass)) basetype = mono_class_enum_basetype_internal (tklass)->type; @@ -888,8 +855,7 @@ MONO_RESTORE_WARNING if (!bcheck_blob (p, 0, boundp, error)) return NULL; MonoBoolean val = *p++; - if (arr) - mono_array_set_internal (arr, MonoBoolean, i, val); + // TODO: add to array } break; case MONO_TYPE_CHAR: @@ -899,8 +865,7 @@ MONO_RESTORE_WARNING if (!bcheck_blob (p, 1, boundp, error)) return NULL; guint16 val = read16 (p); - if (arr) - mono_array_set_internal (arr, guint16, i, val); + // TODO: add to array p += 2; } break; @@ -911,8 +876,7 @@ MONO_RESTORE_WARNING if (!bcheck_blob (p, 3, boundp, error)) return NULL; guint32 val = read32 (p); - if (arr) - mono_array_set_internal (arr, guint32, i, val); + // TODO: add to array p += 4; } break; @@ -922,8 +886,7 @@ MONO_RESTORE_WARNING return NULL; double val; readr8 (p, &val); - if (arr) - mono_array_set_internal (arr, double, i, val); + // TODO: add to array p += 8; } break; @@ -933,8 +896,7 @@ MONO_RESTORE_WARNING if (!bcheck_blob (p, 7, boundp, error)) return NULL; guint64 val = read64 (p); - if (arr) - mono_array_set_internal (arr, guint64, i, val); + // TODO: add to array p += 8; } break; @@ -942,25 +904,11 @@ MONO_RESTORE_WARNING case MONO_TYPE_OBJECT: case MONO_TYPE_STRING: case MONO_TYPE_SZARRAY: { - if (arr) { - HANDLE_FUNCTION_ENTER (); - MONO_HANDLE_NEW (MonoArray, arr); - - for (i = 0; i < alen; i++) { - MonoObject *item = NULL; - load_cattr_value_noalloc (image, m_class_get_byval_arg (tklass), &item, p, boundp, &p, error); - if (!is_ok (error)) - return NULL; - mono_array_setref_internal (arr, i, item); - } - HANDLE_FUNCTION_RETURN (); - } else { - for (i = 0; i < alen; i++) { - MonoObject *item = NULL; - load_cattr_value_noalloc (image, m_class_get_byval_arg (tklass), &item, p, boundp, &p, error); - if (!is_ok (error)) - return NULL; - } + for (i = 0; i < alen; i++) { + gpointer* dummy = load_cattr_value_noalloc (image, m_class_get_byval_arg (tklass), p, boundp, &p, error); + if (!is_ok (error)) + return NULL; + // TODO: add to array } break; } @@ -968,9 +916,8 @@ MONO_RESTORE_WARNING g_error ("Type 0x%02x not handled in custom attr array decoding", basetype); } *end = p; - - if (out_obj) - *out_obj = (MonoObject*)arr; + + // TODO: return array return NULL; } default: @@ -1616,7 +1563,7 @@ mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMeth typed_args = g_new0 (gpointer, sig->param_count); for (i = 0; i < sig->param_count; ++i) { - typed_args [i] = load_cattr_value_noalloc (image, sig->params [i], NULL, p, data_end, &p, error); + typed_args [i] = load_cattr_value_noalloc (image, sig->params [i], p, data_end, &p, error); return_if_nok (error); } @@ -1685,7 +1632,7 @@ mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMeth arginfo [j].type = field->type; arginfo [j].field = field; - named_args [j] = load_cattr_value_noalloc (image, field->type, NULL, named, data_end, &named, error); + named_args [j] = load_cattr_value_noalloc (image, field->type, named, data_end, &named, error); if (!is_ok (error)) { g_free (name); goto fail; @@ -1706,7 +1653,7 @@ mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMeth arginfo [j].type = prop_type; arginfo [j].prop = prop; - named_args [j] = load_cattr_value_noalloc (image, prop_type, NULL, named, data_end, &named, error); + named_args [j] = load_cattr_value_noalloc (image, prop_type, named, data_end, &named, error); if (!is_ok (error)) { g_free (name); goto fail; From a2c5f3826897cc135a4c4e9c13a860ecba8c320e Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Fri, 13 May 2022 15:13:52 +0200 Subject: [PATCH 03/24] Cleaning up the case when object is used as attribute parameter --- src/mono/mono/metadata/custom-attrs.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/mono/mono/metadata/custom-attrs.c b/src/mono/mono/metadata/custom-attrs.c index 15655e449c5fc9..8ee05f3e5f827e 100644 --- a/src/mono/mono/metadata/custom-attrs.c +++ b/src/mono/mono/metadata/custom-attrs.c @@ -752,9 +752,7 @@ MONO_RESTORE_WARNING if (!bcheck_blob (p, 0, boundp, error)) return NULL; char subt = *p++; - MonoObject *obj; MonoClass *subc = NULL; - void *val; if (subt == CATTR_TYPE_SYSTEM_TYPE) { return load_cattr_type (image, t, FALSE, p, boundp, end, error, &slen); @@ -804,22 +802,7 @@ MONO_RESTORE_WARNING } else { g_error ("Unknown type 0x%02x for object type encoding in custom attr", subt); } - val = load_cattr_value_noalloc (image, m_class_get_byval_arg (subc), p, boundp, end, error); - - // TODO: check this below, for now just assert - g_assert(FALSE); - - // if (is_ok (error)) { - // obj = mono_object_new_checked (subc, error); - // g_assert (!m_class_has_references (subc)); - // if (is_ok (error)) - // mono_gc_memmove_atomic (mono_object_get_data (obj), val, mono_class_value_size (subc, NULL)); - // g_assert (out_obj); - // *out_obj = obj; - // } - - // g_free (val); - return NULL; + return load_cattr_value_noalloc (image, m_class_get_byval_arg (subc), p, boundp, end, error); } case MONO_TYPE_SZARRAY: { guint32 i, alen, basetype; From f6d1989b304cb029c0a817a812c0462ac3818702 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Wed, 18 May 2022 17:10:43 +0200 Subject: [PATCH 04/24] Adding support for MonoCustomAttrValue type --- src/mono/mono/metadata/custom-attrs-types.h | 23 ++++ src/mono/mono/metadata/custom-attrs.c | 132 ++++++-------------- src/mono/mono/mini/aot-compiler.c | 20 +++ 3 files changed, 79 insertions(+), 96 deletions(-) create mode 100644 src/mono/mono/metadata/custom-attrs-types.h diff --git a/src/mono/mono/metadata/custom-attrs-types.h b/src/mono/mono/metadata/custom-attrs-types.h new file mode 100644 index 00000000000000..f6845f017fe7b2 --- /dev/null +++ b/src/mono/mono/metadata/custom-attrs-types.h @@ -0,0 +1,23 @@ +/** + * \file + */ + +#ifndef __MONO_CUSTOM_ATTRS_TYPES_H__ +#define __MONO_CUSTOM_ATTRS_TYPES_H__ + +typedef struct _MonoCustomAttrValueArray MonoCustomAttrValueArray; + +typedef struct _MonoCustomAttrValue { + union { + gpointer primitive; /* int/enum/MonoType/string */ + MonoCustomAttrValueArray *array; + } value; + MonoTypeEnum type : 8; +} MonoCustomAttrValue; + +struct _MonoCustomAttrValueArray { + int len; + MonoCustomAttrValue values[MONO_ZERO_LEN_ARRAY]; +}; + +#endif /* __MONO_CUSTOM_ATTRS_TYPES_H__ */ diff --git a/src/mono/mono/metadata/custom-attrs.c b/src/mono/mono/metadata/custom-attrs.c index 8ee05f3e5f827e..f4816158431b82 100644 --- a/src/mono/mono/metadata/custom-attrs.c +++ b/src/mono/mono/metadata/custom-attrs.c @@ -19,6 +19,7 @@ #include "mono/metadata/gc-internals.h" #include "mono/metadata/mono-endian.h" #include "mono/metadata/object-internals.h" +#include "mono/metadata/custom-attrs-types.h" #include "mono/metadata/custom-attrs-internals.h" #include "mono/metadata/sre-internals.h" #include "mono/metadata/reflection-internals.h" @@ -628,13 +629,15 @@ MONO_RESTORE_WARNING /* * Load custrom attribute without mono allocation - invoked from AOT compiler + * Caller needs to deallocate memory of the return value */ -static void* +static MonoCustomAttrValue* load_cattr_value_noalloc (MonoImage *image, MonoType *t, const char *p, const char *boundp, const char **end, MonoError *error) { int type = t->type; guint32 slen; MonoClass *tklass = t->data.klass; + MonoCustomAttrValue* result = (MonoCustomAttrValue *)g_malloc (sizeof (MonoCustomAttrValue)); g_assert (boundp); error_init (error); @@ -650,6 +653,7 @@ load_cattr_value_noalloc (MonoImage *image, MonoType *t, const char *p, const ch g_error ("Unhandled type of generic instance in load_cattr_value_noalloc: %s", m_class_get_name (cc)); } } + result->type = type; handle_enum: switch (type) { @@ -661,7 +665,8 @@ load_cattr_value_noalloc (MonoImage *image, MonoType *t, const char *p, const ch return NULL; *bval = *p; *end = p + 1; - return bval; + result->value.primitive = bval; + return result; } case MONO_TYPE_CHAR: case MONO_TYPE_U2: @@ -671,7 +676,8 @@ load_cattr_value_noalloc (MonoImage *image, MonoType *t, const char *p, const ch return NULL; *val = read16 (p); *end = p + 2; - return val; + result->value.primitive = val; + return result; } #if SIZEOF_VOID_P == 4 case MONO_TYPE_U: @@ -685,7 +691,8 @@ load_cattr_value_noalloc (MonoImage *image, MonoType *t, const char *p, const ch return NULL; *val = read32 (p); *end = p + 4; - return val; + result->value.primitive = val; + return result; } #if SIZEOF_VOID_P == 8 case MONO_TYPE_U: /* error out instead? this should probably not happen */ @@ -698,7 +705,8 @@ load_cattr_value_noalloc (MonoImage *image, MonoType *t, const char *p, const ch return NULL; *val = read64 (p); *end = p + 8; - return val; + result->value.primitive = val; + return result; } case MONO_TYPE_R8: { double *val = (double *)g_malloc (sizeof (double)); @@ -706,7 +714,8 @@ load_cattr_value_noalloc (MonoImage *image, MonoType *t, const char *p, const ch return NULL; readr8 (p, val); *end = p + 8; - return val; + result->value.primitive = val; + return result; } case MONO_TYPE_VALUETYPE: if (m_class_is_enumtype (t->data.klass)) { @@ -721,7 +730,8 @@ load_cattr_value_noalloc (MonoImage *image, MonoType *t, const char *p, const ch return NULL; *val = read64 (p); *end = p + 8; - return val; + result->value.primitive = val; + return result; } } g_error ("generic valutype %s not handled in custom attr value decoding", m_class_get_name (t->data.klass)); @@ -743,10 +753,12 @@ MONO_RESTORE_WARNING if (slen > 0 && !bcheck_blob (p, slen - 1, boundp, error)) return NULL; *end = p + slen; - return (void*)start; + result->value.primitive = (gpointer)start; + return result; } case MONO_TYPE_CLASS: { - return load_cattr_type (image, t, TRUE, p, boundp, end, error, &slen); + result->value.primitive = load_cattr_type (image, t, TRUE, p, boundp, end, error, &slen);; + return result; } case MONO_TYPE_OBJECT: { if (!bcheck_blob (p, 0, boundp, error)) @@ -755,7 +767,8 @@ MONO_RESTORE_WARNING MonoClass *subc = NULL; if (subt == CATTR_TYPE_SYSTEM_TYPE) { - return load_cattr_type (image, t, FALSE, p, boundp, end, error, &slen); + result->value.primitive = load_cattr_type (image, t, FALSE, p, boundp, end, error, &slen); + return result; } else if (subt == 0x0E) { type = MONO_TYPE_STRING; goto handle_enum; @@ -802,10 +815,11 @@ MONO_RESTORE_WARNING } else { g_error ("Unknown type 0x%02x for object type encoding in custom attr", subt); } - return load_cattr_value_noalloc (image, m_class_get_byval_arg (subc), p, boundp, end, error); + result->value.primitive = load_cattr_value_noalloc (image, m_class_get_byval_arg (subc), p, boundp, end, error); + return result; } case MONO_TYPE_SZARRAY: { - guint32 i, alen, basetype; + guint32 i, alen; if (!bcheck_blob (p, 3, boundp, error)) return NULL; @@ -816,92 +830,17 @@ MONO_RESTORE_WARNING return NULL; } - basetype = m_class_get_byval_arg (tklass)->type; - if (basetype == MONO_TYPE_VALUETYPE && m_class_is_enumtype (tklass)) - basetype = mono_class_enum_basetype_internal (tklass)->type; + result->value.array = g_malloc (sizeof (MonoCustomAttrValueArray) + alen * sizeof (MonoCustomAttrValue)); + result->value.array->len = alen; - if (basetype == MONO_TYPE_GENERICINST) { - MonoGenericClass * mgc = m_class_get_byval_arg (tklass)->data.generic_class; - MonoClass * cc = mgc->container_class; - if (m_class_is_enumtype (cc)) { - basetype = m_class_get_byval_arg (m_class_get_element_class (cc))->type; - } else { - g_error ("Unhandled type of generic instance in load_cattr_value_noalloc: %s[]", m_class_get_name (cc)); - } - } - - switch (basetype) { - case MONO_TYPE_U1: - case MONO_TYPE_I1: - case MONO_TYPE_BOOLEAN: - for (i = 0; i < alen; i++) { - if (!bcheck_blob (p, 0, boundp, error)) - return NULL; - MonoBoolean val = *p++; - // TODO: add to array - } - break; - case MONO_TYPE_CHAR: - case MONO_TYPE_U2: - case MONO_TYPE_I2: - for (i = 0; i < alen; i++) { - if (!bcheck_blob (p, 1, boundp, error)) - return NULL; - guint16 val = read16 (p); - // TODO: add to array - p += 2; - } - break; - case MONO_TYPE_R4: - case MONO_TYPE_U4: - case MONO_TYPE_I4: - for (i = 0; i < alen; i++) { - if (!bcheck_blob (p, 3, boundp, error)) - return NULL; - guint32 val = read32 (p); - // TODO: add to array - p += 4; - } - break; - case MONO_TYPE_R8: - for (i = 0; i < alen; i++) { - if (!bcheck_blob (p, 7, boundp, error)) - return NULL; - double val; - readr8 (p, &val); - // TODO: add to array - p += 8; - } - break; - case MONO_TYPE_U8: - case MONO_TYPE_I8: - for (i = 0; i < alen; i++) { - if (!bcheck_blob (p, 7, boundp, error)) - return NULL; - guint64 val = read64 (p); - // TODO: add to array - p += 8; - } - break; - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - case MONO_TYPE_SZARRAY: { - for (i = 0; i < alen; i++) { - gpointer* dummy = load_cattr_value_noalloc (image, m_class_get_byval_arg (tklass), p, boundp, &p, error); - if (!is_ok (error)) - return NULL; - // TODO: add to array - } - break; - } - default: - g_error ("Type 0x%02x not handled in custom attr array decoding", basetype); + for (i = 0; i < alen; i++) { + MonoCustomAttrValue* array_element = load_cattr_value_noalloc (image, m_class_get_byval_arg (tklass), p, boundp, &p, error); + if (!is_ok (error)) + return NULL; + result->value.array->values[i] = *array_element; } *end = p; - - // TODO: return array - return NULL; + return result; } default: g_error ("Type 0x%02x not handled in custom attr value decoding", type); @@ -1615,7 +1554,8 @@ mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMeth arginfo [j].type = field->type; arginfo [j].field = field; - named_args [j] = load_cattr_value_noalloc (image, field->type, named, data_end, &named, error); + named_args [j] = load_cattr_value_noalloc (image, field->type, named, data_end, &named, error); + if (!is_ok (error)) { g_free (name); goto fail; diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 3ade4cce92ba9f..6d38d2e8e313a6 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -5202,6 +5203,25 @@ MONO_RESTORE_WARNING memcpy (export_name, named, slen); export_name [slen] = 0; } + if (named_arg_info [j].field && !strcmp (named_arg_info [j].field->name, "CallConvs")) { + MonoCustomAttrValue* arg_value = (MonoCustomAttrValue*) named_args [j]; + g_assert(arg_value->type == MONO_TYPE_SZARRAY); + + MonoCustomAttrValueArray* value_array = (MonoCustomAttrValueArray*) arg_value->value.array; + g_assert(value_array->len == 1); + + MonoType* specified_type = (MonoType*)value_array->values[0].value.primitive; + g_assert(specified_type->type == MONO_TYPE_CLASS); + + MonoClass *cmod_klass = mono_class_from_mono_type_internal (specified_type); + g_assert(m_class_get_image (cmod_klass) == mono_defaults.corlib); + g_assert(!strcmp (m_class_get_name_space (cmod_klass), "System.Runtime.CompilerServices")); + + const char *name = m_class_get_name (cmod_klass); + g_print ("Method %s has UnmanagedCallersOnlyAttribute specified with the following calling convention: %s \n", mono_method_get_full_name (method), name); + + // TODO: free + } } g_free (named_args); g_free (named_arg_info); From ee3a6cef0081d7003137072b0d472001c017476a Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Thu, 19 May 2022 21:03:09 +0200 Subject: [PATCH 05/24] Enable native to managed wrapper to receive calling convention attribute --- src/mono/mono/metadata/marshal.c | 79 +++++++++++++++++++++++++++++++ src/mono/mono/mini/aot-compiler.c | 20 -------- 2 files changed, 79 insertions(+), 20 deletions(-) diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 5f59ef95e22219..d5ec0b943ad7cd 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -56,6 +56,7 @@ MONO_PRAGMA_WARNING_POP() #include "mono/metadata/handle.h" #include "mono/metadata/object-internals.h" #include "mono/metadata/custom-attrs-internals.h" +#include #include "mono/metadata/abi-details.h" #include "mono/metadata/custom-attrs-internals.h" #include "mono/metadata/loader-internals.h" @@ -3350,6 +3351,82 @@ mono_marshal_set_callconv_from_unmanaged_callconv_attribute (MonoMethod *method, mono_custom_attrs_free(cinfo); } +static void mono_marshal_set_signature_callconv_from_attribute(MonoMethodSignature *sig, MonoType *cmod_type, MonoError *error) +{ + g_assert (cmod_type->type == MONO_TYPE_CLASS); + MonoClass *cmod_klass = mono_class_from_mono_type_internal (cmod_type); + g_assert (m_class_get_image (cmod_klass) == mono_defaults.corlib); + g_assert (!strcmp (m_class_get_name_space (cmod_klass), "System.Runtime.CompilerServices")); + + const char *name = m_class_get_name (cmod_klass); + g_assert (!strstr (name, "CallConv") != name); + name += strlen ("CallConv"); + + if (!strcmp (name, "Cdecl")) + sig->call_convention = MONO_CALL_C; + else if (!strcmp (name, "Stdcall")) + sig->call_convention = MONO_CALL_STDCALL; + else if (!strcmp (name, "Thiscall")) + sig->call_convention = MONO_CALL_THISCALL; + else if (!strcmp (name, "Fastcall")) + sig->call_convention = MONO_CALL_FASTCALL; + else if (!strcmp (name, "SuppressGCTransition")) + sig->suppress_gc_transition = 1; + // TODO: CallConvMemberFunction? +} + +static void +mono_marshal_set_callconv_from_unmanaged_callers_only_attribute (MonoMethod *method, MonoMethodSignature *csig) +{ + MonoClass *attr_class = mono_class_try_get_unmanaged_callers_only_attribute_class (); + if (!attr_class) + return; + + ERROR_DECL (error); + MonoCustomAttrInfo *cinfo = mono_custom_attrs_from_method_checked (method, error); + if (!is_ok (error) || !cinfo) { + mono_error_cleanup (error); + return; + } + + mono_array_size_t i; + MonoCustomAttrEntry *attr = NULL; + for (i = 0; i < cinfo->num_attrs; ++i) { + MonoClass *ctor_class = cinfo->attrs [i].ctor->klass; + if (ctor_class == attr_class) { + attr = &cinfo->attrs [i]; + break; + } + } + + if (attr != NULL) + { + 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 (mono_defaults.corlib, attr->ctor, attr->data, attr->data_size, &typed_args, &named_args, &num_named_args, &named_arg_info, error); + for (int i = 0; i < num_named_args; ++i) { + if (named_arg_info [i].field && !strcmp (named_arg_info [i].field->name, "CallConvs")) { + MonoCustomAttrValue* calling_conventions_attr = (MonoCustomAttrValue*) named_args [i]; + g_assert(calling_conventions_attr->type == MONO_TYPE_SZARRAY); + + MonoCustomAttrValueArray* calling_conventions = (MonoCustomAttrValueArray*) calling_conventions_attr->value.array; + g_assert(calling_conventions->len == 1); + + MonoType* calling_convention = (MonoType*)calling_conventions->values[0].value.primitive; + mono_marshal_set_signature_callconv_from_attribute (csig, calling_convention, error); + } + } + g_free (named_args); + g_free (named_arg_info); + } + + if (!cinfo->cached) + mono_custom_attrs_free(cinfo); +} + + /** * mono_marshal_get_native_wrapper: * \param method The \c MonoMethod to wrap. @@ -4045,6 +4122,8 @@ mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, if (invoke) mono_marshal_set_callconv_from_modopt (invoke, csig, TRUE); + else + mono_marshal_set_callconv_from_unmanaged_callers_only_attribute(method, csig); /* The attribute is only available in Net 2.0 */ if (delegate_klass && mono_class_try_get_unmanaged_function_pointer_attribute_class ()) { diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 6d38d2e8e313a6..3ade4cce92ba9f 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include @@ -5203,25 +5202,6 @@ MONO_RESTORE_WARNING memcpy (export_name, named, slen); export_name [slen] = 0; } - if (named_arg_info [j].field && !strcmp (named_arg_info [j].field->name, "CallConvs")) { - MonoCustomAttrValue* arg_value = (MonoCustomAttrValue*) named_args [j]; - g_assert(arg_value->type == MONO_TYPE_SZARRAY); - - MonoCustomAttrValueArray* value_array = (MonoCustomAttrValueArray*) arg_value->value.array; - g_assert(value_array->len == 1); - - MonoType* specified_type = (MonoType*)value_array->values[0].value.primitive; - g_assert(specified_type->type == MONO_TYPE_CLASS); - - MonoClass *cmod_klass = mono_class_from_mono_type_internal (specified_type); - g_assert(m_class_get_image (cmod_klass) == mono_defaults.corlib); - g_assert(!strcmp (m_class_get_name_space (cmod_klass), "System.Runtime.CompilerServices")); - - const char *name = m_class_get_name (cmod_klass); - g_print ("Method %s has UnmanagedCallersOnlyAttribute specified with the following calling convention: %s \n", mono_method_get_full_name (method), name); - - // TODO: free - } } g_free (named_args); g_free (named_arg_info); From 66db12d4063624e59ae5a9ac3e669d21394a2514 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Fri, 20 May 2022 11:16:49 +0200 Subject: [PATCH 06/24] Removing type information from MonoCustomAttrValue - the type is available in CattrNameArg --- src/mono/mono/metadata/custom-attrs-types.h | 1 - src/mono/mono/metadata/custom-attrs.c | 1 - 2 files changed, 2 deletions(-) diff --git a/src/mono/mono/metadata/custom-attrs-types.h b/src/mono/mono/metadata/custom-attrs-types.h index f6845f017fe7b2..f84d6721e0013b 100644 --- a/src/mono/mono/metadata/custom-attrs-types.h +++ b/src/mono/mono/metadata/custom-attrs-types.h @@ -12,7 +12,6 @@ typedef struct _MonoCustomAttrValue { gpointer primitive; /* int/enum/MonoType/string */ MonoCustomAttrValueArray *array; } value; - MonoTypeEnum type : 8; } MonoCustomAttrValue; struct _MonoCustomAttrValueArray { diff --git a/src/mono/mono/metadata/custom-attrs.c b/src/mono/mono/metadata/custom-attrs.c index f4816158431b82..be5ae219bedf54 100644 --- a/src/mono/mono/metadata/custom-attrs.c +++ b/src/mono/mono/metadata/custom-attrs.c @@ -653,7 +653,6 @@ load_cattr_value_noalloc (MonoImage *image, MonoType *t, const char *p, const ch g_error ("Unhandled type of generic instance in load_cattr_value_noalloc: %s", m_class_get_name (cc)); } } - result->type = type; handle_enum: switch (type) { From ef5190fd6f82f159266b686d4c7903e4775a2e9e Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Fri, 20 May 2022 11:17:29 +0200 Subject: [PATCH 07/24] Adding error info when asserting --- src/mono/mono/metadata/marshal.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index d5ec0b943ad7cd..40933c7cbabbc8 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -3409,11 +3409,11 @@ mono_marshal_set_callconv_from_unmanaged_callers_only_attribute (MonoMethod *met for (int i = 0; i < num_named_args; ++i) { if (named_arg_info [i].field && !strcmp (named_arg_info [i].field->name, "CallConvs")) { MonoCustomAttrValue* calling_conventions_attr = (MonoCustomAttrValue*) named_args [i]; - g_assert(calling_conventions_attr->type == MONO_TYPE_SZARRAY); + g_assertf(named_arg_info [i].field->type->type == MONO_TYPE_SZARRAY, "UnmanagedCallersOnlyAttribute parameter %s must be an array, specified for method %s", named_arg_info [i].field->name, method->name); MonoCustomAttrValueArray* calling_conventions = (MonoCustomAttrValueArray*) calling_conventions_attr->value.array; - g_assert(calling_conventions->len == 1); - + g_assertf(calling_conventions->len == 1, "Only a single calling convention is supported for UnmanagedCallersOnlyAttribute parameter %s, specified for method %s", named_arg_info [i].field->name, method->name); + MonoType* calling_convention = (MonoType*)calling_conventions->values[0].value.primitive; mono_marshal_set_signature_callconv_from_attribute (csig, calling_convention, error); } From 9a690c0efe0d293d0515792e85f6764c8fb6557b Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Fri, 20 May 2022 11:30:37 +0200 Subject: [PATCH 08/24] Cleanup --- src/mono/mono/metadata/marshal.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 40933c7cbabbc8..324fba579143a2 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -3372,7 +3372,10 @@ static void mono_marshal_set_signature_callconv_from_attribute(MonoMethodSignatu sig->call_convention = MONO_CALL_FASTCALL; else if (!strcmp (name, "SuppressGCTransition")) sig->suppress_gc_transition = 1; - // TODO: CallConvMemberFunction? + // TODO: Support CallConvMemberFunction? + // TODO: Support multiple calling convetions? + // - Switch MonoCallConvention enum values to powers of 2 + // - Adjust the code above with 'anding' the attribute parameter value } static void @@ -3416,6 +3419,8 @@ mono_marshal_set_callconv_from_unmanaged_callers_only_attribute (MonoMethod *met MonoType* calling_convention = (MonoType*)calling_conventions->values[0].value.primitive; mono_marshal_set_signature_callconv_from_attribute (csig, calling_convention, error); + + g_free(calling_conventions); } } g_free (named_args); From d5e927e54258a70fa512450441de947901f8d42c Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Mon, 23 May 2022 11:22:47 +0200 Subject: [PATCH 09/24] Fix handling return values of mono_reflection_create_custom_attr_data_args_noalloc --- src/mono/mono/component/debugger-agent.c | 7 ++++++- src/mono/mono/metadata/marshal-shared.c | 11 +++++++++-- src/mono/mono/metadata/marshal.c | 11 +++++++---- src/mono/mono/metadata/native-library.c | 5 ++++- src/mono/mono/mini/aot-compiler.c | 5 ++++- src/mono/mono/mini/driver.c | 5 ++++- 6 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/mono/mono/component/debugger-agent.c b/src/mono/mono/component/debugger-agent.c index 75b2e0d9d94400..9e67fe9248d8fc 100644 --- a/src/mono/mono/component/debugger-agent.c +++ b/src/mono/mono/component/debugger-agent.c @@ -91,6 +91,7 @@ #include "debugger-engine.h" #include #include +#include #include #include @@ -2934,6 +2935,7 @@ static gint32 isFixedSizeArray (MonoClassField *f) gpointer *typed_args, *named_args; CattrNamedArg *arginfo; int num_named_args; + MonoCustomAttrValue *attr_value; mono_reflection_create_custom_attr_data_args_noalloc (mono_get_corlib (), attr->ctor, attr->data, attr->data_size, &typed_args, &named_args, &num_named_args, &arginfo, error); @@ -2941,7 +2943,10 @@ static gint32 isFixedSizeArray (MonoClassField *f) ret = 0; goto leave; } - ret = *(gint32*)typed_args [1]; + + attr_value = (MonoCustomAttrValue*)typed_args[1]; + ret = *(gint32*)attr_value->value.primitive; + g_free (typed_args [1]); g_free (typed_args); g_free (named_args); diff --git a/src/mono/mono/metadata/marshal-shared.c b/src/mono/mono/metadata/marshal-shared.c index 9d8f37bfa86346..c48666b14da807 100644 --- a/src/mono/mono/metadata/marshal-shared.c +++ b/src/mono/mono/metadata/marshal-shared.c @@ -8,6 +8,7 @@ #include "metadata/marshal-shared.h" #include "metadata/method-builder-ilgen.h" #include "metadata/custom-attrs-internals.h" +#include "metadata/custom-attrs-types.h" #include "metadata/class-init.h" #include "mono/metadata/class-internals.h" #include "metadata/reflection-internals.h" @@ -221,13 +222,19 @@ mono_marshal_shared_get_fixed_buffer_attr (MonoClassField *field, MonoType **out gpointer *typed_args, *named_args; CattrNamedArg *arginfo; int num_named_args; + MonoCustomAttrValue *etype_attr_value, *len_attr_value; mono_reflection_create_custom_attr_data_args_noalloc (mono_defaults.corlib, attr->ctor, attr->data, attr->data_size, &typed_args, &named_args, &num_named_args, &arginfo, error); if (!is_ok (error)) return FALSE; - *out_etype = (MonoType*)typed_args [0]; - *out_len = *(gint32*)typed_args [1]; + + etype_attr_value = (MonoCustomAttrValue*)typed_args[0]; + *out_etype = (MonoType*)etype_attr_value->value.primitive; + + len_attr_value = (MonoCustomAttrValue*)typed_args[1]; + *out_len = *(gint32*)len_attr_value->value.primitive; + g_free (typed_args [1]); g_free (typed_args); g_free (named_args); diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 324fba579143a2..023875a1d8b544 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -56,7 +56,7 @@ MONO_PRAGMA_WARNING_POP() #include "mono/metadata/handle.h" #include "mono/metadata/object-internals.h" #include "mono/metadata/custom-attrs-internals.h" -#include +#include "mono/metadata/custom-attrs-types.h" #include "mono/metadata/abi-details.h" #include "mono/metadata/custom-attrs-internals.h" #include "mono/metadata/loader-internals.h" @@ -4159,22 +4159,25 @@ mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, gint32 charset = 0; MonoBoolean set_last_error = 0; int num_named_args; + MonoCustomAttrValue *call_conv_attr_value; mono_reflection_create_custom_attr_data_args_noalloc (mono_defaults.corlib, attr->ctor, attr->data, attr->data_size, &typed_args, &named_args, &num_named_args, &arginfo, error); g_assert (is_ok (error)); /* typed args */ - call_conv = *(gint32*)typed_args [0]; + call_conv_attr_value = (MonoCustomAttrValue*)typed_args [0]; + call_conv = *(gint32*)call_conv_attr_value->value.primitive; /* named args */ for (i = 0; i < num_named_args; ++i) { CattrNamedArg *narg = &arginfo [i]; + MonoCustomAttrValue *attr_value = (MonoCustomAttrValue*)named_args [i]; g_assert (narg->field); if (!strcmp (narg->field->name, "CharSet")) { - charset = *(gint32*)named_args [i]; + charset = *(gint32*)attr_value->value.primitive; } else if (!strcmp (narg->field->name, "SetLastError")) { - set_last_error = *(MonoBoolean*)named_args [i]; + set_last_error = *(MonoBoolean*)attr_value->value.primitive; } else if (!strcmp (narg->field->name, "BestFitMapping")) { // best_fit_mapping = *(MonoBoolean*)mono_object_unbox_internal (o); } else if (!strcmp (narg->field->name, "ThrowOnUnmappableChar")) { diff --git a/src/mono/mono/metadata/native-library.c b/src/mono/mono/metadata/native-library.c index 9b86e48b3e68cb..50ba73037c3287 100644 --- a/src/mono/mono/metadata/native-library.c +++ b/src/mono/mono/metadata/native-library.c @@ -12,6 +12,7 @@ #include "mono/utils/mono-path.h" #include "mono/metadata/native-library.h" #include "mono/metadata/custom-attrs-internals.h" +#include "mono/metadata/custom-attrs-types.h" static int pinvoke_search_directories_count; static char **pinvoke_search_directories; @@ -947,6 +948,7 @@ get_dllimportsearchpath_flags (MonoCustomAttrInfo *cinfo) gpointer *typed_args, *named_args; CattrNamedArg *arginfo; int num_named_args; + MonoCustomAttrValue *flags_attr_value; mono_reflection_create_custom_attr_data_args_noalloc (m_class_get_image (attr->ctor->klass), attr->ctor, attr->data, attr->data_size, &typed_args, &named_args, &num_named_args, &arginfo, error); @@ -955,7 +957,8 @@ get_dllimportsearchpath_flags (MonoCustomAttrInfo *cinfo) return -4; } - flags = *(gint32*)typed_args [0]; + flags_attr_value = (MonoCustomAttrValue*)typed_args [0]; + flags = *(gint32*)flags_attr_value->value.primitive; g_free (typed_args [0]); g_free (typed_args); g_free (named_args); diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 3ade4cce92ba9f..85c1904bcec278 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -5192,11 +5193,13 @@ MONO_RESTORE_WARNING gpointer *named_args = NULL; CattrNamedArg *named_arg_info = NULL; int num_named_args = 0; + MonoCustomAttrValue *attr_value = NULL; 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]; + attr_value = (MonoCustomAttrValue *)named_args [j]; + named = (const char *)attr_value->value.primitive; slen = mono_metadata_decode_value (named, &named); export_name = (char *)g_malloc (slen + 1); memcpy (export_name, named, slen); diff --git a/src/mono/mono/mini/driver.c b/src/mono/mono/mini/driver.c index 37c892d91ca04d..3568ab546d9e59 100644 --- a/src/mono/mono/mini/driver.c +++ b/src/mono/mono/mini/driver.c @@ -50,6 +50,7 @@ #include "mono/metadata/w32handle.h" #include "mono/metadata/callspec.h" #include "mono/metadata/custom-attrs-internals.h" +#include "mono/metadata/custom-attrs-types.h" #include #include @@ -432,6 +433,7 @@ method_should_be_regression_tested (MonoMethod *method, gboolean interp) gpointer *typed_args, *named_args; int num_named_args; CattrNamedArg *arginfo; + MonoCustomAttrValue *attr_value; mono_reflection_create_custom_attr_data_args_noalloc ( mono_defaults.corlib, centry->ctor, centry->data, centry->data_size, @@ -439,7 +441,8 @@ method_should_be_regression_tested (MonoMethod *method, gboolean interp) if (!is_ok (error)) continue; - const char *arg = (const char*)typed_args [0]; + attr_value = (MonoCustomAttrValue *)typed_args [0]; + const char *arg = (const char*)attr_value->value.primitive; mono_metadata_decode_value (arg, &arg); char *utf8_str = (char*)arg; //this points into image memory that is constant g_free (typed_args); From 04ba8f6afced93f45b5ebafe1e8fb42454905414 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Wed, 25 May 2022 09:59:45 +0200 Subject: [PATCH 10/24] Fix build errors --- src/mono/mono/metadata/marshal.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 023875a1d8b544..b0f1b007c9f7a1 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -3358,10 +3358,11 @@ static void mono_marshal_set_signature_callconv_from_attribute(MonoMethodSignatu g_assert (m_class_get_image (cmod_klass) == mono_defaults.corlib); g_assert (!strcmp (m_class_get_name_space (cmod_klass), "System.Runtime.CompilerServices")); + int calling_convention_id_offset = strlen ("CallConv"); const char *name = m_class_get_name (cmod_klass); - g_assert (!strstr (name, "CallConv") != name); - name += strlen ("CallConv"); + g_assert (!strncmp (name, "CallConv", calling_convention_id_offset)); + name += calling_convention_id_offset; if (!strcmp (name, "Cdecl")) sig->call_convention = MONO_CALL_C; else if (!strcmp (name, "Stdcall")) @@ -3409,7 +3410,7 @@ mono_marshal_set_callconv_from_unmanaged_callers_only_attribute (MonoMethod *met CattrNamedArg *named_arg_info = NULL; int num_named_args = 0; mono_reflection_create_custom_attr_data_args_noalloc (mono_defaults.corlib, attr->ctor, attr->data, attr->data_size, &typed_args, &named_args, &num_named_args, &named_arg_info, error); - for (int i = 0; i < num_named_args; ++i) { + for (i = 0; i < num_named_args; ++i) { if (named_arg_info [i].field && !strcmp (named_arg_info [i].field->name, "CallConvs")) { MonoCustomAttrValue* calling_conventions_attr = (MonoCustomAttrValue*) named_args [i]; g_assertf(named_arg_info [i].field->type->type == MONO_TYPE_SZARRAY, "UnmanagedCallersOnlyAttribute parameter %s must be an array, specified for method %s", named_arg_info [i].field->name, method->name); From f1e073441e80c62c8289db66e9de90948544f2f7 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Wed, 25 May 2022 10:21:10 +0200 Subject: [PATCH 11/24] When multiple conventions are specified generate a warning and take the first one into account, otherwise ignore --- src/mono/mono/metadata/marshal.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index b0f1b007c9f7a1..523ab11ee2a47b 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -3416,11 +3416,13 @@ mono_marshal_set_callconv_from_unmanaged_callers_only_attribute (MonoMethod *met g_assertf(named_arg_info [i].field->type->type == MONO_TYPE_SZARRAY, "UnmanagedCallersOnlyAttribute parameter %s must be an array, specified for method %s", named_arg_info [i].field->name, method->name); MonoCustomAttrValueArray* calling_conventions = (MonoCustomAttrValueArray*) calling_conventions_attr->value.array; - g_assertf(calling_conventions->len == 1, "Only a single calling convention is supported for UnmanagedCallersOnlyAttribute parameter %s, specified for method %s", named_arg_info [i].field->name, method->name); - - MonoType* calling_convention = (MonoType*)calling_conventions->values[0].value.primitive; - mono_marshal_set_signature_callconv_from_attribute (csig, calling_convention, error); - + if (calling_conventions->len > 0) { + if (calling_conventions->len > 1) + g_warning ("Multiple calling conventions are not supported for UnmanagedCallersOnlyAttribute parameter %s, specified for method %s. Only the first calling convention will be taken into account", named_arg_info [i].field->name, method->name); + // TODO: Support multiple conventions? + MonoType* calling_convention = (MonoType*)calling_conventions->values[0].value.primitive; + mono_marshal_set_signature_callconv_from_attribute (csig, calling_convention, error); + } g_free(calling_conventions); } } From a51e9bd5ccfb4bf3443020dc725898fc375ef0d3 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Wed, 25 May 2022 11:06:34 +0200 Subject: [PATCH 12/24] Fix uint to int conversion --- src/mono/mono/metadata/marshal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 523ab11ee2a47b..f71870f8548eb5 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -3358,7 +3358,7 @@ static void mono_marshal_set_signature_callconv_from_attribute(MonoMethodSignatu g_assert (m_class_get_image (cmod_klass) == mono_defaults.corlib); g_assert (!strcmp (m_class_get_name_space (cmod_klass), "System.Runtime.CompilerServices")); - int calling_convention_id_offset = strlen ("CallConv"); + size_t calling_convention_id_offset = strlen ("CallConv"); const char *name = m_class_get_name (cmod_klass); g_assert (!strncmp (name, "CallConv", calling_convention_id_offset)); From 48d99604f1760ee8afe32693c05942d8ef6b4c84 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Wed, 25 May 2022 11:27:21 +0200 Subject: [PATCH 13/24] Reverting "[mono] Avoid an assertion when cattrs with array parameters are constructed during AOT. (#69077)" since 'load_cattr_value' is not used anymore during AOT compiling This reverts commit d2a7a6d7ce968cc36015b8185d9287f5e206163e. --- src/mono/mono/metadata/custom-attrs.c | 57 ++++++++++----------------- 1 file changed, 20 insertions(+), 37 deletions(-) diff --git a/src/mono/mono/metadata/custom-attrs.c b/src/mono/mono/metadata/custom-attrs.c index be5ae219bedf54..8ae355c89ac28f 100644 --- a/src/mono/mono/metadata/custom-attrs.c +++ b/src/mono/mono/metadata/custom-attrs.c @@ -497,7 +497,7 @@ MONO_RESTORE_WARNING return NULL; } case MONO_TYPE_SZARRAY: { - MonoArray *arr = NULL; + MonoArray *arr; guint32 i, alen, basetype; if (!bcheck_blob (p, 3, boundp, error)) @@ -509,10 +509,8 @@ MONO_RESTORE_WARNING return NULL; } - if (out_obj) { - arr = mono_array_new_checked (tklass, alen, error); - return_val_if_nok (error, NULL); - } + arr = mono_array_new_checked (tklass, alen, error); + return_val_if_nok (error, NULL); basetype = m_class_get_byval_arg (tklass)->type; if (basetype == MONO_TYPE_VALUETYPE && m_class_is_enumtype (tklass)) @@ -536,8 +534,7 @@ MONO_RESTORE_WARNING if (!bcheck_blob (p, 0, boundp, error)) return NULL; MonoBoolean val = *p++; - if (arr) - mono_array_set_internal (arr, MonoBoolean, i, val); + mono_array_set_internal (arr, MonoBoolean, i, val); } break; case MONO_TYPE_CHAR: @@ -547,8 +544,7 @@ MONO_RESTORE_WARNING if (!bcheck_blob (p, 1, boundp, error)) return NULL; guint16 val = read16 (p); - if (arr) - mono_array_set_internal (arr, guint16, i, val); + mono_array_set_internal (arr, guint16, i, val); p += 2; } break; @@ -559,8 +555,7 @@ MONO_RESTORE_WARNING if (!bcheck_blob (p, 3, boundp, error)) return NULL; guint32 val = read32 (p); - if (arr) - mono_array_set_internal (arr, guint32, i, val); + mono_array_set_internal (arr, guint32, i, val); p += 4; } break; @@ -570,8 +565,7 @@ MONO_RESTORE_WARNING return NULL; double val; readr8 (p, &val); - if (arr) - mono_array_set_internal (arr, double, i, val); + mono_array_set_internal (arr, double, i, val); p += 8; } break; @@ -581,8 +575,7 @@ MONO_RESTORE_WARNING if (!bcheck_blob (p, 7, boundp, error)) return NULL; guint64 val = read64 (p); - if (arr) - mono_array_set_internal (arr, guint64, i, val); + mono_array_set_internal (arr, guint64, i, val); p += 8; } break; @@ -590,35 +583,26 @@ MONO_RESTORE_WARNING case MONO_TYPE_OBJECT: case MONO_TYPE_STRING: case MONO_TYPE_SZARRAY: { - if (arr) { - HANDLE_FUNCTION_ENTER (); - MONO_HANDLE_NEW (MonoArray, arr); - - for (i = 0; i < alen; i++) { - MonoObject *item = NULL; - load_cattr_value (image, m_class_get_byval_arg (tklass), &item, p, boundp, &p, error); - if (!is_ok (error)) - return NULL; - mono_array_setref_internal (arr, i, item); - } - HANDLE_FUNCTION_RETURN (); - } else { - for (i = 0; i < alen; i++) { - MonoObject *item = NULL; - load_cattr_value (image, m_class_get_byval_arg (tklass), &item, p, boundp, &p, error); - if (!is_ok (error)) - return NULL; - } + HANDLE_FUNCTION_ENTER (); + MONO_HANDLE_NEW (MonoArray, arr); + + for (i = 0; i < alen; i++) { + MonoObject *item = NULL; + load_cattr_value (image, m_class_get_byval_arg (tklass), &item, p, boundp, &p, error); + if (!is_ok (error)) + return NULL; + mono_array_setref_internal (arr, i, item); } + HANDLE_FUNCTION_RETURN (); break; } default: g_error ("Type 0x%02x not handled in custom attr array decoding", basetype); } *end = p; + g_assert (out_obj); + *out_obj = (MonoObject*)arr; - if (out_obj) - *out_obj = (MonoObject*)arr; return NULL; } default: @@ -1447,7 +1431,6 @@ mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *meth * 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. - * For arrays, NULL is returned. * TYPED_ARGS, NAMED_ARGS, and NAMED_ARG_INFO should be freed using g_free (). */ void From e95949ad6ec10c72e3d61c7230f2e16bcf7eabcf Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Wed, 25 May 2022 11:51:05 +0200 Subject: [PATCH 14/24] Cleaning up unreachable code --- src/mono/mono/metadata/custom-attrs.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/src/mono/mono/metadata/custom-attrs.c b/src/mono/mono/metadata/custom-attrs.c index 8ae355c89ac28f..a5b09b3f05e647 100644 --- a/src/mono/mono/metadata/custom-attrs.c +++ b/src/mono/mono/metadata/custom-attrs.c @@ -378,8 +378,6 @@ load_cattr_value (MonoImage *image, MonoType *t, MonoObject **out_obj, const cha break; 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 @@ -393,8 +391,6 @@ MONO_RESTORE_WARNING if (slen > 0 && !bcheck_blob (p, slen - 1, boundp, error)) return NULL; *end = p + slen; - if (!out_obj) - 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 @@ -410,14 +406,10 @@ MONO_RESTORE_WARNING } case MONO_TYPE_CLASS: { MonoType *cattr_type = load_cattr_type (image, t, TRUE, p, boundp, end, error, &slen); - if (out_obj) { - if (!cattr_type ) - return NULL; - *out_obj = (MonoObject*)mono_type_get_object_checked (cattr_type , error); + if (!cattr_type ) return NULL; - } else { - return cattr_type; - } + *out_obj = (MonoObject*)mono_type_get_object_checked (cattr_type , error); + return NULL; } case MONO_TYPE_OBJECT: { if (!bcheck_blob (p, 0, boundp, error)) @@ -429,14 +421,10 @@ MONO_RESTORE_WARNING if (subt == CATTR_TYPE_SYSTEM_TYPE) { MonoType *cattr_type = load_cattr_type (image, t, FALSE, p, boundp, end, error, &slen); - if (out_obj) { - if (!cattr_type) - return NULL; - *out_obj = (MonoObject*)mono_type_get_object_checked (cattr_type, error); + if (!cattr_type) return NULL; - } else { - return cattr_type; - } + *out_obj = (MonoObject*)mono_type_get_object_checked (cattr_type, error); + return NULL; } else if (subt == 0x0E) { type = MONO_TYPE_STRING; goto handle_enum; From 673609e7bd820e97c5d5061a7af5d16c3190e368 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Tue, 24 May 2022 22:50:29 +0200 Subject: [PATCH 15/24] Adding stripped-down version of UnmanagedCallersOnly attribute tests for Mono Aot --- src/tests/Interop/CMakeLists.txt | 1 + .../CMakeLists.txt | 10 +++ .../UnmanagedCallersOnly_MonoAotDll.cpp | 17 +++++ .../UnmanagedCallersOnly_MonoAotTest.cs | 73 +++++++++++++++++++ .../UnmanagedCallersOnly_MonoAotTest.csproj | 14 ++++ 5 files changed, 115 insertions(+) create mode 100644 src/tests/Interop/UnmanagedCallersOnly_MonoAot/CMakeLists.txt create mode 100644 src/tests/Interop/UnmanagedCallersOnly_MonoAot/UnmanagedCallersOnly_MonoAotDll.cpp create mode 100644 src/tests/Interop/UnmanagedCallersOnly_MonoAot/UnmanagedCallersOnly_MonoAotTest.cs create mode 100644 src/tests/Interop/UnmanagedCallersOnly_MonoAot/UnmanagedCallersOnly_MonoAotTest.csproj diff --git a/src/tests/Interop/CMakeLists.txt b/src/tests/Interop/CMakeLists.txt index 2d9e84209b2cfd..6d66d38a5a1038 100644 --- a/src/tests/Interop/CMakeLists.txt +++ b/src/tests/Interop/CMakeLists.txt @@ -35,6 +35,7 @@ add_subdirectory(PInvoke/SafeHandles) add_subdirectory(PInvoke/Vector2_3_4) add_subdirectory(UnmanagedCallConv) add_subdirectory(UnmanagedCallersOnly) +add_subdirectory(UnmanagedCallersOnly_MonoAot) add_subdirectory(PrimitiveMarshalling/Bool) add_subdirectory(PrimitiveMarshalling/UIntPtr) add_subdirectory(ArrayMarshalling/BoolArray) diff --git a/src/tests/Interop/UnmanagedCallersOnly_MonoAot/CMakeLists.txt b/src/tests/Interop/UnmanagedCallersOnly_MonoAot/CMakeLists.txt new file mode 100644 index 00000000000000..719a46c9fba938 --- /dev/null +++ b/src/tests/Interop/UnmanagedCallersOnly_MonoAot/CMakeLists.txt @@ -0,0 +1,10 @@ +project (UnmanagedCallersOnly_MonoAotDll) +include ("${CLR_INTEROP_TEST_ROOT}/Interop.cmake") +set(SOURCES UnmanagedCallersOnly_MonoAotDll.cpp ) + +# add the executable +add_library (UnmanagedCallersOnly_MonoAotDll SHARED ${SOURCES}) +target_link_libraries(UnmanagedCallersOnly_MonoAotDll ${LINK_LIBRARIES_ADDITIONAL}) + +# add the install targets +install (TARGETS UnmanagedCallersOnly_MonoAotDll DESTINATION bin) diff --git a/src/tests/Interop/UnmanagedCallersOnly_MonoAot/UnmanagedCallersOnly_MonoAotDll.cpp b/src/tests/Interop/UnmanagedCallersOnly_MonoAot/UnmanagedCallersOnly_MonoAotDll.cpp new file mode 100644 index 00000000000000..d3ead331faf9dc --- /dev/null +++ b/src/tests/Interop/UnmanagedCallersOnly_MonoAot/UnmanagedCallersOnly_MonoAotDll.cpp @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include + +typedef int (__stdcall *CALLBACKPROC_STDCALL)(int n); +typedef int (__cdecl *CALLBACKPROC_CDECL)(int n); + +extern "C" DLL_EXPORT int STDMETHODCALLTYPE CallManagedProc_Stdcall(CALLBACKPROC_STDCALL pCallbackProc, int n) +{ + return pCallbackProc(n); +} + +extern "C" DLL_EXPORT int STDMETHODCALLTYPE CallManagedProc_Cdecl(CALLBACKPROC_CDECL pCallbackProc, int n) +{ + return pCallbackProc(n); +} diff --git a/src/tests/Interop/UnmanagedCallersOnly_MonoAot/UnmanagedCallersOnly_MonoAotTest.cs b/src/tests/Interop/UnmanagedCallersOnly_MonoAot/UnmanagedCallersOnly_MonoAotTest.cs new file mode 100644 index 00000000000000..60c7412307ef81 --- /dev/null +++ b/src/tests/Interop/UnmanagedCallersOnly_MonoAot/UnmanagedCallersOnly_MonoAotTest.cs @@ -0,0 +1,73 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Threading; +using Xunit; + +// Stripped-down variant of Interop/UnmanagedCallersOnly/* test used for testing Mono AOT support for UnmanagedCallersOnly attribute +public unsafe class Program +{ + public static class UnmanagedCallersOnly_MonoAotDll + { + [DllImport(nameof(UnmanagedCallersOnly_MonoAotDll))] + public static extern int CallManagedProc_Stdcall(delegate* unmanaged[Stdcall] callbackProc, int n); + + [DllImport(nameof(UnmanagedCallersOnly_MonoAotDll))] + public static extern int CallManagedProc_Cdecl(delegate* unmanaged[Cdecl] callbackProc, int n); + } + + public static int Main(string[] args) + { + var result = 100; + + result += TestUnmanagedCallersOnlyValid_CallConvStdcall(); + result += TestUnmanagedCallersOnlyValid_CallConvCdecl(); + + return result; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + public static int ManagedDoubleCallback_Stdcall(int n) + { + return DoubleImpl(n); + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) })] + public static int ManagedDoubleCallback_Cdecl(int n) + { + return DoubleImpl(n); + } + + private static int DoubleImpl(int n) + { + return 2 * n; + } + + public static int TestUnmanagedCallersOnlyValid_CallConvStdcall() + { + Console.WriteLine($"Running {nameof(TestUnmanagedCallersOnlyValid_CallConvStdcall)}..."); + + int n = 12345; + int expected = DoubleImpl(n); + int actual = UnmanagedCallersOnly_MonoAotDll.CallManagedProc_Stdcall(&ManagedDoubleCallback_Stdcall, n); + + return expected == actual ? 0 : -1; + } + + public static int TestUnmanagedCallersOnlyValid_CallConvCdecl() + { + Console.WriteLine($"Running {nameof(TestUnmanagedCallersOnlyValid_CallConvCdecl)}..."); + + int n = 12345; + int expected = DoubleImpl(n); + int actual = UnmanagedCallersOnly_MonoAotDll.CallManagedProc_Cdecl(&ManagedDoubleCallback_Cdecl, n); + + return expected == actual ? 0 : -1; + } +} diff --git a/src/tests/Interop/UnmanagedCallersOnly_MonoAot/UnmanagedCallersOnly_MonoAotTest.csproj b/src/tests/Interop/UnmanagedCallersOnly_MonoAot/UnmanagedCallersOnly_MonoAotTest.csproj new file mode 100644 index 00000000000000..8932cacf53f7cd --- /dev/null +++ b/src/tests/Interop/UnmanagedCallersOnly_MonoAot/UnmanagedCallersOnly_MonoAotTest.csproj @@ -0,0 +1,14 @@ + + + Exe + true + + + + + + + + + + From e8a5b608f2bf6d3271eab748f6fc0e2d6e96e463 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Wed, 25 May 2022 21:24:57 +0200 Subject: [PATCH 16/24] Disabling UnmanagedCallersOnly test on wasm since tests currently do not support building native libraries --- src/tests/issues.targets | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tests/issues.targets b/src/tests/issues.targets index 072fe62e989e76..85438d76277a90 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -3338,6 +3338,9 @@ https://github.com/dotnet/runtime/issues/41519 + + https://github.com/dotnet/runtime/issues/41519 + https://github.com/dotnet/runtime/issues/41472 From a3fdffb88536832778e0562cacb604fe2cbc07f9 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Mon, 30 May 2022 14:58:12 +0200 Subject: [PATCH 17/24] Disabling UnmanagedCallersOnly test on Andriod since tests currently do not support building native libraries --- src/tests/issues.targets | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tests/issues.targets b/src/tests/issues.targets index 85438d76277a90..060df6ce10c4c7 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -3704,6 +3704,9 @@ needs triage + + needs triage + needs triage From 19dc4ebba90905b1c0a3904d50aadf98ece93c53 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Thu, 26 May 2022 18:47:03 +0200 Subject: [PATCH 18/24] Moving MonoCustomAttrValue types to custom-attrs-internals.h --- src/mono/mono/component/debugger-agent.c | 1 - .../mono/metadata/custom-attrs-internals.h | 14 ++++++++++++ src/mono/mono/metadata/custom-attrs-types.h | 22 ------------------- src/mono/mono/metadata/custom-attrs.c | 1 - src/mono/mono/metadata/marshal-shared.c | 1 - src/mono/mono/metadata/marshal.c | 1 - src/mono/mono/metadata/native-library.c | 1 - src/mono/mono/mini/aot-compiler.c | 1 - src/mono/mono/mini/driver.c | 1 - 9 files changed, 14 insertions(+), 29 deletions(-) delete mode 100644 src/mono/mono/metadata/custom-attrs-types.h diff --git a/src/mono/mono/component/debugger-agent.c b/src/mono/mono/component/debugger-agent.c index 9e67fe9248d8fc..43066d9dfe229b 100644 --- a/src/mono/mono/component/debugger-agent.c +++ b/src/mono/mono/component/debugger-agent.c @@ -91,7 +91,6 @@ #include "debugger-engine.h" #include #include -#include #include #include diff --git a/src/mono/mono/metadata/custom-attrs-internals.h b/src/mono/mono/metadata/custom-attrs-internals.h index 16a232a80db5f4..c821ba1730d226 100644 --- a/src/mono/mono/metadata/custom-attrs-internals.h +++ b/src/mono/mono/metadata/custom-attrs-internals.h @@ -9,6 +9,20 @@ #include #include +typedef struct _MonoCustomAttrValueArray MonoCustomAttrValueArray; + +typedef struct _MonoCustomAttrValue { + union { + gpointer primitive; /* int/enum/MonoType/string */ + MonoCustomAttrValueArray *array; + } value; +} MonoCustomAttrValue; + +struct _MonoCustomAttrValueArray { + int len; + MonoCustomAttrValue values[MONO_ZERO_LEN_ARRAY]; +}; + MonoCustomAttrInfo* mono_custom_attrs_from_builders (MonoImage *alloc_img, MonoImage *image, MonoArray *cattrs); diff --git a/src/mono/mono/metadata/custom-attrs-types.h b/src/mono/mono/metadata/custom-attrs-types.h deleted file mode 100644 index f84d6721e0013b..00000000000000 --- a/src/mono/mono/metadata/custom-attrs-types.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * \file - */ - -#ifndef __MONO_CUSTOM_ATTRS_TYPES_H__ -#define __MONO_CUSTOM_ATTRS_TYPES_H__ - -typedef struct _MonoCustomAttrValueArray MonoCustomAttrValueArray; - -typedef struct _MonoCustomAttrValue { - union { - gpointer primitive; /* int/enum/MonoType/string */ - MonoCustomAttrValueArray *array; - } value; -} MonoCustomAttrValue; - -struct _MonoCustomAttrValueArray { - int len; - MonoCustomAttrValue values[MONO_ZERO_LEN_ARRAY]; -}; - -#endif /* __MONO_CUSTOM_ATTRS_TYPES_H__ */ diff --git a/src/mono/mono/metadata/custom-attrs.c b/src/mono/mono/metadata/custom-attrs.c index a5b09b3f05e647..0a46fbccaee96c 100644 --- a/src/mono/mono/metadata/custom-attrs.c +++ b/src/mono/mono/metadata/custom-attrs.c @@ -19,7 +19,6 @@ #include "mono/metadata/gc-internals.h" #include "mono/metadata/mono-endian.h" #include "mono/metadata/object-internals.h" -#include "mono/metadata/custom-attrs-types.h" #include "mono/metadata/custom-attrs-internals.h" #include "mono/metadata/sre-internals.h" #include "mono/metadata/reflection-internals.h" diff --git a/src/mono/mono/metadata/marshal-shared.c b/src/mono/mono/metadata/marshal-shared.c index c48666b14da807..5de0c3cb3e2963 100644 --- a/src/mono/mono/metadata/marshal-shared.c +++ b/src/mono/mono/metadata/marshal-shared.c @@ -8,7 +8,6 @@ #include "metadata/marshal-shared.h" #include "metadata/method-builder-ilgen.h" #include "metadata/custom-attrs-internals.h" -#include "metadata/custom-attrs-types.h" #include "metadata/class-init.h" #include "mono/metadata/class-internals.h" #include "metadata/reflection-internals.h" diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index f71870f8548eb5..488e60ca4850fa 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -56,7 +56,6 @@ MONO_PRAGMA_WARNING_POP() #include "mono/metadata/handle.h" #include "mono/metadata/object-internals.h" #include "mono/metadata/custom-attrs-internals.h" -#include "mono/metadata/custom-attrs-types.h" #include "mono/metadata/abi-details.h" #include "mono/metadata/custom-attrs-internals.h" #include "mono/metadata/loader-internals.h" diff --git a/src/mono/mono/metadata/native-library.c b/src/mono/mono/metadata/native-library.c index 50ba73037c3287..48ecf90032078d 100644 --- a/src/mono/mono/metadata/native-library.c +++ b/src/mono/mono/metadata/native-library.c @@ -12,7 +12,6 @@ #include "mono/utils/mono-path.h" #include "mono/metadata/native-library.h" #include "mono/metadata/custom-attrs-internals.h" -#include "mono/metadata/custom-attrs-types.h" static int pinvoke_search_directories_count; static char **pinvoke_search_directories; diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 85c1904bcec278..24925b1f894eba 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include diff --git a/src/mono/mono/mini/driver.c b/src/mono/mono/mini/driver.c index 3568ab546d9e59..55f7035720e301 100644 --- a/src/mono/mono/mini/driver.c +++ b/src/mono/mono/mini/driver.c @@ -50,7 +50,6 @@ #include "mono/metadata/w32handle.h" #include "mono/metadata/callspec.h" #include "mono/metadata/custom-attrs-internals.h" -#include "mono/metadata/custom-attrs-types.h" #include #include From 7efb13d648ec75d97a38ee5b1bec7036c41d85ae Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Fri, 27 May 2022 18:28:52 +0200 Subject: [PATCH 19/24] Adding back type information for MonoCustomAttrValue in order to properly free array typed arguments --- src/mono/mono/metadata/custom-attrs-internals.h | 1 + src/mono/mono/metadata/custom-attrs.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/mono/mono/metadata/custom-attrs-internals.h b/src/mono/mono/metadata/custom-attrs-internals.h index c821ba1730d226..213b7504a10259 100644 --- a/src/mono/mono/metadata/custom-attrs-internals.h +++ b/src/mono/mono/metadata/custom-attrs-internals.h @@ -16,6 +16,7 @@ typedef struct _MonoCustomAttrValue { gpointer primitive; /* int/enum/MonoType/string */ MonoCustomAttrValueArray *array; } value; + MonoTypeEnum type : 8; } MonoCustomAttrValue; struct _MonoCustomAttrValueArray { diff --git a/src/mono/mono/metadata/custom-attrs.c b/src/mono/mono/metadata/custom-attrs.c index 0a46fbccaee96c..9151726390acfe 100644 --- a/src/mono/mono/metadata/custom-attrs.c +++ b/src/mono/mono/metadata/custom-attrs.c @@ -624,6 +624,7 @@ load_cattr_value_noalloc (MonoImage *image, MonoType *t, const char *p, const ch g_error ("Unhandled type of generic instance in load_cattr_value_noalloc: %s", m_class_get_name (cc)); } } + result->type = type; handle_enum: switch (type) { From ce225378e5e78c247f1040773f0bd9cc2519386d Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Mon, 30 May 2022 15:04:51 +0200 Subject: [PATCH 20/24] Adding MonoDecodeCustomAttr to simplify usage of mono_reflection_create_custom_attr_data_args_noalloc --- src/mono/mono/component/debugger-agent.c | 18 +-- .../mono/metadata/custom-attrs-internals.h | 15 ++- src/mono/mono/metadata/custom-attrs.c | 125 ++++++++++++------ src/mono/mono/metadata/marshal-shared.c | 21 +-- src/mono/mono/metadata/marshal.c | 51 +++---- src/mono/mono/metadata/native-library.c | 17 +-- src/mono/mono/mini/aot-compiler.c | 18 +-- src/mono/mono/mini/driver.c | 17 +-- 8 files changed, 140 insertions(+), 142 deletions(-) diff --git a/src/mono/mono/component/debugger-agent.c b/src/mono/mono/component/debugger-agent.c index 43066d9dfe229b..ae1a275192559b 100644 --- a/src/mono/mono/component/debugger-agent.c +++ b/src/mono/mono/component/debugger-agent.c @@ -2931,25 +2931,15 @@ static gint32 isFixedSizeArray (MonoClassField *f) MonoClass *fixed_size_class = mono_class_try_get_fixed_buffer_class (); if (fixed_size_class != NULL && mono_class_has_parent (ctor_class, fixed_size_class)) { attr = &cinfo->attrs [aindex]; - gpointer *typed_args, *named_args; - CattrNamedArg *arginfo; - int num_named_args; - MonoCustomAttrValue *attr_value; - - mono_reflection_create_custom_attr_data_args_noalloc (mono_get_corlib (), attr->ctor, attr->data, attr->data_size, - &typed_args, &named_args, &num_named_args, &arginfo, error); + MonoDecodeCustomAttr *decoded_args = NULL; + mono_reflection_create_custom_attr_data_args_noalloc (mono_get_corlib (), attr->ctor, attr->data, attr->data_size, &decoded_args, error); if (!is_ok (error)) { ret = 0; goto leave; } - attr_value = (MonoCustomAttrValue*)typed_args[1]; - ret = *(gint32*)attr_value->value.primitive; - - g_free (typed_args [1]); - g_free (typed_args); - g_free (named_args); - g_free (arginfo); + ret = *(gint32*)decoded_args->typed_args[1]->value.primitive; + mono_reflection_free_custom_attr_data_args_noalloc (decoded_args); return ret; } } diff --git a/src/mono/mono/metadata/custom-attrs-internals.h b/src/mono/mono/metadata/custom-attrs-internals.h index 213b7504a10259..73297b467584cd 100644 --- a/src/mono/mono/metadata/custom-attrs-internals.h +++ b/src/mono/mono/metadata/custom-attrs-internals.h @@ -24,6 +24,14 @@ struct _MonoCustomAttrValueArray { MonoCustomAttrValue values[MONO_ZERO_LEN_ARRAY]; }; +typedef struct _MonoDecodeCustomAttr { + int typed_args_num; + int named_args_num; + MonoCustomAttrValue **typed_args; + MonoCustomAttrValue **named_args; + CattrNamedArg *named_args_info; +} MonoDecodeCustomAttr; + MonoCustomAttrInfo* mono_custom_attrs_from_builders (MonoImage *alloc_img, MonoImage *image, MonoArray *cattrs); @@ -48,8 +56,9 @@ MONO_COMPONENT_API void mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, MonoArrayHandleOut typed_args_out, MonoArrayHandleOut named_args_out, CattrNamedArg **named_arg_info, MonoError *error); MONO_COMPONENT_API void -mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, - gpointer **typed_args_out, gpointer **named_args_out, int *num_named_args, - CattrNamedArg **named_arg_info, MonoError *error); +mono_reflection_free_custom_attr_data_args_noalloc(MonoDecodeCustomAttr* decoded_args); + +MONO_COMPONENT_API void +mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, MonoDecodeCustomAttr** decoded_args, MonoError *error); #endif /* __MONO_METADATA_REFLECTION_CUSTOM_ATTRS_INTERNALS_H__ */ diff --git a/src/mono/mono/metadata/custom-attrs.c b/src/mono/mono/metadata/custom-attrs.c index 9151726390acfe..f0922e9a6b6caf 100644 --- a/src/mono/mono/metadata/custom-attrs.c +++ b/src/mono/mono/metadata/custom-attrs.c @@ -598,9 +598,18 @@ MONO_RESTORE_WARNING return NULL; } + /* - * Load custrom attribute without mono allocation - invoked from AOT compiler - * Caller needs to deallocate memory of the return value + * load_cattr_value_noalloc: + * + * Loads custro attribute values without mono allocation (invoked when AOT compiling). + * Returns MonoCustomAttrValue: + * - for primitive types: + * - (bools, ints, and enums) a pointer to the value is returned. + * - for types, the address of the loaded type is returned (DON'T FREE). + * - for strings, the address in the metadata blob is returned (DON'T FREE). + * - for arrays: + * - MonoCustomAttrValueArray* is returned. */ static MonoCustomAttrValue* load_cattr_value_noalloc (MonoImage *image, MonoType *t, const char *p, const char *boundp, const char **end, MonoError *error) @@ -1412,35 +1421,80 @@ mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *meth *named_arg_info = NULL; } +/* + * free_decoded_custom_attr: + * + * Handles freeing of MonoCustomAttrValue type properly. + * Strings and MonoType* are not freed since they come from the metadata. + */ +void +free_decoded_custom_attr(MonoCustomAttrValue* cattr_val) +{ + if (!cattr_val) + return; + + if (cattr_val->type == MONO_TYPE_SZARRAY) { + for (int i = 0; i < cattr_val->value.array->len; i++) + free_decoded_custom_attr (&cattr_val->value.array->values[i]); + g_free (cattr_val->value.array); + } else if (cattr_val->type != MONO_TYPE_STRING && cattr_val->type != MONO_TYPE_CLASS) { + g_free (cattr_val->value.primitive); + } +} + +/* + * mono_reflection_free_custom_attr_data_args_noalloc: + * + * Frees up MonoDecodeCustomAttr type. + * Must be called after mono_reflection_create_custom_attr_data_args_noalloc to properly free up allocated struct. + */ +void +mono_reflection_free_custom_attr_data_args_noalloc (MonoDecodeCustomAttr* decoded_args) +{ + if (!decoded_args) + return; + + // free typed args + for (int i = 0; i < decoded_args->typed_args_num; i++) { + free_decoded_custom_attr(decoded_args->typed_args[i]); + g_free(decoded_args->typed_args[i]); + } + g_free(decoded_args->typed_args); + + // free named args + for (int i = 0; i < decoded_args->named_args_num; i++) { + free_decoded_custom_attr(decoded_args->named_args[i]); + g_free(decoded_args->named_args[i]); + } + g_free(decoded_args->named_args); + + // free named args info + g_free(decoded_args->named_args_info); + + g_free(decoded_args); +} + /* * 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/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 (). + * Same as mono_reflection_create_custom_attr_data_args but allocate no managed objects. + * Returns MonoDecodeCustomAttr struct with information about typed and named arguments. + * Typed and named arguments are represented as array of MonoCustomAttrValue. + * Return value - decoded_args_out must be freed using mono_reflection_free_custom_attr_data_args_noalloc (). */ void -mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, - gpointer **typed_args_out, gpointer **named_args_out, int *num_named_args, - CattrNamedArg **named_arg_info, MonoError *error) +mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, MonoDecodeCustomAttr** decoded_args_out, MonoError *error) { - gpointer *typed_args, *named_args; MonoClass *attrklass; const char *p = (const char*)data; const char *data_end = p + len; const char *named; guint32 i, j, num_named; - CattrNamedArg *arginfo = NULL; + MonoDecodeCustomAttr *decoded_args = NULL; MonoMethodSignature *sig = mono_method_signature_internal (method); - *typed_args_out = NULL; - *named_args_out = NULL; - *named_arg_info = NULL; - - typed_args = NULL; - named_args = NULL; + *decoded_args_out = NULL; + decoded_args = g_malloc0 (sizeof (MonoDecodeCustomAttr)); error_init (error); @@ -1452,10 +1506,10 @@ mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMeth /* skip prolog */ p += 2; - typed_args = g_new0 (gpointer, sig->param_count); - + decoded_args->typed_args_num = sig->param_count; + decoded_args->typed_args = g_malloc0 (sig->param_count * sizeof (MonoCustomAttrValue*)); for (i = 0; i < sig->param_count; ++i) { - typed_args [i] = load_cattr_value_noalloc (image, sig->params [i], p, data_end, &p, error); + decoded_args->typed_args [i] = load_cattr_value_noalloc (image, sig->params [i], p, data_end, &p, error); return_if_nok (error); } @@ -1465,14 +1519,15 @@ mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMeth if (!bcheck_blob (named, 1, data_end, error)) goto fail; num_named = read16 (named); - named_args = g_new0 (gpointer, num_named); + + decoded_args->named_args_num = num_named; + decoded_args->named_args = g_malloc0 (num_named * sizeof (MonoCustomAttrValue*)); + return_if_nok (error); named += 2; attrklass = method->klass; - arginfo = g_new0 (CattrNamedArg, num_named); - *named_arg_info = arginfo; - *num_named_args = num_named; + decoded_args->named_args_info = g_new0 (CattrNamedArg, num_named); /* Parse each named arg, and add to arginfo. Each named argument could * be a field name or a property name followed by a value. */ @@ -1521,10 +1576,10 @@ mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMeth goto fail; } - arginfo [j].type = field->type; - arginfo [j].field = field; + decoded_args->named_args_info [j].type = field->type; + decoded_args->named_args_info [j].field = field; - named_args [j] = load_cattr_value_noalloc (image, field->type, named, data_end, &named, error); + decoded_args->named_args [j] = load_cattr_value_noalloc (image, field->type, named, data_end, &named, error); if (!is_ok (error)) { g_free (name); @@ -1543,10 +1598,10 @@ mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMeth prop_type = prop->get? mono_method_signature_internal (prop->get)->ret : mono_method_signature_internal (prop->set)->params [mono_method_signature_internal (prop->set)->param_count - 1]; - arginfo [j].type = prop_type; - arginfo [j].prop = prop; + decoded_args->named_args_info [j].type = prop_type; + decoded_args->named_args_info [j].prop = prop; - named_args [j] = load_cattr_value_noalloc (image, prop_type, named, data_end, &named, error); + decoded_args->named_args [j] = load_cattr_value_noalloc (image, prop_type, named, data_end, &named, error); if (!is_ok (error)) { g_free (name); goto fail; @@ -1555,15 +1610,11 @@ mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMeth g_free (name); } - *typed_args_out = typed_args; - *named_args_out = named_args; + *decoded_args_out = decoded_args; return; fail: mono_error_set_generic_error (error, "System.Reflection", "CustomAttributeFormatException", "Binary format of the specified custom attribute was invalid."); - g_free (typed_args); - g_free (named_args); - g_free (arginfo); - *named_arg_info = NULL; + mono_reflection_free_custom_attr_data_args_noalloc(decoded_args); } void diff --git a/src/mono/mono/metadata/marshal-shared.c b/src/mono/mono/metadata/marshal-shared.c index 5de0c3cb3e2963..0f56a130d1f61e 100644 --- a/src/mono/mono/metadata/marshal-shared.c +++ b/src/mono/mono/metadata/marshal-shared.c @@ -218,26 +218,15 @@ mono_marshal_shared_get_fixed_buffer_attr (MonoClassField *field, MonoType **out } } if (attr) { - gpointer *typed_args, *named_args; - CattrNamedArg *arginfo; - int num_named_args; - MonoCustomAttrValue *etype_attr_value, *len_attr_value; - - mono_reflection_create_custom_attr_data_args_noalloc (mono_defaults.corlib, attr->ctor, attr->data, attr->data_size, - &typed_args, &named_args, &num_named_args, &arginfo, error); + MonoDecodeCustomAttr *decoded_args = NULL; + mono_reflection_create_custom_attr_data_args_noalloc (mono_defaults.corlib, attr->ctor, attr->data, attr->data_size, &decoded_args, error); if (!is_ok (error)) return FALSE; - etype_attr_value = (MonoCustomAttrValue*)typed_args[0]; - *out_etype = (MonoType*)etype_attr_value->value.primitive; + *out_etype = (MonoType*)decoded_args->typed_args[0]->value.primitive; + *out_len = *(gint32*)decoded_args->typed_args[1]->value.primitive; - len_attr_value = (MonoCustomAttrValue*)typed_args[1]; - *out_len = *(gint32*)len_attr_value->value.primitive; - - g_free (typed_args [1]); - g_free (typed_args); - g_free (named_args); - g_free (arginfo); + mono_reflection_free_custom_attr_data_args_noalloc (decoded_args); } if (cinfo && !cinfo->cached) mono_custom_attrs_free (cinfo); diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 488e60ca4850fa..5103591f4c91bd 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -3404,29 +3404,22 @@ mono_marshal_set_callconv_from_unmanaged_callers_only_attribute (MonoMethod *met if (attr != NULL) { - 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 (mono_defaults.corlib, attr->ctor, attr->data, attr->data_size, &typed_args, &named_args, &num_named_args, &named_arg_info, error); - for (i = 0; i < num_named_args; ++i) { - if (named_arg_info [i].field && !strcmp (named_arg_info [i].field->name, "CallConvs")) { - MonoCustomAttrValue* calling_conventions_attr = (MonoCustomAttrValue*) named_args [i]; - g_assertf(named_arg_info [i].field->type->type == MONO_TYPE_SZARRAY, "UnmanagedCallersOnlyAttribute parameter %s must be an array, specified for method %s", named_arg_info [i].field->name, method->name); - - MonoCustomAttrValueArray* calling_conventions = (MonoCustomAttrValueArray*) calling_conventions_attr->value.array; + MonoDecodeCustomAttr *decoded_args = NULL; + mono_reflection_create_custom_attr_data_args_noalloc (mono_defaults.corlib, attr->ctor, attr->data, attr->data_size, &decoded_args, error); + for (i = 0; i < decoded_args->named_args_num; ++i) { + if (decoded_args->named_args_info [i].field && !strcmp (decoded_args->named_args_info [i].field->name, "CallConvs")) { + g_assertf(decoded_args->named_args_info [i].field->type->type == MONO_TYPE_SZARRAY, "UnmanagedCallersOnlyAttribute parameter %s must be an array, specified for method %s", decoded_args->named_args_info [i].field->name, method->name); + MonoCustomAttrValueArray *calling_conventions = decoded_args->named_args[i]->value.array; if (calling_conventions->len > 0) { if (calling_conventions->len > 1) - g_warning ("Multiple calling conventions are not supported for UnmanagedCallersOnlyAttribute parameter %s, specified for method %s. Only the first calling convention will be taken into account", named_arg_info [i].field->name, method->name); + g_warning ("Multiple calling conventions are not supported for UnmanagedCallersOnlyAttribute parameter %s, specified for method %s. Only the first calling convention will be taken into account", decoded_args->named_args_info [i].field->name, method->name); // TODO: Support multiple conventions? MonoType* calling_convention = (MonoType*)calling_conventions->values[0].value.primitive; mono_marshal_set_signature_callconv_from_attribute (csig, calling_convention, error); } - g_free(calling_conventions); } } - g_free (named_args); - g_free (named_arg_info); + mono_reflection_free_custom_attr_data_args_noalloc (decoded_args); } if (!cinfo->cached) @@ -4155,31 +4148,25 @@ mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, } } if (attr) { - gpointer *typed_args, *named_args; - CattrNamedArg *arginfo; gint32 call_conv; gint32 charset = 0; MonoBoolean set_last_error = 0; - int num_named_args; - MonoCustomAttrValue *call_conv_attr_value; + MonoDecodeCustomAttr *decoded_args = NULL; - mono_reflection_create_custom_attr_data_args_noalloc (mono_defaults.corlib, attr->ctor, attr->data, attr->data_size, - &typed_args, &named_args, &num_named_args, &arginfo, error); + mono_reflection_create_custom_attr_data_args_noalloc (mono_defaults.corlib, attr->ctor, attr->data, attr->data_size, &decoded_args, error); g_assert (is_ok (error)); /* typed args */ - call_conv_attr_value = (MonoCustomAttrValue*)typed_args [0]; - call_conv = *(gint32*)call_conv_attr_value->value.primitive; + call_conv = *(gint32*)decoded_args->typed_args[0]->value.primitive; /* named args */ - for (i = 0; i < num_named_args; ++i) { - CattrNamedArg *narg = &arginfo [i]; - MonoCustomAttrValue *attr_value = (MonoCustomAttrValue*)named_args [i]; - + for (i = 0; i < decoded_args->named_args_num; ++i) { + CattrNamedArg *narg = &decoded_args->named_args_info[i]; g_assert (narg->field); + if (!strcmp (narg->field->name, "CharSet")) { - charset = *(gint32*)attr_value->value.primitive; + charset = *(gint32*)decoded_args->named_args [i]->value.primitive; } else if (!strcmp (narg->field->name, "SetLastError")) { - set_last_error = *(MonoBoolean*)attr_value->value.primitive; + set_last_error = *(MonoBoolean*)decoded_args->named_args [i]->value.primitive; } else if (!strcmp (narg->field->name, "BestFitMapping")) { // best_fit_mapping = *(MonoBoolean*)mono_object_unbox_internal (o); } else if (!strcmp (narg->field->name, "ThrowOnUnmappableChar")) { @@ -4187,12 +4174,8 @@ mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, } else { g_assert_not_reached (); } - g_free (named_args [i]); } - g_free (typed_args [0]); - g_free (typed_args); - g_free (named_args); - g_free (arginfo); + mono_reflection_free_custom_attr_data_args_noalloc (decoded_args); memset (&piinfo, 0, sizeof (piinfo)); m.piinfo = &piinfo; diff --git a/src/mono/mono/metadata/native-library.c b/src/mono/mono/metadata/native-library.c index 48ecf90032078d..b4bf868ec78b12 100644 --- a/src/mono/mono/metadata/native-library.c +++ b/src/mono/mono/metadata/native-library.c @@ -944,24 +944,15 @@ get_dllimportsearchpath_flags (MonoCustomAttrInfo *cinfo) if (!attr) return -3; - gpointer *typed_args, *named_args; - CattrNamedArg *arginfo; - int num_named_args; - MonoCustomAttrValue *flags_attr_value; - - mono_reflection_create_custom_attr_data_args_noalloc (m_class_get_image (attr->ctor->klass), attr->ctor, attr->data, attr->data_size, - &typed_args, &named_args, &num_named_args, &arginfo, error); + MonoDecodeCustomAttr *decoded_args = NULL; + mono_reflection_create_custom_attr_data_args_noalloc (m_class_get_image (attr->ctor->klass), attr->ctor, attr->data, attr->data_size, &decoded_args, error); if (!is_ok (error)) { mono_error_cleanup (error); return -4; } - flags_attr_value = (MonoCustomAttrValue*)typed_args [0]; - flags = *(gint32*)flags_attr_value->value.primitive; - g_free (typed_args [0]); - g_free (typed_args); - g_free (named_args); - g_free (arginfo); + flags = *(gint32*)decoded_args->typed_args[0]->value.primitive; + mono_reflection_free_custom_attr_data_args_noalloc (decoded_args); return flags; } diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 24925b1f894eba..a6bb80d251a6d8 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -5188,25 +5188,19 @@ MONO_RESTORE_WARNING exit (1); } - gpointer *typed_args = NULL; - gpointer *named_args = NULL; - CattrNamedArg *named_arg_info = NULL; - int num_named_args = 0; - MonoCustomAttrValue *attr_value = NULL; - 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); + MonoDecodeCustomAttr *decoded_args = NULL; + mono_reflection_create_custom_attr_data_args_noalloc (acfg->image, e->ctor, e->data, e->data_size, &decoded_args, 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")) { - attr_value = (MonoCustomAttrValue *)named_args [j]; - named = (const char *)attr_value->value.primitive; + for (j = 0; j < decoded_args->named_args_num; ++j) { + if (decoded_args->named_args_info [j].field && !strcmp (decoded_args->named_args_info [j].field->name, "EntryPoint")) { + named = (const char *)decoded_args->named_args[j]->value.primitive; 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); + mono_reflection_free_custom_attr_data_args_noalloc (decoded_args); wrapper = mono_marshal_get_managed_wrapper (method, NULL, 0, error); mono_error_assert_ok (error); diff --git a/src/mono/mono/mini/driver.c b/src/mono/mono/mini/driver.c index 55f7035720e301..ba7568ed551626 100644 --- a/src/mono/mono/mini/driver.c +++ b/src/mono/mono/mini/driver.c @@ -429,24 +429,15 @@ method_should_be_regression_tested (MonoMethod *method, gboolean interp) if (strcmp (m_class_get_name (klass), "CategoryAttribute") || mono_method_signature_internal (centry->ctor)->param_count != 1) continue; - gpointer *typed_args, *named_args; - int num_named_args; - CattrNamedArg *arginfo; - MonoCustomAttrValue *attr_value; - - mono_reflection_create_custom_attr_data_args_noalloc ( - mono_defaults.corlib, centry->ctor, centry->data, centry->data_size, - &typed_args, &named_args, &num_named_args, &arginfo, error); + MonoDecodeCustomAttr *decoded_args = NULL; + mono_reflection_create_custom_attr_data_args_noalloc (mono_defaults.corlib, centry->ctor, centry->data, centry->data_size, &decoded_args, error); if (!is_ok (error)) continue; - attr_value = (MonoCustomAttrValue *)typed_args [0]; - const char *arg = (const char*)attr_value->value.primitive; + const char *arg = (const char*)decoded_args->typed_args[0]->value.primitive; 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); + mono_reflection_free_custom_attr_data_args_noalloc (decoded_args); if (interp && !strcmp (utf8_str, "!INTERPRETER")) { g_print ("skip %s...\n", method->name); From 5d053f9044f9cd254aeb51a2da2b830c981cdc53 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Mon, 30 May 2022 16:11:36 +0200 Subject: [PATCH 21/24] Mark functions not used outside of TU as static --- src/mono/mono/metadata/custom-attrs.c | 2 +- src/mono/mono/metadata/marshal.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/metadata/custom-attrs.c b/src/mono/mono/metadata/custom-attrs.c index f0922e9a6b6caf..46ca6c0d50b537 100644 --- a/src/mono/mono/metadata/custom-attrs.c +++ b/src/mono/mono/metadata/custom-attrs.c @@ -1427,7 +1427,7 @@ mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *meth * Handles freeing of MonoCustomAttrValue type properly. * Strings and MonoType* are not freed since they come from the metadata. */ -void +static void free_decoded_custom_attr(MonoCustomAttrValue* cattr_val) { if (!cattr_val) diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 5103591f4c91bd..4b874bf27723d6 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -3350,7 +3350,8 @@ mono_marshal_set_callconv_from_unmanaged_callconv_attribute (MonoMethod *method, mono_custom_attrs_free(cinfo); } -static void mono_marshal_set_signature_callconv_from_attribute(MonoMethodSignature *sig, MonoType *cmod_type, MonoError *error) +static void +mono_marshal_set_signature_callconv_from_attribute(MonoMethodSignature *sig, MonoType *cmod_type, MonoError *error) { g_assert (cmod_type->type == MONO_TYPE_CLASS); MonoClass *cmod_klass = mono_class_from_mono_type_internal (cmod_type); From 297768faba2d18faa14ddeb78d50bbd02b8550a0 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Mon, 30 May 2022 18:58:03 +0200 Subject: [PATCH 22/24] No need to recursively free custom attribute parameter since only 1-D arrays are supported --- src/mono/mono/metadata/custom-attrs.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/metadata/custom-attrs.c b/src/mono/mono/metadata/custom-attrs.c index 46ca6c0d50b537..4da29bd6da1153 100644 --- a/src/mono/mono/metadata/custom-attrs.c +++ b/src/mono/mono/metadata/custom-attrs.c @@ -1434,8 +1434,11 @@ free_decoded_custom_attr(MonoCustomAttrValue* cattr_val) return; if (cattr_val->type == MONO_TYPE_SZARRAY) { - for (int i = 0; i < cattr_val->value.array->len; i++) - free_decoded_custom_attr (&cattr_val->value.array->values[i]); + // attribute parameter types only support single-dimensional arrays + for (int i = 0; i < cattr_val->value.array->len; i++) { + if (cattr_val->value.array->values[i].type != MONO_TYPE_STRING && cattr_val->value.array->values[i].type != MONO_TYPE_CLASS) + g_free(cattr_val->value.array->values[i].value.primitive); + } g_free (cattr_val->value.array); } else if (cattr_val->type != MONO_TYPE_STRING && cattr_val->type != MONO_TYPE_CLASS) { g_free (cattr_val->value.primitive); From cb73c27ad924dfd2d4704ad73bedcc2b86ff8021 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Tue, 31 May 2022 17:12:50 +0200 Subject: [PATCH 23/24] Use return value instead of out parameter when returning MonoDecodeCustomAttr* --- src/mono/mono/component/debugger-agent.c | 3 +-- .../mono/metadata/custom-attrs-internals.h | 4 ++-- src/mono/mono/metadata/custom-attrs.c | 19 ++++++++----------- src/mono/mono/metadata/marshal-shared.c | 3 +-- src/mono/mono/metadata/marshal.c | 8 +++----- src/mono/mono/metadata/native-library.c | 3 +-- src/mono/mono/mini/aot-compiler.c | 3 +-- src/mono/mono/mini/driver.c | 3 +-- 8 files changed, 18 insertions(+), 28 deletions(-) diff --git a/src/mono/mono/component/debugger-agent.c b/src/mono/mono/component/debugger-agent.c index ae1a275192559b..3019faec2c1f1f 100644 --- a/src/mono/mono/component/debugger-agent.c +++ b/src/mono/mono/component/debugger-agent.c @@ -2931,8 +2931,7 @@ static gint32 isFixedSizeArray (MonoClassField *f) MonoClass *fixed_size_class = mono_class_try_get_fixed_buffer_class (); if (fixed_size_class != NULL && mono_class_has_parent (ctor_class, fixed_size_class)) { attr = &cinfo->attrs [aindex]; - MonoDecodeCustomAttr *decoded_args = NULL; - mono_reflection_create_custom_attr_data_args_noalloc (mono_get_corlib (), attr->ctor, attr->data, attr->data_size, &decoded_args, error); + MonoDecodeCustomAttr *decoded_args = mono_reflection_create_custom_attr_data_args_noalloc (mono_get_corlib (), attr->ctor, attr->data, attr->data_size, error); if (!is_ok (error)) { ret = 0; goto leave; diff --git a/src/mono/mono/metadata/custom-attrs-internals.h b/src/mono/mono/metadata/custom-attrs-internals.h index 73297b467584cd..8f0d25f563cb42 100644 --- a/src/mono/mono/metadata/custom-attrs-internals.h +++ b/src/mono/mono/metadata/custom-attrs-internals.h @@ -58,7 +58,7 @@ mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *meth MONO_COMPONENT_API void mono_reflection_free_custom_attr_data_args_noalloc(MonoDecodeCustomAttr* decoded_args); -MONO_COMPONENT_API void -mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, MonoDecodeCustomAttr** decoded_args, MonoError *error); +MONO_COMPONENT_API MonoDecodeCustomAttr* +mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, MonoError *error); #endif /* __MONO_METADATA_REFLECTION_CUSTOM_ATTRS_INTERNALS_H__ */ diff --git a/src/mono/mono/metadata/custom-attrs.c b/src/mono/mono/metadata/custom-attrs.c index 4da29bd6da1153..4f44f68ecbd5b8 100644 --- a/src/mono/mono/metadata/custom-attrs.c +++ b/src/mono/mono/metadata/custom-attrs.c @@ -1483,22 +1483,19 @@ mono_reflection_free_custom_attr_data_args_noalloc (MonoDecodeCustomAttr* decode * Same as mono_reflection_create_custom_attr_data_args but allocate no managed objects. * Returns MonoDecodeCustomAttr struct with information about typed and named arguments. * Typed and named arguments are represented as array of MonoCustomAttrValue. - * Return value - decoded_args_out must be freed using mono_reflection_free_custom_attr_data_args_noalloc (). + * Return value must be freed using mono_reflection_free_custom_attr_data_args_noalloc (). */ -void -mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, MonoDecodeCustomAttr** decoded_args_out, MonoError *error) +MonoDecodeCustomAttr* +mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, MonoError *error) { MonoClass *attrklass; const char *p = (const char*)data; const char *data_end = p + len; const char *named; guint32 i, j, num_named; - MonoDecodeCustomAttr *decoded_args = NULL; + MonoDecodeCustomAttr *decoded_args = g_malloc0 (sizeof (MonoDecodeCustomAttr)); MonoMethodSignature *sig = mono_method_signature_internal (method); - *decoded_args_out = NULL; - decoded_args = g_malloc0 (sizeof (MonoDecodeCustomAttr)); - error_init (error); mono_class_init_internal (method->klass); @@ -1513,7 +1510,7 @@ mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMeth decoded_args->typed_args = g_malloc0 (sig->param_count * sizeof (MonoCustomAttrValue*)); for (i = 0; i < sig->param_count; ++i) { decoded_args->typed_args [i] = load_cattr_value_noalloc (image, sig->params [i], p, data_end, &p, error); - return_if_nok (error); + return_val_if_nok (error, NULL); } named = p; @@ -1526,7 +1523,7 @@ mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMeth decoded_args->named_args_num = num_named; decoded_args->named_args = g_malloc0 (num_named * sizeof (MonoCustomAttrValue*)); - return_if_nok (error); + return_val_if_nok (error, NULL); named += 2; attrklass = method->klass; @@ -1613,11 +1610,11 @@ mono_reflection_create_custom_attr_data_args_noalloc (MonoImage *image, MonoMeth g_free (name); } - *decoded_args_out = decoded_args; - return; + return decoded_args; fail: mono_error_set_generic_error (error, "System.Reflection", "CustomAttributeFormatException", "Binary format of the specified custom attribute was invalid."); mono_reflection_free_custom_attr_data_args_noalloc(decoded_args); + return NULL; } void diff --git a/src/mono/mono/metadata/marshal-shared.c b/src/mono/mono/metadata/marshal-shared.c index 0f56a130d1f61e..7c67f9dd3fe363 100644 --- a/src/mono/mono/metadata/marshal-shared.c +++ b/src/mono/mono/metadata/marshal-shared.c @@ -218,8 +218,7 @@ mono_marshal_shared_get_fixed_buffer_attr (MonoClassField *field, MonoType **out } } if (attr) { - MonoDecodeCustomAttr *decoded_args = NULL; - mono_reflection_create_custom_attr_data_args_noalloc (mono_defaults.corlib, attr->ctor, attr->data, attr->data_size, &decoded_args, error); + MonoDecodeCustomAttr *decoded_args = mono_reflection_create_custom_attr_data_args_noalloc (mono_defaults.corlib, attr->ctor, attr->data, attr->data_size, error); if (!is_ok (error)) return FALSE; diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 4b874bf27723d6..6ce6e794d40d68 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -3405,8 +3405,8 @@ mono_marshal_set_callconv_from_unmanaged_callers_only_attribute (MonoMethod *met if (attr != NULL) { - MonoDecodeCustomAttr *decoded_args = NULL; - mono_reflection_create_custom_attr_data_args_noalloc (mono_defaults.corlib, attr->ctor, attr->data, attr->data_size, &decoded_args, error); + MonoDecodeCustomAttr *decoded_args = mono_reflection_create_custom_attr_data_args_noalloc (mono_defaults.corlib, attr->ctor, attr->data, attr->data_size, error); + mono_error_assert_ok (error); for (i = 0; i < decoded_args->named_args_num; ++i) { if (decoded_args->named_args_info [i].field && !strcmp (decoded_args->named_args_info [i].field->name, "CallConvs")) { g_assertf(decoded_args->named_args_info [i].field->type->type == MONO_TYPE_SZARRAY, "UnmanagedCallersOnlyAttribute parameter %s must be an array, specified for method %s", decoded_args->named_args_info [i].field->name, method->name); @@ -4152,9 +4152,7 @@ mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, gint32 call_conv; gint32 charset = 0; MonoBoolean set_last_error = 0; - MonoDecodeCustomAttr *decoded_args = NULL; - - mono_reflection_create_custom_attr_data_args_noalloc (mono_defaults.corlib, attr->ctor, attr->data, attr->data_size, &decoded_args, error); + MonoDecodeCustomAttr *decoded_args = mono_reflection_create_custom_attr_data_args_noalloc (mono_defaults.corlib, attr->ctor, attr->data, attr->data_size, error); g_assert (is_ok (error)); /* typed args */ diff --git a/src/mono/mono/metadata/native-library.c b/src/mono/mono/metadata/native-library.c index b4bf868ec78b12..c912d769508999 100644 --- a/src/mono/mono/metadata/native-library.c +++ b/src/mono/mono/metadata/native-library.c @@ -944,8 +944,7 @@ get_dllimportsearchpath_flags (MonoCustomAttrInfo *cinfo) if (!attr) return -3; - MonoDecodeCustomAttr *decoded_args = NULL; - mono_reflection_create_custom_attr_data_args_noalloc (m_class_get_image (attr->ctor->klass), attr->ctor, attr->data, attr->data_size, &decoded_args, error); + MonoDecodeCustomAttr *decoded_args = mono_reflection_create_custom_attr_data_args_noalloc (m_class_get_image (attr->ctor->klass), attr->ctor, attr->data, attr->data_size, error); if (!is_ok (error)) { mono_error_cleanup (error); return -4; diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index a6bb80d251a6d8..2f84f35f79aaa0 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -5188,8 +5188,7 @@ MONO_RESTORE_WARNING exit (1); } - MonoDecodeCustomAttr *decoded_args = NULL; - mono_reflection_create_custom_attr_data_args_noalloc (acfg->image, e->ctor, e->data, e->data_size, &decoded_args, error); + MonoDecodeCustomAttr *decoded_args = mono_reflection_create_custom_attr_data_args_noalloc (acfg->image, e->ctor, e->data, e->data_size, error); mono_error_assert_ok (error); for (j = 0; j < decoded_args->named_args_num; ++j) { if (decoded_args->named_args_info [j].field && !strcmp (decoded_args->named_args_info [j].field->name, "EntryPoint")) { diff --git a/src/mono/mono/mini/driver.c b/src/mono/mono/mini/driver.c index ba7568ed551626..c77fdb92675f47 100644 --- a/src/mono/mono/mini/driver.c +++ b/src/mono/mono/mini/driver.c @@ -429,8 +429,7 @@ method_should_be_regression_tested (MonoMethod *method, gboolean interp) if (strcmp (m_class_get_name (klass), "CategoryAttribute") || mono_method_signature_internal (centry->ctor)->param_count != 1) continue; - MonoDecodeCustomAttr *decoded_args = NULL; - mono_reflection_create_custom_attr_data_args_noalloc (mono_defaults.corlib, centry->ctor, centry->data, centry->data_size, &decoded_args, error); + MonoDecodeCustomAttr *decoded_args = mono_reflection_create_custom_attr_data_args_noalloc (mono_defaults.corlib, centry->ctor, centry->data, centry->data_size, error); if (!is_ok (error)) continue; From 92902c3dc18b0827f5b25fcb781c455c456bffc6 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Tue, 31 May 2022 17:40:16 +0200 Subject: [PATCH 24/24] Cleanup: typo, formatting, use utility functions --- src/mono/mono/metadata/custom-attrs.c | 2 +- src/mono/mono/metadata/marshal.c | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/mono/mono/metadata/custom-attrs.c b/src/mono/mono/metadata/custom-attrs.c index 4f44f68ecbd5b8..170c6a05e43b95 100644 --- a/src/mono/mono/metadata/custom-attrs.c +++ b/src/mono/mono/metadata/custom-attrs.c @@ -602,7 +602,7 @@ MONO_RESTORE_WARNING /* * load_cattr_value_noalloc: * - * Loads custro attribute values without mono allocation (invoked when AOT compiling). + * Loads custom attribute values without mono allocation (invoked when AOT compiling). * Returns MonoCustomAttrValue: * - for primitive types: * - (bools, ints, and enums) a pointer to the value is returned. diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 6ce6e794d40d68..96e67f123eec8a 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -3358,11 +3358,10 @@ mono_marshal_set_signature_callconv_from_attribute(MonoMethodSignature *sig, Mon g_assert (m_class_get_image (cmod_klass) == mono_defaults.corlib); g_assert (!strcmp (m_class_get_name_space (cmod_klass), "System.Runtime.CompilerServices")); - size_t calling_convention_id_offset = strlen ("CallConv"); const char *name = m_class_get_name (cmod_klass); - g_assert (!strncmp (name, "CallConv", calling_convention_id_offset)); + g_assert (g_str_has_prefix (name, "CallConv")); - name += calling_convention_id_offset; + name += strlen ("CallConv"); if (!strcmp (name, "Cdecl")) sig->call_convention = MONO_CALL_C; else if (!strcmp (name, "Stdcall")) @@ -3403,8 +3402,7 @@ mono_marshal_set_callconv_from_unmanaged_callers_only_attribute (MonoMethod *met } } - if (attr != NULL) - { + if (attr != NULL) { MonoDecodeCustomAttr *decoded_args = mono_reflection_create_custom_attr_data_args_noalloc (mono_defaults.corlib, attr->ctor, attr->data, attr->data_size, error); mono_error_assert_ok (error); for (i = 0; i < decoded_args->named_args_num; ++i) {