Merge pull request #2802 from BrzVlad/feature-evacuation-opt2
[mono.git] / mono / metadata / coree.c
index 7f3e0468052e6cfc7003bfc5308037df7eb5a27d..326251cc140c53a575ff7e227abcdeea92bc2782 100644 (file)
@@ -5,17 +5,12 @@
  *   Kornel Pal <http://www.kornelpal.hu/>
  *
  * Copyright (C) 2008 Kornel Pal
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
 #include <config.h>
 
-#ifdef PLATFORM_WIN32
-
-#if _WIN32_WINNT < 0x0501
-/* Required for ACTCTX. */
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
-#endif /* _WIN32_WINNT < 0x0501 */
+#ifdef HOST_WIN32
 
 #include <string.h>
 #include <glib.h>
@@ -33,6 +28,8 @@
 #include "environment.h"
 #include "coree.h"
 
+#include <shellapi.h>
+
 HMODULE coree_module_handle = NULL;
 
 static gboolean init_from_coree = FALSE;
@@ -140,13 +137,14 @@ BOOL STDMETHODCALLTYPE _CorDllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpRes
 /* Called by ntdll.dll reagardless of entry point after _CorValidateImage. */
 __int32 STDMETHODCALLTYPE _CorExeMain(void)
 {
+       MonoError error;
        MonoDomain* domain;
        MonoAssembly* assembly;
        MonoImage* image;
        MonoMethod* method;
        guint32 entry;
        gchar* file_name;
-       gchar* error;
+       gchar* corlib_version_error;
        int argc;
        gunichar2** argvw;
        gchar** argv;
@@ -156,9 +154,9 @@ __int32 STDMETHODCALLTYPE _CorExeMain(void)
        init_from_coree = TRUE;
        domain = mono_runtime_load (file_name, NULL);
 
-       error = (gchar*) mono_check_corlib_version ();
-       if (error) {
-               g_free (error);
+       corlib_version_error = (gchar*) mono_check_corlib_version ();
+       if (corlib_version_error) {
+               g_free (corlib_version_error);
                g_free (file_name);
                MessageBox (NULL, L"Corlib not in sync with this runtime.", NULL, MB_ICONERROR);
                mono_runtime_quit ();
@@ -183,9 +181,10 @@ __int32 STDMETHODCALLTYPE _CorExeMain(void)
                ExitProcess (1);
        }
 
-       method = mono_get_method (image, entry, NULL);
+       method = mono_get_method_checked (image, entry, NULL, NULL, &error);
        if (method == NULL) {
                g_free (file_name);
+               mono_error_cleanup (&error); /* FIXME don't swallow the error */
                MessageBox (NULL, L"The entry point method could not be loaded.", NULL, MB_ICONERROR);
                mono_runtime_quit ();
                ExitProcess (1);
@@ -226,10 +225,12 @@ STDAPI _CorValidateImage(PVOID *ImageBase, LPCWSTR FileName)
 {
        IMAGE_DOS_HEADER* DosHeader;
        IMAGE_NT_HEADERS32* NtHeaders32;
-       IMAGE_NT_HEADERS64* NtHeaders64;
        IMAGE_DATA_DIRECTORY* CliHeaderDir;
+#ifdef _WIN64
+       IMAGE_NT_HEADERS64* NtHeaders64;
        MonoCLIHeader* CliHeader;
        DWORD SizeOfHeaders;
+#endif
        DWORD* Address;
        DWORD OldProtect;
 
@@ -252,6 +253,24 @@ STDAPI _CorValidateImage(PVOID *ImageBase, LPCWSTR FileName)
                if (!CliHeaderDir->VirtualAddress)
                        return STATUS_INVALID_IMAGE_FORMAT;
 
+               CliHeader = (MonoCLIHeader*)((DWORD_PTR)DosHeader + CliHeaderDir->VirtualAddress);
+               if (CliHeader->ch_flags & CLI_FLAGS_32BITREQUIRED)
+                       return STATUS_INVALID_IMAGE_FORMAT;
+
+               if (CliHeader->ch_flags & CLI_FLAGS_ILONLY)
+               {
+                       /* Avoid calling _CorDllMain because imports are not resolved for IL only images. */
+                       if (NtHeaders64->OptionalHeader.AddressOfEntryPoint != 0)
+                       {
+                               Address = &NtHeaders64->OptionalHeader.AddressOfEntryPoint;
+                               if (!VirtualProtect(Address, sizeof(DWORD), PAGE_READWRITE, &OldProtect))
+                                       return E_UNEXPECTED;
+                               *Address = (DWORD)0;
+                               if (!VirtualProtect(Address, sizeof(DWORD), OldProtect, &OldProtect))
+                                       return E_UNEXPECTED;
+                       }
+               }
+
                return STATUS_SUCCESS;
        }
 
@@ -392,7 +411,9 @@ HMODULE WINAPI MonoLoadImage(LPCWSTR FileName)
        HANDLE MapHandle;
        IMAGE_DOS_HEADER* DosHeader;
        IMAGE_NT_HEADERS32* NtHeaders32;
+#ifdef _WIN64
        IMAGE_NT_HEADERS64* NtHeaders64;
+#endif
        HMODULE ModuleHandle;
 
        FileHandle = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
@@ -440,7 +461,9 @@ InvalidImageFormat:
                goto UnmapView;
        }
 
+#ifdef _WIN64
 ValidImage:
+#endif
        UnmapViewOfFile(DosHeader);
        CloseHandle(MapHandle);
 
@@ -718,8 +741,8 @@ STDAPI MonoFixupExe(HMODULE ModuleHandle)
                                                return E_FAIL;
 
                                        BaseRelocSize -= RelocBlockSize;
-                                       RelocBlock = (USHORT*)((DWORD_PTR)BaseReloc + IMAGE_SIZEOF_BASE_RELOCATION);
-                                       RelocBlockSize -= IMAGE_SIZEOF_BASE_RELOCATION;
+                                       RelocBlock = (USHORT*)((DWORD_PTR)BaseReloc + sizeof(IMAGE_BASE_RELOCATION));
+                                       RelocBlockSize -= sizeof(IMAGE_BASE_RELOCATION);
                                        RelocBlockSize /= sizeof(USHORT);
 
                                        while (RelocBlockSize-- != 0)
@@ -905,4 +928,4 @@ mono_fixup_exe_image (MonoImage* image)
                MonoFixupExe ((HMODULE) image->raw_data);
 }
 
-#endif /* PLATFORM_WIN32 */
+#endif /* HOST_WIN32 */