|
13 | 13 | #ifdef ENABLE_METADATA_UPDATE
|
14 | 14 |
|
15 | 15 | #include <glib.h>
|
| 16 | +#include "mono/metadata/assembly-internals.h" |
16 | 17 | #include "mono/metadata/metadata-internals.h"
|
17 | 18 | #include "mono/metadata/metadata-update.h"
|
18 | 19 | #include "mono/metadata/object-internals.h"
|
@@ -62,6 +63,71 @@ typedef struct _DeltaInfo {
|
62 | 63 | } DeltaInfo;
|
63 | 64 |
|
64 | 65 |
|
| 66 | +#define DOTNET_MODIFIABLE_ASSEMBLIES "DOTNET_MODIFIABLE_ASSEMBLIES" |
| 67 | + |
| 68 | +/** |
| 69 | + * mono_metadata_update_enable: |
| 70 | + * \param modifiable_assemblies_out: set to MonoModifiableAssemblies value |
| 71 | + * |
| 72 | + * Returns \c TRUE if metadata updates are enabled at runtime. False otherwise. |
| 73 | + * |
| 74 | + * If \p modifiable_assemblies_out is not \c NULL, it's set on return. |
| 75 | + * |
| 76 | + * The result depends on the value of the DOTNET_MODIFIABLE_ASSEMBLIES |
| 77 | + * environment variable. "debug" means debuggable assemblies are modifiable, |
| 78 | + * all other values are ignored and metadata updates are disabled. |
| 79 | + */ |
| 80 | +gboolean |
| 81 | +mono_metadata_update_enabled (int *modifiable_assemblies_out) |
| 82 | +{ |
| 83 | + static gboolean inited = FALSE; |
| 84 | + static int modifiable = MONO_MODIFIABLE_ASSM_NONE; |
| 85 | + |
| 86 | + if (!inited) { |
| 87 | + char *val = g_getenv (DOTNET_MODIFIABLE_ASSEMBLIES); |
| 88 | + if (!g_strcasecmp (val, "debug")) |
| 89 | + modifiable = MONO_MODIFIABLE_ASSM_DEBUG; |
| 90 | + g_free (val); |
| 91 | + inited = TRUE; |
| 92 | + } |
| 93 | + if (modifiable_assemblies_out) |
| 94 | + *modifiable_assemblies_out = modifiable; |
| 95 | + return modifiable != MONO_MODIFIABLE_ASSM_NONE; |
| 96 | +} |
| 97 | + |
| 98 | +static gboolean |
| 99 | +assembly_update_supported (MonoAssembly *assm) |
| 100 | +{ |
| 101 | + int modifiable = 0; |
| 102 | + if (!mono_metadata_update_enabled (&modifiable)) |
| 103 | + return FALSE; |
| 104 | + if (modifiable == MONO_MODIFIABLE_ASSM_DEBUG && |
| 105 | + mono_assembly_is_jit_optimizer_disabled (assm)) |
| 106 | + return TRUE; |
| 107 | + return FALSE; |
| 108 | +} |
| 109 | + |
| 110 | +/** |
| 111 | + * mono_metadata_update_no_inline: |
| 112 | + * \param caller: the calling method |
| 113 | + * \param callee: the method being called |
| 114 | + * |
| 115 | + * Returns \c TRUE if \p callee should not be inlined into \p caller. |
| 116 | + * |
| 117 | + * If metadata updates are enabled either for the caller or callee's module, |
| 118 | + * the callee should not be inlined. |
| 119 | + * |
| 120 | + */ |
| 121 | +gboolean |
| 122 | +mono_metadata_update_no_inline (MonoMethod *caller, MonoMethod *callee) |
| 123 | +{ |
| 124 | + if (!mono_metadata_update_enabled (NULL)) |
| 125 | + return FALSE; |
| 126 | + MonoAssembly *caller_assm = m_class_get_image(caller->klass)->assembly; |
| 127 | + MonoAssembly *callee_assm = m_class_get_image(callee->klass)->assembly; |
| 128 | + return mono_assembly_is_jit_optimizer_disabled (caller_assm) || mono_assembly_is_jit_optimizer_disabled (callee_assm); |
| 129 | +} |
| 130 | + |
65 | 131 | static void
|
66 | 132 | mono_metadata_update_ee_init (MonoError *error);
|
67 | 133 |
|
@@ -881,6 +947,11 @@ mono_image_load_enc_delta (MonoImage *image_base, gconstpointer dmeta_bytes, uin
|
881 | 947 | if (!is_ok (error))
|
882 | 948 | return;
|
883 | 949 |
|
| 950 | + if (!assembly_update_supported (image_base->assembly)) { |
| 951 | + mono_error_set_invalid_operation (error, "The assembly can not be edited or changed."); |
| 952 | + return; |
| 953 | + } |
| 954 | + |
884 | 955 | const char *basename = image_base->filename;
|
885 | 956 | /* FIXME:
|
886 | 957 | * (1) do we need to memcpy dmeta_bytes ? (maybe)
|
|
0 commit comments