diff --git a/src/mono/mono/mini/mini-amd64.c b/src/mono/mono/mini/mini-amd64.c
index bc4eedd8f86c5e..832d958758c156 100644
--- a/src/mono/mono/mini/mini-amd64.c
+++ b/src/mono/mono/mini/mini-amd64.c
@@ -355,7 +355,7 @@ collect_field_info_nested (MonoClass *klass, GArray *fields_array, int offset, g
g_assert(info);
for (guint32 i = 0; i < info->num_fields; ++i) {
if (MONO_TYPE_ISSTRUCT (info->fields [i].field->type)) {
- collect_field_info_nested (mono_class_from_mono_type_internal (info->fields [i].field->type), fields_array, info->fields [i].offset, pinvoke, unicode);
+ collect_field_info_nested (mono_class_from_mono_type_internal (info->fields [i].field->type), fields_array, (offset + info->fields [i].offset), pinvoke, unicode);
} else {
guint32 align;
StructFieldInfo f;
@@ -365,7 +365,7 @@ collect_field_info_nested (MonoClass *klass, GArray *fields_array, int offset, g
info->fields [i].mspec,
&align, TRUE, unicode);
f.offset = offset + info->fields [i].offset;
- if (i == info->num_fields - 1 && f.size + f.offset < info->native_size) {
+ if ((i == info->num_fields - 1) && ((f.size + f.offset) < info->native_size)) {
/* This can happen with .pack directives eg. 'fixed' arrays */
if (MONO_TYPE_IS_PRIMITIVE (f.type)) {
/* Replicate the last field to fill out the remaining place, since the code in add_valuetype () needs type information */
diff --git a/src/tests/Interop/StructMarshalling/PInvoke/GameControllerButtonBind.cs b/src/tests/Interop/StructMarshalling/PInvoke/GameControllerButtonBind.cs
new file mode 100644
index 00000000000000..a65994f2307a3f
--- /dev/null
+++ b/src/tests/Interop/StructMarshalling/PInvoke/GameControllerButtonBind.cs
@@ -0,0 +1,63 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Text;
+
+public unsafe partial struct GameControllerButtonBind
+{
+ public GameControllerButtonBind
+ (
+ GameControllerBindType? bindType = null,
+ GameControllerButtonBindValue? value = null
+ ) : this()
+ {
+ if (bindType is not null)
+ {
+ BindType = bindType.Value;
+ }
+
+ if (value is not null)
+ {
+ Value = value.Value;
+ }
+ }
+
+ public GameControllerBindType BindType;
+
+ public GameControllerButtonBindValue Value;
+}
+
+public enum GameControllerBindType : int
+{
+ ControllerBindtypeNone = 0x0,
+ ControllerBindtypeButton = 0x1,
+ ControllerBindtypeAxis = 0x2,
+ ControllerBindtypeHat = 0x3,
+ None = 0x0,
+ Button = 0x1,
+ Axis = 0x2,
+ Hat = 0x3,
+}
+
+[StructLayout(LayoutKind.Explicit)]
+public unsafe partial struct GameControllerButtonBindValue
+{
+ [FieldOffset(0)]
+ public int Button;
+
+ [FieldOffset(0)]
+ public int Axis;
+
+ [FieldOffset(0)]
+ public GameControllerButtonBindValueHat Hat;
+}
+
+public unsafe partial struct GameControllerButtonBindValueHat
+{
+ public int Hat;
+
+ public int HatMask;
+}
diff --git a/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.cpp b/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.cpp
index 9278650d20dce8..e19eec7feb0737 100644
--- a/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.cpp
+++ b/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.cpp
@@ -1297,3 +1297,8 @@ extern "C" DLL_EXPORT Int32CLongStruct STDMETHODCALLTYPE AddCLongs(Int32CLongStr
{
return { lhs.i + rhs.i, lhs.l + rhs.l };
}
+
+extern "C" DLL_EXPORT SDL_GameControllerBindType STDMETHODCALLTYPE getBindType(SDL_GameControllerButtonBind button)
+{
+ return button.bindType;
+}
diff --git a/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.h b/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.h
index 4a74572717890c..cb59b80bf09888 100644
--- a/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.h
+++ b/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.h
@@ -974,3 +974,26 @@ struct Int32CLongStruct
int32_t i;
long l;
};
+
+typedef enum
+{
+ SDL_CONTROLLER_BINDTYPE_NONE = 0,
+ SDL_CONTROLLER_BINDTYPE_BUTTON,
+ SDL_CONTROLLER_BINDTYPE_AXIS,
+ SDL_CONTROLLER_BINDTYPE_HAT
+} SDL_GameControllerBindType;
+
+typedef struct SDL_GameControllerButtonBind
+{
+ SDL_GameControllerBindType bindType;
+ union
+ {
+ int button;
+ int axis;
+ struct {
+ int hat;
+ int hat_mask;
+ } hat;
+ } value;
+
+} SDL_GameControllerButtonBind;
diff --git a/src/tests/Interop/StructMarshalling/PInvoke/NestedStruct.cs b/src/tests/Interop/StructMarshalling/PInvoke/NestedStruct.cs
new file mode 100644
index 00000000000000..870e75bff62525
--- /dev/null
+++ b/src/tests/Interop/StructMarshalling/PInvoke/NestedStruct.cs
@@ -0,0 +1,27 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Runtime.InteropServices;
+using Xunit;
+
+public class Managed
+{
+ [DllImport("MarshalStructAsParam")]
+ static extern GameControllerBindType getBindType (GameControllerButtonBind button);
+
+ public static int Main()
+ {
+ GameControllerButtonBind button = new GameControllerButtonBind(GameControllerBindType.ControllerBindtypeAxis, null);
+ if (getBindType(button) == GameControllerBindType.ControllerBindtypeAxis)
+ {
+ Console.WriteLine("\nTEST PASSED!");
+ return 100;
+ }
+ else
+ {
+ Console.WriteLine("\nTEST FAILED!");
+ return 1;
+ }
+ }
+}
diff --git a/src/tests/Interop/StructMarshalling/PInvoke/NestedStruct.csproj b/src/tests/Interop/StructMarshalling/PInvoke/NestedStruct.csproj
new file mode 100644
index 00000000000000..0b0d4aa0836435
--- /dev/null
+++ b/src/tests/Interop/StructMarshalling/PInvoke/NestedStruct.csproj
@@ -0,0 +1,14 @@
+
+
+ exe
+ true
+
+
+
+
+
+
+
+
+
+
diff --git a/src/tests/issues.targets b/src/tests/issues.targets
index 6d1ae189b60f92..d681c89afc915e 100644
--- a/src/tests/issues.targets
+++ b/src/tests/issues.targets
@@ -4062,6 +4062,9 @@
mobile and wasm don't support tests with native libraries. wasm also needs static linking
+
+ https://github.com/dotnet/runtime/issues/64127
+