Bug 37913 - JIT code generator fails on MSVC managed C++ ctor IL code on x86_64 target
Summary: JIT code generator fails on MSVC managed C++ ctor IL code on x86_64 target
Status: NEW
Alias: None
Product: Runtime
Classification: Mono
Component: JIT (show other bugs)
Version: 4.2.0 (C6)
Hardware: PC Linux
: --- normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2016-01-22 16:06 UTC by Paul Gofman
Modified: 2016-02-09 09:46 UTC (History)
4 users (show)

See Also:
Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Patch partially fixing check_call_signature and type_from_op for TARGET_AMD64 (3.19 KB, patch)
2016-01-22 16:06 UTC, Paul Gofman
Details | Diff
Test case (see README in the archive for details) (171.98 KB, application/x-compressed-tar)
2016-01-22 16:30 UTC, Paul Gofman
Details
IL test case for i8 -> ptr argument conversion (1.02 KB, text/plain)
2016-02-05 22:53 UTC, Vincent Povirk
Details
Test IL assembly (2.93 KB, text/plain)
2016-02-09 09:43 UTC, Paul Gofman
Details
Fix type compatibility checks in method_to_ir.c for I8/I4/PTR under x64 (6.18 KB, patch)
2016-02-09 09:46 UTC, Paul Gofman
Details | Diff

Description Paul Gofman 2016-01-22 16:06:02 UTC
Created attachment 14671 [details]
Patch partially fixing check_call_signature and type_from_op for TARGET_AMD64

I was making some efforts to let 64 bit Wine run .NET assemblies (mixed mode at the first place) through Mono. Here is the thread on wine-devel: https://www.winehq.org/pipermail/wine-devel/2016-January/111339.html with some details.

I have a test case compiled with MSVC which has a DLL with a managed C++ class (which in turn calls pure .NET assembly but this is not relevant to this issue). IL code for constructor for this class causes "Invalid IL code" exception with Mono. The problem is that 'check_call_signature' and 'type_from_op' methods (called from mono_method_to_ir in method-to-ir.c) do not mind that PTR size is 8 bytes for TARGET_AMD64.

I am attaching the patch which completely fixes the issue for me (I am using mono from the latest wine-mono git). The patch is not complete though as I did not touch the tables which did not affect my case. Please mind that remaining STACK_PTR <-> STACK_I4 match in TARGET_AMD64 bin_num_table version is not an obvious mistake: it is also required to make my IL code to pass the JIT compiler.

After that I could also reproduce the issue just using mono.exe (64 bit exe under Linux), small wraparound assembly (compiled with Mono mcs) and managed code DLL from my initial example. In the next comment I will add an archive with this test case (source & binaries) in the next comment.
Comment 1 Paul Gofman 2016-01-22 16:30:41 UTC
Created attachment 14673 [details]
Test case (see README in the archive for details)

Relevant part of assembly call trace is:

[0000000000000009: 0.01916 7] ENTER: <Module>:<CrtImplementationDetails>.LanguageSupport.Initialize (<CrtImplementationDetails>.LanguageSupport*)(000000000033ECD0, )
[0000000000000009: 0.01938 8] ENTER: (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr)([System.InvalidProgramException:0000000000B78CB0], 0000000000000000, 0000000000000000, 0000000000A67720, )
[0000000000000009: 0.01940 9] ENTER: System.InvalidProgramException:.ctor ()(this:0000000000B78CB0[System.InvalidProgramException ./run.exe], )
[0000000000000009: 0.01942 10] ENTER: System.SystemException:.ctor (string)(this:0000000000B78CB0[System.InvalidProgramException ./run.exe], [STRING:0000000000E12FA0:Metadata is invalid.], )
[0000000000000009: 0.01943 11] ENTER: System.Exception:.ctor (string)(this:0000000000B78CB0[System.InvalidProgramException ./run.exe], [STRING:0000000000E12FA0:Metadata is invalid.], )
[0000000000000009: 0.01945 11] LEAVE: System.Exception:.ctor (string)
[0000000000000009: 0.01946 10] LEAVE: System.SystemException:.ctor (string)
[0000000000000009: 0.01946 9] LEAVE: System.InvalidProgramException:.ctor ()
[0000000000000009: 0.01947 8] LEAVE: (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr)[OBJECT:0000000000000000]
[0000000000000009: 0.01966 8] ENTER: (wrapper runtime-invoke) <Module>:runtime_invoke_object__this__ (object,intptr,intptr,intptr)([System.InvalidProgramException:0000000000B78CB0], 0000000000000000, 000000000033E4E0, 0000000000A67920, )
[0000000000000009: 0.01968 9] ENTER: System.Exception:get_Message ()(this:0000000000B78CB0[System.InvalidProgramException ./run.exe], )
[0000000000000009: 0.01969 9] LEAVE: System.Exception:get_Message ()[STRING:0000000000E13E70:Invalid IL code in <Module>:gcroot<System::String ^>.= (gcroot<System::String ^>*,string): IL_0004: call      0x0a000012



'call      0x0a000012' is a call to IntPtr(void *). IL compiler fails in check_call_signature (the actual parameter args [i]->type is STACK_I8):
		case MONO_TYPE_I:
		case MONO_TYPE_U:
		case MONO_TYPE_PTR:
		case MONO_TYPE_FNPTR:
			if (args [i]->type != STACK_I4 && args [i]->type != STACK_PTR && args [i]->type != STACK_MP && args [i]->type != STACK_OBJ)
				return 1;


If to fix just that, the other IL code errors follow. My patch fixed all of them for me, but apparently there are more cases.
Comment 2 Vincent Povirk 2016-02-05 22:53:49 UTC
Created attachment 14927 [details]
IL test case for i8 -> ptr argument conversion

I tried writing a test case for calling void* methods with an i8 value. Surprisingly, it succeeds on 64-bit and 32-bit Windows. 32-bit Windows does not truncate the i8 value.

I don't know if that's reliable or just how it happens to compile in this case.
Comment 3 Paul Gofman 2016-02-09 09:43:50 UTC
Created attachment 14956 [details]
Test IL assembly

I extended Vincent's test case a bit, and updated the patch to make test case work under mono 64 bit. This test case outputs the same as patched mono under win64, and crashes under win32.
Comment 4 Paul Gofman 2016-02-09 09:46:02 UTC
Created attachment 14957 [details]
Fix type compatibility checks in method_to_ir.c for I8/I4/PTR under x64

Note You need to log in before you can comment on or make changes to this bug.