[Mono-dev] [PATCH] Win32 pinvoke3 runtime tests fixes
Hello All, I did some investigation on Win32 about why the pinvoke3 runtime test was failing. What I found was a calling convention error in the test, and two struct marshaling bugs. For the calling convention problem I simply added a __stdcall statement in libtest.c to the function pointer declaration that was missing it. The two calling convention bugs I was able to handle in the epilog. See comments in patch for more detail. The final problem I found was similar to a problem I observed before when working on Winx64. Zoltan fixed the problem with r104552 so I decided to take a chance and try that fix out for x86 and the problem went away. One last thing to point out is that this test does not even run on .NET. Does this mean that Mono is better than .Net in this case? ;) Unhandled Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Runtime.InteropServices.MarshalDirectiveException: Method's type signature is not PInvoke compatible. at Tests.mono_test_marshal_delegate2(SimpleDelegate2 d) at Tests.test_0_marshal_struct_delegate() --- End of inner exception stack trace --- at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandletypeOwner) at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at TestDriver.RunTests(Type type, String[] args) at TestDriver.RunTests(Type type) at Tests.Main() -bill ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] [PATCH] Win32 pinvoke3 runtime tests fixes
Forgot to add the patch. Sorry long day. :( On Thu, Jul 17, 2008 at 7:14 PM, Bill Holmes <[EMAIL PROTECTED]> wrote: > Hello All, > > I did some investigation on Win32 about why the pinvoke3 runtime test > was failing. What I found was a calling convention error in the test, > and two struct marshaling bugs. > > For the calling convention problem I simply added a __stdcall > statement in libtest.c to the function pointer declaration that was > missing it. > > The two calling convention bugs I was able to handle in the epilog. > See comments in patch for more detail. > > The final problem I found was similar to a problem I observed before > when working on Winx64. Zoltan fixed the problem with r104552 so I > decided to take a chance and try that fix out for x86 and the problem > went away. > > One last thing to point out is that this test does not even run on > .NET. Does this mean that Mono is better than .Net in this case? ;) > > Unhandled Exception: System.Reflection.TargetInvocationException: > Exception has been thrown by the target of an invocation. ---> > System.Runtime.InteropServices.MarshalDirectiveException: Method's > type signature is not PInvoke compatible. > at Tests.mono_test_marshal_delegate2(SimpleDelegate2 d) > at Tests.test_0_marshal_struct_delegate() > --- End of inner exception stack trace --- > at System.RuntimeMethodHandle._InvokeMethodFast(Object target, > Object[] arguments, SignatureStruct& sig, MethodAttributes > methodAttributes, RuntimeTypeHandletypeOwner) > at System.RuntimeMethodHandle.InvokeMethodFast(Object target, > Object[] arguments, Signature sig, MethodAttributes methodAttributes, > RuntimeTypeHandle typeOwner) > at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, > BindingFlags invokeAttr, Binder binder, Object[] parameters, > CultureInfo culture, Boolean skipVisibilityChecks) > at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, > BindingFlags invokeAttr, Binder binder, Object[] parameters, > CultureInfo culture) > at TestDriver.RunTests(Type type, String[] args) > at TestDriver.RunTests(Type type) > at Tests.Main() > > -bill > pinvoke3.diff Description: Binary data ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] [PATCH] Win32 pinvoke3 runtime tests fixes
Hello All, I am sending an update to this patch since there have been some discussion since the original posting. The 2 changes since the previous patch are in mono_arch_emit_epilog. @@ -4186,6 +4192,11 @@ } } + if (MONO_TYPE_ISSTRUCT (mono_method_signature (cfg->method)->ret) && (cinfo->ret.storage == ArgOnStack) && (cfg->vret_addr)) { + /* When return structs are passed on the stack the address needs to be stored in eax. */ + x86_mov_reg_membase (code, X86_EAX, cfg->vret_addr->sreg1, cfg->vret_addr->inst_offset, sizeof (gpointer)); + } + x86_leave (code); if (CALLCONV_IS_STDCALL (sig)) { It was brought to my attention on IRC that the address of the return struct needs to be in the return register for more platforms than just Win32. I removed the 'if Win32' preprocessor check so that this occurs on all platforms. @@ -4177,6 +4177,12 @@ break; case ArgOnDoubleFpStack: x86_fld_membase (code, cfg->ret->inst_basereg, cfg->ret->inst_offset + (quad * sizeof (gpointer)), TRUE); +#ifdef PLATFORM_WIN32 + /* Structs that contain only a double are stored spanning eax and edx. */ + /* This is needed for calling methods that were compiled the MSVC compiler. */ + x86_mov_reg_membase (code, return_regs[0], cfg->ret->inst_basereg, cfg->ret->inst_offset, 4); + x86_mov_reg_membase (code, return_regs[1], cfg->ret->inst_basereg, cfg->ret->inst_offset + sizeof (gpointer), 4); +#endif break; case ArgNone: break; I found that this is a difference between the way the MSVC and the Cygwin gcc compiler handle structs with doubles. MS stores the double across the 2 return registers while gcc uses the float registers. I am suggesting that for Windows we store the value in both locations as we can not determine which compiler generated the method that we are attempting to call. I would also like to put this change into the branch as well. -bill On Thu, Jul 17, 2008 at 7:14 PM, Bill Holmes <[EMAIL PROTECTED]> wrote: > Hello All, > > I did some investigation on Win32 about why the pinvoke3 runtime test > was failing. What I found was a calling convention error in the test, > and two struct marshaling bugs. > > For the calling convention problem I simply added a __stdcall > statement in libtest.c to the function pointer declaration that was > missing it. > > The two calling convention bugs I was able to handle in the epilog. > See comments in patch for more detail. > > The final problem I found was similar to a problem I observed before > when working on Winx64. Zoltan fixed the problem with r104552 so I > decided to take a chance and try that fix out for x86 and the problem > went away. > > One last thing to point out is that this test does not even run on > .NET. Does this mean that Mono is better than .Net in this case? ;) > > Unhandled Exception: System.Reflection.TargetInvocationException: > Exception has been thrown by the target of an invocation. ---> > System.Runtime.InteropServices.MarshalDirectiveException: Method's > type signature is not PInvoke compatible. > at Tests.mono_test_marshal_delegate2(SimpleDelegate2 d) > at Tests.test_0_marshal_struct_delegate() > --- End of inner exception stack trace --- > at System.RuntimeMethodHandle._InvokeMethodFast(Object target, > Object[] arguments, SignatureStruct& sig, MethodAttributes > methodAttributes, RuntimeTypeHandletypeOwner) > at System.RuntimeMethodHandle.InvokeMethodFast(Object target, > Object[] arguments, Signature sig, MethodAttributes methodAttributes, > RuntimeTypeHandle typeOwner) > at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, > BindingFlags invokeAttr, Binder binder, Object[] parameters, > CultureInfo culture, Boolean skipVisibilityChecks) > at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, > BindingFlags invokeAttr, Binder binder, Object[] parameters, > CultureInfo culture) > at TestDriver.RunTests(Type type, String[] args) > at TestDriver.RunTests(Type type) > at Tests.Main() > > -bill > pinvoke3_08_07_28.diff Description: Binary data ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] [PATCH] Win32 pinvoke3 runtime tests fixes
Hi, 2008/7/28 Bill Holmes <[EMAIL PROTECTED]>: > Hello All, > > I am sending an update to this patch since there have been some > discussion since the original posting. > > The 2 changes since the previous patch are in mono_arch_emit_epilog. > > @@ -4186,6 +4192,11 @@ >} >} > > + if (MONO_TYPE_ISSTRUCT (mono_method_signature (cfg->method)->ret) && > (cinfo->ret.storage == ArgOnStack) && (cfg->vret_addr)) { > + /* When return structs are passed on the stack the address > needs to > be stored in eax. */ > + x86_mov_reg_membase (code, X86_EAX, cfg->vret_addr->sreg1, > cfg->vret_addr->inst_offset, sizeof (gpointer)); > + } > + >x86_leave (code); > >if (CALLCONV_IS_STDCALL (sig)) { > > It was brought to my attention on IRC that the address of the return > struct needs to be in the return register for more platforms than just > Win32. I removed the 'if Win32' preprocessor check so that this > occurs on all platforms. > What platforms needs this ? It doesn't look like it is needed on linux. Also, this should only be needed for methods which can be called from native code ( method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED). Other than that, the patch look ok to me. Zoltan ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] [PATCH] Win32 pinvoke3 runtime tests fixes
Hello Zoltan, This was a link that was shared with me on IRC. >From http://www.sco.com/developers/devspecs/abi386-4.pdf "A function that returns a structure or union also sets %eax to the value of the original address of the caller's area before it returns. Thus when the caller receives control again, the address of the returned object resides in register %eax and can be used to access the object. Both the calling and the called functions must cooperate to pass the return value successfully:" > Also, this should > only be needed for methods which can be called from native code ( > method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED). > I will add this. -bill ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list