Hi,
From: Jonathan Chambers This patch seems to be the cause of the build failures on Win32:
I have tracked down the issue. The problem is that "load_aot_module_from_cache" calls that calls "mono_dl_open" that calls "LoadLibrary" with just a file name without a full path. This will result in MS.NET assemblies being loaded when MS.NET is in PATH. I don't know how load_aot_module_from_cache is supposed to work but I think this is a bug in load_aot_module_from_cache.
On the other hand my patch had a bug with reference counting when the image was loaded using LoadLibrary outside of image.c. Assembly name is a pointer to raw_data that was freed that caused the problems you described. This should now be fixed.
Please try the attached patch. If the build is still broken please let me know.
Kornél
Index: mono/mono/metadata/domain.c =================================================================== --- mono/mono/metadata/domain.c (revision 102399) +++ mono/mono/metadata/domain.c (working copy) @@ -1161,12 +1161,9 @@ if (domain) g_assert_not_reached (); - /* FIXME: This causes Win32 build to break. */ -#if 0 #if defined(PLATFORM_WIN32) && !defined(_WIN64) - mono_load_coree (); + mono_load_coree (exe_filename); #endif -#endif mono_perfcounters_init (); @@ -1205,6 +1202,11 @@ */ get_runtimes_from_exe (exe_filename, &exe_image, runtimes); #ifdef PLATFORM_WIN32 + if (!exe_image) { + exe_image = mono_assembly_open_from_bundle (exe_filename, NULL, FALSE); + if (!exe_image) + exe_image = mono_image_open (exe_filename, NULL); + } mono_fixup_exe_image (exe_image); #endif } else if (runtime_version != NULL) { @@ -1610,8 +1612,7 @@ void mono_cleanup (void) { - if (exe_image) - mono_image_close (exe_image); + mono_close_exe_image (); mono_loader_cleanup (); mono_classes_cleanup (); @@ -1625,6 +1626,13 @@ DeleteCriticalSection (&appdomains_mutex); } +void +mono_close_exe_image (void) +{ + if (exe_image) + mono_image_close (exe_image); +} + /** * mono_get_root_domain: * Index: mono/mono/metadata/image.c =================================================================== --- mono/mono/metadata/image.c (revision 102399) +++ mono/mono/metadata/image.c (working copy) @@ -24,6 +24,7 @@ #include "metadata-internals.h" #include "profiler-private.h" #include "loader.h" +#include "marshal.h" #include "coree.h" #include <mono/io-layer/io-layer.h> #include <mono/utils/mono-logger.h> @@ -1077,11 +1078,10 @@ #ifdef PLATFORM_WIN32 /* fname is not duplicated. */ MonoImage* -mono_image_open_from_module_handle (HMODULE module_handle, const char* fname, MonoImageOpenStatus* status) +mono_image_open_from_module_handle (HMODULE module_handle, char* fname, int ref_count, MonoImageOpenStatus* status) { MonoImage* image; MonoCLIImageInfo* iinfo; - guint16* fname_utf16; image = g_new0 (MonoImage, 1); image->raw_data = (char*) module_handle; @@ -1089,10 +1089,10 @@ iinfo = g_new0 (MonoCLIImageInfo, 1); image->image_info = iinfo; image->name = fname; - image->ref_count = 1; + image->ref_count = ref_count; image = do_mono_image_load (image, status, TRUE); - image = register_image (image); + return register_image (image); } #endif @@ -1110,42 +1110,66 @@ if (!refonly && coree_module_handle) { HMODULE module_handle; guint16 *fname_utf16; + DWORD last_error; absfname = mono_path_resolve_symlinks (fname); + fname_utf16 = NULL; /* There is little overhead because the OS loader lock is held by LoadLibrary. */ mono_images_lock (); image = g_hash_table_lookup (loaded_images_hash, absfname); if (image) { + g_assert (image->is_module_handle); + if (image->ref_count == 0) { + MonoCLIImageInfo *iinfo = image->image_info; + + if (iinfo->cli_header.coff.coff_attributes & COFF_ATTRIBUTE_LIBRARY_IMAGE) { + /* Increment reference count on images loaded outside of the runtime. */ + fname_utf16 = g_utf8_to_utf16 (absfname, -1, NULL, NULL, NULL); + module_handle = LoadLibrary (fname_utf16); + g_assert (module_handle != NULL); + } + } mono_image_addref (image); mono_images_unlock (); + if (fname_utf16) + g_free (fname_utf16); g_free (absfname); return image; } fname_utf16 = g_utf8_to_utf16 (absfname, -1, NULL, NULL, NULL); module_handle = LoadLibrary (fname_utf16); + if (status && module_handle == NULL) + last_error = GetLastError (); /* mono_image_open_from_module_handle is called by _CorDllMain. */ image = g_hash_table_lookup (loaded_images_hash, absfname); + if (image) + mono_image_addref (image); mono_images_unlock (); g_free (fname_utf16); - if (image) { - /* No mono_image_addref required. */; + if (module_handle == NULL) { + g_assert (!image); g_free (absfname); - return image; + if (status) { + if (last_error == ERROR_BAD_EXE_FORMAT || last_error == STATUS_INVALID_IMAGE_FORMAT) + *status = MONO_IMAGE_IMAGE_INVALID; + else + *status = MONO_IMAGE_ERROR_ERRNO; + } + return NULL; } - if (module_handle == NULL) { + if (image) { + g_assert (image->is_module_handle); g_free (absfname); - if (status) - *status = MONO_IMAGE_ERROR_ERRNO; - return NULL; + return image; } - return mono_image_open_from_module_handle (module_handle, absfname, status); + return mono_image_open_from_module_handle (module_handle, absfname, 1, status); } #endif @@ -1331,6 +1355,23 @@ if (InterlockedDecrement (&image->ref_count) > 0) return; +#ifdef PLATFORM_WIN32 + if (image->is_module_handle) { + MonoCLIImageInfo *iinfo = image->image_info; + + if (iinfo->cli_header.coff.coff_attributes & COFF_ATTRIBUTE_LIBRARY_IMAGE) { + mono_images_lock (); + if (image->ref_count == 0) { + /* Image will be closed by _CorDllMain. */ + FreeLibrary ((HMODULE) image->raw_data); + mono_images_unlock (); + return; + } + mono_images_unlock (); + } + } +#endif + mono_profiler_module_event (image, MONO_PROFILE_START_UNLOAD); mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Unloading image %s [%p].", image->name, image); @@ -1364,13 +1405,17 @@ if (image->assembly_name && (g_hash_table_lookup (loaded_images, image->assembly_name) == image)) g_hash_table_remove (loaded_images, (char *) image->assembly_name); - mono_images_unlock (); +#ifdef PLATFORM_WIN32 + if (image->is_module_handle) { + MonoCLIImageInfo *iinfo = image->image_info; -#ifdef PLATFORM_WIN32 - if (image->is_module_handle) - FreeLibrary ((HMODULE) image->raw_data); + if (!(iinfo->cli_header.coff.coff_attributes & COFF_ATTRIBUTE_LIBRARY_IMAGE)) + FreeLibrary ((HMODULE) image->raw_data); + } #endif + mono_images_unlock (); + if (image->raw_buffer_used) { if (image->raw_data != NULL) mono_raw_buffer_free (image->raw_data); Index: mono/mono/metadata/threads.c =================================================================== --- mono/mono/metadata/threads.c (revision 102399) +++ mono/mono/metadata/threads.c (working copy) @@ -186,6 +186,7 @@ static GArray *delayed_free_table = NULL; static gboolean shutting_down = FALSE; +static gboolean threads_initialized = FALSE; guint32 mono_thread_get_tls_key (void) @@ -2258,6 +2259,8 @@ * anything up. */ GetCurrentProcess (); + + threads_initialized = TRUE; } void mono_thread_cleanup (void) @@ -2281,6 +2284,7 @@ * critical sections can be locked when mono_thread_cleanup is * called. */ + threads_initialized = FALSE; DeleteCriticalSection (&threads_mutex); DeleteCriticalSection (&interlocked_mutex); DeleteCriticalSection (&contexts_mutex); @@ -2663,6 +2667,9 @@ { gsize self = GetCurrentThreadId (); + if (!threads_initialized) + return; + mono_threads_lock (); THREAD_DEBUG (g_message ("%s: There are %d threads to abort", __func__, mono_g_hash_table_size (threads)); Index: mono/mono/metadata/coree.c =================================================================== --- mono/mono/metadata/coree.c (revision 102399) +++ mono/mono/metadata/coree.c (working copy) @@ -14,9 +14,12 @@ #include <string.h> #include <glib.h> #include <mono/io-layer/io-layer.h> +#include <mono/utils/mono-path.h> +#include "cil-coff.h" #include "metadata-internals.h" #include "image.h" #include "assembly.h" +#include "domain-internals.h" #include "appdomain.h" #include "object.h" #include "loader.h" @@ -24,18 +27,11 @@ #include "environment.h" #include "coree.h" -#define STATUS_SUCCESS 0x00000000L -#define STATUS_INVALID_IMAGE_FORMAT 0xC000007BL - -typedef struct _EXPORT_FIXUP -{ - LPCSTR Name; - DWORD_PTR ProcAddress; -} EXPORT_FIXUP; - HMODULE mono_module_handle = NULL; HMODULE coree_module_handle = NULL; +static gboolean init_from_coree = FALSE; + gchar* mono_get_module_file_name (HMODULE module_handle) { @@ -84,8 +80,9 @@ file_name = mono_get_module_file_name (hInst); if (mono_get_root_domain ()) { - image = mono_image_open_from_module_handle (hInst, mono_path_resolve_symlinks (file_name), NULL); + image = mono_image_open_from_module_handle (hInst, mono_path_resolve_symlinks (file_name), 0, NULL); } else { + init_from_coree = TRUE; mono_runtime_load (file_name, NULL); error = (gchar*) mono_check_corlib_version (); if (error) { @@ -96,6 +93,10 @@ } image = mono_image_open (file_name, NULL); + mono_close_exe_image (); + if (image) + /* Decrement reference count to zero. (Image will not be closed.) */ + mono_image_close (image); } if (!image) { @@ -108,18 +109,29 @@ * loader trampolines should be used and assembly loading should * probably be delayed until the first call to an exported function. */ - if (image->tables [MONO_TABLE_ASSEMBLY].rows) + if (image->tables [MONO_TABLE_ASSEMBLY].rows && ((MonoCLIImageInfo*) image->image_info)->cli_cli_header.ch_vtable_fixups.rva) assembly = mono_assembly_open (file_name, NULL); g_free (file_name); break; + case DLL_PROCESS_DETACH: + if (lpReserved != NULL) + /* The process is terminating. */ + return TRUE; + file_name = mono_get_module_file_name (hInst); + image = mono_image_loaded (file_name); + if (image) + mono_image_close (image); + + g_free (file_name); + break; } return TRUE; } /* Called by ntdll.dll reagardless of entry point after _CorValidateImage. */ -__int32 STDMETHODCALLTYPE _CorExeMain() +__int32 STDMETHODCALLTYPE _CorExeMain(void) { MonoDomain* domain; MonoAssembly* assembly; @@ -134,6 +146,7 @@ int i; file_name = mono_get_module_file_name (GetModuleHandle (NULL)); + init_from_coree = TRUE; domain = mono_runtime_load (file_name, NULL); error = (gchar*) mono_check_corlib_version (); @@ -146,6 +159,7 @@ } assembly = mono_assembly_open (file_name, NULL); + mono_close_exe_image (); if (!assembly) { g_free (file_name); MessageBox (NULL, L"Cannot open assembly.", NULL, MB_ICONERROR); @@ -189,7 +203,7 @@ /* Called by msvcrt.dll when shutting down. */ void STDMETHODCALLTYPE CorExitProcess(int exitCode) { - if (!mono_runtime_is_shutting_down ()) { + if (mono_get_root_domain () && !mono_runtime_is_shutting_down ()) { mono_runtime_set_shutting_down (); mono_thread_suspend_all_other_threads (); mono_runtime_quit (); @@ -203,7 +217,7 @@ IMAGE_DOS_HEADER* DosHeader; IMAGE_NT_HEADERS* NtHeaders; DWORD* Address; - DWORD dwOldProtect; + DWORD OldProtect; DosHeader = (IMAGE_DOS_HEADER*)*ImageBase; if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE) @@ -217,13 +231,13 @@ return STATUS_INVALID_IMAGE_FORMAT; Address = &NtHeaders->OptionalHeader.AddressOfEntryPoint; - if (!VirtualProtect(Address, sizeof(DWORD), PAGE_READWRITE, &dwOldProtect)) + if (!VirtualProtect(Address, sizeof(DWORD), PAGE_READWRITE, &OldProtect)) return E_UNEXPECTED; if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) *Address = (DWORD)((DWORD_PTR)&_CorDllMain - (DWORD_PTR)DosHeader); else *Address = (DWORD)((DWORD_PTR)&_CorExeMain - (DWORD_PTR)DosHeader); - if (!VirtualProtect(Address, sizeof(DWORD), dwOldProtect, &dwOldProtect)) + if (!VirtualProtect(Address, sizeof(DWORD), OldProtect, &OldProtect)) return E_UNEXPECTED; return STATUS_SUCCESS; @@ -235,11 +249,29 @@ /* Nothing to do. */ } +STDAPI CorBindToRuntimeEx(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, DWORD startupFlags, REFCLSID rclsid, REFIID riid, LPVOID FAR *ppv) +{ + return E_NOTIMPL; +} + +STDAPI CorBindToRuntime(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, REFCLSID rclsid, REFIID riid, LPVOID FAR *ppv) +{ + return CorBindToRuntimeEx (pwszVersion, pwszBuildFlavor, 0, rclsid, riid, ppv); +} + /* Fixup exported functions of mscoree.dll to our implementations. */ STDAPI MonoFixupCorEE(HMODULE ModuleHandle) { + typedef struct _EXPORT_FIXUP + { + LPCSTR Name; + DWORD_PTR ProcAddress; + } EXPORT_FIXUP; + /* Has to be binary ordered. */ const EXPORT_FIXUP ExportFixups[] = { + {"CorBindToRuntime", (DWORD_PTR)&CorBindToRuntime}, + {"CorBindToRuntimeEx", (DWORD_PTR)&CorBindToRuntimeEx}, {"CorExitProcess", (DWORD_PTR)&CorExitProcess}, {"_CorDllMain", (DWORD_PTR)&_CorDllMain}, {"_CorExeMain", (DWORD_PTR)&_CorExeMain}, @@ -257,7 +289,7 @@ WORD* NameOrdinals; EXPORT_FIXUP* ExportFixup; DWORD* Address; - DWORD dwOldProtect; + DWORD OldProtect; DWORD_PTR ProcAddress; DWORD i; @@ -295,10 +327,10 @@ Address = &Functions[NameOrdinals[i]]; ProcAddress = (DWORD_PTR)DosHeader + *Address; if (ProcAddress != ExportFixup->ProcAddress) { - if (!VirtualProtect(Address, sizeof(DWORD), PAGE_READWRITE, &dwOldProtect)) + if (!VirtualProtect(Address, sizeof(DWORD), PAGE_READWRITE, &OldProtect)) return E_UNEXPECTED; *Address = (DWORD)(ExportFixup->ProcAddress - (DWORD_PTR)DosHeader); - if (!VirtualProtect(Address, sizeof(DWORD), dwOldProtect, &dwOldProtect)) + if (!VirtualProtect(Address, sizeof(DWORD), OldProtect, &OldProtect)) return E_UNEXPECTED; } ExportFixup++; @@ -315,7 +347,7 @@ IMAGE_DOS_HEADER* DosHeader; IMAGE_NT_HEADERS* NtHeaders; DWORD_PTR* Address; - DWORD dwOldProtect; + DWORD OldProtect; DWORD_PTR BaseDiff; DosHeader = (IMAGE_DOS_HEADER*)ModuleHandle; @@ -332,6 +364,20 @@ if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) return S_OK; + if (NtHeaders->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR) + { + IMAGE_DATA_DIRECTORY* CliHeaderDir; + MonoCLIHeader* CliHeader; + + CliHeaderDir = &NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR]; + if (CliHeaderDir->VirtualAddress && CliHeaderDir->Size) + { + CliHeader = (MonoCLIHeader*)((DWORD_PTR)DosHeader + CliHeaderDir->VirtualAddress); + if (CliHeader->ch_flags & CLI_FLAGS_ILONLY) + return S_OK; + } + } + BaseDiff = (DWORD_PTR)DosHeader - NtHeaders->OptionalHeader.ImageBase; if (BaseDiff != 0) { @@ -339,10 +385,10 @@ return E_FAIL; Address = &NtHeaders->OptionalHeader.ImageBase; - if (!VirtualProtect(Address, sizeof(DWORD_PTR), PAGE_READWRITE, &dwOldProtect)) + if (!VirtualProtect(Address, sizeof(DWORD_PTR), PAGE_READWRITE, &OldProtect)) return E_UNEXPECTED; *Address = (DWORD_PTR)DosHeader; - if (!VirtualProtect(Address, sizeof(DWORD_PTR), dwOldProtect, &dwOldProtect)) + if (!VirtualProtect(Address, sizeof(DWORD_PTR), OldProtect, &OldProtect)) return E_UNEXPECTED; if (NtHeaders->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BASERELOC) @@ -388,10 +434,10 @@ #else case IMAGE_REL_BASED_HIGHLOW: #endif - if (!VirtualProtect(RelocFixup, sizeof(DWORD_PTR), PAGE_EXECUTE_READWRITE, &dwOldProtect)) + if (!VirtualProtect(RelocFixup, sizeof(DWORD_PTR), PAGE_EXECUTE_READWRITE, &OldProtect)) return E_UNEXPECTED; *RelocFixup += BaseDiff; - if (!VirtualProtect(RelocFixup, sizeof(DWORD_PTR), dwOldProtect, &dwOldProtect)) + if (!VirtualProtect(RelocFixup, sizeof(DWORD_PTR), OldProtect, &OldProtect)) return E_UNEXPECTED; break; @@ -438,10 +484,10 @@ if (ProcAddress == 0) return E_FAIL; Address = (DWORD_PTR*)((DWORD_PTR)ImportThunkData - ImportDesc->OriginalFirstThunk + ImportDesc->FirstThunk); - if (!VirtualProtect(Address, sizeof(DWORD_PTR), PAGE_READWRITE, &dwOldProtect)) + if (!VirtualProtect(Address, sizeof(DWORD_PTR), PAGE_READWRITE, &OldProtect)) return E_UNEXPECTED; *Address = ProcAddress; - if (!VirtualProtect(Address, sizeof(DWORD_PTR), dwOldProtect, &dwOldProtect)) + if (!VirtualProtect(Address, sizeof(DWORD_PTR), OldProtect, &OldProtect)) return E_UNEXPECTED; ImportThunkData++; } @@ -454,8 +500,69 @@ return S_OK; } +static void +mono_set_act_ctx (const char* file_name) +{ + typedef __out HANDLE (WINAPI* CREATEACTCTXW_PROC) (__in PCACTCTXW pActCtx); + typedef BOOL (WINAPI* ACTIVATEACTCTX_PROC) (__inout_opt HANDLE hActCtx, __out ULONG_PTR* lpCookie); + + HMODULE kernel32_handle; + CREATEACTCTXW_PROC CreateActCtx_proc; + ACTIVATEACTCTX_PROC ActivateActCtx_proc; + gchar* full_path; + gunichar2* full_path_utf16; + gchar* dir_name; + gunichar2* dir_name_utf16; + gchar* base_name; + gunichar2* base_name_utf16; + ACTCTX act_ctx; + HANDLE handle; + ULONG_PTR cookie; + + kernel32_handle = GetModuleHandle (L"kernel32.dll"); + if (!kernel32_handle) + return; + CreateActCtx_proc = (CREATEACTCTXW_PROC) GetProcAddress (kernel32_handle, "CreateActCtxW"); + if (!CreateActCtx_proc) + return; + ActivateActCtx_proc = (ACTIVATEACTCTX_PROC) GetProcAddress (kernel32_handle, "ActivateActCtx"); + if (!ActivateActCtx_proc) + return; + + full_path = mono_path_canonicalize (file_name); + full_path_utf16 = g_utf8_to_utf16 (full_path, -1, NULL, NULL, NULL); + dir_name = g_path_get_dirname (full_path); + dir_name_utf16 = g_utf8_to_utf16 (dir_name, -1, NULL, NULL, NULL); + base_name = g_path_get_basename (full_path); + base_name_utf16 = g_utf8_to_utf16 (base_name, -1, NULL, NULL, NULL); + g_free (base_name); + g_free (dir_name); + g_free (full_path); + + memset (&act_ctx, 0, sizeof (ACTCTX)); + act_ctx.cbSize = sizeof (ACTCTX); + act_ctx.dwFlags = ACTCTX_FLAG_SET_PROCESS_DEFAULT | ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID | ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_APPLICATION_NAME_VALID; + act_ctx.lpSource = full_path_utf16; + act_ctx.lpAssemblyDirectory = dir_name_utf16; + act_ctx.lpResourceName = MAKEINTRESOURCE (CREATEPROCESS_MANIFEST_RESOURCE_ID); + act_ctx.lpApplicationName = base_name_utf16; + + handle = CreateActCtx_proc (&act_ctx); + if (handle == INVALID_HANDLE_VALUE && GetLastError () == ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET) { + act_ctx.dwFlags &= ~ACTCTX_FLAG_SET_PROCESS_DEFAULT; + handle = CreateActCtx_proc (&act_ctx); + } + + g_free (base_name_utf16); + g_free (dir_name_utf16); + g_free (full_path_utf16); + + if (handle != INVALID_HANDLE_VALUE) + ActivateActCtx_proc (handle, &cookie); +} + void -mono_load_coree () +mono_load_coree (const char* exe_file_name) { gunichar2* file_name; UINT required_size; @@ -464,6 +571,9 @@ if (coree_module_handle) return; + if (!init_from_coree && exe_file_name) + mono_set_act_ctx (exe_file_name); + /* ntdll.dll loads mscoree.dll from the system32 directory. */ required_size = GetSystemDirectory (NULL, 0); file_name = g_new (gunichar2, required_size + 12); @@ -485,7 +595,7 @@ void mono_fixup_exe_image (MonoImage* image) { - if (image && image->is_module_handle && (HMODULE) image->raw_data != GetModuleHandle (NULL)) + if (!init_from_coree && image && image->is_module_handle) MonoFixupExe ((HMODULE) image->raw_data); } Index: mono/mono/metadata/coree.h =================================================================== --- mono/mono/metadata/coree.h (revision 102399) +++ mono/mono/metadata/coree.h (working copy) @@ -17,6 +17,9 @@ #include <mono/io-layer/io-layer.h> #include "image.h" +#define STATUS_SUCCESS 0x00000000L +#define STATUS_INVALID_IMAGE_FORMAT 0xC000007BL + STDAPI MonoFixupCorEE(HMODULE ModuleHandle); STDAPI MonoFixupExe(HMODULE ModuleHandle); @@ -24,11 +27,11 @@ extern HMODULE coree_module_handle; gchar* mono_get_module_file_name (HMODULE module_handle); -void mono_load_coree (); +void mono_load_coree (const char* file_name); void mono_fixup_exe_image (MonoImage* image); /* Declared in image.c. */ -MonoImage* mono_image_open_from_module_handle (HMODULE module_handle, const char* fname, MonoImageOpenStatus* status); +MonoImage* mono_image_open_from_module_handle (HMODULE module_handle, char* fname, int ref_count, MonoImageOpenStatus* status); #endif /* PLATFORM_WIN32 */ Index: mono/mono/metadata/domain-internals.h =================================================================== --- mono/mono/metadata/domain-internals.h (revision 102399) +++ mono/mono/metadata/domain-internals.h (working copy) @@ -233,6 +233,9 @@ mono_cleanup (void) MONO_INTERNAL; void +mono_close_exe_image (void) MONO_INTERNAL; + +void mono_jit_info_table_add (MonoDomain *domain, MonoJitInfo *ji) MONO_INTERNAL; void Index: mono/mono/utils/mono-path.c =================================================================== --- mono/mono/utils/mono-path.c (revision 102399) +++ mono/mono/utils/mono-path.c (working copy) @@ -39,6 +39,9 @@ g_free (tmpdir); } +#ifdef PLATFORM_WIN32 + g_strdelimit (abspath, "/", '\\'); +#endif abspath = g_strreverse (abspath); backc = 0;
_______________________________________________ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list