diff --git a/Directory.Build.props b/Directory.Build.props
index f79e516b4e36d..da0e850f98b5e 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -154,7 +154,7 @@
<_runtimeOS Condition="'$(TargetsMobile)' == 'true'">$(TargetOS.ToLowerInvariant())
<_portableOS>linux
- <_portableOS Condition="'$(_runtimeOS)' == 'linux-musl'">linux-musl
+ <_portableOS Condition="'$(_runtimeOS)' == 'linux-musl' or $(_runtimeOS.StartsWith('alpine'))">linux-musl
<_portableOS Condition="'$(_runtimeOS)' == 'linux-bionic'">linux-bionic
<_portableOS Condition="'$(_hostOS)' == 'OSX'">osx
<_portableOS Condition="'$(_runtimeOS)' == 'win' or '$(TargetOS)' == 'windows'">win
@@ -207,6 +207,7 @@
$(PackageRID)
$(_portableOS)-$(TargetArchitecture)
true
+ true
diff --git a/eng/native/tryrun.cmake b/eng/native/tryrun.cmake
index 6355b0988f7ca..056c6606b17a4 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 d9726460ccfe4..c28563f86197f 100644
--- a/src/coreclr/pal/src/CMakeLists.txt
+++ b/src/coreclr/pal/src/CMakeLists.txt
@@ -315,6 +315,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 8d7f79ed3f08b..043939ad2da28 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 811c84a140d32..4e958a44b30d5 100644
--- a/src/coreclr/vm/i386/cgenx86.cpp
+++ b/src/coreclr/vm/i386/cgenx86.cpp
@@ -1133,6 +1133,7 @@ extern "C" DWORD __stdcall avx512StateSupport()
#else // !TARGET_UNIX
+#if !__has_builtin(__cpuid)
void __cpuid(int cpuInfo[4], int function_id)
{
// Based on the Clang implementation provided in cpuid.h:
@@ -1143,7 +1144,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:
@@ -1154,6 +1157,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 cdff32677c0f5..08a82cd7e835d 100644
--- a/src/mono/CMakeLists.txt
+++ b/src/mono/CMakeLists.txt
@@ -216,6 +216,35 @@ 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
+ # TODO: Eventually merge with eng/native/configureplatform.cmake
+ 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 CLR_CMAKE_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 CLR_CMAKE_LINUX_MUSL
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ endif()
+
+ if(DEFINED CLR_CMAKE_LINUX_ID)
+ if(CLR_CMAKE_LINUX_ID STREQUAL alpine)
+ set(CLR_CMAKE_HOST_ALPINE_LINUX 1)
+ set(CLR_CMAKE_HOST_OS ${CLR_CMAKE_LINUX_ID})
+ endif()
+
+ if(CLR_CMAKE_LINUX_MUSL STREQUAL musl)
+ set(CLR_CMAKE_HOST_LINUX_MUSL 1)
+ endif()
+ endif(DEFINED CLR_CMAKE_LINUX_ID)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
set(HOST_LINUX 1)
add_definitions(-D_GNU_SOURCE -D_REENTRANT)
@@ -893,6 +922,12 @@ if(HOST_IOS OR HOST_ANDROID OR HOST_MACCAT)
else()
set(DISABLE_DLLMAP 1)
endif()
+
+if(CLR_CMAKE_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 59fea4a2f72e1..5bac7fdf1c656 100644
--- a/src/mono/mono.proj
+++ b/src/mono/mono.proj
@@ -554,19 +554,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/CMakeLists.txt b/src/mono/mono/mini/CMakeLists.txt
index 30df4bac1f779..1133e420fa977 100644
--- a/src/mono/mono/mini/CMakeLists.txt
+++ b/src/mono/mono/mini/CMakeLists.txt
@@ -373,6 +373,10 @@ if(NOT DISABLE_SHARED_LIBS)
target_compile_definitions(monosgen-objects PRIVATE -DMONO_DLL_EXPORT)
endif()
target_sources(monosgen-shared PRIVATE $)
+ # Alpine Linux implements ucontext in a different library
+ if(CLR_CMAKE_HOST_ALPINE_LINUX AND TARGET_S390X)
+ target_link_libraries(monosgen-shared PRIVATE ucontext)
+ endif(CLR_CMAKE_HOST_ALPINE_LINUX AND TARGET_S390X)
set_target_properties(monosgen-shared PROPERTIES OUTPUT_NAME ${MONO_SHARED_LIB_NAME})
target_link_libraries (monosgen-shared PRIVATE monoapi)
target_include_directories (monosgen-shared PRIVATE monoapi)
@@ -534,6 +538,10 @@ if(NOT DISABLE_EXECUTABLES)
set_target_properties(mono-sgen PROPERTIES OUTPUT_NAME mono-aot-cross)
endif()
target_link_libraries(mono-sgen PRIVATE monoapi monosgen-static ${OS_LIBS} ${LLVM_LIBS} ${ICU_LIBS} ${Z_LIBS})
+ # Alpine Linux implements ucontext in a different library
+ if(CLR_CMAKE_HOST_ALPINE_LINUX AND TARGET_S390X)
+ target_link_libraries(mono-sgen PRIVATE ucontext)
+ endif(CLR_CMAKE_HOST_ALPINE_LINUX AND TARGET_S390X)
if(NOT DISABLE_COMPONENTS AND STATIC_COMPONENTS AND NOT DISABLE_LINK_STATIC_COMPONENTS)
# if components are built statically, link them into runtime.
target_sources(mono-sgen PRIVATE "${mono-components-objects}")
diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c
index c481f69adc8cd..4db6c9a0ae73d 100644
--- a/src/mono/mono/mini/mini-runtime.c
+++ b/src/mono/mono/mini/mini-runtime.c
@@ -4383,6 +4383,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)
{
@@ -4544,6 +4568,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 a1f0fe6f68e4d..a9db2d336ca5c 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 0929a0b49ecf4..86311e1950758 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