[sgen] Ensure the cardtable code is 64bits clean.
[mono.git] / mono / metadata / coree.c
index 15b218e03800a4e7b8a89cce56cb9a645d839c21..9e48a3fe07749222d678cbc693ef0a21672a5b0b 100644 (file)
@@ -9,7 +9,7 @@
 
 #include <config.h>
 
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
 
 #if _WIN32_WINNT < 0x0501
 /* Required for ACTCTX. */
@@ -252,6 +252,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;
        }
 
@@ -301,8 +319,8 @@ STDAPI _CorValidateImage(PVOID *ImageBase, LPCWSTR FileName)
        NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
        NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
        NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
-       NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size = 0;
-       NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress = 0;
+       NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size = NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size;
+       NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress = NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress;
        NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size = 0;
        NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress = 0;
        NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size;
@@ -344,6 +362,9 @@ STDAPI _CorValidateImage(PVOID *ImageBase, LPCWSTR FileName)
        if (NtHeaders32->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)
                return STATUS_INVALID_IMAGE_FORMAT;
 
+       if (NtHeaders32->OptionalHeader.NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR)
+               return STATUS_INVALID_IMAGE_FORMAT;
+
        CliHeaderDir = &NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR];
        if (!CliHeaderDir->VirtualAddress)
                return STATUS_INVALID_IMAGE_FORMAT;
@@ -382,6 +403,79 @@ STDAPI CorBindToRuntime(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, REFCLSID r
        return CorBindToRuntimeEx (pwszVersion, pwszBuildFlavor, 0, rclsid, riid, ppv);
 }
 
+HMODULE WINAPI MonoLoadImage(LPCWSTR FileName)
+{
+       HANDLE FileHandle;
+       DWORD FileSize;
+       HANDLE MapHandle;
+       IMAGE_DOS_HEADER* DosHeader;
+       IMAGE_NT_HEADERS32* NtHeaders32;
+       IMAGE_NT_HEADERS64* NtHeaders64;
+       HMODULE ModuleHandle;
+
+       FileHandle = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+       if (FileHandle == INVALID_HANDLE_VALUE)
+               return NULL;
+
+       FileSize = GetFileSize(FileHandle, NULL); 
+       if (FileSize == INVALID_FILE_SIZE)
+               goto CloseFile;
+
+       MapHandle = CreateFileMapping(FileHandle, NULL, PAGE_READONLY, 0, 0, NULL);
+       if (MapHandle == NULL)
+               goto CloseFile;
+
+       DosHeader = (IMAGE_DOS_HEADER*)MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0);
+       if (DosHeader == NULL)
+               goto CloseMap;
+
+       if (FileSize < sizeof(IMAGE_DOS_HEADER) || DosHeader->e_magic != IMAGE_DOS_SIGNATURE || FileSize < DosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS32))
+               goto InvalidImageFormat;
+
+       NtHeaders32 = (IMAGE_NT_HEADERS32*)((DWORD_PTR)DosHeader + DosHeader->e_lfanew);
+       if (NtHeaders32->Signature != IMAGE_NT_SIGNATURE)
+               goto InvalidImageFormat;
+
+#ifdef _WIN64
+       NtHeaders64 = (IMAGE_NT_HEADERS64*)NtHeaders32;
+       if (NtHeaders64->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
+       {
+               if (FileSize < DosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS64) ||
+                       NtHeaders64->OptionalHeader.NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR ||
+                       !NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress)
+                               goto InvalidImageFormat;
+
+               goto ValidImage;
+       }
+#endif
+
+       if (NtHeaders32->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC ||
+               NtHeaders32->OptionalHeader.NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR ||
+               !NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress)
+       {
+InvalidImageFormat:
+               SetLastError(STATUS_INVALID_IMAGE_FORMAT);
+               goto UnmapView;
+       }
+
+ValidImage:
+       UnmapViewOfFile(DosHeader);
+       CloseHandle(MapHandle);
+
+       ModuleHandle = LoadLibrary(FileName);
+
+       CloseHandle(FileHandle);
+       return ModuleHandle;
+
+UnmapView:
+       UnmapViewOfFile(DosHeader);
+CloseMap:
+       CloseHandle(MapHandle);
+CloseFile:
+       CloseHandle(FileHandle);
+       return NULL;
+}
+
 typedef struct _EXPORT_FIXUP
 {
        LPCSTR Name;
@@ -642,8 +736,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)
@@ -791,6 +885,7 @@ mono_set_act_ctx (const char* file_name)
 void
 mono_load_coree (const char* exe_file_name)
 {
+       HMODULE module_handle;
        gunichar2* file_name;
        UINT required_size;
        UINT size;
@@ -810,13 +905,15 @@ mono_load_coree (const char* exe_file_name)
                file_name [size++] = L'\\';
        memcpy (&file_name [size], L"mscoree.dll", 12 * sizeof (gunichar2));
 
-       coree_module_handle = LoadLibrary (file_name);
+       module_handle = LoadLibrary (file_name);
        g_free (file_name);
 
-       if (coree_module_handle && !SUCCEEDED (MonoFixupCorEE (coree_module_handle))) {
-               FreeLibrary (coree_module_handle);
-               coree_module_handle = NULL;
+       if (module_handle && !SUCCEEDED (MonoFixupCorEE (module_handle))) {
+               FreeLibrary (module_handle);
+               module_handle = NULL;
        }
+
+       coree_module_handle = module_handle;
 }
 
 void
@@ -826,4 +923,4 @@ mono_fixup_exe_image (MonoImage* image)
                MonoFixupExe ((HMODULE) image->raw_data);
 }
 
-#endif /* PLATFORM_WIN32 */
+#endif /* HOST_WIN32 */