diff --git a/Directory.Build.props b/Directory.Build.props
index c815af2041b714..04fcdf5422a324 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -180,6 +180,8 @@
$(PackageRID)
$(_portableOS)-$(TargetArchitecture)
+
+ true
diff --git a/eng/native/tryrun.cmake b/eng/native/tryrun.cmake
index 96199969da69c9..d6fcc9d3859f19 100644
--- a/eng/native/tryrun.cmake
+++ b/eng/native/tryrun.cmake
@@ -8,7 +8,9 @@ endmacro()
if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/armv7-alpine-linux-musleabihf OR
EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/armv6-alpine-linux-musleabihf OR
- EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/aarch64-alpine-linux-musl)
+ EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/aarch64-alpine-linux-musl OR
+ EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/s390x-alpine-linux-musl OR
+ EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/i586-alpine-linux-musl)
set(ALPINE_LINUX 1)
elseif(EXISTS ${CROSS_ROOTFS}/bin/freebsd-version)
diff --git a/src/coreclr/pal/src/CMakeLists.txt b/src/coreclr/pal/src/CMakeLists.txt
index ba13ab392f0c53..b1ff84b29858c3 100644
--- a/src/coreclr/pal/src/CMakeLists.txt
+++ b/src/coreclr/pal/src/CMakeLists.txt
@@ -319,6 +319,11 @@ if(CLR_CMAKE_TARGET_LINUX)
target_link_libraries(coreclrpal ${UNWIND_LIBS})
endif(CLR_CMAKE_USE_SYSTEM_LIBUNWIND)
+ # bundled libunwind requires using libucontext on alpine and x86
+ if(CLR_CMAKE_TARGET_ALPINE_LINUX AND CLR_CMAKE_TARGET_ARCH_I386)
+ target_link_libraries(coreclrpal ucontext)
+ endif(CLR_CMAKE_TARGET_ALPINE_LINUX AND CLR_CMAKE_TARGET_ARCH_I386)
+
endif(CLR_CMAKE_TARGET_LINUX)
if(CLR_CMAKE_TARGET_NETBSD)
diff --git a/src/coreclr/pal/src/misc/perfjitdump.cpp b/src/coreclr/pal/src/misc/perfjitdump.cpp
index d80bd58038cbad..3488397b0da051 100644
--- a/src/coreclr/pal/src/misc/perfjitdump.cpp
+++ b/src/coreclr/pal/src/misc/perfjitdump.cpp
@@ -25,7 +25,7 @@
#include
#include
#include
-#include
+#include
#include "../inc/llvm/ELF.h"
diff --git a/src/coreclr/vm/i386/cgenx86.cpp b/src/coreclr/vm/i386/cgenx86.cpp
index 6af331cc6a351c..9ed3c09645f66c 100644
--- a/src/coreclr/vm/i386/cgenx86.cpp
+++ b/src/coreclr/vm/i386/cgenx86.cpp
@@ -1163,6 +1163,7 @@ extern "C" DWORD __stdcall xmmYmmStateSupport()
#else // !TARGET_UNIX
+#if !__has_builtin(__cpuid)
void __cpuid(int cpuInfo[4], int function_id)
{
// Based on the Clang implementation provided in cpuid.h:
@@ -1173,7 +1174,9 @@ void __cpuid(int cpuInfo[4], int function_id)
: "0"(function_id)
);
}
+#endif
+#if !__has_builtin(__cpuidex)
void __cpuidex(int cpuInfo[4], int function_id, int subFunction_id)
{
// Based on the Clang implementation provided in cpuid.h:
@@ -1184,6 +1187,7 @@ void __cpuidex(int cpuInfo[4], int function_id, int subFunction_id)
: "0"(function_id), "2"(subFunction_id)
);
}
+#endif
extern "C" DWORD __stdcall xmmYmmStateSupport()
{
diff --git a/src/mono/CMakeLists.txt b/src/mono/CMakeLists.txt
index 49a73b1b709c37..ff0041257c2730 100644
--- a/src/mono/CMakeLists.txt
+++ b/src/mono/CMakeLists.txt
@@ -208,6 +208,33 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
# Enable the "full RELRO" options (RELRO & BIND_NOW) at link time
add_link_options(-Wl,-z,relro)
add_link_options(-Wl,-z,now)
+ # Detect Linux ID
+ set(LINUX_ID_FILE "/etc/os-release")
+ if(CMAKE_CROSSCOMPILING)
+ set(LINUX_ID_FILE "${CMAKE_SYSROOT}${LINUX_ID_FILE}")
+ endif()
+
+ if(EXISTS ${LINUX_ID_FILE})
+ execute_process(
+ COMMAND bash -c "source ${LINUX_ID_FILE} && echo \$ID"
+ OUTPUT_VARIABLE LINUX_ID
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ execute_process(
+ COMMAND bash -c "if strings \"${CMAKE_SYSROOT}/usr/bin/ldd\" 2>&1 | grep -q musl; then echo musl; fi"
+ OUTPUT_VARIABLE LINUX_MUSL
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ endif()
+
+ if(DEFINED LINUX_ID)
+ if(LINUX_ID STREQUAL alpine)
+ set(HOST_ALPINE_LINUX 1)
+ endif()
+
+ if(LINUX_MUSL STREQUAL musl)
+ set(HOST_LINUX_MUSL 1)
+ endif()
+ endif(DEFINED LINUX_ID)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
set(HOST_LINUX 1)
add_definitions(-D_GNU_SOURCE -D_REENTRANT)
@@ -784,6 +811,12 @@ if (TARGET_BROWSER)
# sys/errno.h exists, but just emits a warning and includes errno.h
unset(HAVE_SYS_ERRNO_H)
endif()
+
+if(HOST_ALPINE_LINUX)
+ # On Alpine Linux, we need to ensure that the reported stack range for the primary thread is
+ # larger than the initial committed stack size.
+ add_definitions(-DENSURE_PRIMARY_STACK_SIZE)
+endif()
### End of OS specific checks
add_subdirectory(mono)
diff --git a/src/mono/mono.proj b/src/mono/mono.proj
index fb98ffc1896906..83368eefa439ab 100644
--- a/src/mono/mono.proj
+++ b/src/mono/mono.proj
@@ -417,12 +417,18 @@
<_MonoCFLAGS Include="-Wl,--build-id=sha1" />
+ <_MonoCFLAGS Include="-Wno-int-conversion" />
<_MonoCXXFLAGS Include="-Wl,--build-id=sha1" />
<_MonoAOTCFLAGS Include="-Wl,--build-id=sha1" />
+ <_MonoAOTCFLAGS Include="-Wno-int-conversion" />
<_MonoAOTCXXFLAGS Include="-Wl,--build-id=sha1" />
+
+ <_MonoAOTCFLAGS Include="-lucontext" />
+ <_MonoCFLAGS Include="-lucontext" />
+
@@ -500,16 +506,18 @@
darwin-x86_64
windows-x86_64
<_MonoRuntimeFilePath>$(MonoObjDir)out\lib\$(MonoFileName)
- <_LinuxAbi Condition="'$(TargetsAndroid)' != 'true'">gnu
- <_LinuxAbi Condition="'$(TargetsAndroid)' == 'true'">android
+ <_LinuxAbi Condition="'$(TargetsAndroid)' != 'true' and '$(TargetsLinuxMusl)' != 'true'">linux-gnu
+ <_LinuxAbi Condition="'$(TargetsAndroid)' != 'true' and '$(TargetsLinuxMusl)' == 'true'">alpine-linux-musl
+ <_LinuxAbi Condition="'$(TargetsAndroid)' == 'true'">linux-android
<_LinuxFloatAbi Condition="'$(TargetsAndroid)' != 'true'">hf
<_Objcopy>objcopy
- <_Objcopy Condition="'$(Platform)' == 'arm'">arm-linux-$(_LinuxAbi)eabi$(_LinuxFloatAbi)-$(_Objcopy)
- <_Objcopy Condition="'$(Platform)' == 'arm64'">aarch64-linux-$(_LinuxAbi)-$(_Objcopy)
- <_Objcopy Condition="'$(Platform)' == 's390x'">s390x-linux-$(_LinuxAbi)-$(_Objcopy)
- <_Objcopy Condition="'$(Platform)' == 'x64'">x86_64-linux-$(_LinuxAbi)-$(_Objcopy)
- <_Objcopy Condition="'$(Platform)' == 'x86'">i686-linux-$(_LinuxAbi)-$(_Objcopy)
+ <_Objcopy Condition="'$(Platform)' == 'arm'">arm-$(_LinuxAbi)eabi$(_LinuxFloatAbi)-$(_Objcopy)
+ <_Objcopy Condition="'$(Platform)' == 'arm64'">aarch64-$(_LinuxAbi)-$(_Objcopy)
+ <_Objcopy Condition="'$(Platform)' == 's390x'">s390x-$(_LinuxAbi)-$(_Objcopy)
+ <_Objcopy Condition="'$(Platform)' == 'x64'">x86_64-$(_LinuxAbi)-$(_Objcopy)
+ <_Objcopy Condition="'$(Platform)' == 'x86'">i686-$(_LinuxAbi)-$(_Objcopy)
<_Objcopy Condition="'$(TargetsAndroid)' == 'true'">$(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/$(MonoToolchainPrebuiltOS)/bin/$(_Objcopy)
+ <_Objcopy Condition="'$(TargetsLinuxMusl)' == 'true' and '$(CrossBuild)' != 'true'">objcopy
diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c
index 812a8348c5f438..20a8377c1f5dc8 100644
--- a/src/mono/mono/mini/mini-runtime.c
+++ b/src/mono/mono/mini/mini-runtime.c
@@ -4313,6 +4313,30 @@ mini_llvm_init (void)
#endif
}
+#ifdef ENSURE_PRIMARY_STACK_SIZE
+/*++
+ Function:
+ EnsureStackSize
+
+ Abstract:
+ This fixes a problem on MUSL where the initial stack size reported by the
+ pthread_attr_getstack is about 128kB, but this limit is not fixed and
+ the stack can grow dynamically. The problem is that it makes the
+ functions ReflectionInvocation::[Try]EnsureSufficientExecutionStack
+ to fail for real life scenarios like e.g. compilation of corefx.
+ Since there is no real fixed limit for the stack, the code below
+ ensures moving the stack limit to a value that makes reasonable
+ real life scenarios work.
+
+ --*/
+static MONO_NO_OPTIMIZATION MONO_NEVER_INLINE void
+ensure_stack_size (size_t size)
+{
+ volatile uint8_t *s = (uint8_t *)g_alloca(size);
+ *s = 0;
+}
+#endif // ENSURE_PRIMARY_STACK_SIZE
+
void
mini_add_profiler_argument (const char *desc)
{
@@ -4468,6 +4492,11 @@ mini_init (const char *filename, const char *runtime_version)
mono_w32handle_init ();
#endif
+#ifdef ENSURE_PRIMARY_STACK_SIZE
+ // TODO: https://github.com/dotnet/runtime/issues/72920
+ ensure_stack_size (5 * 1024 * 1024);
+#endif // ENSURE_PRIMARY_STACK_SIZE
+
mono_thread_info_runtime_init (&ticallbacks);
if (g_hasenv ("MONO_DEBUG")) {
diff --git a/src/mono/mono/utils/mono-context.h b/src/mono/mono/utils/mono-context.h
index bd1a3cd0104c2a..db4ba452bcb070 100644
--- a/src/mono/mono/utils/mono-context.h
+++ b/src/mono/mono/utils/mono-context.h
@@ -11,6 +11,14 @@
#ifndef __MONO_MONO_CONTEXT_H__
#define __MONO_MONO_CONTEXT_H__
+/*
+ * Handle non-gnu libc versions with nothing in features.h
+ * We have no idea what they're compatible with, so always fail.
+ */
+#ifndef __GLIBC_PREREQ
+# define __GLIBC_PREREQ(x,y) 0
+#endif
+
#include "mono-compiler.h"
#include "mono-sigcontext.h"
#include "mono-machine.h"