#endif
#include <mono/metadata/image.h>
#include <mono/metadata/assembly.h>
-#include <mono/metadata/cil-coff.h>
#include <mono/metadata/metadata.h>
#include <mono/metadata/metadata-internals.h>
#include <mono/metadata/tabledefs.h>
#include <mono/metadata/reflection.h>
#include <mono/metadata/exception.h>
#include <mono/metadata/security-manager.h>
+#include <mono/metadata/security-core-clr.h>
+#include <mono/metadata/attrdefs.h>
#include <mono/os/gc_wrapper.h>
#include <mono/utils/mono-counters.h>
ta->aname.public_key_token [0] ? (char *)ta->aname.public_key_token : "null");
}
+static inline void
+mono_type_name_check_byref (MonoType *type, GString *str)
+{
+ if (type->byref)
+ g_string_append_c (str, '&');
+}
+
static void
mono_type_get_name_recurse (MonoType *type, GString *str, gboolean is_recursed,
MonoTypeNameFormat format)
for (i = 1; i < rank; i++)
g_string_append_c (str, ',');
g_string_append_c (str, ']');
+
+ mono_type_name_check_byref (type, str);
+
if (format == MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED)
_mono_type_get_assembly_name (type->data.array->eklass, str);
break;
mono_type_get_name_recurse (
&type->data.klass->byval_arg, str, FALSE, nested_format);
g_string_append (str, "[]");
+
+ mono_type_name_check_byref (type, str);
+
if (format == MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED)
_mono_type_get_assembly_name (type->data.klass, str);
break;
mono_type_get_name_recurse (
type->data.type, str, FALSE, nested_format);
g_string_append_c (str, '*');
+
+ mono_type_name_check_byref (type, str);
+
if (format == MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED)
_mono_type_get_assembly_name (mono_class_from_mono_type (type->data.type), str);
break;
case MONO_TYPE_MVAR:
g_assert (type->data.generic_param->name);
g_string_append (str, type->data.generic_param->name);
+
+ mono_type_name_check_byref (type, str);
+
break;
default:
klass = mono_class_from_mono_type (type);
else
g_string_append_c (str, ']');
}
+
+ mono_type_name_check_byref (type, str);
+
if ((format == MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED) &&
(type->type != MONO_TYPE_VAR) && (type->type != MONO_TYPE_MVAR))
_mono_type_get_assembly_name (klass, str);
mono_type_get_name_recurse (type, result, FALSE, format);
- if (type->byref)
- g_string_append_c (result, '&');
-
return g_string_free (result, FALSE);
}
break;
}
+#if NO_UNALIGNED_ACCESS
if (layout != TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) {
/*
* For small structs, set min_align to at least the struct size, since the
* JIT memset/memcpy code assumes this and generates unaligned accesses
* otherwise. See #78990 for a testcase.
+ * FIXME: Fix the memset/memcpy code instead.
*/
if (class->instance_size <= sizeof (MonoObject) + sizeof (gpointer))
class->min_align = MAX (class->min_align, class->instance_size - sizeof (MonoObject));
}
+#endif
class->size_inited = 1;
return;
}
+static void
+check_core_clr_override_method (MonoClass *class, MonoMethod *override, MonoMethod *base)
+{
+ MonoSecurityCoreCLRLevel override_level = mono_security_core_clr_method_level (override, FALSE);
+ MonoSecurityCoreCLRLevel base_level = mono_security_core_clr_method_level (base, FALSE);
+
+ if (override_level != base_level && base_level == MONO_SECURITY_CORE_CLR_CRITICAL) {
+ class->exception_type = MONO_EXCEPTION_TYPE_LOAD;
+ class->exception_data = NULL;
+ }
+}
+
/*
* LOCKING: this is supposed to be called with the loader lock held.
*/
override_map = g_hash_table_new (mono_aligned_addr_hash, NULL);
g_hash_table_insert (override_map, overrides [i * 2], overrides [i * 2 + 1]);
+
+ if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+ check_core_clr_override_method (class, vtable [dslot], decl);
}
}
mono_secman_inheritancedemand_method (cm, im);
}
+ if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+ check_core_clr_override_method (class, cm, im);
+
g_assert (io + l <= max_vtsize);
vtable [io + l] = cm;
}
mono_secman_inheritancedemand_method (cm, im);
}
+ if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+ check_core_clr_override_method (class, cm, im);
+
g_assert (io + l <= max_vtsize);
vtable [io + l] = cm;
break;
mono_secman_inheritancedemand_method (cm, im);
}
+ if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+ check_core_clr_override_method (class, cm, im);
+
g_assert (io + l <= max_vtsize);
vtable [io + l] = cm;
break;
mono_secman_inheritancedemand_method (cm, m1);
}
+ if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+ check_core_clr_override_method (class, cm, m1);
+
slot = k->methods [j]->slot;
g_assert (cm->slot < max_vtsize);
if (!override_map)
if (!override_map)
override_map = g_hash_table_new (mono_aligned_addr_hash, NULL);
g_hash_table_insert (override_map, decl, overrides [i * 2 + 1]);
+
+ if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+ check_core_clr_override_method (class, vtable [decl->slot], decl);
}
}
}
}
+static void
+check_core_clr_inheritance (MonoClass *class)
+{
+ MonoSecurityCoreCLRLevel class_level, parent_level;
+ MonoClass *parent = class->parent;
+
+ if (!parent)
+ return;
+
+ class_level = mono_security_core_clr_class_level (class);
+ parent_level = mono_security_core_clr_class_level (parent);
+
+ if (class_level < parent_level) {
+ class->exception_type = MONO_EXCEPTION_TYPE_LOAD;
+ class->exception_data = NULL;
+ }
+}
+
/**
* mono_class_init:
* @class: the class to initialize
mono_secman_inheritancedemand_class (class, class->parent);
}
+ if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+ check_core_clr_inheritance (class);
+
if (mono_debugger_start_class_init_func)
mono_debugger_start_class_init_func (class);
* @type_spec: typespec token
* @context: the generic context used to evaluate generic instantiations in
*/
-static MonoClass *
+static MonoType *
mono_type_retrieve_from_typespec (MonoImage *image, guint32 type_spec, MonoGenericContext *context)
{
MonoType *t = mono_type_create_from_typespec (image, type_spec);
MonoClass *class = NULL;
if (image->dynamic)
- return mono_lookup_dynamic_token (image, type_token);
+ return mono_lookup_dynamic_token (image, type_token, context);
switch (type_token & 0xff000000){
case MONO_TOKEN_TYPE_DEF:
//FIXME: this will not fix the very issue for which mono_type_get_full exists -but how to do it then?
if (image->dynamic)
- return mono_class_get_type (mono_lookup_dynamic_token (image, type_token));
+ return mono_class_get_type (mono_lookup_dynamic_token (image, type_token, context));
if ((type_token & 0xff000000) != MONO_TOKEN_TYPE_SPEC) {
MonoClass *class = mono_class_get_full (image, type_token, context);
return FALSE;
}
+static gboolean
+mono_class_has_variant_generic_params (MonoClass *klass)
+{
+ int i;
+ MonoGenericContainer *container;
+
+ if (!klass->generic_class)
+ return FALSE;
+
+ container = klass->generic_class->container_class->generic_container;
+
+ for (i = 0; i < container->type_argc; ++i)
+ if (container->type_params [i].flags & (MONO_GEN_PARAM_VARIANT|MONO_GEN_PARAM_COVARIANT))
+ return TRUE;
+
+ return FALSE;
+}
+
gboolean
mono_class_is_assignable_from (MonoClass *klass, MonoClass *oklass)
{
if (MONO_CLASS_IMPLEMENTS_INTERFACE (oklass, klass->interface_id))
return TRUE;
+
+ if (mono_class_has_variant_generic_params (klass)) {
+ if (oklass->generic_class) {
+ int i;
+ gboolean match = FALSE;
+ MonoClass *container_class1 = klass->generic_class->container_class;
+ MonoClass *container_class2 = oklass->generic_class->container_class;
+
+ /*
+ * Check whenever the generic definition of oklass implements the
+ * generic definition of klass. The IMPLEMENTS_INTERFACE stuff is not usable
+ * here since the relevant tables are not set up.
+ */
+ for (i = 0; i < container_class2->interface_offsets_count; ++i)
+ if ((container_class2->interfaces_packed [i] == container_class1) || (container_class2->interfaces_packed [i]->generic_class && (container_class2->interfaces_packed [i]->generic_class->container_class == container_class1)))
+ match = TRUE;
+
+ if (match) {
+ MonoGenericContainer *container;
+
+ container = klass->generic_class->container_class->generic_container;
+
+ match = TRUE;
+ for (i = 0; i < container->type_argc; ++i) {
+ MonoClass *param1_class = mono_class_from_mono_type (klass->generic_class->context.class_inst->type_argv [i]);
+ MonoClass *param2_class = mono_class_from_mono_type (oklass->generic_class->context.class_inst->type_argv [i]);
+
+ /*
+ * The _VARIANT and _COVARIANT constants should read _COVARIANT and
+ * _CONTRAVARIANT, but they are in a public header so we can't fix it.
+ */
+ if (param1_class != param2_class) {
+ if ((container->type_params [i].flags & MONO_GEN_PARAM_VARIANT) && mono_class_is_assignable_from (param1_class, param2_class))
+ ;
+ else if (((container->type_params [i].flags & MONO_GEN_PARAM_COVARIANT) && mono_class_is_assignable_from (param2_class, param1_class)))
+ ;
+ else
+ match = FALSE;
+ }
+ }
+
+ if (match)
+ return TRUE;
+ }
+ }
+ }
} else if (klass->rank) {
MonoClass *eclass, *eoclass;
{
if (image->dynamic) {
MonoClass *tmp_handle_class;
- gpointer obj = mono_lookup_dynamic_token_class (image, token, &tmp_handle_class);
+ gpointer obj = mono_lookup_dynamic_token_class (image, token, &tmp_handle_class, context);
g_assert (tmp_handle_class);
if (handle_class)
}
gpointer
-mono_lookup_dynamic_token (MonoImage *image, guint32 token)
+mono_lookup_dynamic_token (MonoImage *image, guint32 token, MonoGenericContext *context)
{
MonoClass *handle_class;
- return lookup_dynamic (image, token, &handle_class);
+ return lookup_dynamic (image, token, &handle_class, context);
}
gpointer
-mono_lookup_dynamic_token_class (MonoImage *image, guint32 token, MonoClass **handle_class)
+mono_lookup_dynamic_token_class (MonoImage *image, guint32 token, MonoClass **handle_class, MonoGenericContext *context)
{
- return lookup_dynamic (image, token, handle_class);
+ return lookup_dynamic (image, token, handle_class, context);
}
static MonoGetCachedClassInfo get_cached_class_info = NULL;
return FALSE;
}
+/*
+ * If klass is a generic type or if it is derived from a generic type, return the
+ * MonoClass of the generic definition
+ * Returns NULL if not found
+ */
+static MonoClass*
+get_generic_definition_class (MonoClass *klass)
+{
+ while (klass) {
+ if (klass->generic_class && klass->generic_class->container_class)
+ return klass->generic_class->container_class;
+ klass = klass->parent;
+ }
+ return NULL;
+}
+
/* FIXME: check visibility of type, too */
static gboolean
can_access_member (MonoClass *access_klass, MonoClass *member_klass, int access_level)
{
- if (access_klass->generic_class && member_klass->generic_class &&
- access_klass->generic_class->container_class && member_klass->generic_class->container_class) {
+ MonoClass *member_generic_def;
+ if (access_klass->generic_class && access_klass->generic_class->container_class &&
+ (member_generic_def = get_generic_definition_class (member_klass))) {
if (can_access_member (access_klass->generic_class->container_class,
- member_klass->generic_class->container_class, access_level))
+ member_generic_def, access_level))
return TRUE;
}