[Mono-dev] mixed-mode assemblies in wine

Kornél Pál kornelpal at gmail.com
Mon Feb 28 18:32:41 EST 2011

I forgot about the mixed mode Visaul C++ application issue:

Mixed-mode code is supported, however the C++ runtime (by MS) assumes 
some runtime internals (COM interop (may work by now), fixed RVA fields 
are shared between app domain, and maybe others) that are not supported 
by the runtime and are not specific to mixed-mode assembly support. 
Those could be some of them a controversial features as are not portable 
across little/big endian like the fixed RVA thing.


Kornél Pál wrote:
> Hi,
> I have some unsubmitted modifications to mixed-mode support I made about
> a year ago. I should revise them and those may improve mixed-mode support.
> I haven't had time to sort out the verifier conflict but that should be
> possible and hopefully easy to resolve.
> My preferred way would be to call exports that Windows calls:
> - _CorValidateImage on image load
> - _CorImageUnloading on image unload
> - _CorExeMain instead of exe entry point
> - _CorDllMain instaad of dll entry
> - the C runtime (not the OS) should also call CorExitProcess on normal
> termination (exit)
> All of the above functions are (vaguely, from the wrong perspective)
> documented on MSDN.
> This would render MonoFixupCorEE unnecessary.
> I also planned to get rid of MonoFixupExe and drop support for
> mixed-mode assemblies by using mono.exe and introduce a loader that
> would call CreateProcess on the managed (may be mixed-mode) .exe, inject
> a loader .dll (or a custom mscoree.dll) by modifying IAT, remove IL-only
> flag so that the OS loader will not load MS.NET mscorlib.dll, and do
> inicialization in that loader .dll called by OS loader. This would not
> affect functionality of mono.dll just would not fixup mscoree.dll by
> default that also would play more nicely with standalone verifier,
> dumper, etc. tools and CoreCLR.
> I also have the impression that implementing .NET Framework
> functionality in Wine may not be the right architecture. Ideally those
> belong to Mono. Since I know that Mono does not accept GPL to runtime
> (requires MIT X11 license or special permissions to Novell; althoug is
> licensed under GPL) and Wine prefers GPL this may not be suitable.
> Wine loader should call mscoree.dll just like Windows loader does
> (system32\mscoree.dll is hardcoded, cannot use your own).
> If you prefer to keep mscoree.dll code in Wine, then I belive that Wine
> mscoree.dll should load mono.dll (as it already does) and forward the
> above five basic exports to mono.dll and implement other exports on its
> own by calling native Mono API.
> Kornél
> Vincent Povirk wrote:
>> Two very interesting things happened in Mono recently:
>> 1. The "implement type compare for 1b" assert failure that would
>> usually occur when loading a mixed-mode assembly in Mono was fixed. So
>> whoever did that, thank you.
>> 2. Rodrigo Kumpera added an ENABLE_COREE define, default off, because
>> that code was breaking the verifier. He tells me I can test this by
>> running a hello world program using --security=verifiable.
>> These two changes had the combined effect of getting me to think about
>> mixed-mode assemblies and forcing me to notice all of Mono's coree
>> code and how it works.
>> Apparently the native code in a mixed-mode assembly works like a
>> p/invoke, except that the invoked function is inside the assembly
>> instead of a library export. Before we can call that code, we need the
>> assembly to be loaded using the OS loader, so it's linked properly.
>> But because all assemblies link to mscoree.dll and execute _CorExeMain
>> or _CorDllMain (and the OS does that itself in recent Windows
>> versions), that would load MS .NET. So Mono loads mscoree.dll itself
>> on Windows before it loads any assemblies, and hooks the mscoree
>> functions so they go to implementations in libmono.
>> This makes sense on Windows, but it's no good on Wine, where
>> mscoree.dll loads Mono. I can't work sanely on the unmanaged API in
>> Wine if it's going to be bypassed by Mono half of the time.
>> But we still need Mono to load the assemblies using the OS loader so
>> it can invoke native methods.
>> So I would like to propose that both mixed-mode behaviors (using the
>> OS loader and hooking mscoree) be default off but optionally activated
>> by embedding API calls (which Wine would call), or switches (which
>> mono_main would translate into the appropriate embedding calls). That
>> is, we would have a function that, if called very early on, would load
>> mscoree.dll and do the hooking, and set a flag so that Mono tries to
>> load assemblies using the OS loader. We would have another,
>> independent function that only sets that flag, which Wine would use.
>> (I think we'll also need access to something like
>> mono_image_open_from_module_handle, so we can give Mono the handle to
>> an already-loaded exe file in _CorExeMain.)
>> Does this seem doable?
>> Once that's done, I'd like to get Wine's mscoree.dll to a point where
>> it's on par with Mono's mixed-mode assembly support. What is that
>> support currently used for, and what are you using to test it? AFAICT
>> an ordinary assembly written in managed c++ and compiled with VS will
>> always fail to load in Mono.
>> Do you have any sense of what's required to make assemblies linking
>> msvcrt (my eventual goal) work? I have so far been unable to create a
>> build of Mono that can call native functions without hooking mscoree,
>> so I can't really tell what's going on. There was speculation in a
>> Wine bug that _CorDllMain needs to call some entry points in
>> assemblies, named PostDllMain and PostRawDllMain, but given that they
>> were actually fields containing.. some number.. maybe it was an RVA?..
>> I wasn't sure what to do with that.

More information about the Mono-devel-list mailing list