From 0662f82b5f21c16522622c07f2c79d464793dbc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Mon, 28 Sep 2026 16:38:32 +0900 Subject: [PATCH 1/7] Enable NativeAOT runtime builds for Browser and WASI The general shape of the bring-up matches the approach in https://github.com/dotnet/runtime/pull/126633. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 82b79dc1-18fc-4c04-9748-ea5b7ff3dc0b --- eng/Subsets.props | 2 +- src/coreclr/CMakeLists.txt | 4 +-- src/coreclr/gc/env/gcenv.base.h | 4 +-- src/coreclr/nativeaot/Runtime/AsmOffsets.h | 4 +++ src/coreclr/nativeaot/Runtime/CMakeLists.txt | 14 +++++++++ .../nativeaot/Runtime/Portable/CMakeLists.txt | 14 +++++++-- .../nativeaot/Runtime/StackFrameIterator.cpp | 4 +++ .../nativeaot/Runtime/inc/CommonTypes.h | 4 +-- src/coreclr/nativeaot/Runtime/thread.cpp | 4 ++- .../nativeaot/Runtime/unix/NativeContext.h | 3 ++ .../nativeaot/Runtime/unix/PalCreateDump.h | 2 ++ .../nativeaot/Runtime/unix/PalUnix.cpp | 4 ++- .../nativeaot/Runtime/unix/UnixSignals.h | 2 ++ .../nativeaot/Runtime/wasm/AsmOffsetsCpu.h | 31 +++++++++++++++++++ .../nativeaot/Runtime/wasm/PalCreateDump.cpp | 18 +++++++++++ 15 files changed, 102 insertions(+), 12 deletions(-) create mode 100644 src/coreclr/nativeaot/Runtime/wasm/AsmOffsetsCpu.h create mode 100644 src/coreclr/nativeaot/Runtime/wasm/PalCreateDump.cpp diff --git a/eng/Subsets.props b/eng/Subsets.props index 874f666820ee5b..a6b04e2beaaa05 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -359,7 +359,7 @@ $(ClrRuntimeBuildSubsets);ClrCdacSubset=true - + $(ClrRuntimeBuildSubsets);ClrNativeAotSubset=true diff --git a/src/coreclr/CMakeLists.txt b/src/coreclr/CMakeLists.txt index 483f6caee6a365..619f7ae0426f52 100644 --- a/src/coreclr/CMakeLists.txt +++ b/src/coreclr/CMakeLists.txt @@ -177,9 +177,7 @@ if ((NOT CLR_CMAKE_TARGET_BROWSER AND NOT CLR_CMAKE_TARGET_WASI) OR CLR_CROSS_CO endif () if(NOT CLR_CROSS_COMPONENTS_BUILD) - if(NOT CLR_CMAKE_HOST_ARCH_WASM) - add_subdirectory(nativeaot) - endif() + add_subdirectory(nativeaot) endif(NOT CLR_CROSS_COMPONENTS_BUILD) # Above projects do not build with these compile options diff --git a/src/coreclr/gc/env/gcenv.base.h b/src/coreclr/gc/env/gcenv.base.h index 02f8863b640869..04ed51a495aeff 100644 --- a/src/coreclr/gc/env/gcenv.base.h +++ b/src/coreclr/gc/env/gcenv.base.h @@ -188,10 +188,10 @@ typedef DWORD (WINAPI *PTHREAD_START_ROUTINE)(void* lpThreadParameter); #define MemoryBarrier __sync_synchronize #endif // __riscv -#ifdef HOST_BROWSER +#ifdef HOST_WASM #define YieldProcessor() #define MemoryBarrier __sync_synchronize -#endif // HOST_BROWSER +#endif // HOST_WASM #endif // _MSC_VER diff --git a/src/coreclr/nativeaot/Runtime/AsmOffsets.h b/src/coreclr/nativeaot/Runtime/AsmOffsets.h index c46652f53fc843..47712c532c6e7f 100644 --- a/src/coreclr/nativeaot/Runtime/AsmOffsets.h +++ b/src/coreclr/nativeaot/Runtime/AsmOffsets.h @@ -52,11 +52,15 @@ ASM_OFFSET( 0, 0, Thread, m_eeAllocContext) ASM_OFFSET( 2c, 40, Thread, m_ThreadStateFlags) ASM_OFFSET( 30, 48, Thread, m_pTransitionFrame) ASM_OFFSET( 34, 50, Thread, m_pDeferredTransitionFrame) +#ifdef FEATURE_HIJACK ASM_OFFSET( 40, 68, Thread, m_ppvHijackedReturnAddressLocation) ASM_OFFSET( 44, 70, Thread, m_pvHijackedReturnAddress) +#endif // FEATURE_HIJACK #if defined(TARGET_ARM64) ASM_OFFSET( 48, 78, Thread, m_pSpForPacSign) ASM_OFFSET( 4c, 80, Thread, m_pExInfoStackHead) +#elif defined(TARGET_WASM) +ASM_OFFSET( 40, FF, Thread, m_pExInfoStackHead) #else ASM_OFFSET( 48, 78, Thread, m_pExInfoStackHead) #endif diff --git a/src/coreclr/nativeaot/Runtime/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/CMakeLists.txt index 9c8b9ed1be4298..68f393da212099 100644 --- a/src/coreclr/nativeaot/Runtime/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/CMakeLists.txt @@ -215,6 +215,20 @@ else() unix/UnixNativeCodeManager.cpp ) + if(CLR_CMAKE_TARGET_ARCH_WASM) + list(REMOVE_ITEM COMMON_RUNTIME_SOURCES + unix/PalCreateDump.cpp + ${GC_DIR}/unix/gcenv.unix.cpp + ${GC_DIR}/unix/numasupport.cpp + ${GC_DIR}/unix/cgroup.cpp + ) + list(APPEND COMMON_RUNTIME_SOURCES + wasm/PalCreateDump.cpp + ${GC_DIR}/wasm/gcenv.cpp + ) + include_directories(${GC_DIR}/unix) + endif() + include(${CLR_SRC_NATIVE_DIR}/external/llvm-libunwind.cmake) set(NATIVEAOT_LOCALIZE_LIBUNWIND_SYMBOLS OFF) diff --git a/src/coreclr/nativeaot/Runtime/Portable/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/Portable/CMakeLists.txt index d24a892a035bbd..8e0fffeda0af5d 100644 --- a/src/coreclr/nativeaot/Runtime/Portable/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/Portable/CMakeLists.txt @@ -5,9 +5,18 @@ project(PortableRuntime) add_definitions(-DFEATURE_PORTABLE_HELPERS) -add_library(PortableRuntime STATIC ${COMMON_RUNTIME_SOURCES} ${PORTABLE_RUNTIME_SOURCES}) +add_library(Runtime.GC.Workstation OBJECT ${GC_WKS_SVR_SOURCES}) +set_target_properties(Runtime.GC.Workstation PROPERTIES UNITY_BUILD ON UNITY_BUILD_BATCH_SIZE 0) + +add_library(PortableRuntime STATIC + ${COMMON_RUNTIME_SOURCES} + ${PORTABLE_RUNTIME_SOURCES} + ${NATIVEAOT_RUNTIME_DIR}/AsmOffsetsVerify.cpp + $) target_link_libraries(PortableRuntime PRIVATE aotminipal) +add_library(standalonegc-disabled STATIC ${STANDALONEGC_DISABLED_SOURCES}) + # Get the current list of definitions get_compile_definitions(DEFINITIONS) set(ASM_OFFSETS_CSPP ${NATIVEAOT_RUNTIME_DIR}/../Runtime.Base/src/AsmOffsets.cspp) @@ -29,9 +38,10 @@ endif() add_custom_command( # The AsmOffsetsPortable.cs is consumed later by the managed build TARGET PortableRuntime + POST_BUILD COMMAND ${CMAKE_CXX_COMPILER} ${COMPILER_LANGUAGE} ${DEFINITIONS} ${PREPROCESSOR_FLAGS} -I"${ARCH_SOURCES_DIR}" "${ASM_OFFSETS_CSPP}" >"${CMAKE_CURRENT_BINARY_DIR}/AsmOffsetsPortable.cs" - DEPENDS "${NATIVEAOT_RUNTIME_DIR}/AsmOffsets.cpp" "${NATIVEAOT_RUNTIME_DIR}/AsmOffsets.h" ) install_static_library(PortableRuntime aotsdk nativeaot) +install_static_library(standalonegc-disabled aotsdk nativeaot) install_static_library(aotminipal aotsdk nativeaot) diff --git a/src/coreclr/nativeaot/Runtime/StackFrameIterator.cpp b/src/coreclr/nativeaot/Runtime/StackFrameIterator.cpp index 7a6a45d76a33b4..80b16788e0864c 100644 --- a/src/coreclr/nativeaot/Runtime/StackFrameIterator.cpp +++ b/src/coreclr/nativeaot/Runtime/StackFrameIterator.cpp @@ -633,6 +633,9 @@ void StackFrameIterator::InternalInit(Thread * pThreadToWalk, PTR_PAL_LIMITED_CO // thunks report a conservative range). void StackFrameIterator::InternalInit(Thread * pThreadToWalk, NATIVE_CONTEXT* pCtx, uint32_t dwFlags) { +#ifdef HOST_WASM + PORTABILITY_ASSERT("StackFrameIterator::InternalInit with native context"); +#else ASSERT((dwFlags & MethodStateCalculated) == 0); EnterInitialInvalidState(pThreadToWalk); @@ -854,6 +857,7 @@ void StackFrameIterator::InternalInit(Thread * pThreadToWalk, NATIVE_CONTEXT* pC // adjust for thunks, if needed EnsureInitializedToManagedFrame(); +#endif // HOST_WASM } void StackFrameIterator::EnsureInitializedToManagedFrame() diff --git a/src/coreclr/nativeaot/Runtime/inc/CommonTypes.h b/src/coreclr/nativeaot/Runtime/inc/CommonTypes.h index 7776c909c9457b..54e3de82497b97 100644 --- a/src/coreclr/nativeaot/Runtime/inc/CommonTypes.h +++ b/src/coreclr/nativeaot/Runtime/inc/CommonTypes.h @@ -44,7 +44,7 @@ typedef uint32_t UInt32_BOOL; // windows 4-byte BOOL, 0 -> false, #define UInt32_FALSE 0 #define UInt32_TRUE 1 -#if defined(FEATURE_EVENT_TRACE) && defined(TARGET_UNIX) +#if (defined(FEATURE_EVENT_TRACE) && defined(TARGET_UNIX)) || defined(TARGET_WASM) typedef int BOOL; typedef void* LPVOID; typedef uint32_t UINT; @@ -55,7 +55,7 @@ typedef uint32_t ULONG; typedef int64_t LONGLONG; typedef uint8_t BYTE; typedef uint16_t UINT16; -#endif // FEATURE_EVENT_TRACE && TARGET_UNIX +#endif // (FEATURE_EVENT_TRACE && TARGET_UNIX) || TARGET_WASM // Hijack funcs are not called, they are "returned to". And when done, they return to the actual caller. // Thus they cannot have any parameters or return anything. diff --git a/src/coreclr/nativeaot/Runtime/thread.cpp b/src/coreclr/nativeaot/Runtime/thread.cpp index 938eb4ad84087a..bd0552cd9c89fe 100644 --- a/src/coreclr/nativeaot/Runtime/thread.cpp +++ b/src/coreclr/nativeaot/Runtime/thread.cpp @@ -416,7 +416,7 @@ void Thread::Destroy() extern OBJECTREF * t_pShadowStackTop; extern OBJECTREF * t_pShadowStackBottom; -void GcScanWasmShadowStack(void * pfnEnumCallback, void * pvCallbackData) +void GcScanWasmShadowStack(ScanFunc* pfnEnumCallback, ScanContext* pvCallbackData) { // Wasm does not permit iteration of stack frames so is uses a shadow stack instead EnumGcRefsInRegionConservatively(t_pShadowStackBottom, t_pShadowStackTop, pfnEnumCallback, pvCallbackData); @@ -472,6 +472,7 @@ bool Thread::GcScanRoots(GcScanRootsCallbackFunc * pfnEnumCallback, void * token } #endif //DACCESS_COMPILE +#ifndef TARGET_WASM void Thread::GcScanRootsWorker(ScanFunc * pfnEnumCallback, ScanContext * pvCallbackData, StackFrameIterator & frameIterator) { PTR_OBJECTREF pHijackedReturnValue = NULL; @@ -594,6 +595,7 @@ void Thread::GcScanRootsWorker(ScanFunc * pfnEnumCallback, ScanContext * pvCallb } } } +#endif // !TARGET_WASM #ifndef DACCESS_COMPILE diff --git a/src/coreclr/nativeaot/Runtime/unix/NativeContext.h b/src/coreclr/nativeaot/Runtime/unix/NativeContext.h index 6edfca16e63b13..1def1222f57f8d 100644 --- a/src/coreclr/nativeaot/Runtime/unix/NativeContext.h +++ b/src/coreclr/nativeaot/Runtime/unix/NativeContext.h @@ -4,6 +4,8 @@ #ifndef __NATIVE_CONTEXT_H__ #define __NATIVE_CONTEXT_H__ +#ifndef HOST_WASM + #if HAVE_UCONTEXT_H #include #else @@ -277,4 +279,5 @@ struct NATIVE_CONTEXT #endif // TARGET_ARM }; +#endif // !HOST_WASM #endif // __NATIVE_CONTEXT_H__ diff --git a/src/coreclr/nativeaot/Runtime/unix/PalCreateDump.h b/src/coreclr/nativeaot/Runtime/unix/PalCreateDump.h index 0487a13c218605..1c5a16fc02ba75 100644 --- a/src/coreclr/nativeaot/Runtime/unix/PalCreateDump.h +++ b/src/coreclr/nativeaot/Runtime/unix/PalCreateDump.h @@ -7,5 +7,7 @@ extern bool PalCreateDumpInitialize(); extern void PalCreateCrashDumpIfEnabled(); +#ifndef HOST_WASM extern void PalCreateCrashDumpIfEnabled(int signal, siginfo_t* siginfo = nullptr, void* context = nullptr, void* exceptionRecord = nullptr); +#endif // !HOST_WASM extern void PalCreateCrashDumpIfEnabled(void* pExceptionRecord); diff --git a/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp b/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp index 7dc06b8dd705b5..3f5db5c92f2b42 100644 --- a/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp +++ b/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp @@ -187,12 +187,14 @@ void PalGetPDBInfo(HANDLE hOsHandle, GUID * pGuidSignature, _Out_ uint32_t * pdw static void UnmaskActivationSignal() { +#ifndef HOST_WASM sigset_t signal_set; sigemptyset(&signal_set); sigaddset(&signal_set, INJECT_ACTIVATION_SIGNAL); int sigmaskRet = pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL); _ASSERTE(sigmaskRet == 0); +#endif // !HOST_WASM } // This functions configures behavior of the signals that are not @@ -703,7 +705,7 @@ void PalFlushInstructionCache(_In_ void* pAddress, size_t size) } #elif (defined(HOST_MACCATALYST) || defined(HOST_IOS) || defined(HOST_TVOS)) && defined(HOST_ARM64) sys_icache_invalidate (pAddress, size); -#else +#elif !defined(HOST_WASM) __builtin___clear_cache((char *)pAddress, (char *)pAddress + size); #endif } diff --git a/src/coreclr/nativeaot/Runtime/unix/UnixSignals.h b/src/coreclr/nativeaot/Runtime/unix/UnixSignals.h index 60e08d461e3830..a5193230778627 100644 --- a/src/coreclr/nativeaot/Runtime/unix/UnixSignals.h +++ b/src/coreclr/nativeaot/Runtime/unix/UnixSignals.h @@ -12,9 +12,11 @@ #define INJECT_ACTIVATION_SIGNAL SIGUSR1 #endif +#ifndef TARGET_WASI typedef void (*SignalHandler)(int code, siginfo_t* siginfo, void* context); bool AddSignalHandler(int signal, SignalHandler handler, struct sigaction* previousAction); +#endif // !TARGET_WASI void RestoreSignalHandler(int signal_id, struct sigaction* previousAction); #endif // __UNIX_SIGNALS_H__ diff --git a/src/coreclr/nativeaot/Runtime/wasm/AsmOffsetsCpu.h b/src/coreclr/nativeaot/Runtime/wasm/AsmOffsetsCpu.h new file mode 100644 index 00000000000000..ac96ed43f0df1e --- /dev/null +++ b/src/coreclr/nativeaot/Runtime/wasm/AsmOffsetsCpu.h @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// +// This file is used by AsmOffsets.h to validate that our +// assembly-code offsets always match their C++ counterparts. +// +// NOTE: the offsets MUST be in hex notation WITHOUT the 0x prefix + +PLAT_ASM_SIZEOF(98, ExInfo) +PLAT_ASM_OFFSET(0, ExInfo, m_pPrevExInfo) +PLAT_ASM_OFFSET(4, ExInfo, m_pExContext) +PLAT_ASM_OFFSET(8, ExInfo, m_exception) +PLAT_ASM_OFFSET(0c, ExInfo, m_kind) +PLAT_ASM_OFFSET(0d, ExInfo, m_passNumber) +PLAT_ASM_OFFSET(10, ExInfo, m_idxCurClause) +PLAT_ASM_OFFSET(14, ExInfo, m_frameIter) +PLAT_ASM_OFFSET(94, ExInfo, m_notifyDebuggerSP) + +PLAT_ASM_SIZEOF(80, StackFrameIterator) +PLAT_ASM_OFFSET(08, StackFrameIterator, m_FramePointer) +PLAT_ASM_OFFSET(0c, StackFrameIterator, m_ControlPC) +PLAT_ASM_OFFSET(10, StackFrameIterator, m_RegDisplay) +PLAT_ASM_OFFSET(78, StackFrameIterator, m_OriginalControlPC) +PLAT_ASM_OFFSET(7c, StackFrameIterator, m_pPreviousTransitionFrame) + +PLAT_ASM_SIZEOF(4, PAL_LIMITED_CONTEXT) +PLAT_ASM_OFFSET(0, PAL_LIMITED_CONTEXT, IP) + +PLAT_ASM_SIZEOF(8, REGDISPLAY) +PLAT_ASM_OFFSET(0, REGDISPLAY, SP) diff --git a/src/coreclr/nativeaot/Runtime/wasm/PalCreateDump.cpp b/src/coreclr/nativeaot/Runtime/wasm/PalCreateDump.cpp new file mode 100644 index 00000000000000..6517b992438aab --- /dev/null +++ b/src/coreclr/nativeaot/Runtime/wasm/PalCreateDump.cpp @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "PalCreateDump.h" + +// WebAssembly does not support crash dumps. +void PalCreateCrashDumpIfEnabled() +{ +} + +void PalCreateCrashDumpIfEnabled(void* pExceptionRecord) +{ +} + +bool PalCreateDumpInitialize() +{ + return true; +} From 1514031d8d8fdbf04bed7d6c264285b7bb090f9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Mon, 28 Sep 2026 16:43:18 +0900 Subject: [PATCH 2/7] Use shared Unix crash dump handling for NativeAOT on WASM Match CoreCLR by skipping dump initialization and disabling process-based dump creation on WebAssembly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 82b79dc1-18fc-4c04-9748-ea5b7ff3dc0b --- src/coreclr/nativeaot/Runtime/CMakeLists.txt | 2 -- .../nativeaot/Runtime/unix/PalCreateDump.cpp | 16 ++++++++++++++-- src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp | 2 ++ .../nativeaot/Runtime/wasm/PalCreateDump.cpp | 18 ------------------ 4 files changed, 16 insertions(+), 22 deletions(-) delete mode 100644 src/coreclr/nativeaot/Runtime/wasm/PalCreateDump.cpp diff --git a/src/coreclr/nativeaot/Runtime/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/CMakeLists.txt index 68f393da212099..059d3652e7790b 100644 --- a/src/coreclr/nativeaot/Runtime/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/CMakeLists.txt @@ -217,13 +217,11 @@ else() if(CLR_CMAKE_TARGET_ARCH_WASM) list(REMOVE_ITEM COMMON_RUNTIME_SOURCES - unix/PalCreateDump.cpp ${GC_DIR}/unix/gcenv.unix.cpp ${GC_DIR}/unix/numasupport.cpp ${GC_DIR}/unix/cgroup.cpp ) list(APPEND COMMON_RUNTIME_SOURCES - wasm/PalCreateDump.cpp ${GC_DIR}/wasm/gcenv.cpp ) include_directories(${GC_DIR}/unix) diff --git a/src/coreclr/nativeaot/Runtime/unix/PalCreateDump.cpp b/src/coreclr/nativeaot/Runtime/unix/PalCreateDump.cpp index 13a511eafba58d..6b698a351e56b0 100644 --- a/src/coreclr/nativeaot/Runtime/unix/PalCreateDump.cpp +++ b/src/coreclr/nativeaot/Runtime/unix/PalCreateDump.cpp @@ -20,7 +20,9 @@ #include #include #endif +#ifndef HOST_WASM #include +#endif #include #include #include @@ -207,6 +209,9 @@ CreateCrashDump( char* errorMessageBuffer, int cbErrorMessageBuffer) { +#ifdef HOST_WASM + return false; +#else int pipe_descs[4]; if (pipe(pipe_descs) == -1 || pipe(pipe_descs + 2) == -1) { @@ -343,6 +348,7 @@ CreateCrashDump( } } return true; +#endif // HOST_WASM } #endif // !defined(HOST_MACCATALYST) && !defined(HOST_IOS) && !defined(HOST_TVOS) @@ -374,6 +380,7 @@ static void DoNotOptimize(const void* p) (no return value) --*/ +#ifndef HOST_WASM void PalCreateCrashDumpIfEnabled(int signal, siginfo_t* siginfo, void* context, void* exceptionRecord) { @@ -468,17 +475,22 @@ PalCreateCrashDumpIfEnabled(int signal, siginfo_t* siginfo, void* context, void* } #endif // !defined(HOST_MACCATALYST) && !defined(HOST_IOS) && !defined(HOST_TVOS) } +#endif // !HOST_WASM void PalCreateCrashDumpIfEnabled() { +#ifndef HOST_WASM PalCreateCrashDumpIfEnabled(SIGABRT, nullptr, nullptr, nullptr); +#endif } void PalCreateCrashDumpIfEnabled(void* pExceptionRecord) { +#ifndef HOST_WASM PalCreateCrashDumpIfEnabled(SIGABRT, nullptr, nullptr, pExceptionRecord); +#endif } /*++ @@ -547,7 +559,7 @@ Return bool PalCreateDumpInitialize() { -#if !defined(HOST_MACCATALYST) && !defined(HOST_IOS) && !defined(HOST_TVOS) +#if !defined(HOST_MACCATALYST) && !defined(HOST_IOS) && !defined(HOST_TVOS) && !defined(HOST_WASM) bool enabled = false; RhConfig::Environment::TryGetBooleanValue("DbgEnableMiniDump", &enabled); if (enabled) @@ -657,7 +669,7 @@ PalCreateDumpInitialize() return false; } } -#endif // !defined(HOST_MACCATALYST) && !defined(HOST_IOS) && !defined(HOST_TVOS) +#endif // !defined(HOST_MACCATALYST) && !defined(HOST_IOS) && !defined(HOST_TVOS) && !defined(HOST_WASM) return true; } diff --git a/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp b/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp index 3f5db5c92f2b42..3f6ef57b84a273 100644 --- a/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp +++ b/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp @@ -312,10 +312,12 @@ bool PalInit() ConfigureSignals(); +#ifndef HOST_WASM if (!PalCreateDumpInitialize()) { return false; } +#endif // !HOST_WASM GCConfig::Initialize(); diff --git a/src/coreclr/nativeaot/Runtime/wasm/PalCreateDump.cpp b/src/coreclr/nativeaot/Runtime/wasm/PalCreateDump.cpp deleted file mode 100644 index 6517b992438aab..00000000000000 --- a/src/coreclr/nativeaot/Runtime/wasm/PalCreateDump.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#include "PalCreateDump.h" - -// WebAssembly does not support crash dumps. -void PalCreateCrashDumpIfEnabled() -{ -} - -void PalCreateCrashDumpIfEnabled(void* pExceptionRecord) -{ -} - -bool PalCreateDumpInitialize() -{ - return true; -} From 307c297408cfd77f90f3ffe00ae06274548827bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Mon, 28 Sep 2026 16:50:40 +0900 Subject: [PATCH 3/7] Align NativeAOT WASM platform guards Select WASM and Unix GC sources explicitly, gate activation signal handling on FEATURE_HIJACK, and use the existing no-op crash dump initialization on WASM. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 27009bcd-0b03-42cc-a37a-42d4cfeff5d8 --- src/coreclr/nativeaot/Runtime/CMakeLists.txt | 28 +++++++++---------- .../nativeaot/Runtime/unix/PalUnix.cpp | 10 ++++--- .../nativeaot/Runtime/unix/UnixSignals.h | 2 -- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/CMakeLists.txt index 059d3652e7790b..1f85be71dddf80 100644 --- a/src/coreclr/nativeaot/Runtime/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/CMakeLists.txt @@ -200,12 +200,22 @@ else() ${RUNTIME_DIR}/unix/CLREventBase.cpp unix/PalUnix.cpp unix/PalCreateDump.cpp - ${GC_DIR}/unix/gcenv.unix.cpp - ${GC_DIR}/unix/numasupport.cpp ${GC_DIR}/unix/events.cpp - ${GC_DIR}/unix/cgroup.cpp ) + if(CLR_CMAKE_TARGET_ARCH_WASM) + list(APPEND COMMON_RUNTIME_SOURCES + ${GC_DIR}/wasm/gcenv.cpp + ) + include_directories(${GC_DIR}/unix) + else() + list(APPEND COMMON_RUNTIME_SOURCES + ${GC_DIR}/unix/gcenv.unix.cpp + ${GC_DIR}/unix/numasupport.cpp + ${GC_DIR}/unix/cgroup.cpp + ) + endif() + list(APPEND FULL_RUNTIME_SOURCES unix/cgroupcpu.cpp unix/HardwareExceptions.cpp @@ -215,18 +225,6 @@ else() unix/UnixNativeCodeManager.cpp ) - if(CLR_CMAKE_TARGET_ARCH_WASM) - list(REMOVE_ITEM COMMON_RUNTIME_SOURCES - ${GC_DIR}/unix/gcenv.unix.cpp - ${GC_DIR}/unix/numasupport.cpp - ${GC_DIR}/unix/cgroup.cpp - ) - list(APPEND COMMON_RUNTIME_SOURCES - ${GC_DIR}/wasm/gcenv.cpp - ) - include_directories(${GC_DIR}/unix) - endif() - include(${CLR_SRC_NATIVE_DIR}/external/llvm-libunwind.cmake) set(NATIVEAOT_LOCALIZE_LIBUNWIND_SYMBOLS OFF) diff --git a/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp b/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp index 3f6ef57b84a273..f9fbb67d9d320f 100644 --- a/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp +++ b/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp @@ -16,7 +16,9 @@ #include "gcenv.ee.h" #include "gcconfig.h" #include "holder.h" +#ifdef FEATURE_HIJACK #include "UnixSignals.h" +#endif // FEATURE_HIJACK #include "NativeContext.h" #include "HardwareExceptions.h" #include "PalCreateDump.h" @@ -185,17 +187,17 @@ void PalGetPDBInfo(HANDLE hOsHandle, GUID * pGuidSignature, _Out_ uint32_t * pdw #endif } +#ifdef FEATURE_HIJACK static void UnmaskActivationSignal() { -#ifndef HOST_WASM sigset_t signal_set; sigemptyset(&signal_set); sigaddset(&signal_set, INJECT_ACTIVATION_SIGNAL); int sigmaskRet = pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL); _ASSERTE(sigmaskRet == 0); -#endif // !HOST_WASM } +#endif // FEATURE_HIJACK // This functions configures behavior of the signals that are not // related to hardware exception handling. @@ -312,12 +314,10 @@ bool PalInit() ConfigureSignals(); -#ifndef HOST_WASM if (!PalCreateDumpInitialize()) { return false; } -#endif // !HOST_WASM GCConfig::Initialize(); @@ -387,7 +387,9 @@ void PalAttachThread(void* thread) tls_destructionMonitor.SetThread(thread); #endif +#ifdef FEATURE_HIJACK UnmaskActivationSignal(); +#endif // FEATURE_HIJACK } #if !defined(FEATURE_PORTABLE_HELPERS) && !defined(FEATURE_RX_THUNKS) diff --git a/src/coreclr/nativeaot/Runtime/unix/UnixSignals.h b/src/coreclr/nativeaot/Runtime/unix/UnixSignals.h index a5193230778627..60e08d461e3830 100644 --- a/src/coreclr/nativeaot/Runtime/unix/UnixSignals.h +++ b/src/coreclr/nativeaot/Runtime/unix/UnixSignals.h @@ -12,11 +12,9 @@ #define INJECT_ACTIVATION_SIGNAL SIGUSR1 #endif -#ifndef TARGET_WASI typedef void (*SignalHandler)(int code, siginfo_t* siginfo, void* context); bool AddSignalHandler(int signal, SignalHandler handler, struct sigaction* previousAction); -#endif // !TARGET_WASI void RestoreSignalHandler(int signal_id, struct sigaction* previousAction); #endif // __UNIX_SIGNALS_H__ From 23596b18d8fec9a498b589a9689ccc4e032fd31c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Mon, 28 Sep 2026 17:03:25 +0900 Subject: [PATCH 4/7] Remove LPVOID dependency from PTR_PTR_VOID Define PTR_PTR_VOID using PTR_VOID and restore NativeAOT's event-tracing-only compatibility typedefs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 27009bcd-0b03-42cc-a37a-42d4cfeff5d8 --- src/coreclr/inc/daccess.h | 2 +- src/coreclr/nativeaot/Runtime/inc/CommonTypes.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/coreclr/inc/daccess.h b/src/coreclr/inc/daccess.h index b3f97772c24ef3..a5532de09fdab7 100644 --- a/src/coreclr/inc/daccess.h +++ b/src/coreclr/inc/daccess.h @@ -2129,7 +2129,7 @@ inline void DACCOP_IGNORE(DacCopWarningCode code, const char * szReasonString) typedef uintptr_t TADDR; typedef void* PTR_VOID; -typedef LPVOID* PTR_PTR_VOID; +typedef PTR_VOID* PTR_PTR_VOID; typedef const void* PTR_CVOID; #define DPTR(type) type* diff --git a/src/coreclr/nativeaot/Runtime/inc/CommonTypes.h b/src/coreclr/nativeaot/Runtime/inc/CommonTypes.h index 54e3de82497b97..7776c909c9457b 100644 --- a/src/coreclr/nativeaot/Runtime/inc/CommonTypes.h +++ b/src/coreclr/nativeaot/Runtime/inc/CommonTypes.h @@ -44,7 +44,7 @@ typedef uint32_t UInt32_BOOL; // windows 4-byte BOOL, 0 -> false, #define UInt32_FALSE 0 #define UInt32_TRUE 1 -#if (defined(FEATURE_EVENT_TRACE) && defined(TARGET_UNIX)) || defined(TARGET_WASM) +#if defined(FEATURE_EVENT_TRACE) && defined(TARGET_UNIX) typedef int BOOL; typedef void* LPVOID; typedef uint32_t UINT; @@ -55,7 +55,7 @@ typedef uint32_t ULONG; typedef int64_t LONGLONG; typedef uint8_t BYTE; typedef uint16_t UINT16; -#endif // (FEATURE_EVENT_TRACE && TARGET_UNIX) || TARGET_WASM +#endif // FEATURE_EVENT_TRACE && TARGET_UNIX // Hijack funcs are not called, they are "returned to". And when done, they return to the actual caller. // Thus they cannot have any parameters or return anything. From 43cf7f63f79972d047eaa8667606097bc5e2133f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Mon, 28 Sep 2026 17:48:43 +0900 Subject: [PATCH 5/7] Share NativeAOT assembly offset verification sources Move AsmOffsetsVerify.cpp to COMMON_RUNTIME_SOURCES so Full and Portable inherit the same source entry. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 56ce0dc4-30ad-4c7a-99f5-c31a1a6adedc --- src/coreclr/nativeaot/Runtime/CMakeLists.txt | 2 +- src/coreclr/nativeaot/Runtime/Portable/CMakeLists.txt | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/CMakeLists.txt index 1f85be71dddf80..06d92e2a4d70f5 100644 --- a/src/coreclr/nativeaot/Runtime/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/CMakeLists.txt @@ -25,6 +25,7 @@ set(GC_WKS_SVR_SOURCES ) set(COMMON_RUNTIME_SOURCES + AsmOffsetsVerify.cpp rhassert.cpp ${RUNTIME_DIR}/MiscNativeHelpers.cpp Crst.cpp @@ -89,7 +90,6 @@ set(STANDALONEGC_ENABLED_SOURCES ) set(FULL_RUNTIME_SOURCES - AsmOffsetsVerify.cpp ThunksMapping.cpp ) diff --git a/src/coreclr/nativeaot/Runtime/Portable/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/Portable/CMakeLists.txt index 8e0fffeda0af5d..6b119ff5feade6 100644 --- a/src/coreclr/nativeaot/Runtime/Portable/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/Portable/CMakeLists.txt @@ -11,7 +11,6 @@ set_target_properties(Runtime.GC.Workstation PROPERTIES UNITY_BUILD ON UNITY_BUI add_library(PortableRuntime STATIC ${COMMON_RUNTIME_SOURCES} ${PORTABLE_RUNTIME_SOURCES} - ${NATIVEAOT_RUNTIME_DIR}/AsmOffsetsVerify.cpp $) target_link_libraries(PortableRuntime PRIVATE aotminipal) From c0c3d52f4c74495dc9a667e67e5584d057d1c228 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Tue, 29 Sep 2026 07:24:24 +0900 Subject: [PATCH 6/7] Align NativeAOT WASM crash dump guards with Apple mobile Exclude dump-only helpers and state on WASM alongside Apple mobile platforms, retaining unsupported-operation behavior at the PAL entry points. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 56ce0dc4-30ad-4c7a-99f5-c31a1a6adedc --- .../nativeaot/Runtime/unix/PalCreateDump.cpp | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime/unix/PalCreateDump.cpp b/src/coreclr/nativeaot/Runtime/unix/PalCreateDump.cpp index 6b698a351e56b0..26fcad3a346c20 100644 --- a/src/coreclr/nativeaot/Runtime/unix/PalCreateDump.cpp +++ b/src/coreclr/nativeaot/Runtime/unix/PalCreateDump.cpp @@ -52,7 +52,7 @@ #include #include -#if !defined(HOST_MACCATALYST) && !defined(HOST_IOS) && !defined(HOST_TVOS) +#if !defined(HOST_MACCATALYST) && !defined(HOST_IOS) && !defined(HOST_TVOS) && !defined(HOST_WASM) // Crash dump generating program arguments. MAX_ARGV_ENTRIES is the max number // of entries if every createdump option/argument is passed. @@ -209,9 +209,6 @@ CreateCrashDump( char* errorMessageBuffer, int cbErrorMessageBuffer) { -#ifdef HOST_WASM - return false; -#else int pipe_descs[4]; if (pipe(pipe_descs) == -1 || pipe(pipe_descs + 2) == -1) { @@ -348,11 +345,11 @@ CreateCrashDump( } } return true; -#endif // HOST_WASM } -#endif // !defined(HOST_MACCATALYST) && !defined(HOST_IOS) && !defined(HOST_TVOS) +#endif // !defined(HOST_MACCATALYST) && !defined(HOST_IOS) && !defined(HOST_TVOS) && !defined(HOST_WASM) +#ifndef HOST_WASM // Helper function to prevent compiler from optimizing away a variable #if defined(__llvm__) __attribute__((noinline, optnone)) @@ -380,14 +377,13 @@ static void DoNotOptimize(const void* p) (no return value) --*/ -#ifndef HOST_WASM void PalCreateCrashDumpIfEnabled(int signal, siginfo_t* siginfo, void* context, void* exceptionRecord) { // Preserve context pointer to prevent optimization DoNotOptimize(&context); -#if !defined(HOST_MACCATALYST) && !defined(HOST_IOS) && !defined(HOST_TVOS) +#if !defined(HOST_MACCATALYST) && !defined(HOST_IOS) && !defined(HOST_TVOS) && !defined(HOST_WASM) // If enabled, launch the create minidump utility and wait until it completes if (g_argvCreateDump[0] != nullptr) { @@ -473,7 +469,7 @@ PalCreateCrashDumpIfEnabled(int signal, siginfo_t* siginfo, void* context, void* free(signalAddressArg); free(exceptionRecordArg); } -#endif // !defined(HOST_MACCATALYST) && !defined(HOST_IOS) && !defined(HOST_TVOS) +#endif // !defined(HOST_MACCATALYST) && !defined(HOST_IOS) && !defined(HOST_TVOS) && !defined(HOST_WASM) } #endif // !HOST_WASM @@ -522,7 +518,7 @@ PalGenerateCoreDump( char* errorMessageBuffer, int cbErrorMessageBuffer) { -#if !defined(HOST_MACCATALYST) && !defined(HOST_IOS) && !defined(HOST_TVOS) +#if !defined(HOST_MACCATALYST) && !defined(HOST_IOS) && !defined(HOST_TVOS) && !defined(HOST_WASM) const char* argvCreateDump[MAX_ARGV_ENTRIES]; if (dumpType <= DumpTypeUnknown || dumpType > DumpTypeMax) { @@ -540,7 +536,7 @@ PalGenerateCoreDump( return result; #else return false; -#endif // !defined(HOST_MACCATALYST) && !defined(HOST_IOS) && !defined(HOST_TVOS) +#endif // !defined(HOST_MACCATALYST) && !defined(HOST_IOS) && !defined(HOST_TVOS) && !defined(HOST_WASM) } /*++ From 484ef744645263af61fb4cb0da9983392d955bf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Tue, 29 Sep 2026 07:58:38 +0900 Subject: [PATCH 7/7] Share NativeAOT WASI signal declarations Forward-declare siginfo_t in UnixSignals.h for WASI and retain the crash dump overloads and wrapper calls on WASM, matching Apple mobile exclusions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 56ce0dc4-30ad-4c7a-99f5-c31a1a6adedc --- src/coreclr/nativeaot/Runtime/unix/PalCreateDump.cpp | 8 +------- src/coreclr/nativeaot/Runtime/unix/PalCreateDump.h | 4 +--- src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp | 2 -- src/coreclr/nativeaot/Runtime/unix/UnixSignals.h | 4 ++++ 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime/unix/PalCreateDump.cpp b/src/coreclr/nativeaot/Runtime/unix/PalCreateDump.cpp index 26fcad3a346c20..203988bf6511b3 100644 --- a/src/coreclr/nativeaot/Runtime/unix/PalCreateDump.cpp +++ b/src/coreclr/nativeaot/Runtime/unix/PalCreateDump.cpp @@ -7,6 +7,7 @@ #include #include #include "config.h" +#include "PalCreateDump.h" #include #include #include @@ -15,7 +16,6 @@ #include #include #include -#include #if HAVE_PRCTL_H #include #include @@ -349,7 +349,6 @@ CreateCrashDump( #endif // !defined(HOST_MACCATALYST) && !defined(HOST_IOS) && !defined(HOST_TVOS) && !defined(HOST_WASM) -#ifndef HOST_WASM // Helper function to prevent compiler from optimizing away a variable #if defined(__llvm__) __attribute__((noinline, optnone)) @@ -471,22 +470,17 @@ PalCreateCrashDumpIfEnabled(int signal, siginfo_t* siginfo, void* context, void* } #endif // !defined(HOST_MACCATALYST) && !defined(HOST_IOS) && !defined(HOST_TVOS) && !defined(HOST_WASM) } -#endif // !HOST_WASM void PalCreateCrashDumpIfEnabled() { -#ifndef HOST_WASM PalCreateCrashDumpIfEnabled(SIGABRT, nullptr, nullptr, nullptr); -#endif } void PalCreateCrashDumpIfEnabled(void* pExceptionRecord) { -#ifndef HOST_WASM PalCreateCrashDumpIfEnabled(SIGABRT, nullptr, nullptr, pExceptionRecord); -#endif } /*++ diff --git a/src/coreclr/nativeaot/Runtime/unix/PalCreateDump.h b/src/coreclr/nativeaot/Runtime/unix/PalCreateDump.h index 1c5a16fc02ba75..65805dfe3aebb5 100644 --- a/src/coreclr/nativeaot/Runtime/unix/PalCreateDump.h +++ b/src/coreclr/nativeaot/Runtime/unix/PalCreateDump.h @@ -3,11 +3,9 @@ #pragma once -#include +#include "UnixSignals.h" extern bool PalCreateDumpInitialize(); extern void PalCreateCrashDumpIfEnabled(); -#ifndef HOST_WASM extern void PalCreateCrashDumpIfEnabled(int signal, siginfo_t* siginfo = nullptr, void* context = nullptr, void* exceptionRecord = nullptr); -#endif // !HOST_WASM extern void PalCreateCrashDumpIfEnabled(void* pExceptionRecord); diff --git a/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp b/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp index f9fbb67d9d320f..008407eb490e5d 100644 --- a/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp +++ b/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp @@ -16,9 +16,7 @@ #include "gcenv.ee.h" #include "gcconfig.h" #include "holder.h" -#ifdef FEATURE_HIJACK #include "UnixSignals.h" -#endif // FEATURE_HIJACK #include "NativeContext.h" #include "HardwareExceptions.h" #include "PalCreateDump.h" diff --git a/src/coreclr/nativeaot/Runtime/unix/UnixSignals.h b/src/coreclr/nativeaot/Runtime/unix/UnixSignals.h index 60e08d461e3830..e9218fdeb2c1c4 100644 --- a/src/coreclr/nativeaot/Runtime/unix/UnixSignals.h +++ b/src/coreclr/nativeaot/Runtime/unix/UnixSignals.h @@ -6,6 +6,10 @@ #include +#ifdef TARGET_WASI +struct siginfo_t; +#endif // TARGET_WASI + #ifdef SIGRTMIN #define INJECT_ACTIVATION_SIGNAL SIGRTMIN #else