diff --git a/src/coreclr/debug/crashreport/CMakeLists.txt b/src/coreclr/debug/crashreport/CMakeLists.txt index c9827e1713a6ba..77177df2ed067a 100644 --- a/src/coreclr/debug/crashreport/CMakeLists.txt +++ b/src/coreclr/debug/crashreport/CMakeLists.txt @@ -10,6 +10,9 @@ set(CRASHREPORT_SOURCES inproccrashreportwatchdog.cpp ) +include(configure.cmake) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) add_library(inproccrashreport OBJECT ${CRASHREPORT_SOURCES}) target_include_directories(inproccrashreport PRIVATE ${CLR_DIR}/pal/src/include) diff --git a/src/coreclr/debug/crashreport/config.h.in b/src/coreclr/debug/crashreport/config.h.in new file mode 100644 index 00000000000000..1c181913c13508 --- /dev/null +++ b/src/coreclr/debug/crashreport/config.h.in @@ -0,0 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#pragma once + +#cmakedefine01 HAVE_POLL +#cmakedefine01 HAVE_UCONTEXT_H diff --git a/src/coreclr/debug/crashreport/configure.cmake b/src/coreclr/debug/crashreport/configure.cmake new file mode 100644 index 00000000000000..79dc8f4ce747b2 --- /dev/null +++ b/src/coreclr/debug/crashreport/configure.cmake @@ -0,0 +1,4 @@ +check_function_exists(poll HAVE_POLL) +check_include_files(ucontext.h HAVE_UCONTEXT_H) + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) diff --git a/src/coreclr/debug/crashreport/inproccrashreporter.cpp b/src/coreclr/debug/crashreport/inproccrashreporter.cpp index 64f3a451197ffb..8d3e9806cedf0e 100644 --- a/src/coreclr/debug/crashreport/inproccrashreporter.cpp +++ b/src/coreclr/debug/crashreport/inproccrashreporter.cpp @@ -15,6 +15,7 @@ #include "pal.h" #include "volatile.h" +#include "config.h" #include #include diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 638ca0ce6db455..af02d286a0d861 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -10507,7 +10507,14 @@ GenTree* Compiler::gtNewLoadValueNode(var_types type, ClassLayout* layout, GenTr { unsigned lclNum = addr->AsLclFld()->GetLclNum(); LclVarDsc* varDsc = lvaGetDesc(lclNum); +#if defined(TARGET_SUNOS) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnonnull" +#endif if ((varDsc->TypeGet() == type) && ((type != TYP_STRUCT) || layout->CanAssignFrom(varDsc->GetLayout()))) +#if defined(TARGET_SUNOS) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif { return gtNewLclvNode(lclNum, type); } diff --git a/src/native/corehost/hostmisc/pal.h b/src/native/corehost/hostmisc/pal.h index 405b8d63073450..1e764523f3bb9b 100644 --- a/src/native/corehost/hostmisc/pal.h +++ b/src/native/corehost/hostmisc/pal.h @@ -22,18 +22,18 @@ typedef wchar_t pal_char_t; // C++ mode: MSVC's default (non-conforming) preprocessor leaves L##__FUNCTION__ // unexpanded so that it evaluates to MSVC's wide function-name literal. Using a // two-step helper here would force argument expansion and break that. -#define _X(s) L ## s +#define PAL_X(s) L ## s #else // C mode: MSVC's /std:c11 conforming preprocessor (and other conforming // compilers) suppress argument expansion before ##. A two-step helper forces // the argument to be expanded first so e.g. _X(HOST_VERSION) yields a wide // string literal rather than the identifier LHOST_VERSION. #define _X_HELPER(s) L ## s -#define _X(s) _X_HELPER(s) +#define PAL_X(s) _X_HELPER(s) #endif #else // !_WIN32 typedef char pal_char_t; -#define _X(s) s +#define PAL_X(s) s #endif // _WIN32 // Max path buffer for apphost string operations @@ -122,6 +122,21 @@ typedef void* pal_proc_t; #include "configure.h" +#if defined(TARGET_SUNOS) + // Ensure character traits have been processed safely before we intercept the identifier + #if defined(__cplusplus) + #include + #include + #else + #include + #endif + + // Wipe the system bitmask and instantly route it to your project's PAL_X layout + #undef _X +#endif + +#define _X(s) PAL_X(s) + // Wide-stringify the value of a macro: _STRINGIFY(FOO) -> _X(""). #define _STRINGIFY(s) _X(s) diff --git a/src/native/corehost/hostmisc/pal.unix.c b/src/native/corehost/hostmisc/pal.unix.c index 73aebb83de2286..7af16f77a805c3 100644 --- a/src/native/corehost/hostmisc/pal.unix.c +++ b/src/native/corehost/hostmisc/pal.unix.c @@ -102,6 +102,10 @@ bool pal_readdir_onlydirectories(const pal_char_t* path, pal_readdir_callback_t #if HAVE_DIRENT_D_TYPE int entry_type = entry->d_type; #else +#define DT_UNKNOWN 0 +#define DT_DIR 4 +#define DT_REG 8 +#define DT_LNK 10 int entry_type = DT_UNKNOWN; #endif @@ -357,11 +361,6 @@ bool pal_utf8_to_palstr(const char* utf8, pal_char_t* out, size_t out_len) return true; } -// Two-level stringize so PATH_MAX's value (not its name) can be used as an -// explicit sscanf field width below. -#define PROC_MAPS_STR2(x) #x -#define PROC_MAPS_STR(x) PROC_MAPS_STR2(x) - // dlopen on some systems only finds a loaded library when given its full path. // As a fallback, scan /proc/self/maps for a mapped file whose name contains // library_name. On success sets *dll and *out_path (heap-allocated, caller @@ -378,8 +377,12 @@ static bool get_loaded_library_from_proc_maps(const pal_char_t* library_name, pa char found_path[PATH_MAX + 1]; while (getline(&line, &line_cap, file) != -1) { + // Build the sscanf format dynamically to safely handle parenthesized PATH_MAX values on some platforms (like Haiku) + char fmt[64]; + snprintf(fmt, sizeof(fmt), "%%*p-%%*p %%*[-rwxsp] %%*p %%*[:0-9a-f] %%*d %%%ds\n", PATH_MAX); + char buf[PATH_MAX + 1]; // + 1 for the NUL terminator - if (sscanf(line, "%*p-%*p %*[-rwxsp] %*p %*[:0-9a-f] %*d %" PROC_MAPS_STR(PATH_MAX) "s\n", buf) == 1) + if (sscanf(line, fmt, buf) == 1) { const char* last_sep = strrchr(buf, DIR_SEPARATOR); if (last_sep == NULL) diff --git a/src/native/libs/System.Native/pal_networkstatistics.c b/src/native/libs/System.Native/pal_networkstatistics.c index 7c88508ca57400..ec9c8bb0cb54e7 100644 --- a/src/native/libs/System.Native/pal_networkstatistics.c +++ b/src/native/libs/System.Native/pal_networkstatistics.c @@ -642,7 +642,7 @@ int32_t SystemNative_GetActiveUdpListeners(IPEndPointInfo* infos, int32_t* infoC // route/interface sysctl APIs (rt_msghdr), not the protocol statistics that live in tcp_var.h. // Gate them on HAVE_RT_MSGHDR so platforms that lack tcp_var.h but do have rt_msghdr (e.g. OpenBSD) // still get the real implementation instead of the ENOTSUP stub. -#if HAVE_RT_MSGHDR +#if HAVE_RT_MSGHDR && HAVE_SYS_SYSCTL_H #include #include #include @@ -858,4 +858,4 @@ int32_t SystemNative_GetNumRoutes(void) errno = ENOTSUP; return -1; } -#endif // HAVE_RT_MSGHDR +#endif // HAVE_RT_MSGHDR && HAVE_SYS_SYSCTL_H diff --git a/src/native/minipal/ospagesize.c b/src/native/minipal/ospagesize.c index b5ece750e1a2cf..88e9354556fdc7 100644 --- a/src/native/minipal/ospagesize.c +++ b/src/native/minipal/ospagesize.c @@ -13,8 +13,13 @@ uint32_t minipal_getpagesize(void) { +#if defined(TARGET_HAIKU) && defined(__clang__) + static _Atomic uint32_t cached_page_size = 0; + uint32_t page_size = __c11_atomic_load(&cached_page_size, memory_order_relaxed); +#else static atomic_uint cached_page_size = 0; uint32_t page_size = atomic_load_explicit(&cached_page_size, memory_order_relaxed); +#endif if (page_size == 0) { long sc = sysconf(_SC_PAGESIZE); @@ -25,7 +30,11 @@ uint32_t minipal_getpagesize(void) abort(); } page_size = (uint32_t)sc; +#if defined(TARGET_HAIKU) && defined(__clang__) + __c11_atomic_store(&cached_page_size, page_size, memory_order_relaxed); +#else atomic_store_explicit(&cached_page_size, page_size, memory_order_relaxed); +#endif } return page_size; }