diff --git a/Directory.Build.props b/Directory.Build.props
index ce67527ff8ed12..a59e2b8707d211 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -22,7 +22,6 @@
$(_hostOS)
true
true
- true
@@ -200,6 +199,9 @@
$(PackageRID)
$(_portableOS)-$(TargetArchitecture)
+
+ true
+ true
diff --git a/eng/native/tryrun.cmake b/eng/native/tryrun.cmake
index 5c5344bd80161c..545013f6c7d556 100644
--- a/eng/native/tryrun.cmake
+++ b/eng/native/tryrun.cmake
@@ -8,7 +8,11 @@ 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/ppc64le-alpine-linux-musl OR
+ EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/i586-alpine-linux-musl OR
+ EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/riscv64-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 1315dac0cb1b94..553b54971dd0b0 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 and ppc64le
+ if(CLR_CMAKE_TARGET_ALPINE_LINUX AND (CLR_CMAKE_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_POWERPC64))
+ target_link_libraries(coreclrpal ucontext)
+ endif(CLR_CMAKE_TARGET_ALPINE_LINUX AND (CLR_CMAKE_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_POWERPC64))
+
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 cc8d46ef1caa49..f7d43b5cef5af4 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 356dab119f78b0..48d9d107f9f16f 100644
--- a/src/coreclr/vm/i386/cgenx86.cpp
+++ b/src/coreclr/vm/i386/cgenx86.cpp
@@ -1108,6 +1108,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:
@@ -1118,7 +1119,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:
@@ -1129,6 +1132,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 6dbf542183bcdc..85c7f3c511c1fd 100644
--- a/src/mono/CMakeLists.txt
+++ b/src/mono/CMakeLists.txt
@@ -219,6 +219,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)
@@ -899,6 +926,12 @@ if(HOST_IOS OR HOST_ANDROID OR HOST_MACCAT)
else()
set(DISABLE_DLLMAP 1)
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
include_directories("${CLR_SRC_NATIVE_DIR}")
diff --git a/src/mono/mono.proj b/src/mono/mono.proj
index 38731e968660a5..f71c8eb7ced814 100644
--- a/src/mono/mono.proj
+++ b/src/mono/mono.proj
@@ -464,12 +464,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" />
+
@@ -554,19 +560,21 @@
darwin-x86_64
windows-x86_64
<_MonoRuntimeFilePath>$(MonoObjDir)out\lib\$(MonoFileName)
- <_LinuxAbi Condition="'$(TargetsAndroid)' != 'true' and '$(TargetsLinuxBionic)' != 'true'">gnu
- <_LinuxAbi Condition="'$(TargetsAndroid)' == 'true' or '$(TargetsLinuxBionic)' == 'true'">android
+ <_LinuxAbi Condition="'$(TargetsAndroid)' != 'true' and '$(TargetsLinuxBionic)' != 'true' and '$(TargetsLinuxMusl)' != 'true'">linux-gnu
+ <_LinuxAbi Condition="'$(TargetsAndroid)' != 'true' and '$(TargetsLinuxBionic)' != 'true' and '$(TargetsLinuxMusl)' == 'true'">alpine-linux-musl
+ <_LinuxAbi Condition="'$(TargetsAndroid)' == 'true' or '$(TargetsLinuxBionic)' == 'true'">linux-android
<_LinuxFloatAbi Condition="'$(TargetsAndroid)' != 'true' and '$(TargetsLinuxBionic)' != 'true'">hf
<_Objcopy>objcopy
- <_Objcopy Condition="'$(Platform)' == 'arm'">arm-linux-$(_LinuxAbi)eabi$(_LinuxFloatAbi)-$(_Objcopy)
- <_Objcopy Condition="'$(Platform)' == 'armv6'">arm-linux-$(_LinuxAbi)eabi$(_LinuxFloatAbi)-$(_Objcopy)
- <_Objcopy Condition="'$(Platform)' == 'arm64'">aarch64-linux-$(_LinuxAbi)-$(_Objcopy)
- <_Objcopy Condition="'$(Platform)' == 'riscv64'">riscv64-linux-$(_LinuxAbi)-$(_Objcopy)
- <_Objcopy Condition="'$(Platform)' == 's390x'">s390x-linux-$(_LinuxAbi)-$(_Objcopy)
- <_Objcopy Condition="'$(Platform)' == 'ppc64le'">powerpc64le-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)' == 'armv6'">arm-$(_LinuxAbi)eabi$(_LinuxFloatAbi)-$(_Objcopy)
+ <_Objcopy Condition="'$(Platform)' == 'arm64'">aarch64-$(_LinuxAbi)-$(_Objcopy)
+ <_Objcopy Condition="'$(Platform)' == 'riscv64'">riscv64-$(_LinuxAbi)-$(_Objcopy)
+ <_Objcopy Condition="'$(Platform)' == 's390x'">s390x-$(_LinuxAbi)-$(_Objcopy)
+ <_Objcopy Condition="'$(Platform)' == 'ppc64le'">powerpc64le-$(_LinuxAbi)-$(_Objcopy)
+ <_Objcopy Condition="'$(Platform)' == 'x64'">x86_64-$(_LinuxAbi)-$(_Objcopy)
+ <_Objcopy Condition="'$(Platform)' == 'x86'">i686-$(_LinuxAbi)-$(_Objcopy)
<_Objcopy Condition="'$(TargetsAndroid)' == 'true' or '$(TargetsLinuxBionic)' == 'true'">$(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/$(MonoToolchainPrebuiltOS)/bin/llvm-objcopy
+ <_Objcopy Condition="'$(TargetsLinuxMusl)' == 'true' and '$(CrossBuild)' != 'true'">objcopy
<_ObjcopyPrefix Condition="'$(MonoCrossDir)' != '' and '$(Platform)' == 'riscv64'">llvm-objcopy-
diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c
index 5aa0502bc0800e..bedfff92c4be28 100644
--- a/src/mono/mono/mini/mini-runtime.c
+++ b/src/mono/mono/mini/mini-runtime.c
@@ -4408,6 +4408,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)
{
@@ -4565,6 +4589,11 @@ mini_init (const char *filename)
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 a1f0fe6f68e4d1..a9db2d336ca5ca 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"
diff --git a/src/native/libs/System.Native/pal_io.c b/src/native/libs/System.Native/pal_io.c
index 7f775ff88697c7..d211328f714ddb 100644
--- a/src/native/libs/System.Native/pal_io.c
+++ b/src/native/libs/System.Native/pal_io.c
@@ -1267,7 +1267,7 @@ int32_t SystemNative_CopyFile(intptr_t sourceFd, intptr_t destinationFd, int64_t
// Try copying data using a copy-on-write clone. This shares storage between the files.
if (sourceLength != 0)
{
- while ((ret = ioctl(outFd, FICLONE, inFd)) < 0 && errno == EINTR);
+ while ((ret = ioctl(outFd, (int)FICLONE, inFd)) < 0 && errno == EINTR);
copied = ret == 0;
}
#endif