diff --git a/NuGet.config b/NuGet.config
index 3fc86e82b96350..f03ecf8fdc4d9e 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -9,7 +9,7 @@
-
+
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index f27a5a2c8c5a34..75e43e3f8b51f2 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -8,17 +8,17 @@
https://github.com/dotnet/msquic
7312355e44fd230b7aa26c7190f3870391751476
-
+
https://github.com/dotnet/emsdk
- 3c754f28788fae642dc307a948479204e9f7dd5a
+ f472bde6484a7b860c6647cf2ac64fd2870853e0
-
+
https://github.com/dotnet/emsdk
- 3c754f28788fae642dc307a948479204e9f7dd5a
+ f472bde6484a7b860c6647cf2ac64fd2870853e0
-
+
https://github.com/dotnet/emsdk
- 3c754f28788fae642dc307a948479204e9f7dd5a
+ f472bde6484a7b860c6647cf2ac64fd2870853e0
https://github.com/dotnet/wcf
diff --git a/eng/Versions.props b/eng/Versions.props
index 39c129ed45e2af..e0b393d0202986 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -176,9 +176,9 @@
11.1.0-alpha.1.21416.1
11.1.0-alpha.1.21416.1
- 6.0.22
- 6.0.22
- 6.0.22
+ 6.0.23
+ 6.0.23
+ 6.0.23
$(MicrosoftNETWorkloadEmscriptenManifest60100Version)
1.1.87-gba258badda
diff --git a/src/coreclr/pal/src/include/pal/sharedmemory.h b/src/coreclr/pal/src/include/pal/sharedmemory.h
index 0cf5a61a5a1d6f..c6e5abe97c3a78 100644
--- a/src/coreclr/pal/src/include/pal/sharedmemory.h
+++ b/src/coreclr/pal/src/include/pal/sharedmemory.h
@@ -91,11 +91,9 @@ class SharedMemoryException
class SharedMemoryHelpers
{
private:
- static const mode_t PermissionsMask_CurrentUser_ReadWrite;
static const mode_t PermissionsMask_CurrentUser_ReadWriteExecute;
static const mode_t PermissionsMask_AllUsers_ReadWrite;
static const mode_t PermissionsMask_AllUsers_ReadWriteExecute;
-
public:
static const UINT32 InvalidProcessId;
static const SIZE_T InvalidThreadId;
@@ -111,12 +109,12 @@ class SharedMemoryHelpers
static void BuildSharedFilesPath(PathCharString& destination, const char *suffix, int suffixByteCount);
static bool AppendUInt32String(PathCharString& destination, UINT32 value);
- static bool EnsureDirectoryExists(const char *path, bool isGlobalLockAcquired, bool hasCurrentUserAccessOnly, bool setStickyFlag, bool createIfNotExist = true, bool isSystemDirectory = false);
+ static bool EnsureDirectoryExists(const char *path, bool isGlobalLockAcquired, bool createIfNotExist = true, bool isSystemDirectory = false);
private:
static int Open(LPCSTR path, int flags, mode_t mode = static_cast(0));
public:
static int OpenDirectory(LPCSTR path);
- static int CreateOrOpenFile(LPCSTR path, bool createIfNotExist = true, bool isSessionScope = true, bool *createdRef = nullptr);
+ static int CreateOrOpenFile(LPCSTR path, bool createIfNotExist = true, bool *createdRef = nullptr);
static void CloseFile(int fileDescriptor);
static SIZE_T GetFileSize(int fileDescriptor);
diff --git a/src/coreclr/pal/src/sharedmemory/sharedmemory.cpp b/src/coreclr/pal/src/sharedmemory/sharedmemory.cpp
index 84c10384b233de..2cec2008582119 100644
--- a/src/coreclr/pal/src/sharedmemory/sharedmemory.cpp
+++ b/src/coreclr/pal/src/sharedmemory/sharedmemory.cpp
@@ -62,7 +62,6 @@ DWORD SharedMemoryException::GetErrorCode() const
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SharedMemoryHelpers
-const mode_t SharedMemoryHelpers::PermissionsMask_CurrentUser_ReadWrite = S_IRUSR | S_IWUSR;
const mode_t SharedMemoryHelpers::PermissionsMask_CurrentUser_ReadWriteExecute = S_IRUSR | S_IWUSR | S_IXUSR;
const mode_t SharedMemoryHelpers::PermissionsMask_AllUsers_ReadWrite =
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
@@ -97,8 +96,6 @@ SIZE_T SharedMemoryHelpers::AlignUp(SIZE_T value, SIZE_T alignment)
bool SharedMemoryHelpers::EnsureDirectoryExists(
const char *path,
bool isGlobalLockAcquired,
- bool hasCurrentUserAccessOnly,
- bool setStickyFlag,
bool createIfNotExist,
bool isSystemDirectory)
{
@@ -106,13 +103,6 @@ bool SharedMemoryHelpers::EnsureDirectoryExists(
_ASSERTE(!(isSystemDirectory && createIfNotExist)); // should not create or change permissions on system directories
_ASSERTE(SharedMemoryManager::IsCreationDeletionProcessLockAcquired());
_ASSERTE(!isGlobalLockAcquired || SharedMemoryManager::IsCreationDeletionFileLockAcquired());
- _ASSERTE(!(setStickyFlag && hasCurrentUserAccessOnly)); // Sticky bit doesn't make sense with current user access only
-
- mode_t mode = hasCurrentUserAccessOnly ? PermissionsMask_CurrentUser_ReadWriteExecute : PermissionsMask_AllUsers_ReadWriteExecute;
- if (setStickyFlag)
- {
- mode |= S_ISVTX;
- }
// Check if the path already exists
struct stat statInfo;
@@ -133,11 +123,11 @@ bool SharedMemoryHelpers::EnsureDirectoryExists(
if (isGlobalLockAcquired)
{
- if (mkdir(path, mode) != 0)
+ if (mkdir(path, PermissionsMask_AllUsers_ReadWriteExecute) != 0)
{
throw SharedMemoryException(static_cast(SharedMemoryError::IO));
}
- if (chmod(path, mode) != 0)
+ if (chmod(path, PermissionsMask_AllUsers_ReadWriteExecute) != 0)
{
rmdir(path);
throw SharedMemoryException(static_cast(SharedMemoryError::IO));
@@ -152,7 +142,7 @@ bool SharedMemoryHelpers::EnsureDirectoryExists(
{
throw SharedMemoryException(static_cast(SharedMemoryError::IO));
}
- if (chmod(tempPath, mode) != 0)
+ if (chmod(tempPath, PermissionsMask_AllUsers_ReadWriteExecute) != 0)
{
rmdir(tempPath);
throw SharedMemoryException(static_cast(SharedMemoryError::IO));
@@ -192,11 +182,11 @@ bool SharedMemoryHelpers::EnsureDirectoryExists(
// For non-system directories (such as gSharedFilesPath/SHARED_MEMORY_RUNTIME_TEMP_DIRECTORY_NAME),
// require sufficient permissions for all users and try to update them if requested to create the directory, so that
// shared memory files may be shared by all processes on the system.
- if ((statInfo.st_mode & mode) == mode)
+ if ((statInfo.st_mode & PermissionsMask_AllUsers_ReadWriteExecute) == PermissionsMask_AllUsers_ReadWriteExecute)
{
return true;
}
- if (!createIfNotExist || chmod(path, mode) != 0)
+ if (!createIfNotExist || chmod(path, PermissionsMask_AllUsers_ReadWriteExecute) != 0)
{
// We were not asked to create the path or we weren't able to set the new permissions.
// As a last resort, check that at least the current user has full access.
@@ -253,7 +243,7 @@ int SharedMemoryHelpers::OpenDirectory(LPCSTR path)
return fileDescriptor;
}
-int SharedMemoryHelpers::CreateOrOpenFile(LPCSTR path, bool createIfNotExist, bool isSessionScope, bool *createdRef)
+int SharedMemoryHelpers::CreateOrOpenFile(LPCSTR path, bool createIfNotExist, bool *createdRef)
{
_ASSERTE(path != nullptr);
_ASSERTE(path[0] != '\0');
@@ -283,13 +273,12 @@ int SharedMemoryHelpers::CreateOrOpenFile(LPCSTR path, bool createIfNotExist, bo
// File does not exist, create the file
openFlags |= O_CREAT | O_EXCL;
- mode_t mode = isSessionScope ? PermissionsMask_CurrentUser_ReadWrite : PermissionsMask_AllUsers_ReadWrite;
- fileDescriptor = Open(path, openFlags, mode);
+ fileDescriptor = Open(path, openFlags, PermissionsMask_AllUsers_ReadWrite);
_ASSERTE(fileDescriptor != -1);
// The permissions mask passed to open() is filtered by the process' permissions umask, so open() may not set all of
// the requested permissions. Use chmod() to set the proper permissions.
- if (chmod(path, mode) != 0)
+ if (chmod(path, PermissionsMask_AllUsers_ReadWrite) != 0)
{
CloseFile(fileDescriptor);
unlink(path);
@@ -675,7 +664,7 @@ SharedMemoryProcessDataHeader *SharedMemoryProcessDataHeader::CreateOrOpen(
SharedMemoryHelpers::VerifyStringOperation(SharedMemoryManager::CopySharedMemoryBasePath(filePath));
SharedMemoryHelpers::VerifyStringOperation(filePath.Append('/'));
SharedMemoryHelpers::VerifyStringOperation(id.AppendSessionDirectoryName(filePath));
- if (!SharedMemoryHelpers::EnsureDirectoryExists(filePath, true /* isGlobalLockAcquired */, id.IsSessionScope(), false /* setStickyFlag */, createIfNotExist))
+ if (!SharedMemoryHelpers::EnsureDirectoryExists(filePath, true /* isGlobalLockAcquired */, createIfNotExist))
{
_ASSERTE(!createIfNotExist);
return nullptr;
@@ -688,7 +677,7 @@ SharedMemoryProcessDataHeader *SharedMemoryProcessDataHeader::CreateOrOpen(
SharedMemoryHelpers::VerifyStringOperation(filePath.Append(id.GetName(), id.GetNameCharCount()));
bool createdFile;
- int fileDescriptor = SharedMemoryHelpers::CreateOrOpenFile(filePath, createIfNotExist, id.IsSessionScope(), &createdFile);
+ int fileDescriptor = SharedMemoryHelpers::CreateOrOpenFile(filePath, createIfNotExist, &createdFile);
if (fileDescriptor == -1)
{
_ASSERTE(!createIfNotExist);
@@ -1163,8 +1152,6 @@ void SharedMemoryManager::AcquireCreationDeletionFileLock()
if (!SharedMemoryHelpers::EnsureDirectoryExists(
*gSharedFilesPath,
false /* isGlobalLockAcquired */,
- false /* hasCurrentUserAccessOnly */,
- true /* setStickyFlag */,
false /* createIfNotExist */,
true /* isSystemDirectory */))
{
@@ -1172,14 +1159,10 @@ void SharedMemoryManager::AcquireCreationDeletionFileLock()
}
SharedMemoryHelpers::EnsureDirectoryExists(
*s_runtimeTempDirectoryPath,
- false /* isGlobalLockAcquired */,
- false /* hasCurrentUserAccessOnly */,
- true /* setStickyFlag */);
+ false /* isGlobalLockAcquired */);
SharedMemoryHelpers::EnsureDirectoryExists(
*s_sharedMemoryDirectoryPath,
- false /* isGlobalLockAcquired */,
- false /* hasCurrentUserAccessOnly */,
- true /* setStickyFlag */);
+ false /* isGlobalLockAcquired */);
s_creationDeletionLockFileDescriptor = SharedMemoryHelpers::OpenDirectory(*s_sharedMemoryDirectoryPath);
if (s_creationDeletionLockFileDescriptor == -1)
{
diff --git a/src/coreclr/pal/src/synchobj/mutex.cpp b/src/coreclr/pal/src/synchobj/mutex.cpp
index d2499c7c2ae278..85bf3da1e79a64 100644
--- a/src/coreclr/pal/src/synchobj/mutex.cpp
+++ b/src/coreclr/pal/src/synchobj/mutex.cpp
@@ -1121,7 +1121,7 @@ SharedMemoryProcessDataHeader *NamedMutexProcessData::CreateOrOpen(
SharedMemoryHelpers::BuildSharedFilesPath(lockFilePath, SHARED_MEMORY_LOCK_FILES_DIRECTORY_NAME);
if (created)
{
- SharedMemoryHelpers::EnsureDirectoryExists(lockFilePath, true /* isGlobalLockAcquired */, false /* hasCurrentUserAccessOnly */, true /* setStickyFlag */);
+ SharedMemoryHelpers::EnsureDirectoryExists(lockFilePath, true /* isGlobalLockAcquired */);
}
// Create the session directory
@@ -1130,7 +1130,7 @@ SharedMemoryProcessDataHeader *NamedMutexProcessData::CreateOrOpen(
SharedMemoryHelpers::VerifyStringOperation(id->AppendSessionDirectoryName(lockFilePath));
if (created)
{
- SharedMemoryHelpers::EnsureDirectoryExists(lockFilePath, true /* isGlobalLockAcquired */, id->IsSessionScope(), false /* setStickyFlag */);
+ SharedMemoryHelpers::EnsureDirectoryExists(lockFilePath, true /* isGlobalLockAcquired */);
autoCleanup.m_lockFilePath = &lockFilePath;
autoCleanup.m_sessionDirectoryPathCharCount = lockFilePath.GetCount();
}
@@ -1138,7 +1138,7 @@ SharedMemoryProcessDataHeader *NamedMutexProcessData::CreateOrOpen(
// Create or open the lock file
SharedMemoryHelpers::VerifyStringOperation(lockFilePath.Append('/'));
SharedMemoryHelpers::VerifyStringOperation(lockFilePath.Append(id->GetName(), id->GetNameCharCount()));
- int lockFileDescriptor = SharedMemoryHelpers::CreateOrOpenFile(lockFilePath, created, id->IsSessionScope());
+ int lockFileDescriptor = SharedMemoryHelpers::CreateOrOpenFile(lockFilePath, created);
if (lockFileDescriptor == -1)
{
_ASSERTE(!created);
diff --git a/src/libraries/Native/Unix/CMakeLists.txt b/src/libraries/Native/Unix/CMakeLists.txt
index 89c2317d107a88..cc14d13da12815 100644
--- a/src/libraries/Native/Unix/CMakeLists.txt
+++ b/src/libraries/Native/Unix/CMakeLists.txt
@@ -218,6 +218,17 @@ else ()
message(FATAL_ERROR "Unknown build type. Set CMAKE_BUILD_TYPE to DEBUG or RELEASE.")
endif ()
+if(CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS)
+ # Clang will by default emit objc_msgSend stubs in Xcode 14, which ld from earlier Xcodes doesn't understand.
+ # We disable this by passing -fno-objc-msgsend-selector-stubs to clang.
+ # We can probably remove this flag once we require developers to use Xcode 14.
+ # Ref: https://github.com/xamarin/xamarin-macios/issues/16223
+ check_c_compiler_flag(-fno-objc-msgsend-selector-stubs COMPILER_SUPPORTS_FNO_OBJC_MSGSEND_SELECTOR_STUBS)
+ if(COMPILER_SUPPORTS_FNO_OBJC_MSGSEND_SELECTOR_STUBS)
+ set(CLR_CMAKE_COMMON_OBJC_FLAGS "${CLR_CMAKE_COMMON_OBJC_FLAGS} -fno-objc-msgsend-selector-stubs")
+ endif()
+endif()
+
if(CLR_CMAKE_TARGET_BROWSER)
elseif (CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS)
add_definitions(-D__APPLE_USE_RFC_3542)
diff --git a/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt b/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt
index f7add30d50b6c2..5435f6b38a29d8 100644
--- a/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt
+++ b/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt
@@ -66,6 +66,7 @@ set(NATIVEGLOBALIZATION_SOURCES
if (CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS)
set(NATIVEGLOBALIZATION_SOURCES ${NATIVEGLOBALIZATION_SOURCES} pal_locale.m)
+ set_source_files_properties(pal_locale.m PROPERTIES COMPILE_FLAGS "${CLR_CMAKE_COMMON_OBJC_FLAGS}")
endif()
# time zone names are filtered out of icu data for the browser and associated functionality is disabled
diff --git a/src/libraries/Native/Unix/System.Native/CMakeLists.txt b/src/libraries/Native/Unix/System.Native/CMakeLists.txt
index 1b06d83880533c..7d118fe6049211 100644
--- a/src/libraries/Native/Unix/System.Native/CMakeLists.txt
+++ b/src/libraries/Native/Unix/System.Native/CMakeLists.txt
@@ -35,13 +35,14 @@ set(NATIVE_SOURCES
if (CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS)
list (APPEND NATIVE_SOURCES pal_autoreleasepool.m)
- set_source_files_properties(pal_autoreleasepool.m PROPERTIES COMPILE_FLAGS -fno-objc-arc)
+ set_source_files_properties(pal_autoreleasepool.m PROPERTIES COMPILE_FLAGS "-fno-objc-arc ${CLR_CMAKE_COMMON_OBJC_FLAGS}")
else()
list (APPEND NATIVE_SOURCES pal_autoreleasepool.c)
endif()
if (CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS)
list (APPEND NATIVE_SOURCES pal_environment.m)
+ set_source_files_properties(pal_environment.m PROPERTIES COMPILE_FLAGS "${CLR_CMAKE_COMMON_OBJC_FLAGS}")
else()
list (APPEND NATIVE_SOURCES pal_environment.c)
endif()
@@ -49,12 +50,14 @@ endif()
if (CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS)
set(NATIVE_SOURCES ${NATIVE_SOURCES}
pal_datetime.m)
+ set_source_files_properties(pal_datetime.m PROPERTIES COMPILE_FLAGS "${CLR_CMAKE_COMMON_OBJC_FLAGS}")
endif()
if (CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS)
set(NATIVE_SOURCES ${NATIVE_SOURCES}
pal_log.m
pal_searchpath.m)
+ set_source_files_properties(pal_log.m pal_searchpath.m PROPERTIES COMPILE_FLAGS "${CLR_CMAKE_COMMON_OBJC_FLAGS}")
else ()
list (APPEND NATIVE_SOURCES
pal_searchpath.c
@@ -65,6 +68,7 @@ endif ()
if (CLR_CMAKE_TARGET_MACCATALYST)
set(NATIVE_SOURCES ${NATIVE_SOURCES}
pal_iossupportversion.m)
+ set_source_files_properties(pal_iossupportversion.m PROPERTIES COMPILE_FLAGS "${CLR_CMAKE_COMMON_OBJC_FLAGS}")
else ()
list (APPEND NATIVE_SOURCES
pal_iossupportversion.c)
diff --git a/src/mono/CMakeLists.txt b/src/mono/CMakeLists.txt
index 49a73b1b709c37..32af6567438634 100644
--- a/src/mono/CMakeLists.txt
+++ b/src/mono/CMakeLists.txt
@@ -784,6 +784,14 @@ if (TARGET_BROWSER)
# sys/errno.h exists, but just emits a warning and includes errno.h
unset(HAVE_SYS_ERRNO_H)
endif()
+
+if(TARGET_DARWIN)
+ check_c_compiler_flag(-fno-objc-msgsend-selector-stubs COMPILER_SUPPORTS_FNO_OBJC_MSGSEND_SELECTOR_STUBS)
+ if(COMPILER_SUPPORTS_FNO_OBJC_MSGSEND_SELECTOR_STUBS)
+ set(CLR_CMAKE_COMMON_OBJC_FLAGS "${CLR_CMAKE_COMMON_OBJC_FLAGS} -fno-objc-msgsend-selector-stubs")
+ endif()
+endif()
+
### End of OS specific checks
add_subdirectory(mono)
diff --git a/src/mono/mono/mini/CMakeLists.txt b/src/mono/mono/mini/CMakeLists.txt
index 128ed08f45b619..1ab14164663022 100644
--- a/src/mono/mono/mini/CMakeLists.txt
+++ b/src/mono/mono/mini/CMakeLists.txt
@@ -89,6 +89,9 @@ if(HAVE_SYS_ICU)
addprefix(icu_shim_sources "${ICU_SHIM_PATH}" "${icu_shim_sources_base}")
set_source_files_properties(${icu_shim_sources} PROPERTIES COMPILE_DEFINITIONS OSX_ICU_LIBRARY_PATH="${OSX_ICU_LIBRARY_PATH}")
set_source_files_properties(${icu_shim_sources} PROPERTIES COMPILE_FLAGS "-I\"${ICU_INCLUDEDIR}\" -I\"${CMAKE_CURRENT_SOURCE_DIR}/../../../libraries/Native/Unix/System.Globalization.Native/\" -I\"${CMAKE_CURRENT_SOURCE_DIR}/../../../libraries/Native/Unix/Common/\" ${ICU_FLAGS}")
+ if(TARGET_DARWIN)
+ set_property(SOURCE "${ICU_SHIM_PATH}/pal_locale.m" APPEND_STRING PROPERTY COMPILE_FLAGS "${CLR_CMAKE_COMMON_OBJC_FLAGS}")
+ endif()
if(TARGET_WIN32)
set_source_files_properties(${icu_shim_sources} PROPERTIES LANGUAGE CXX)
endif()
diff --git a/src/mono/mono/mini/mini-amd64.c b/src/mono/mono/mini/mini-amd64.c
index 4bcbcd9caa9171..b615bc37060c03 100644
--- a/src/mono/mono/mini/mini-amd64.c
+++ b/src/mono/mono/mini/mini-amd64.c
@@ -363,7 +363,7 @@ collect_field_info_nested (MonoClass *klass, GArray *fields_array, int offset, g
g_assert(info);
for (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;
@@ -373,7 +373,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..1cfbdf526f377b
--- /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 31a054303b5095..62d7c3e233593f 100644
--- a/src/tests/issues.targets
+++ b/src/tests/issues.targets
@@ -2912,6 +2912,12 @@
+
+
+ https://github.com/dotnet/runtime/issues/64127
+
+
+
missing assembly