Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions mono/dis/get.c
Original file line number Diff line number Diff line change
Expand Up @@ -1150,8 +1150,10 @@ dis_stringify_type (MonoImage *m, MonoType *type, gboolean is_def)
char *bare = NULL, *mods = NULL;
char *result;

if (type->num_mods)
mods = dis_stringify_modifiers (m, type->num_mods, type->modifiers);
if (type->has_cmods) {
MonoCustomModContainer *cmods = mono_type_get_cmods (type);
mods = dis_stringify_modifiers (cmods->image, cmods->count, cmods->modifiers);
}

switch (type->type){
case MONO_TYPE_BOOLEAN:
Expand Down
16 changes: 10 additions & 6 deletions mono/metadata/icall.c
Original file line number Diff line number Diff line change
Expand Up @@ -7704,20 +7704,24 @@ type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoE
int i, count = 0;
MonoDomain *domain = mono_domain_get ();

MonoCustomModContainer *cmods = mono_type_get_cmods (type);
if (!cmods)
goto fail;

error_init (error);
for (i = 0; i < type->num_mods; ++i) {
if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
for (i = 0; i < cmods->count; ++i) {
if ((optional && !cmods->modifiers [i].required) || (!optional && cmods->modifiers [i].required))
count++;
}
if (!count)
return MONO_HANDLE_NEW (MonoArray, NULL);
goto fail;

MonoArrayHandle res = mono_array_new_handle (domain, mono_defaults.systemtype_class, count, error);
goto_if_nok (error, fail);
count = 0;
for (i = 0; i < type->num_mods; ++i) {
if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
if (!add_modifier_to_array (domain, image, &type->modifiers[i], res, count , error))
for (i = 0; i < cmods->count; ++i) {
if ((optional && !cmods->modifiers [i].required) || (!optional && cmods->modifiers [i].required)) {
if (!add_modifier_to_array (domain, image, &cmods->modifiers [i], res, count , error))
goto fail;
count++;
}
Expand Down
37 changes: 21 additions & 16 deletions mono/metadata/marshal.c
Original file line number Diff line number Diff line change
Expand Up @@ -3624,24 +3624,29 @@ mono_marshal_set_callconv_from_modopt (MonoMethod *method, MonoMethodSignature *

sig = mono_method_signature (method);

MonoCustomModContainer *ret_cmods = NULL;
if (sig->ret)
ret_cmods = mono_type_get_cmods (sig->ret);

/* Change default calling convention if needed */
/* Why is this a modopt ? */
if (sig->ret && sig->ret->num_mods) {
for (i = 0; i < sig->ret->num_mods; ++i) {
ERROR_DECL (error);
MonoClass *cmod_class = mono_class_get_checked (get_method_image (method), sig->ret->modifiers [i].token, error);
g_assert (mono_error_ok (error));
if ((m_class_get_image (cmod_class) == mono_defaults.corlib) && !strcmp (m_class_get_name_space (cmod_class), "System.Runtime.CompilerServices")) {
const char *cmod_class_name = m_class_get_name (cmod_class);
if (!strcmp (cmod_class_name, "CallConvCdecl"))
csig->call_convention = MONO_CALL_C;
else if (!strcmp (cmod_class_name, "CallConvStdcall"))
csig->call_convention = MONO_CALL_STDCALL;
else if (!strcmp (cmod_class_name, "CallConvFastcall"))
csig->call_convention = MONO_CALL_FASTCALL;
else if (!strcmp (cmod_class_name, "CallConvThiscall"))
csig->call_convention = MONO_CALL_THISCALL;
}
if (!ret_cmods)
return;

for (i = 0; i < ret_cmods->count; ++i) {
ERROR_DECL (error);
MonoClass *cmod_class = mono_class_get_checked (ret_cmods->image, ret_cmods->modifiers [i].token, error);
g_assert (mono_error_ok (error));
if ((m_class_get_image (cmod_class) == mono_defaults.corlib) && !strcmp (m_class_get_name_space (cmod_class), "System.Runtime.CompilerServices")) {
const char *cmod_class_name = m_class_get_name (cmod_class);
if (!strcmp (cmod_class_name, "CallConvCdecl"))
csig->call_convention = MONO_CALL_C;
else if (!strcmp (cmod_class_name, "CallConvStdcall"))
csig->call_convention = MONO_CALL_STDCALL;
else if (!strcmp (cmod_class_name, "CallConvFastcall"))
csig->call_convention = MONO_CALL_FASTCALL;
else if (!strcmp (cmod_class_name, "CallConvThiscall"))
csig->call_convention = MONO_CALL_THISCALL;
}
}
}
Expand Down
26 changes: 23 additions & 3 deletions mono/metadata/metadata-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,33 @@ struct _MonoType {
} data;
unsigned int attrs : 16; /* param attributes or field flags */
MonoTypeEnum type : 8;
unsigned int num_mods : 6; /* max 64 modifiers follow at the end */
unsigned int has_cmods : 1;
unsigned int byref : 1;
unsigned int pinned : 1; /* valid when included in a local var signature */
MonoCustomMod modifiers [MONO_ZERO_LEN_ARRAY]; /* this may grow */
};

#define MONO_SIZEOF_TYPE (offsetof (struct _MonoType, modifiers))
typedef struct {
MonoType unmodified;
MonoCustomModContainer cmods;
} MonoTypeWithModifiers;

MonoCustomModContainer *
mono_type_get_cmods (const MonoType *t);

// Note: sizeof (MonoType) is dangerous. It can copy the num_mods
// field without copying the variably sized array. This leads to
// memory unsafety on the stack and/or heap, when we try to traverse
// this array.
//
// Use mono_sizeof_monotype
// to get the size of the memory to copy.
#define MONO_SIZEOF_TYPE sizeof (MonoType)

size_t
mono_sizeof_type_with_mods (uint8_t num_mods);

size_t
mono_sizeof_type (const MonoType *ty);

#define MONO_SECMAN_FLAG_INIT(x) (x & 0x2)
#define MONO_SECMAN_FLAG_GET_VALUE(x) (x & 0x1)
Expand Down
97 changes: 85 additions & 12 deletions mono/metadata/metadata.c
Original file line number Diff line number Diff line change
Expand Up @@ -1755,16 +1755,21 @@ mono_metadata_parse_type_internal (MonoImage *m, MonoGenericContainer *container
}
}

if (count) { // There are mods, so the MonoType will be of nonstandard size.
int size;
MonoCustomModContainer *cmods = NULL;

size = MONO_SIZEOF_TYPE + ((gint32)count) * sizeof (MonoCustomMod);
type = transient ? (MonoType *)g_malloc0 (size) : (MonoType *)mono_image_alloc0 (m, size);
type->num_mods = count;
if (count) { // There are mods, so the MonoType will be of nonstandard size.
if (count > 64) {
mono_error_set_bad_image (error, m, "Invalid type with more than 64 modifiers");
return NULL;
}

size_t size = mono_sizeof_type_with_mods (count);
type = transient ? (MonoType *)g_malloc0 (size) : (MonoType *)mono_image_alloc0 (m, size);
type->has_cmods = TRUE;

cmods = mono_type_get_cmods (type);
cmods->count = count;
cmods->image = m;
} else { // The type is of standard size, so we can allocate it on the stack.
type = &stype;
memset (type, 0, MONO_SIZEOF_TYPE);
Expand All @@ -1785,7 +1790,7 @@ mono_metadata_parse_type_internal (MonoImage *m, MonoGenericContainer *container
break;
case MONO_TYPE_CMOD_REQD:
case MONO_TYPE_CMOD_OPT:
mono_metadata_parse_custom_mod (m, &(type->modifiers [count]), ptr, &ptr);
mono_metadata_parse_custom_mod (m, &(cmods->modifiers [count]), ptr, &ptr);
count ++;
break;
default:
Expand All @@ -1804,7 +1809,7 @@ mono_metadata_parse_type_internal (MonoImage *m, MonoGenericContainer *container
*rptr = ptr;

// Possibly we can return an already-allocated type instead of the one we decoded
if (!type->num_mods && !transient) {
if (!type->has_cmods && !transient) {
/* no need to free type here, because it is on the stack */
if ((type->type == MONO_TYPE_CLASS || type->type == MONO_TYPE_VALUETYPE) && !type->pinned && !type->attrs) {
MonoType *ret = type->byref ? m_class_get_this_arg (type->data.klass) : m_class_get_byval_arg (type->data.klass);
Expand Down Expand Up @@ -2017,7 +2022,7 @@ mono_metadata_signature_dup_internal_with_padding (MonoImage *image, MonoMemPool
MonoMethodSignature *ret;
sigsize = sig_header_size = MONO_SIZEOF_METHOD_SIGNATURE + sig->param_count * sizeof (MonoType *) + padding;
if (sig->ret)
sigsize += MONO_SIZEOF_TYPE;
sigsize += mono_sizeof_type (sig->ret);

if (image) {
ret = (MonoMethodSignature *)mono_image_alloc (image, sigsize);
Expand All @@ -2034,7 +2039,7 @@ mono_metadata_signature_dup_internal_with_padding (MonoImage *image, MonoMemPool
// Danger! Do not alter padding use without changing the dup_add_this below
intptr_t end_of_header = (intptr_t)( (char*)(ret) + sig_header_size);
ret->ret = (MonoType *)end_of_header;
memcpy (ret->ret, sig->ret, MONO_SIZEOF_TYPE);
memcpy (ret->ret, sig->ret, mono_sizeof_type (sig->ret));
}

return ret;
Expand Down Expand Up @@ -5435,6 +5440,39 @@ do_mono_metadata_type_equal (MonoType *t1, MonoType *t2, gboolean signature_only
if (t1->type != t2->type || t1->byref != t2->byref)
return FALSE;

if (t1->has_cmods != t2->has_cmods)
return FALSE;

if (t1->has_cmods) {
MonoCustomModContainer *cm1 = mono_type_get_cmods (t1);
MonoCustomModContainer *cm2 = mono_type_get_cmods (t2);

g_assert (cm1);
g_assert (cm2);

// ECMA 335, 7.1.1:
// The CLI itself shall treat required and optional modifiers in the same manner.
// Two signatures that differ only by the addition of a custom modifier
// (required or optional) shall not be considered to match.
if (cm1->count != cm2->count)
return FALSE;

for (int i=0; i < cm1->count; i++) {
if (cm1->modifiers[i].required != cm2->modifiers[i].required)
return FALSE;

// FIXME: propagate error to caller
ERROR_DECL (error);
MonoClass *c1 = mono_class_get_checked (cm1->image, cm1->modifiers [i].token, error);
mono_error_assert_ok (error);
MonoClass *c2 = mono_class_get_checked (cm2->image, cm2->modifiers [i].token, error);
mono_error_assert_ok (error);

if (c1 != c2)
return FALSE;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does custom modifier order matter? if I have t modreq(mod1) modreq(mod2) t vs t modreq(mod2) modreq(mod1) are those the same type or different?

}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you need to also compare cm1->modifiers[i].required != cm2->modifiers[i].required

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was added by a line earlier in the loop body

}

switch (t1->type) {
case MONO_TYPE_VOID:
case MONO_TYPE_BOOLEAN:
Expand Down Expand Up @@ -5565,9 +5603,7 @@ MonoType *
mono_metadata_type_dup (MonoImage *image, const MonoType *o)
{
MonoType *r = NULL;
int sizeof_o = MONO_SIZEOF_TYPE;
if (o->num_mods)
sizeof_o += o->num_mods * sizeof (MonoCustomMod);
size_t sizeof_o = mono_sizeof_type (o);

r = image ? (MonoType *)mono_image_alloc0 (image, sizeof_o) : (MonoType *)g_malloc (sizeof_o);

Expand Down Expand Up @@ -7107,3 +7143,40 @@ mono_loader_get_strict_strong_names (void)
{
return check_strong_names_strictly;
}


MonoCustomModContainer *
mono_type_get_cmods (const MonoType *t)
{
if (!t->has_cmods)
return NULL;

MonoTypeWithModifiers *full = (MonoTypeWithModifiers *)t;

return &full->cmods;
}

size_t
mono_sizeof_type_with_mods (uint8_t num_mods)
{
size_t accum = 0;
accum += sizeof (MonoType);
if (num_mods == 0)
return accum;

accum += offsetof (struct _MonoCustomModContainer, modifiers);
accum += sizeof (MonoCustomMod) * num_mods;
return accum;
}

size_t
mono_sizeof_type (const MonoType *ty)
{
MonoCustomModContainer *cmods = mono_type_get_cmods (ty);
if (cmods)
return mono_sizeof_type_with_mods (cmods->count);
else
return sizeof (MonoType);
}


6 changes: 6 additions & 0 deletions mono/metadata/metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,12 @@ typedef struct {
unsigned int token : 31;
} MonoCustomMod;

typedef struct _MonoCustomModContainer {
uint8_t count; /* max 64 modifiers follow at the end */
MonoImage *image; /* Image containing types in modifiers array */
MonoCustomMod modifiers [1]; /* Actual length is count */
} MonoCustomModContainer;

struct _MonoArrayType {
MonoClass *eklass;
// Number of dimensions of the array
Expand Down
11 changes: 6 additions & 5 deletions mono/metadata/sre-encode.c
Original file line number Diff line number Diff line change
Expand Up @@ -671,19 +671,20 @@ mono_dynimage_encode_fieldref_signature (MonoDynamicImage *assembly, MonoImage *

sigbuffer_add_value (&buf, 0x06);
/* encode custom attributes before the type */
if (type->num_mods) {
for (i = 0; i < type->num_mods; ++i) {
if (type->has_cmods) {
MonoCustomModContainer *cmods = mono_type_get_cmods (type);
for (i = 0; i < cmods->count; ++i) {
if (field_image) {
ERROR_DECL (error);
MonoClass *klass = mono_class_get_checked (field_image, type->modifiers [i].token, error);
MonoClass *klass = mono_class_get_checked (field_image, cmods->modifiers [i].token, error);
g_assert (mono_error_ok (error)); /* FIXME don't swallow the error */

token = mono_image_typedef_or_ref (assembly, m_class_get_byval_arg (klass));
} else {
token = type->modifiers [i].token;
token = cmods->modifiers [i].token;
}

if (type->modifiers [i].required)
if (cmods->modifiers [i].required)
sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_REQD);
else
sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_OPT);
Expand Down
Loading