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 ()
Version: 4.2.0 (C6)
Hardware: PC Linux
: --- normal
Target Milestone: ---
Assignee: Bugzilla
Depends on:
Reported: 2016-01-22 16:06 UTC by Paul Gofman
Modified: 2016-02-09 09:46 UTC (History)
4 users (show)

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

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
Test case (see README in the archive for details) (171.98 KB, application/x-compressed-tar)
2016-01-22 16:30 UTC, Paul Gofman
IL test case for i8 -> ptr argument conversion (1.02 KB, text/plain)
2016-02-05 22:53 UTC, Vincent Povirk
Test IL assembly (2.93 KB, text/plain)
2016-02-09 09:43 UTC, Paul Gofman
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

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report for Bug 37913 on GitHub or Developer Community if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: GitHub Markdown or Developer Community HTML
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:

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:
			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