[mini] Move netcore hosting functionality into separate file (#32136)
authorRyan Lucia <rylucia@microsoft.com>
Thu, 13 Feb 2020 20:36:18 +0000 (15:36 -0500)
committerGitHub <noreply@github.com>
Thu, 13 Feb 2020 20:36:18 +0000 (15:36 -0500)
* [mini] Move netcore hosting functionality into separate file

* [loader] Don't crash in the preload hook if the TPA paths aren't set

* [loader] Never request a refonly load in netcore preload hook

* Assert not refonly in netcore preload hook

* Add new files to msvc build

src/mono/mono/mini/CMakeLists.txt
src/mono/mono/mini/Makefile.am.in
src/mono/mono/mini/main-core.c
src/mono/mono/mini/monovm.c [new file with mode: 0644]
src/mono/mono/mini/monovm.h [new file with mode: 0644]
src/mono/msvc/libmini-common.targets
src/mono/msvc/libmini-common.targets.filters

index 960b4d8..7d943e6 100644 (file)
@@ -675,7 +675,9 @@ set (mini_common_sources
        mini-runtime.h
        llvmonly-runtime.h
        llvmonly-runtime.c
-       simd-intrinsics-netcore.c)
+       simd-intrinsics-netcore.c
+       monovm.h
+       monovm.c)
 
 set (debugger_sources
   debugger-engine.h
index d23249e..b80aa14 100755 (executable)
@@ -554,7 +554,9 @@ common_sources = \
        ee.h \
        tiered.h \
        tiered.c \
-       mini-runtime.h
+       mini-runtime.h \
+       monovm.h \
+       monovm.c
 
 endif # !ENABLE_MSVC_ONLY
 
index 0b303a3..29f575f 100644 (file)
@@ -9,6 +9,7 @@
 #include <mono/metadata/assembly-internals.h>
 #include <mono/metadata/environment.h>
 #include <mono/metadata/loader-internals.h>
+#include <mono/mini/monovm.h>
 #include <mono/utils/mono-logger-internals.h>
 
 #ifndef STDAPICALLTYPE
@@ -39,168 +40,6 @@ MONO_API int STDAPICALLTYPE coreclr_create_delegate (void* hostHandle, unsigned
        const char* entryPointAssemblyName, const char* entryPointTypeName, const char* entryPointMethodName,
        void** delegate);
 
-typedef struct {
-       int assembly_count;
-       char **basenames; /* Foo.dll */
-       char **assembly_filepaths; /* /blah/blah/blah/Foo.dll */
-} MonoCoreTrustedPlatformAssemblies;
-
-typedef struct {
-       int dir_count;
-       char **dirs;
-} MonoCoreNativeLibPaths;
-
-static MonoCoreTrustedPlatformAssemblies *trusted_platform_assemblies;
-static MonoCoreNativeLibPaths *native_lib_paths;
-
-static void
-mono_core_trusted_platform_assemblies_free (MonoCoreTrustedPlatformAssemblies *a)
-{
-       if (!a)
-               return;
-       g_strfreev (a->basenames);
-       g_strfreev (a->assembly_filepaths);
-       g_free (a);
-}
-
-static void
-mono_core_native_lib_paths_free (MonoCoreNativeLibPaths *dl)
-{
-       if (!dl)
-               return;
-       g_strfreev (dl->dirs);
-       g_free (dl);
-}
-
-static gboolean
-parse_trusted_platform_assemblies (const char *assemblies_paths)
-{
-       // From
-       // https://docs.microsoft.com/en-us/dotnet/core/tutorials/netcore-hosting#step-3---prepare-runtime-properties
-       // this is ';' separated on Windows and ':' separated elsewhere.
-       char **parts = g_strsplit (assemblies_paths, G_SEARCHPATH_SEPARATOR_S, 0);
-       int asm_count = 0;
-       for (char **p = parts; *p != NULL && **p != '\0'; p++) {
-#if 0
-               const char *part = *p;
-               // can't use logger, it's not initialized yet.
-               printf ("\t\tassembly %d = <%s>\n", asm_count, part);
-#endif
-               asm_count++;
-       }
-       MonoCoreTrustedPlatformAssemblies *a = g_new0 (MonoCoreTrustedPlatformAssemblies, 1);
-       a->assembly_count = asm_count;
-       a->assembly_filepaths = parts;
-       a->basenames = g_new0 (char*, asm_count + 1);
-       for (int i = 0; i < asm_count; ++i) {
-               a->basenames[i] = g_path_get_basename (a->assembly_filepaths [i]);
-       }
-       a->basenames [asm_count] = NULL;
-
-       trusted_platform_assemblies = a;
-       return TRUE;
-}
-
-static gboolean
-parse_native_dll_search_directories (const char *native_dlls_dirs)
-{
-       char **parts = g_strsplit (native_dlls_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
-       int dir_count = 0;
-       for (char **p = parts; *p != NULL && **p != '\0'; p++) {
-#if 0
-               const char *part = *p;
-               // can't use logger, it's not initialized yet.
-               printf ("\t\tnative search dir %d = <%s>\n", dir_count, part);
-#endif
-               dir_count++;
-       }
-       MonoCoreNativeLibPaths *dl = g_new0 (MonoCoreNativeLibPaths, 1);
-       dl->dirs = parts;
-       dl->dir_count = dir_count;
-
-       native_lib_paths = dl;
-       return TRUE;
-}
-
-static MonoAssembly*
-mono_core_preload_hook (MonoAssemblyLoadContext *alc, MonoAssemblyName *aname, char **assemblies_path, gboolean refonly, gpointer user_data, MonoError *error)
-{
-       MonoAssembly *result = NULL;
-       MonoCoreTrustedPlatformAssemblies *a = (MonoCoreTrustedPlatformAssemblies *)user_data;
-       /* TODO: check that CoreCLR wants the strong name semantics here */
-       MonoAssemblyCandidatePredicate predicate = &mono_assembly_candidate_predicate_sn_same_name;
-       void* predicate_ud = aname;
-
-       g_assert (aname);
-       g_assert (aname->name);
-       /* alc might be a user ALC - we get here from alc.LoadFromAssemblyName(), but we should load TPA assemblies into the default alc */
-       MonoAssemblyLoadContext *default_alc = mono_domain_default_alc (mono_alc_domain (alc));
-
-       char *basename = g_strconcat (aname->name, ".dll", (const char*)NULL); /* TODO: make sure CoreCLR never needs to load .exe files */
-
-       for (int i = 0; i < a->assembly_count; ++i) {
-               if (!strcmp (basename, a->basenames[i])) {
-                       MonoAssemblyOpenRequest req;
-                       mono_assembly_request_prepare_open (&req, refonly ? MONO_ASMCTX_REFONLY : MONO_ASMCTX_DEFAULT, default_alc);
-                       req.request.predicate = predicate;
-                       req.request.predicate_ud = predicate_ud;
-
-                       const char *fullpath = a->assembly_filepaths[i];
-
-                       gboolean found = g_file_test (fullpath, G_FILE_TEST_IS_REGULAR);
-
-                       if (found) {
-                               MonoImageOpenStatus status;
-                               result = mono_assembly_request_open (fullpath, &req, &status);
-                               /* TODO: do something with the status at the end? */
-                               if (result)
-                                       break;
-                       }
-               }
-       }
-
-       g_free (basename);
-
-       if (!result) {
-               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "netcore preload hook: did not find '%s'.", aname->name);
-       } else {
-               mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "netcore preload hook: loading '%s' from '%s'.", aname->name, result->image->name);
-       }
-       return result;
-}
-
-static void
-install_assembly_loader_hooks (void)
-{
-       mono_install_assembly_preload_hook_v2 (mono_core_preload_hook, (void*)trusted_platform_assemblies, FALSE);
-}
-
-static gboolean
-parse_properties (int propertyCount, const char** propertyKeys, const char** propertyValues)
-{
-       // The a partial list of relevant properties is
-       // https://docs.microsoft.com/en-us/dotnet/core/tutorials/netcore-hosting#step-3---prepare-runtime-properties
-       // TODO: We should also pick up at least APP_PATHS and APP_NI_PATHS
-       // and PLATFORM_RESOURCE_ROOTS for satellite assemblies in culture-specific subdirectories
-
-       for (int i = 0; i < propertyCount; ++i) {
-               if (!strcmp (propertyKeys[i], "TRUSTED_PLATFORM_ASSEMBLIES")) {
-                       parse_trusted_platform_assemblies (propertyValues[i]);
-               } else if (!strcmp (propertyKeys[i], "NATIVE_DLL_SEARCH_DIRECTORIES")) {
-                       parse_native_dll_search_directories (propertyValues[i]);
-               } else if (!strcmp (propertyKeys[i], "System.Globalization.Invariant")) {
-                       // TODO: Ideally we should propagate this through AppContext options
-                       g_setenv ("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT", propertyValues[i], TRUE);
-               } else {
-#if 0
-                       // can't use mono logger, it's not initialized yet.
-                       printf ("\t Unprocessed property %03d '%s': <%s>\n", i, propertyKeys[i], propertyValues[i]);
-#endif
-               }
-       }
-       return TRUE;
-}
-
 //
 // Initialize the CoreCLR. Creates and starts CoreCLR host and creates an app domain
 //
@@ -220,26 +59,9 @@ int STDAPICALLTYPE coreclr_initialize (const char* exePath, const char* appDomai
        int propertyCount, const char** propertyKeys, const char** propertyValues,
        void** hostHandle, unsigned int* domainId)
 {
-       mono_runtime_register_appctx_properties (propertyCount, propertyKeys, propertyValues);
-
-       // TODO: TRUSTED_PLATFORM_ASSEMBLIES is the property key for managed assemblies mapping
-       if (!parse_properties (propertyCount, propertyKeys, propertyValues))
-               return 0x80004005; /* E_FAIL */
-
-       install_assembly_loader_hooks ();
-       if (native_lib_paths != NULL)
-               mono_set_pinvoke_search_directories (native_lib_paths->dir_count, native_lib_paths->dirs);
-
-       /*
-        * Don't use Mono's legacy assembly name matching behavior - respect
-        * the requested version and culture.
-        */
-       mono_loader_set_strict_assembly_name_check (TRUE);
-
-       return 0;
+       return monovm_initialize (propertyCount, propertyKeys, propertyValues);
 }
 
-
 //
 // Execute a managed assembly with given arguments
 //
@@ -258,36 +80,7 @@ int STDAPICALLTYPE coreclr_execute_assembly (void* hostHandle, unsigned int doma
        int argc, const char** argv,
        const char* managedAssemblyPath, unsigned int* exitCode)
 {
-       if (exitCode == NULL)
-       {
-               return -1;
-       }
-
-       //
-       // Make room for program name and executable assembly
-       //
-       int mono_argc = argc + 2;
-
-       char **mono_argv = (char **) malloc (sizeof (char *) * (mono_argc + 1 /* null terminated */));
-       const char **ptr = (const char **) mono_argv;
-       
-       *ptr++ = NULL;
-
-       // executable assembly
-       *ptr++ = (char*) managedAssemblyPath;
-
-       // the rest
-       for (int i = 0; i < argc; ++i)
-               *ptr++ = argv [i];
-
-       *ptr = NULL;
-
-       mono_parse_env_options (&mono_argc, &mono_argv);
-
-       // TODO: Should be return code of Main only (mono_jit_exec result)
-       *exitCode = mono_main (mono_argc, mono_argv);
-
-       return 0;
+       return monovm_execute_assembly (argc, argv, managedAssemblyPath, exitCode);
 }
 
 //
@@ -303,18 +96,7 @@ int STDAPICALLTYPE coreclr_execute_assembly (void* hostHandle, unsigned int doma
 //
 int STDAPICALLTYPE coreclr_shutdown_2 (void* hostHandle, unsigned int domainId, int* latchedExitCode)
 {
-       mono_set_pinvoke_search_directories (0, NULL);
-       MonoCoreNativeLibPaths *dl = native_lib_paths;
-       native_lib_paths = NULL;
-       mono_core_native_lib_paths_free (dl);
-
-       MonoCoreTrustedPlatformAssemblies *a = trusted_platform_assemblies;
-       trusted_platform_assemblies = NULL;
-       mono_core_trusted_platform_assemblies_free (a);
-
-       *latchedExitCode = mono_environment_exitcode_get ();
-
-       return 0;
+       return monovm_shutdown (latchedExitCode);
 }
 
 //
diff --git a/src/mono/mono/mini/monovm.c b/src/mono/mono/mini/monovm.c
new file mode 100644 (file)
index 0000000..259f154
--- /dev/null
@@ -0,0 +1,276 @@
+#include <config.h>
+#include <mono/utils/mono-compiler.h>
+#include "monovm.h"
+
+#if ENABLE_NETCORE
+
+#include <mono/metadata/assembly-internals.h>
+#include <mono/metadata/assembly.h>
+#include <mono/metadata/environment.h>
+#include <mono/metadata/loader-internals.h>
+#include <mono/mini/mini-runtime.h>
+#include <mono/mini/mini.h>
+#include <mono/utils/mono-logger-internals.h>
+
+typedef struct {
+       int assembly_count;
+       char **basenames; /* Foo.dll */
+       char **assembly_filepaths; /* /blah/blah/blah/Foo.dll */
+} MonoCoreTrustedPlatformAssemblies;
+
+typedef struct {
+       int dir_count;
+       char **dirs;
+} MonoCoreNativeLibPaths;
+
+static MonoCoreTrustedPlatformAssemblies *trusted_platform_assemblies;
+static MonoCoreNativeLibPaths *native_lib_paths;
+
+static void
+mono_core_trusted_platform_assemblies_free (MonoCoreTrustedPlatformAssemblies *a)
+{
+       if (!a)
+               return;
+       g_strfreev (a->basenames);
+       g_strfreev (a->assembly_filepaths);
+       g_free (a);
+}
+
+static void
+mono_core_native_lib_paths_free (MonoCoreNativeLibPaths *dl)
+{
+       if (!dl)
+               return;
+       g_strfreev (dl->dirs);
+       g_free (dl);
+}
+
+static gboolean
+parse_trusted_platform_assemblies (const char *assemblies_paths)
+{
+       // From
+       // https://docs.microsoft.com/en-us/dotnet/core/tutorials/netcore-hosting#step-3---prepare-runtime-properties
+       // this is ';' separated on Windows and ':' separated elsewhere.
+       char **parts = g_strsplit (assemblies_paths, G_SEARCHPATH_SEPARATOR_S, 0);
+       int asm_count = 0;
+       for (char **p = parts; *p != NULL && **p != '\0'; p++) {
+#if 0
+               const char *part = *p;
+               // can't use logger, it's not initialized yet.
+               printf ("\t\tassembly %d = <%s>\n", asm_count, part);
+#endif
+               asm_count++;
+       }
+       MonoCoreTrustedPlatformAssemblies *a = g_new0 (MonoCoreTrustedPlatformAssemblies, 1);
+       a->assembly_count = asm_count;
+       a->assembly_filepaths = parts;
+       a->basenames = g_new0 (char*, asm_count + 1);
+       for (int i = 0; i < asm_count; ++i) {
+               a->basenames[i] = g_path_get_basename (a->assembly_filepaths [i]);
+       }
+       a->basenames [asm_count] = NULL;
+
+       trusted_platform_assemblies = a;
+       return TRUE;
+}
+
+static gboolean
+parse_native_dll_search_directories (const char *native_dlls_dirs)
+{
+       char **parts = g_strsplit (native_dlls_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
+       int dir_count = 0;
+       for (char **p = parts; *p != NULL && **p != '\0'; p++) {
+#if 0
+               const char *part = *p;
+               // can't use logger, it's not initialized yet.
+               printf ("\t\tnative search dir %d = <%s>\n", dir_count, part);
+#endif
+               dir_count++;
+       }
+       MonoCoreNativeLibPaths *dl = g_new0 (MonoCoreNativeLibPaths, 1);
+       dl->dirs = parts;
+       dl->dir_count = dir_count;
+
+       native_lib_paths = dl;
+       return TRUE;
+}
+
+static MonoAssembly*
+mono_core_preload_hook (MonoAssemblyLoadContext *alc, MonoAssemblyName *aname, char **assemblies_path, gboolean refonly, gpointer user_data, MonoError *error)
+{
+       MonoAssembly *result = NULL;
+       MonoCoreTrustedPlatformAssemblies *a = (MonoCoreTrustedPlatformAssemblies *)user_data;
+       /* TODO: check that CoreCLR wants the strong name semantics here */
+       MonoAssemblyCandidatePredicate predicate = &mono_assembly_candidate_predicate_sn_same_name;
+       void* predicate_ud = aname;
+       char *basename = NULL;
+
+       if (a == NULL) // no TPA paths set
+               goto leave;
+
+       g_assert (aname);
+       g_assert (aname->name);
+       g_assert (!refonly);
+       /* alc might be a user ALC - we get here from alc.LoadFromAssemblyName(), but we should load TPA assemblies into the default alc */
+       MonoAssemblyLoadContext *default_alc = mono_domain_default_alc (mono_alc_domain (alc));
+
+       basename = g_strconcat (aname->name, ".dll", (const char*)NULL); /* TODO: make sure CoreCLR never needs to load .exe files */
+
+       for (int i = 0; i < a->assembly_count; ++i) {
+               if (!strcmp (basename, a->basenames[i])) {
+                       MonoAssemblyOpenRequest req;
+                       mono_assembly_request_prepare_open (&req, MONO_ASMCTX_DEFAULT, default_alc);
+                       req.request.predicate = predicate;
+                       req.request.predicate_ud = predicate_ud;
+
+                       const char *fullpath = a->assembly_filepaths[i];
+
+                       gboolean found = g_file_test (fullpath, G_FILE_TEST_IS_REGULAR);
+
+                       if (found) {
+                               MonoImageOpenStatus status;
+                               result = mono_assembly_request_open (fullpath, &req, &status);
+                               /* TODO: do something with the status at the end? */
+                               if (result)
+                                       break;
+                       }
+               }
+       }
+
+leave:
+       g_free (basename);
+
+       if (!result) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "netcore preload hook: did not find '%s'.", aname->name);
+       } else {
+               mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "netcore preload hook: loading '%s' from '%s'.", aname->name, result->image->name);
+       }
+       return result;
+}
+
+static void
+install_assembly_loader_hooks (void)
+{
+       mono_install_assembly_preload_hook_v2 (mono_core_preload_hook, (void*)trusted_platform_assemblies, FALSE);
+}
+
+static gboolean
+parse_properties (int propertyCount, const char **propertyKeys, const char **propertyValues)
+{
+       // The a partial list of relevant properties is
+       // https://docs.microsoft.com/en-us/dotnet/core/tutorials/netcore-hosting#step-3---prepare-runtime-properties
+       // TODO: We should also pick up at least APP_PATHS and APP_NI_PATHS
+       // and PLATFORM_RESOURCE_ROOTS for satellite assemblies in culture-specific subdirectories
+
+       for (int i = 0; i < propertyCount; ++i) {
+               if (!strcmp (propertyKeys[i], "TRUSTED_PLATFORM_ASSEMBLIES")) {
+                       parse_trusted_platform_assemblies (propertyValues[i]);
+               } else if (!strcmp (propertyKeys[i], "NATIVE_DLL_SEARCH_DIRECTORIES")) {
+                       parse_native_dll_search_directories (propertyValues[i]);
+               } else if (!strcmp (propertyKeys[i], "System.Globalization.Invariant")) {
+                       // TODO: Ideally we should propagate this through AppContext options
+                       g_setenv ("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT", propertyValues[i], TRUE);
+               } else {
+#if 0
+                       // can't use mono logger, it's not initialized yet.
+                       printf ("\t Unprocessed property %03d '%s': <%s>\n", i, propertyKeys[i], propertyValues[i]);
+#endif
+               }
+       }
+       return TRUE;
+}
+
+int
+monovm_initialize (int propertyCount, const char **propertyKeys, const char **propertyValues)
+{
+       mono_runtime_register_appctx_properties (propertyCount, propertyKeys, propertyValues);
+
+       if (!parse_properties (propertyCount, propertyKeys, propertyValues))
+               return 0x80004005; /* E_FAIL */
+
+       install_assembly_loader_hooks ();
+       if (native_lib_paths != NULL)
+               mono_set_pinvoke_search_directories (native_lib_paths->dir_count, native_lib_paths->dirs);
+
+       /*
+        * Don't use Mono's legacy assembly name matching behavior - respect
+        * the requested version and culture.
+        */
+       mono_loader_set_strict_assembly_name_check (TRUE);
+
+       return 0;
+}
+
+int
+monovm_execute_assembly (int argc, const char **argv, const char *managedAssemblyPath, unsigned int *exitCode)
+{
+       if (exitCode == NULL)
+       {
+               return -1;
+       }
+
+       //
+       // Make room for program name and executable assembly
+       //
+       int mono_argc = argc + 2;
+
+       char **mono_argv = (char **) malloc (sizeof (char *) * (mono_argc + 1 /* null terminated */));
+       const char **ptr = (const char **) mono_argv;
+       
+       *ptr++ = NULL;
+
+       // executable assembly
+       *ptr++ = (char*) managedAssemblyPath;
+
+       // the rest
+       for (int i = 0; i < argc; ++i)
+               *ptr++ = argv [i];
+
+       *ptr = NULL;
+
+       mono_parse_env_options (&mono_argc, &mono_argv);
+
+       // TODO: Should be return code of Main only (mono_jit_exec result)
+       *exitCode = mono_main (mono_argc, mono_argv);
+
+       return 0;
+}
+
+int
+monovm_shutdown (int *latchedExitCode)
+{
+       mono_set_pinvoke_search_directories (0, NULL);
+       MonoCoreNativeLibPaths *dl = native_lib_paths;
+       native_lib_paths = NULL;
+       mono_core_native_lib_paths_free (dl);
+
+       MonoCoreTrustedPlatformAssemblies *a = trusted_platform_assemblies;
+       trusted_platform_assemblies = NULL;
+       mono_core_trusted_platform_assemblies_free (a);
+
+       *latchedExitCode = mono_environment_exitcode_get ();
+
+       return 0;
+}
+
+#else
+
+int
+monovm_initialize (int propertyCount, const char **propertyKeys, const char **propertyValues)
+{
+       return -1;
+}
+
+int
+monovm_execute_assembly (int argc, const char **argv, const char *managedAssemblyPath, unsigned int *exitCode)
+{
+       return -1;
+}
+
+int
+monovm_shutdown (int *latchedExitCode)
+{
+       return -1;
+}
+
+#endif // ENABLE_NETCORE
diff --git a/src/mono/mono/mini/monovm.h b/src/mono/mono/mini/monovm.h
new file mode 100644 (file)
index 0000000..1494b04
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef _MONO_MINI_MONOVM_H_
+#define _MONO_MINI_MONOVM_H_
+
+#include <mono/utils/mono-publib.h>
+
+// MonoVM equivalents of the CoreCLR hosting API and helpers
+// Only functional on netcore builds
+
+MONO_API int
+monovm_initialize (int propertyCount, const char **propertyKeys, const char **propertyValues);
+
+MONO_API int
+monovm_execute_assembly (int argc, const char **argv, const char *managedAssemblyPath, unsigned int *exitCode);
+
+MONO_API int
+monovm_shutdown (int *latchedExitCode);
+
+#endif // _MONO_MINI_MONOVM_H_
\ No newline at end of file
index 924b8d4..f151afb 100644 (file)
@@ -82,6 +82,8 @@
     <ClCompile Include="$(MonoSourceLocation)\mono\mini\interp-stubs.c" />
     <ClInclude Include="$(MonoSourceLocation)\mono\mini\llvmonly-runtime.h" />
     <ClCompile Include="$(MonoSourceLocation)\mono\mini\llvmonly-runtime.c" />
+    <ClInclude Include="$(MonoSourceLocation)\mono\mini\monovm.h" />
+    <ClCompile Include="$(MonoSourceLocation)\mono\mini\monovm.c" />
   </ItemGroup>
   <ItemGroup>
     <None Include="$(MonoSourceLocation)\mono\mini\Makefile.am.in" />
index 9c20dae..0bb299e 100644 (file)
     <ClCompile Include="$(MonoSourceLocation)\mono\mini\llvmonly-runtime.c">
       <Filter>Source Files$(MonoMiniFilterSubFolder)\common</Filter>
     </ClCompile>
+    <ClInclude Include="$(MonoSourceLocation)\mono\mini\monovm.h">
+      <Filter>Source Files$(MonoMiniFilterSubFolder)\common</Filter>
+    </ClInclude>
+    <ClCompile Include="$(MonoSourceLocation)\mono\mini\monovm.c">
+      <Filter>Source Files$(MonoMiniFilterSubFolder)\common</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <None Include="$(MonoSourceLocation)\mono\mini\Makefile.am.in">