Hi,
Previously I forgot to try _CorDllMain to load the runtime when it hasn't
been loaded yet. As a result I found that thread_started_event in
mono/mono/metadata/gc.c causes a deadlock in this situation because
_CorDllMain is callled while the OS loader lock is held by the current
thread and no new threads are started while OS loader lock is held. After
examining the purpose of thread_started_event I found that unlike the
comment states it is not required at all so I removed it completely. This
will make startup faster as well. I also checked that finalizer_thread is
called and reaches SetEvent (shutdown_event) at the end.
My test confirmed that Mono even supports mixed-mode assemblies with
exported symbols if they were native DLLs just like MS.NET does.
Kornél
----- Original Message -----
From: Kornél Pál
To: mono-devel
Sent: Friday, April 25, 2008 12:31 AM
Subject: Re: [Mono-dev] [PATCH] Add mixed-mode assembly support on Windows
(now build with cygwin as well)
Hi,
I also modified Makefile to export __stdcall functions without mangling
and
create-windef.pl to include MonoFixupCorEE. Other than these there are no
modifications.
Kornél
----- Original Message -----
From: Kornél Pál
To: mono-devel; Robert Jordan
Sent: Wednesday, April 23, 2008 2:40 PM
Subject: Re: [Mono-dev] [PATCH] Add mixed-mode assembly support on Windows
(now build with cygwin as well)
From: Robert Jordan
I think the following code is from another patch set (the cmd line
encoding issue you sent a patch for). Is it complete?
Index: mono/mono/mini/main.c
Yes, it is. I included it in this patch to be consistent with _CorExeMain
implementation. Also note that command line arguments are parsed as UTF-8
without MONO_EXTERNAL_ENCODINGS. MONO_EXTERNAL_ENCODINGS should not be
supported on Windows, Unicode API should be used instead. Patching main
will
make Mono support non-ASCII command line arguments on Windows. Also note
that because images are loaded using LoadLibrary file names are expected
to
be in UTF-8 that is supported by this main function patch. I still would
vote for removing MONO_EXTERNAL_ENCODINGS support on Windows but that is
out
of the scope of this patch.
If this is solved, I will try to fix the cygwin build.
I managed to fix the build. #include <config.h> had to be moved out of
#ifdef PLATFORM_WIN32 because PLATFORM_WIN32 is defined in config.h in
the
cygwin build.
Please review the patch. Please try it on Linux as well to make sure that
it
doesn't break Linux. And if you like it, please approve the patch.
Kornél
Index: mono/libgc/win32_threads.c
===================================================================
--- mono/libgc/win32_threads.c (revision 101236)
+++ mono/libgc/win32_threads.c (working copy)
@@ -782,7 +782,7 @@
* Pontus Rydin suggests wrapping the thread start routine instead.
*/
#if defined(GC_DLL) || defined(GC_INSIDE_DLL)
-BOOL WINAPI DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved)
+BOOL WINAPI GC_DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved)
{
switch (reason) {
case DLL_PROCESS_ATTACH:
Index: mono/libgc/include/gc.h
===================================================================
--- mono/libgc/include/gc.h (revision 101236)
+++ mono/libgc/include/gc.h (working copy)
@@ -922,6 +922,8 @@
#if defined(GC_WIN32_THREADS) && !defined(__CYGWIN32__) && !defined(__CYGWIN__)
# include <windows.h>
+ BOOL WINAPI GC_DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved);
+
/*
* All threads must be created using GC_CreateThread, so that they will be
* recorded in the thread table. For backwards compatibility, this is not
Index: mono/mono/metadata/loader.c
===================================================================
--- mono/mono/metadata/loader.c (revision 101236)
+++ mono/mono/metadata/loader.c (working copy)
@@ -1394,12 +1394,20 @@
if (cols [1] & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
if (result->klass == mono_defaults.string_class && !strcmp (result->name,
".ctor"))
result->string_ctor = 1;
- } else if ((cols [2] & METHOD_ATTRIBUTE_PINVOKE_IMPL) && (!(cols [1] &
METHOD_IMPL_ATTRIBUTE_NATIVE))) {
+ } else if (cols [2] & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)result;
- MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
+#ifdef PLATFORM_WIN32
+ /* IJW is P/Invoke with a predefined function pointer */
+ if (image->is_module_handle && (cols [1] &
METHOD_IMPL_ATTRIBUTE_NATIVE)) {
+ piinfo->addr = mono_image_rva_map (image, cols [0]);
+ g_assert (piinfo->addr);
+ }
+#endif
piinfo->implmap_idx = mono_metadata_implmap_from_method (image,
idx - 1);
- piinfo->piflags = mono_metadata_decode_row_col (im,
piinfo->implmap_idx - 1, MONO_IMPLMAP_FLAGS);
+ /* native methods can have no map */
+ if (piinfo->implmap_idx)
+ piinfo->piflags = mono_metadata_decode_row_col (&tables
[MONO_TABLE_IMPLMAP], piinfo->implmap_idx - 1, MONO_IMPLMAP_FLAGS);
}
/* FIXME: lazyness for generics too, but how? */
@@ -1900,7 +1908,7 @@
if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)
m->signature->pinvoke = 1;
- else if ((m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) && (!(m->iflags &
METHOD_IMPL_ATTRIBUTE_NATIVE))) {
+ else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
MonoCallConvention conv = 0;
MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)m;
m->signature->pinvoke = 1;
Index: mono/mono/metadata/domain.c
===================================================================
--- mono/mono/metadata/domain.c (revision 101236)
+++ mono/mono/metadata/domain.c (working copy)
@@ -34,9 +34,14 @@
#include <mono/metadata/threads-types.h>
#include <metadata/threads.h>
#include <metadata/profiler-private.h>
+#include <mono/metadata/coree.h>
/* #define DEBUG_DOMAIN_UNLOAD */
+#ifdef PLATFORM_WIN32
+extern HMODULE coree_handle;
+#endif
+
/* we need to use both the Tls* functions and __thread because
* some archs may generate faster jit code with one meachanism
* or the other (we used to do it because tls slots were GC-tracked,
@@ -1160,6 +1165,15 @@
if (domain)
g_assert_not_reached ();
+#if defined(PLATFORM_WIN32) && !defined(_WIN64)
+ /* Fixup exported functions of mscoree.dll to our implementations. */
+ coree_handle = LoadLibrary (L"mscoree.dll");
+ if (coree_handle && !SUCCEEDED (MonoFixupCorEE (coree_handle))) {
+ FreeLibrary (coree_handle);
+ coree_handle = NULL;
+ }
+#endif
+
mono_perfcounters_init ();
mono_counters_register ("Max native code in a domain",
MONO_COUNTER_INT|MONO_COUNTER_JIT, &max_domain_code_size);
@@ -1196,6 +1210,11 @@
* exe_image, and close it during shutdown.
*/
get_runtimes_from_exe (exe_filename, &exe_image, runtimes);
+#ifdef PLATFORM_WIN32
+ /* Executable images are only mapped by the OS loader we need
to do fixups for native code support. */
+ if (exe_image && exe_image->is_module_handle && (HMODULE)
exe_image->raw_data != GetModuleHandle (NULL))
+ MonoFixupExe ((HMODULE) exe_image->raw_data);
+#endif
} else if (runtime_version != NULL) {
runtimes [0] = get_runtime_by_version (runtime_version);
runtimes [1] = NULL;
Index: mono/mono/metadata/appdomain.c
===================================================================
--- mono/mono/metadata/appdomain.c (revision 101236)
+++ mono/mono/metadata/appdomain.c (working copy)
@@ -92,6 +92,21 @@
static void
mono_domain_unload (MonoDomain *domain);
+static MonoLoadFunc load_function = NULL;
+
+void
+mono_install_runtime_load (MonoLoadFunc func)
+{
+ load_function = func;
+}
+
+MonoDomain*
+mono_runtime_load (const char *filename, const char *runtime_version)
+{
+ g_assert (load_function);
+ return load_function (filename, runtime_version);
+}
+
/**
* mono_runtime_init:
* @domain: domain returned by mono_init ()
Index: mono/mono/metadata/appdomain.h
===================================================================
--- mono/mono/metadata/appdomain.h (revision 101236)
+++ mono/mono/metadata/appdomain.h (working copy)
@@ -25,9 +25,17 @@
typedef struct _MonoAppDomain MonoAppDomain;
typedef struct _MonoJitInfo MonoJitInfo;
+typedef MonoDomain* (*MonoLoadFunc) (const char *filename, const char
*runtime_version);
+
typedef void (*MonoDomainFunc) (MonoDomain *domain, gpointer user_data);
+void
+mono_install_runtime_load (MonoLoadFunc func);
+
MonoDomain*
+mono_runtime_load (const char *filename, const char *runtime_version);
+
+MonoDomain*
mono_init (const char *filename);
MonoDomain *
Index: mono/mono/metadata/assembly.c
===================================================================
--- mono/mono/metadata/assembly.c (revision 101236)
+++ mono/mono/metadata/assembly.c (working copy)
@@ -574,6 +574,11 @@
* Registers the root directory for the Mono runtime, for Linux and Solaris 10,
* this auto-detects the prefix where Mono was installed.
*/
+
+#ifdef PLATFORM_WIN32
+HMODULE mono_module_handle;
+#endif
+
void
mono_set_rootdir (void)
{
@@ -581,7 +586,7 @@
gunichar2 moddir [MAXPATHLEN];
gchar *bindir, *installdir, *root, *utf8name, *config;
- GetModuleFileNameW (NULL, moddir, MAXPATHLEN);
+ GetModuleFileNameW (mono_module_handle, moddir, MAXPATHLEN);
utf8name = g_utf16_to_utf8 (moddir, -1, NULL, NULL, NULL);
bindir = g_path_get_dirname (utf8name);
installdir = g_path_get_dirname (bindir);
@@ -1477,6 +1482,10 @@
loaded_assemblies = g_list_prepend (loaded_assemblies, ass);
if (mono_defaults.internals_visible_class)
mono_assembly_load_friends (ass);
+#ifdef PLATFORM_WIN32
+ if (image->is_module_handle)
+ mono_image_fixup_vtable (image);
+#endif
mono_assemblies_unlock ();
mono_assembly_invoke_load_hook (ass);
Index: mono/mono/metadata/image.c
===================================================================
--- mono/mono/metadata/image.c (revision 101236)
+++ mono/mono/metadata/image.c (working copy)
@@ -39,6 +39,10 @@
#define INVALID_ADDRESS 0xffffffff
+#ifdef PLATFORM_WIN32
+HMODULE coree_handle = NULL;
+#endif
+
/*
* Keeps track of the various assemblies loaded
*/
@@ -51,9 +55,11 @@
#define mono_images_unlock() LeaveCriticalSection (&images_mutex)
static CRITICAL_SECTION images_mutex;
+/* returns offset relative to image->raw_data */
guint32
-mono_cli_rva_image_map (MonoCLIImageInfo *iinfo, guint32 addr)
+mono_cli_rva_image_map (MonoImage *image, guint32 addr)
{
+ MonoCLIImageInfo *iinfo = image->image_info;
const int top = iinfo->cli_section_count;
MonoSectionTable *tables = iinfo->cli_section_tables;
int i;
@@ -61,6 +67,10 @@
for (i = 0; i < top; i++){
if ((addr >= tables->st_virtual_address) &&
(addr < tables->st_virtual_address +
tables->st_raw_data_size)){
+#ifdef PLATFORM_WIN32
+ if (image->is_module_handle)
+ return addr;
+#endif
return addr - tables->st_virtual_address +
tables->st_raw_data_ptr;
}
tables++;
@@ -94,6 +104,10 @@
if (!mono_image_ensure_section_idx (image, i))
return NULL;
}
+#ifdef PLATFORM_WIN32
+ if (image->is_module_handle)
+ return image->raw_data + addr;
+#endif
return (char*)iinfo->cli_sections [i] +
(addr - tables->st_virtual_address);
}
@@ -160,6 +174,11 @@
if (sect->st_raw_data_ptr + sect->st_raw_data_size >
image->raw_data_len)
return FALSE;
+#ifdef PLATFORM_WIN32
+ if (image->is_module_handle)
+ iinfo->cli_sections [section] = image->raw_data +
sect->st_virtual_address;
+ else
+#endif
/* FIXME: we ignore the writable flag since we don't patch the binary */
iinfo->cli_sections [section] = image->raw_data + sect->st_raw_data_ptr;
return TRUE;
@@ -230,7 +249,7 @@
{
guint32 offset;
- offset = mono_cli_rva_image_map (iinfo,
iinfo->cli_header.datadir.pe_cli_header.rva);
+ offset = mono_cli_rva_image_map (image,
iinfo->cli_header.datadir.pe_cli_header.rva);
if (offset == INVALID_ADDRESS)
return FALSE;
@@ -298,7 +317,7 @@
guint32 pad;
char *ptr;
- offset = mono_cli_rva_image_map (iinfo,
iinfo->cli_cli_header.ch_metadata.rva);
+ offset = mono_cli_rva_image_map (image,
iinfo->cli_cli_header.ch_metadata.rva);
if (offset == INVALID_ADDRESS)
return FALSE;
@@ -546,6 +565,10 @@
if (image->modules [idx - 1]) {
mono_image_addref (image->modules [idx - 1]);
image->modules [idx - 1]->assembly =
image->assembly;
+#ifdef PLATFORM_WIN32
+ if (image->modules [idx - 1]->is_module_handle)
+ mono_image_fixup_vtable (image->modules
[idx - 1]);
+#endif
/* g_print ("loaded module %s from %s (%p)\n",
module_ref, image->name, image->assembly); */
}
g_free (module_ref);
@@ -642,6 +665,9 @@
{
MonoDotNetHeader64 header64;
+#ifdef PLATFORM_WIN32
+ if (!image->is_module_handle)
+#endif
if (offset + sizeof (MonoDotNetHeader32) > image->raw_data_len)
return -1;
@@ -760,6 +786,11 @@
SWAPPDE (header->datadir.pe_cli_header);
SWAPPDE (header->datadir.pe_reserved);
+#ifdef PLATFORM_WIN32
+ if (image->is_module_handle)
+ image->raw_data_len = header->nt.pe_image_size;
+#endif
+
return offset;
}
@@ -782,6 +813,9 @@
if (status)
*status = MONO_IMAGE_IMAGE_INVALID;
+#ifdef PLATFORM_WIN32
+ if (!image->is_module_handle)
+#endif
if (offset + sizeof (msdos) > image->raw_data_len)
goto invalid_image;
memcpy (&msdos, image->raw_data + offset, sizeof (msdos));
@@ -995,6 +1029,16 @@
g_hash_table_insert (loaded_images, (char *)
image->assembly_name, image);
mono_images_unlock ();
+#ifdef PLATFORM_WIN32
+ if (image->is_module_handle && image->raw_data) {
+ guint16* fname_utf16;
+
+ fname_utf16 = g_utf8_to_utf16 (image->name, -1, NULL, NULL,
NULL);
+ LoadLibrary (fname_utf16);
+ g_free (fname_utf16);
+ }
+#endif
+
return image;
}
@@ -1072,6 +1116,38 @@
}
mono_images_unlock ();
+#ifdef PLATFORM_WIN32
+ /* Load modules using LoadLibrary */
+ if (!refonly && coree_handle) {
+ MonoCLIImageInfo *iinfo;
+ HMODULE module_handle;
+ guint16* fname_utf16;
+
+ fname_utf16 = g_utf8_to_utf16 (fname, -1, NULL, NULL, NULL);
+ module_handle = LoadLibrary (fname_utf16);
+ g_free (fname_utf16);
+
+ if (module_handle == NULL) {
+ if (status)
+ *status = MONO_IMAGE_ERROR_ERRNO;
+ return NULL;
+ }
+
+ image = g_new0 (MonoImage, 1);
+ image->raw_data = (char*) module_handle;
+ image->is_module_handle = TRUE;
+ iinfo = g_new0 (MonoCLIImageInfo, 1);
+ image->image_info = iinfo;
+ image->name = mono_path_resolve_symlinks (fname);
+ image->ref_count = 1;
+
+ image = do_mono_image_load (image, status, TRUE);
+ image = register_image (image);
+ FreeLibrary (module_handle);
+ return image;
+ }
+#endif
+
image = do_mono_image_open (fname, status, TRUE, refonly);
if (image == NULL)
return NULL;
@@ -1114,6 +1190,57 @@
return(do_mono_image_open (fname, status, FALSE, FALSE));
}
+void
+mono_image_fixup_vtable (MonoImage *image)
+{
+#ifdef PLATFORM_WIN32
+ MonoCLIImageInfo *iinfo;
+ MonoPEDirEntry *de;
+ MonoVTableFixup *vtfixup;
+ int count;
+ gpointer slot;
+ guint16 slot_type;
+ int slot_count;
+
+ g_assert (image->is_module_handle);
+
+ iinfo = image->image_info;
+ de = &iinfo->cli_cli_header.ch_vtable_fixups;
+ if (!de->rva || !de->size)
+ return;
+ vtfixup = (MonoVTableFixup*) mono_image_rva_map (image, de->rva);
+ if (!vtfixup)
+ return;
+
+ count = de->size / sizeof (MonoVTableFixup);
+ while (count--) {
+ if (!vtfixup->rva || !vtfixup->count)
+ continue;
+
+ slot = mono_image_rva_map (image, vtfixup->rva);
+ g_assert (slot);
+ slot_type = vtfixup->type;
+ slot_count = vtfixup->count;
+ if (slot_type & VTFIXUP_TYPE_32BIT)
+ while (slot_count--) {
+ *((guint32*) slot) =
mono_marshal_get_vtfixup_ftnptr (image, *((guint32*) slot), slot_type);
+ ((guint32*) slot)++;
+ }
+ else if (slot_type & VTFIXUP_TYPE_64BIT)
+ while (slot_count--) {
+ *((guint64*) slot) =
mono_marshal_get_vtfixup_ftnptr (image, *((guint64*) slot), slot_type);
+ ((guint64*) slot)++;
+ }
+ else
+ g_assert_not_reached();
+
+ vtfixup++;
+ }
+#else
+ g_assert_not_reached();
+#endif
+}
+
static void
free_hash_table (gpointer key, gpointer val, gpointer user_data)
{
@@ -1218,12 +1345,18 @@
mono_images_unlock ();
+#ifdef PLATFORM_WIN32
+ if (image->is_module_handle)
+ FreeLibrary ((HMODULE) image->raw_data);
+#endif
+
if (image->raw_buffer_used) {
if (image->raw_data != NULL)
mono_raw_buffer_free (image->raw_data);
}
if (image->raw_data_allocated) {
+ /* FIXME: do we need this? (image is disposed anyway) */
/* image->raw_metadata and cli_sections might lie inside
image->raw_data */
MonoCLIImageInfo *ii = image->image_info;
@@ -1607,6 +1740,10 @@
}
image->files [fileidx - 1] = res;
+#ifdef PLATFORM_WIN32
+ if (res->is_module_handle)
+ mono_image_fixup_vtable (res);
+#endif
}
mono_loader_unlock ();
g_free (name);
@@ -1658,25 +1795,12 @@
{
MonoCLIImageInfo *iinfo = image->image_info;
MonoPEDirEntry *de = &iinfo->cli_cli_header.ch_strong_name;
- const int top = iinfo->cli_section_count;
- MonoSectionTable *tables = iinfo->cli_section_tables;
- int i;
- guint32 addr = de->rva;
-
+
if (size)
*size = de->size;
if (!de->size || !de->rva)
return 0;
- for (i = 0; i < top; i++){
- if ((addr >= tables->st_virtual_address) &&
- (addr < tables->st_virtual_address +
tables->st_raw_data_size)){
- return tables->st_raw_data_ptr +
- (addr - tables->st_virtual_address);
- }
- tables++;
- }
-
- return 0;
+ return mono_cli_rva_image_map (image, de->rva);
}
/**
Index: mono/mono/metadata/cil-coff.h
===================================================================
--- mono/mono/metadata/cil-coff.h (revision 101236)
+++ mono/mono/metadata/cil-coff.h (working copy)
@@ -247,6 +247,17 @@
} MonoDotNetHeader64;
typedef struct {
+ guint32 rva;
+ guint16 count;
+#define VTFIXUP_TYPE_32BIT 0x01
+#define VTFIXUP_TYPE_64BIT 0x02
+#define VTFIXUP_TYPE_FROM_UNMANAGED 0x04
+#define VTFIXUP_TYPE_RETAIN_APPDOMAIN 0x08
+#define VTFIXUP_TYPE_CALL_MOST_DERIVED 0x10
+ guint16 type;
+} MonoVTableFixup;
+
+typedef struct {
char st_name [8];
guint32 st_virtual_size;
guint32 st_virtual_address;
@@ -311,6 +322,6 @@
MonoCLIHeader cli_cli_header;
} MonoCLIImageInfo;
-guint32 mono_cli_rva_image_map (MonoCLIImageInfo *iinfo, guint32 rva);
+guint32 mono_cli_rva_image_map (MonoImage *image, guint32 rva);
#endif /* __MONO_CIL_COFF_H__ */
Index: mono/mono/metadata/image.h
===================================================================
--- mono/mono/metadata/image.h (revision 101236)
+++ mono/mono/metadata/image.h (working copy)
@@ -45,6 +45,7 @@
MonoImageOpenStatus *status);
MonoImage *mono_image_open_from_data_full (char *data, guint32 data_len,
gboolean need_copy,
MonoImageOpenStatus *status, gboolean
refonly);
+void mono_image_fixup_vtable (MonoImage *image);
MonoImage *mono_image_loaded (const char *name);
MonoImage *mono_image_loaded_full (const char *name, gboolean refonly);
MonoImage *mono_image_loaded_by_guid (const char *guid);
Index: mono/mono/metadata/coree.c
===================================================================
--- mono/mono/metadata/coree.c (revision 0)
+++ mono/mono/metadata/coree.c (revision 0)
@@ -0,0 +1,390 @@
+/*
+ * coree.c: mscoree.dll functions
+ *
+ * Author:
+ * Kornel Pal <http://www.kornelpal.hu/>
+ *
+ * Copyright (C) 2008 Kornel Pal
+ */
+
+#include <config.h>
+
+#ifdef PLATFORM_WIN32
+
+#include <string.h>
+#include <glib.h>
+#include <mono/io-layer/io-layer.h>
+#include "image.h"
+#include "assembly.h"
+#include "appdomain.h"
+#include "object.h"
+#include "loader.h"
+#include "threads.h"
+#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;
+
+/* called by LdrLoadDll of ntdll.dll after _CorValidateImage */
+BOOL STDMETHODCALLTYPE _CorDllMain(HINSTANCE hInst, DWORD dwReason, LPVOID
lpReserved)
+{
+ MonoDomain* domain;
+ gunichar2 filename [MAXPATHLEN];
+ gchar* fname_utf8;
+ gchar* error;
+
+ switch (dwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls (hInst);
+ if (mono_get_root_domain ())
+ return TRUE;
+
+ GetModuleFileName (hInst, filename, MAXPATHLEN);
+ fname_utf8 = g_utf16_to_utf8 (filename, -1, NULL, NULL, NULL);
+ domain = mono_runtime_load (fname_utf8, NULL);
+ error = (gchar*) mono_check_corlib_version ();
+ if (error) {
+ g_free (error);
+ g_free (fname_utf8);
+ mono_runtime_quit ();
+ return FALSE;
+ }
+
+ mono_assembly_open (fname_utf8, NULL);
+ g_free (fname_utf8);
+ break;
+ }
+
+ return TRUE;
+}
+
+/* called by ntdll.dll reagardless of entry point after _CorValidateImage */
+__int32 STDMETHODCALLTYPE _CorExeMain()
+{
+ MonoDomain* domain;
+ MonoAssembly* assembly;
+ MonoImage* image;
+ MonoMethod* method;
+ guint32 entry;
+ int argc;
+ gunichar2** argvw;
+ gchar** argv;
+ gchar* fname_utf8;
+ gchar* error;
+ int i;
+
+ argvw = CommandLineToArgvW (GetCommandLine (), &argc);
+ g_assert (argc);
+ fname_utf8 = g_utf16_to_utf8 (argvw [0], -1, NULL, NULL, NULL);
+
+ domain = mono_runtime_load (fname_utf8, NULL);
+
+ error = (gchar*) mono_check_corlib_version ();
+ if (error) {
+ g_free (error);
+ MessageBox (NULL, L"Corlib not in sync with this runtime.",
NULL, MB_ICONERROR);
+ ExitProcess (1);
+ }
+
+ assembly = mono_assembly_open (fname_utf8, NULL);
+ g_assert (assembly);
+ image = mono_assembly_get_image (assembly);
+
+ entry = mono_image_get_entry_point (image);
+ if (!entry) {
+ MessageBox (NULL, L"Assembly doesn't have an entry point.",
NULL, MB_ICONERROR);
+ ExitProcess (1);
+ }
+
+ method = mono_get_method (image, entry, NULL);
+ if (method == NULL) {
+ MessageBox (NULL, L"The entry point method could not be
loaded.", NULL, MB_ICONERROR);
+ ExitProcess (1);
+ }
+
+ argv = g_new0 (gchar*, argc);
+ argv [0] = fname_utf8;
+ for (i = 1; i < argc; ++i)
+ argv [i] = g_utf16_to_utf8 (argvw [i], -1, NULL, NULL, NULL);
+ LocalFree (argvw);
+
+ mono_runtime_run_main (method, argc, argv, NULL);
+
+ /* return does not terminate the process */
+ ExitProcess (mono_environment_exitcode_get ());
+}
+
+/* called by ntdll.dll before _CorDllMain and _CorExeMain */
+STDAPI _CorValidateImage(PVOID *ImageBase, LPCWSTR FileName)
+{
+ IMAGE_DOS_HEADER* DosHeader;
+ IMAGE_NT_HEADERS* NtHeaders;
+ DWORD* Address;
+ DWORD dwOldProtect;
+
+ DosHeader = (IMAGE_DOS_HEADER*)*ImageBase;
+ if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
+ return STATUS_INVALID_IMAGE_FORMAT;
+
+ NtHeaders = (IMAGE_NT_HEADERS*)((DWORD_PTR)DosHeader +
DosHeader->e_lfanew);
+ if (NtHeaders->Signature != IMAGE_NT_SIGNATURE)
+ return STATUS_INVALID_IMAGE_FORMAT;
+
+ if (NtHeaders->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
+ return STATUS_INVALID_IMAGE_FORMAT;
+
+ Address = &NtHeaders->OptionalHeader.AddressOfEntryPoint;
+ if (!VirtualProtect(Address, sizeof(DWORD), PAGE_READWRITE,
&dwOldProtect))
+ 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))
+ return E_UNEXPECTED;
+
+ return STATUS_SUCCESS;
+}
+
+/* called by ntdll.dll */
+STDAPI_(VOID) _CorImageUnloading(PVOID ImageBase)
+{
+ /* nothing to do */
+}
+
+/* called by msvcrt.dll when shutting down */
+void STDMETHODCALLTYPE CorExitProcess(int exitCode)
+{
+ if (!mono_runtime_is_shutting_down ()) {
+ mono_runtime_set_shutting_down ();
+ mono_thread_suspend_all_other_threads ();
+ mono_runtime_quit ();
+ }
+ ExitProcess (exitCode);
+}
+
+STDAPI MonoFixupCorEE(HMODULE hModule)
+{
+ /* has to be binary ordered */
+ const EXPORT_FIXUP ExportFixups[] = {
+ {"CorExitProcess", (DWORD_PTR)&CorExitProcess},
+ {"_CorDllMain", (DWORD_PTR)&_CorDllMain},
+ {"_CorExeMain", (DWORD_PTR)&_CorExeMain},
+ {"_CorImageUnloading", (DWORD_PTR)&_CorImageUnloading},
+ {"_CorValidateImage", (DWORD_PTR)&_CorValidateImage},
+ {NULL, 0}
+ };
+
+ IMAGE_DOS_HEADER* DosHeader;
+ IMAGE_NT_HEADERS* NtHeaders;
+ IMAGE_DATA_DIRECTORY* ExportDataDir;
+ IMAGE_EXPORT_DIRECTORY* ExportDir;
+ DWORD* Functions;
+ DWORD* Names;
+ WORD* NameOrdinals;
+ EXPORT_FIXUP* ExportFixup;
+ DWORD* Address;
+ DWORD dwOldProtect;
+ DWORD_PTR ProcAddress;
+ DWORD i;
+
+ DosHeader = (IMAGE_DOS_HEADER*)hModule;
+ if (DosHeader == NULL || DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
+ return E_INVALIDARG;
+
+ NtHeaders = (IMAGE_NT_HEADERS*)((DWORD_PTR)DosHeader +
DosHeader->e_lfanew);
+ if (NtHeaders->Signature != IMAGE_NT_SIGNATURE)
+ return E_INVALIDARG;
+
+ if (NtHeaders->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
+ return E_INVALIDARG;
+
+ if (NtHeaders->OptionalHeader.NumberOfRvaAndSizes <=
IMAGE_DIRECTORY_ENTRY_EXPORT)
+ return E_FAIL;
+ ExportDataDir =
&NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
+ if (!ExportDataDir->VirtualAddress || !ExportDataDir->Size)
+ return E_FAIL;
+
+ ExportDir = (IMAGE_EXPORT_DIRECTORY*)((DWORD_PTR)DosHeader +
ExportDataDir->VirtualAddress);
+ Functions = (DWORD*)((DWORD_PTR)DosHeader +
ExportDir->AddressOfFunctions);
+ Names = (DWORD*)((DWORD_PTR)DosHeader + ExportDir->AddressOfNames);
+ NameOrdinals = (WORD*)((DWORD_PTR)DosHeader +
ExportDir->AddressOfNameOrdinals);
+ ExportFixup = (EXPORT_FIXUP*)&ExportFixups;
+
+ for (i = 0; i < ExportDir->NumberOfNames; i++)
+ {
+ int cmp = strcmp((LPCSTR)((DWORD_PTR)DosHeader + Names[i]),
ExportFixup->Name);
+ if (cmp > 0)
+ return E_FAIL;
+ if (cmp == 0)
+ {
+ Address = &Functions[NameOrdinals[i]];
+ ProcAddress = (DWORD_PTR)DosHeader + *Address;
+ if (ProcAddress != ExportFixup->ProcAddress) {
+ if (!VirtualProtect(Address, sizeof(DWORD),
PAGE_READWRITE, &dwOldProtect))
+ return E_UNEXPECTED;
+ *Address = (DWORD)(ExportFixup->ProcAddress -
(DWORD_PTR)DosHeader);
+ if (!VirtualProtect(Address, sizeof(DWORD),
dwOldProtect, &dwOldProtect))
+ return E_UNEXPECTED;
+ }
+ ExportFixup++;
+ if (ExportFixup->Name == NULL)
+ return NOERROR;
+ }
+ }
+ return E_FAIL;
+}
+
+STDAPI MonoFixupExe(HMODULE hModule)
+{
+ IMAGE_DOS_HEADER* DosHeader;
+ IMAGE_NT_HEADERS* NtHeaders;
+ DWORD_PTR* Address;
+ DWORD dwOldProtect;
+ DWORD_PTR BaseDiff;
+
+ DosHeader = (IMAGE_DOS_HEADER*)hModule;
+ if (DosHeader == NULL || DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
+ return E_INVALIDARG;
+
+ NtHeaders = (IMAGE_NT_HEADERS*)((DWORD_PTR)DosHeader +
DosHeader->e_lfanew);
+ if (NtHeaders->Signature != IMAGE_NT_SIGNATURE)
+ return E_INVALIDARG;
+
+ if (NtHeaders->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
+ return E_INVALIDARG;
+
+ if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL)
+ return NOERROR;
+
+ BaseDiff = (DWORD_PTR)DosHeader - NtHeaders->OptionalHeader.ImageBase;
+ if (BaseDiff != 0)
+ {
+ if (NtHeaders->FileHeader.Characteristics &
IMAGE_FILE_RELOCS_STRIPPED)
+ return E_FAIL;
+
+ Address = &NtHeaders->OptionalHeader.ImageBase;
+ if (!VirtualProtect(Address, sizeof(DWORD_PTR), PAGE_READWRITE,
&dwOldProtect))
+ return E_UNEXPECTED;
+ *Address = (DWORD_PTR)DosHeader;
+ if (!VirtualProtect(Address, sizeof(DWORD_PTR), dwOldProtect,
&dwOldProtect))
+ return E_UNEXPECTED;
+
+ if (NtHeaders->OptionalHeader.NumberOfRvaAndSizes >
IMAGE_DIRECTORY_ENTRY_BASERELOC)
+ {
+ IMAGE_DATA_DIRECTORY* BaseRelocDir;
+ IMAGE_BASE_RELOCATION* BaseReloc;
+ USHORT* RelocBlock;
+ ULONG BaseRelocSize;
+ ULONG RelocBlockSize;
+ USHORT RelocOffset;
+ DWORD_PTR UNALIGNED *RelocFixup;
+
+ BaseRelocDir =
&NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
+ if (BaseRelocDir->VirtualAddress && BaseRelocDir->Size)
+ {
+ BaseReloc =
(IMAGE_BASE_RELOCATION*)((DWORD_PTR)DosHeader + BaseRelocDir->VirtualAddress);
+ BaseRelocSize = BaseRelocDir->Size;
+
+ while (BaseRelocSize)
+ {
+ RelocBlockSize = BaseReloc->SizeOfBlock;
+
+ if (!RelocBlockSize || BaseRelocSize <
RelocBlockSize)
+ return E_FAIL;
+
+ BaseRelocSize -= RelocBlockSize;
+ RelocBlock =
(USHORT*)((DWORD_PTR)BaseReloc + IMAGE_SIZEOF_BASE_RELOCATION);
+ RelocBlockSize -=
IMAGE_SIZEOF_BASE_RELOCATION;
+ RelocBlockSize /= sizeof(USHORT);
+
+ while (RelocBlockSize-- != 0)
+ {
+ RelocOffset = *RelocBlock &
(USHORT)0x0fff;
+ RelocFixup =
(DWORD_PTR*)((DWORD_PTR)DosHeader + BaseReloc->VirtualAddress + RelocOffset);
+
+ switch (*RelocBlock >> 12)
+ {
+ case
IMAGE_REL_BASED_ABSOLUTE:
+ break;
+
+#ifdef _WIN64
+ case
IMAGE_REL_BASED_DIR64:
+#else
+ case
IMAGE_REL_BASED_HIGHLOW:
+#endif
+ if
(!VirtualProtect(RelocFixup, sizeof(DWORD_PTR), PAGE_EXECUTE_READWRITE,
&dwOldProtect))
+ return
E_UNEXPECTED;
+ *RelocFixup +=
BaseDiff;
+ if
(!VirtualProtect(RelocFixup, sizeof(DWORD_PTR), dwOldProtect, &dwOldProtect))
+ return
E_UNEXPECTED;
+ break;
+
+ default:
+ return E_FAIL;
+ }
+
+ RelocBlock++;
+ }
+ BaseReloc =
(IMAGE_BASE_RELOCATION*)RelocBlock;
+ }
+ }
+ }
+ }
+
+ if (NtHeaders->OptionalHeader.NumberOfRvaAndSizes >
IMAGE_DIRECTORY_ENTRY_IMPORT)
+ {
+ IMAGE_DATA_DIRECTORY* ImportDir;
+ IMAGE_IMPORT_DESCRIPTOR* ImportDesc;
+ HMODULE hImportModule;
+ IMAGE_THUNK_DATA* ImportThunkData;
+ DWORD_PTR ProcAddress;
+
+ ImportDir =
&NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
+ if (ImportDir->VirtualAddress != 0)
+ {
+ ImportDesc =
(IMAGE_IMPORT_DESCRIPTOR*)((DWORD_PTR)DosHeader + ImportDir->VirtualAddress);
+ while (ImportDesc->Name &&
ImportDesc->OriginalFirstThunk)
+ {
+ hImportModule =
LoadLibraryA((PCSTR)((DWORD_PTR)DosHeader + ImportDesc->Name));
+ if (hImportModule == NULL)
+ return E_FAIL;
+
+ ImportThunkData =
(IMAGE_THUNK_DATA*)((DWORD_PTR)DosHeader + ImportDesc->OriginalFirstThunk);
+ while (ImportThunkData->u1.Ordinal != 0)
+ {
+ if
(IMAGE_SNAP_BY_ORDINAL(ImportThunkData->u1.Ordinal))
+ ProcAddress =
(DWORD_PTR)GetProcAddress(hImportModule,
(LPCSTR)IMAGE_ORDINAL(ImportThunkData->u1.Ordinal));
+ else
+ {
+ IMAGE_IMPORT_BY_NAME* ImportByName
= (IMAGE_IMPORT_BY_NAME*)((DWORD_PTR)DosHeader +
ImportThunkData->u1.AddressOfData);
+ ProcAddress =
(DWORD_PTR)GetProcAddress(hImportModule, ImportByName->Name);
+ }
+ 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))
+ return E_UNEXPECTED;
+ *Address = ProcAddress;
+ if (!VirtualProtect(Address,
sizeof(DWORD_PTR), dwOldProtect, &dwOldProtect))
+ return E_UNEXPECTED;
+ ImportThunkData++;
+ }
+
+ ImportDesc++;
+ }
+ }
+ }
+
+ return NOERROR;
+}
+
+#endif /* PLATFORM_WIN32 */
Property changes on: mono\mono\metadata\coree.c
___________________________________________________________________
Name: svn:eol-style
+ native
Index: mono/mono/metadata/coree.h
===================================================================
--- mono/mono/metadata/coree.h (revision 0)
+++ mono/mono/metadata/coree.h (revision 0)
@@ -0,0 +1,20 @@
+/*
+ * coree.h: mscoree.dll functions
+ *
+ * Author:
+ * Kornel Pal <http://www.kornelpal.hu/>
+ *
+ * Copyright (C) 2008 Kornel Pal
+ */
+
+#ifndef __MONO_COREE_H__
+#define __MONO_COREE_H__
+
+#ifdef PLATFORM_WIN32
+
+STDAPI MonoFixupCorEE(HMODULE hModule);
+STDAPI MonoFixupExe(HMODULE hModule);
+
+#endif /* PLATFORM_WIN32 */
+
+#endif /* __MONO_COREE_H__ */
Property changes on: mono\mono\metadata\coree.h
___________________________________________________________________
Name: svn:eol-style
+ native
Index: mono/mono/metadata/metadata-internals.h
===================================================================
--- mono/mono/metadata/metadata-internals.h (revision 101236)
+++ mono/mono/metadata/metadata-internals.h (working copy)
@@ -77,6 +77,11 @@
guint8 raw_buffer_used : 1;
guint8 raw_data_allocated : 1;
+#ifdef PLATFORM_WIN32
+ /* Module was loaded using LoadLibrary */
+ guint8 is_module_handle : 1;
+#endif
+
/* Whenever this is a dynamically emitted module */
guint8 dynamic : 1;
Index: mono/mono/metadata/marshal.c
===================================================================
--- mono/mono/metadata/marshal.c (revision 101236)
+++ mono/mono/metadata/marshal.c (working copy)
@@ -11,6 +11,7 @@
#include "config.h"
#include "object.h"
#include "loader.h"
+#include "cil-coff.h"
#include "metadata/marshal.h"
#include "metadata/method-builder.h"
#include "metadata/tabledefs.h"
@@ -8471,7 +8472,10 @@
if (!piinfo->addr) {
if (pinvoke)
- mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
+ if (method->iflags & METHOD_IMPL_ATTRIBUTE_NATIVE)
+ exc_arg = "Method contains unsupported native
code";
+ else
+ mono_lookup_pinvoke_call (method, &exc_class,
&exc_arg);
else
piinfo->addr = mono_lookup_internal_call (method);
}
@@ -8681,8 +8685,6 @@
/* FIXME: need a solution for the moving GC here */
mono_mb_emit_ptr (mb, this);
} else {
- /* fixme: */
- g_assert_not_reached ();
}
}
@@ -8789,6 +8791,8 @@
/*
* generates IL code to call managed methods from unmanaged code
+ * marshaling is based on delegate_klass when specified
+ * this pointer is compiled to the wrapper when specified
*/
MonoMethod *
mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass
*delegate_klass, MonoObject *this)
@@ -8815,7 +8819,10 @@
if (!this && (res = mono_marshal_find_in_cache (cache, method)))
return res;
- invoke = mono_class_get_method_from_name (delegate_klass, "Invoke",
mono_method_signature (method)->param_count);
+ if (delegate_klass)
+ invoke = mono_class_get_method_from_name (delegate_klass,
"Invoke", mono_method_signature (method)->param_count);
+ else
+ invoke = method;
invoke_sig = mono_method_signature (invoke);
mspecs = g_new0 (MonoMarshalSpec*, mono_method_signature
(invoke)->param_count + 1);
@@ -8854,7 +8861,7 @@
/* Why is this a modopt ? */
if (invoke_sig->ret && invoke_sig->ret->num_mods) {
for (i = 0; i < invoke_sig->ret->num_mods; ++i) {
- MonoClass *cmod_class = mono_class_get
(delegate_klass->image, invoke_sig->ret->modifiers [i].token);
+ MonoClass *cmod_class = mono_class_get (delegate_klass ?
delegate_klass->image : method->klass->image, invoke_sig->ret->modifiers
[i].token);
g_assert (cmod_class);
if ((cmod_class->image == mono_defaults.corlib) && !strcmp
(cmod_class->name_space, "System.Runtime.CompilerServices")) {
if (!strcmp (cmod_class->name, "CallConvCdecl"))
@@ -8874,7 +8881,7 @@
UnmanagedFunctionPointerAttribute = mono_class_from_name (mono_defaults.corlib,
"System.Runtime.InteropServices", "UnmanagedFunctionPointerAttribute");
/* The attribute is only available in Net 2.0 */
- if (UnmanagedFunctionPointerAttribute) {
+ if (delegate_klass && UnmanagedFunctionPointerAttribute) {
MonoReflectionUnmanagedFunctionPointerAttribute *attr;
MonoCustomAttrInfo *cinfo;
@@ -8918,6 +8925,50 @@
return res;
}
+gpointer
+mono_marshal_get_vtfixup_ftnptr (MonoImage *image, guint32 token, guint16 type)
+{
+ MonoMethod *method;
+ MonoMethodSignature *sig;
+ MonoMethodBuilder *mb;
+ int i, param_count;
+ gboolean callvirt;
+
+ g_assert (token);
+
+ method = mono_get_method (image, token, NULL);
+ g_assert (method);
+
+ if (type & VTFIXUP_TYPE_FROM_UNMANAGED) {
+ method = mono_marshal_get_managed_wrapper (method, NULL, NULL);
+ callvirt = FALSE;
+ } else
+ callvirt = (type & VTFIXUP_TYPE_CALL_MOST_DERIVED) &&
(method->flags & METHOD_ATTRIBUTE_VIRTUAL);
+
+ sig = mono_method_signature (method);
+ mb = mono_mb_new (method->klass, method->name,
MONO_WRAPPER_MANAGED_TO_MANAGED);
+
+ /* FIXME: handle VTFIXUP_TYPE_RETAIN_APPDOMAIN */
+
+ param_count = sig->param_count;
+ if (sig->hasthis)
+ param_count++;
+ for (i = 0; i < param_count; i++)
+ mono_mb_emit_ldarg (mb, i);
+
+ if (callvirt)
+ mono_mb_emit_op (mb, CEE_CALLVIRT, method);
+ else
+ mono_mb_emit_op (mb, CEE_CALL, method);
+ mono_mb_emit_byte (mb, CEE_RET);
+
+ mb->dynamic = 1;
+ method = mono_mb_create_method (mb, sig, param_count);
+ mono_mb_free (mb);
+
+ return mono_compile_method (method);
+}
+
static MonoReflectionType *
type_from_handle (MonoType *handle)
{
Index: mono/mono/metadata/marshal.h
===================================================================
--- mono/mono/metadata/marshal.h (revision 101236)
+++ mono/mono/metadata/marshal.h (working copy)
@@ -140,6 +140,9 @@
MonoMethod *
mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass
*delegate_klass, MonoObject *this) MONO_INTERNAL;
+gpointer
+mono_marshal_get_vtfixup_ftnptr (MonoImage *image, guint32 token, guint16
type) MONO_INTERNAL;
+
MonoMethod *
mono_marshal_get_icall_wrapper (MonoMethodSignature *sig, const char *name,
gconstpointer func, gboolean check_exceptions) MONO_INTERNAL;
Index: mono/mono/metadata/Makefile.am
===================================================================
--- mono/mono/metadata/Makefile.am (revision 101236)
+++ mono/mono/metadata/Makefile.am (working copy)
@@ -108,6 +108,8 @@
console-io.c \
console-io.h \
assembly.c \
+ coree.c \
+ coree.h \
domain.c \
domain-internals.h \
opcodes.c \
Index: mono/mono/metadata/gc.c
===================================================================
--- mono/mono/metadata/gc.c (revision 101236)
+++ mono/mono/metadata/gc.c (working copy)
@@ -54,7 +54,6 @@
#ifndef HAVE_NULL_GC
static HANDLE pending_done_event;
static HANDLE shutdown_event;
-static HANDLE thread_started_event;
#endif
static void
@@ -884,8 +883,6 @@
{
gc_thread = mono_thread_current ();
- SetEvent (thread_started_event);
-
while (!finished) {
/* Wait to be notified that there's at least one
* finaliser to run
@@ -939,17 +936,11 @@
finalizer_event = CreateEvent (NULL, FALSE, FALSE, NULL);
pending_done_event = CreateEvent (NULL, TRUE, FALSE, NULL);
shutdown_event = CreateEvent (NULL, TRUE, FALSE, NULL);
- thread_started_event = CreateEvent (NULL, TRUE, FALSE, NULL);
- if (finalizer_event == NULL || pending_done_event == NULL ||
shutdown_event == NULL || thread_started_event == NULL) {
+ if (finalizer_event == NULL || pending_done_event == NULL ||
shutdown_event == NULL) {
g_assert_not_reached ();
}
mono_thread_create (mono_domain_get (), finalizer_thread, NULL);
- /*
- * Wait until the finalizer thread sets gc_thread since its value is
needed
- * by mono_thread_attach ()
- */
- WaitForSingleObjectEx (thread_started_event, INFINITE, FALSE);
}
void
Index: mono/mono/mini/mini.c
===================================================================
--- mono/mono/mini/mini.c (revision 101236)
+++ mono/mono/mini/mini.c (working copy)
@@ -12321,15 +12321,17 @@
MonoMethod *nm;
MonoMethodPInvoke* piinfo = (MonoMethodPInvoke *) method;
- if (method->iflags & METHOD_IMPL_ATTRIBUTE_NATIVE &&
!MONO_CLASS_IS_IMPORT(method->klass))
- g_error ("Method '%s' in assembly '%s' contains native code and mono
can't run it. The assembly was probably created by Managed C++.\n", mono_method_full_name
(method, TRUE), method->klass->image->name);
-
if (!piinfo->addr) {
if (method->iflags &
METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)
piinfo->addr = mono_lookup_internal_call
(method);
+ else if (method->iflags & METHOD_IMPL_ATTRIBUTE_NATIVE)
+#ifdef PLATFORM_WIN32
+ g_warning ("Method '%s' in assembly '%s' contains native code
that cannot be executed by Mono in modules loaded from byte arrays. The assembly was probably
created using C++/CLI.\n", mono_method_full_name (method, TRUE),
method->klass->image->name);
+#else
+ g_warning ("Method '%s' in assembly '%s' contains native code
that cannot be executed by Mono on this platform. The assembly was probably created using
C++/CLI.\n", mono_method_full_name (method, TRUE), method->klass->image->name);
+#endif
else
- if (method->flags &
METHOD_ATTRIBUTE_PINVOKE_IMPL)
- mono_lookup_pinvoke_call (method, NULL,
NULL);
+ mono_lookup_pinvoke_call (method, NULL, NULL);
}
nm = mono_marshal_get_native_wrapper (method,
check_for_pending_exc);
return mono_get_addr_from_ftnptr (mono_compile_method
(nm));
Index: mono/mono/mini/main.c
===================================================================
--- mono/mono/mini/main.c (revision 101236)
+++ mono/mono/mini/main.c (working copy)
@@ -1,8 +1,31 @@
#include "mini.h"
+#ifdef PLATFORM_WIN32
+
int
+main ()
+{
+ int argc;
+ gunichar2** argvw;
+ gchar** argv;
+ int i;
+
+ argvw = CommandLineToArgvW (GetCommandLine (), &argc);
+ argv = g_new0 (gchar*, argc);
+ for (i = 0; i < argc; i++)
+ argv [i] = g_utf16_to_utf8 (argvw [i], -1, NULL, NULL, NULL);
+
+ LocalFree (argvw);
+
+ return mono_main (argc, argv);
+}
+
+#else
+
+int
main (int argc, char* argv[])
{
return mono_main (argc, argv);
}
+#endif
Index: mono/mono/mini/Makefile.am
===================================================================
--- mono/mono/mini/Makefile.am (revision 101236)
+++ mono/mono/mini/Makefile.am (working copy)
@@ -58,7 +58,7 @@
endif
if PLATFORM_WIN32
-libmono_la_LDFLAGS=-no-undefined -avoid-version $(monoldflags)
+libmono_la_LDFLAGS=-no-undefined -avoid-version -Wl,--kill-at $(monoldflags)
else
libmono_la_LDFLAGS=$(monoldflags)
endif
Index: mono/mono/mini/driver.c
===================================================================
--- mono/mono/mini/driver.c (revision 101236)
+++ mono/mono/mini/driver.c (working copy)
@@ -45,6 +45,7 @@
#include <mono/metadata/security-core-clr.h>
#include <mono/metadata/gc-internal.h>
#include "mono/utils/mono-counters.h"
+#include <mono/os/gc_wrapper.h>
#include "mini.h"
#include "jit.h"
@@ -1006,6 +1007,25 @@
#define error_if_aot_unsupported()
#endif
+#ifdef PLATFORM_WIN32
+extern HMODULE mono_module_handle;
+
+BOOL APIENTRY DllMain (HMODULE module_handle, DWORD reason, LPVOID reserved)
+{
+ if (!GC_DllMain (module_handle, reason, reserved))
+ return FALSE;
+
+ switch (reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ mono_module_handle = module_handle;
+ mono_install_runtime_load (mini_init);
+ break;
+ }
+ return TRUE;
+}
+#endif
+
int
mono_main (int argc, char* argv[])
{
Index: mono/msvc/create-windef.pl
===================================================================
--- mono/msvc/create-windef.pl (revision 101236)
+++ mono/msvc/create-windef.pl (working copy)
@@ -19,6 +19,7 @@
push @symbols, $1;
}
close (SYMS);
+push @symbols, "MonoFixupCorEE";
@symbols = sort @symbols;
open (OUT, ">$outfile") || die "Cannot open '$outfile': $!\n";
Index: mono/msvc/libmono.vcproj
===================================================================
--- mono/msvc/libmono.vcproj (revision 101236)
+++ mono/msvc/libmono.vcproj (working copy)
@@ -2287,6 +2287,14 @@
>
</File>
<File
+ RelativePath="..\mono\metadata\coree.c"
+ >
+ </File>
+ <File
+ RelativePath="..\mono\metadata\coree.h"
+ >
+ </File>
+ <File
RelativePath="..\mono\metadata\culture-info-tables.h"
>
</File>
Index: mono/msvc/mono.def
===================================================================
--- mono/msvc/mono.def (revision 101236)
+++ mono/msvc/mono.def (working copy)
@@ -1,6 +1,7 @@
; file generated by create-windef.pl
LIBRARY mono.dll
EXPORTS
+MonoFixupCorEE
mono_add_internal_call
mono_alloc_special_static_data
mono_array_class_get
Property changes on: mono\msvc\mono.def
___________________________________________________________________
Name: svn:eol-style
+ native
_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list