Skip to content

Fix illumox-x64 build with gcc and clang#129322

Open
am11 wants to merge 7 commits into
dotnet:mainfrom
am11:feature/port/illumos-native-build2
Open

Fix illumox-x64 build with gcc and clang#129322
am11 wants to merge 7 commits into
dotnet:mainfrom
am11:feature/port/illumos-native-build2

Conversation

@am11

@am11 am11 commented Jun 12, 2026

Copy link
Copy Markdown
Member

First, our default build is failing with solaris gcc 13, so couple of fixes for those are included (jit, gcenv etc.). Then it includes clang fixes.

For the first time, cross building runtime repo for illumos-x64 with llvm-toolchain has succeeded. It has two issues which I've reported upstream with minimal repro and workarounds:

For the first one I am adding a workaround in configurecompiler.cmake (if (CMAKE_C_COMPILER_ID MATCHES "GNU") condition). For the second one the hack goes in toolchain.cmake which I am skipping from this PR as I'm running trials to slim it down a bit (current state: https://github.com/am11/runtime/blob/67046c0cf095c5d7888c797226fe736156b5e04c/eng/common/cross/toolchain.cmake#L227-L307).

Together the clang build succeeds on Azure Linux cross environment same as rest of the platforms (freebsd, openbsd, haiku).

Note that the gcc build requires another fix upstream dotnet/dotnet#7206, which I recently broke while fixing sccsid which got broken after we started to use --gc-sections linker option liberally.

@github-actions github-actions Bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Jun 12, 2026
@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Jun 12, 2026
@am11 am11 added area-PAL-coreclr only for closed issues os-SunOS SunOS, currently not officially supported and removed area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI labels Jun 12, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

@am11

am11 commented Jun 12, 2026

Copy link
Copy Markdown
Member Author

cc @gwr, @AustinWise, I know you guys were looking for clang-based crossbuild at some point. While working on OpenBSD bringup, I figured some internal things out for illumos.

If someone could take care of llvm side of patching, that would help. 🙂

memset(&sa_default, 0, sizeof(sa_default)); // On some architectures, sa_mask is a struct so assigning zero to it doesn't compile
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wstrict-prototypes"
sa_default.sa_handler = SIG_DFL;

@am11 am11 Jun 12, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are raised from system headers; I couldn't find a way to make clang happy, so I went with the suppression (and gcc surprisingly ignores it so we don't need additional #ifdef __clang type of condition).

@akoeplinger

Copy link
Copy Markdown
Member

build failure looks related

Comment thread src/coreclr/jit/gentree.h Outdated
#endif

#ifdef MADV_FREE
#if defined(MADV_FREE) && !defined(TARGET_SUNOS)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed? It is strange that it would have MADV_FREE defined and it would fail in the code below.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mono has HAVE_MADVISE, coreclr doesn't. The error was about madvise not being defined:

 [117/162] Building CXX object nativeaot/Runtime/Full/CMakeFiles/Runtime.ServerGC.dir/__/__/__/gc/unix/gcenv.unix.cpp.o
  FAILED: nativeaot/Runtime/Full/CMakeFiles/Runtime.ServerGC.dir/__/__/__/gc/unix/gcenv.unix.cpp.o
  /crossrootfs/x64/bin/x86_64-illumos-g++ --sysroot=/crossrootfs/x64 -DDISABLE_CONTRACTS -DFEATURE_BASICFREEZE -DFEATURE_CONSERVATIVE_GC -DFEATURE_EVENT_TRACE -DFEATURE_HIJACK -DFEATURE_MANUALLY_MANAGED_CARD_BUNDLES -DFEATURE_NATIVEAOT -DFEATURE_PERFTRACING -DFEATURE_READONLY_GS_COOKIE -DFEATURE_RX_THUNKS -DFEATURE_SVR_GC -DFEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP -DGC_DESCRIPTOR -DHOST_64BIT -DHOST_AMD64 -DHOST_UNIX -DNATIVEAOT -DNDEBUG -DTARGET_64BIT -DTARGET_AMD64 -DTARGET_ILLUMOS -DTARGET_SUNOS -DTARGET_UNIX -DUNIX_AMD64_ABI -DURTBLDENV_FRIENDLY=Retail -DVERIFY_HEAP -D_FILE_OFFSET_BITS=64 -D_LIB -D_LIBUNWIND_DISABLE_ZERO_COST_APIS=1 -D_LIBUNWIND_IS_NATIVE_ONLY -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT -D_TIME_BITS=64 -D_XPG4_2 -D__EXTENSIONS__ -I/runtime/artifacts/obj/coreclr/illumos.x64.Release/nativeaot/Runtime/Full -I/runtime/src/coreclr/nativeaot/Runtime/Full -I/runtime/src/native/external/llvm-libunwind/include -I/runtime/src/native -I/runtime/src/native/inc -I/runtime/src/coreclr/pal/prebuilt/inc -I/runtime/artifacts/obj -I/runtime/src/coreclr/nativeaot/Runtime/inc -I/runtime/src/coreclr/nativeaot/Runtime/. -I/runtime/src/coreclr/nativeaot/Runtime/../../gc -I/runtime/src/coreclr/nativeaot/Runtime/../../gc/env -I/runtime/artifacts/obj/coreclr/illumos.x64.Release/nativeaot/Runtime/eventpipe/inc -I/runtime/src/coreclr/runtime -I/runtime/src/coreclr/nativeaot/Runtime/unix -I/runtime/src/coreclr/nativeaot/Runtime/../../pal/inc/rt -I/runtime/src/coreclr/nativeaot/Runtime/amd64 -I/runtime/artifacts/obj/coreclr/illumos.x64.Release/nativeaot/Runtime -I/runtime/src/coreclr/debug/datadescriptor-shared/inc -isystem /crossrootfs/x64/include -fstack-protector -O3 -DNDEBUG -std=gnu++17 -fPIC -O3 -Wall -g -fno-omit-frame-pointer -fno-strict-overflow -fno-strict-aliasing -fstack-protector-strong -Werror -Wno-unused-variable -Wno-unused-value -Wno-unused-function -Wno-tautological-compare -Wno-unknown-pragmas -Wimplicit-fallthrough -Wvla -Wno-invalid-offsetof -Wno-unused-but-set-variable -ffp-contract=off -fno-rtti -Wno-uninitialized -Wno-strict-aliasing -Wno-array-bounds -Wno-misleading-indentation -Wno-stringop-overflow -Wno-restrict -Wno-stringop-truncation -Wno-class-memaccess -faligned-new -fsigned-char -fvisibility=hidden -ffunction-sections -fdata-sections -fno-exceptions -fno-asynchronous-unwind-tables -nostdlib -MD -MT nativeaot/Runtime/Full/CMakeFiles/Runtime.ServerGC.dir/__/__/__/gc/unix/gcenv.unix.cpp.o -MF nativeaot/Runtime/Full/CMakeFiles/Runtime.ServerGC.dir/__/__/__/gc/unix/gcenv.unix.cpp.o.d -o nativeaot/Runtime/Full/CMakeFiles/Runtime.ServerGC.dir/__/__/__/gc/unix/gcenv.unix.cpp.o -c /runtime/src/coreclr/gc/unix/gcenv.unix.cpp
  /runtime/src/coreclr/gc/unix/gcenv.unix.cpp: In static member function 'static bool GCToOSInterface::VirtualReset(void*, size_t, bool)':
  /runtime/src/coreclr/gc/unix/gcenv.unix.cpp:574:10: error: 'madvise' was not declared in this scope; did you mean 'raise'?
    574 |     st = madvise(address, size, MADV_FREE);
        |          ^~~~~~~
        |          raise
  [118/162] Building C object /runtime/artifacts/obj/external/libunwind/CMakeFiles/libunwind.dir/runtime/src/native/external/libunwind/src/dwarf/Lparser.c.o
  [119/162] Building C object /runtime/artifacts/obj/external/libunwind/CMakeFiles/libunwind.dir/runtime/src/native/external/libunwind/src/dwarf/Gexpr.c.o
  [120/162] Building C object /runtime/artifacts/obj/external/libunwind/CMakeFiles/libunwind.dir/runtime/src/native/external/libunwind/src/dwarf/Gparser.c.o
  [121/162] Building CXX object Corehost.Static/hostmisc/CMakeFiles/hostmisc.dir/utils.cpp.o
  [122/162] Building CXX object Corehost.Static/hostmisc/CMakeFiles/hostmisc_public.dir/utils.cpp.o
  ninja: build stopped: subcommand failed.
  /runtime/src/coreclr
  Failed to build "CoreCLR component".
/runtime/src/coreclr/runtime.proj(120,5): error MSB3073: The command ""/runtime/src/coreclr/build-runtime.sh" -x64 -release gcc -cross -os illumos -ninja -targetrid illumos-x64 -cmakeargs "-DCLR_DOTNET_RID=illumos-x64" -cmakeargs "-DCLR_DOTNET_HOST_PATH='/runtime/.dotnet/dotnet'" -cmakeargs "-DCDAC_BUILD_TOOL_BINARY_PATH=/runtime/artifacts/bin/coreclr/illumos.x64.Release/cdac-build-tool/cdac-build-tool.dll" -cmakeargs "-DFEATURE_DYNAMIC_CODE_COMPILED=1" " exited with code 1.

Build FAILED.

/runtime/src/coreclr/runtime.proj(120,5): error MSB3073: The command ""/runtime/src/coreclr/build-runtime.sh" -x64 -release gcc -cross -os illumos -ninja -targetrid illumos-x64 -cmakeargs "-DCLR_DOTNET_RID=illumos-x64" -cmakeargs "-DCLR_DOTNET_HOST_PATH='/runtime/.dotnet/dotnet'" -cmakeargs "-DCDAC_BUILD_TOOL_BINARY_PATH=/runtime/artifacts/bin/coreclr/illumos.x64.Release/cdac-build-tool/cdac-build-tool.dll" -cmakeargs "-DFEATURE_DYNAMIC_CODE_COMPILED=1" " exited with code 1.
    0 Warning(s)
    1 Error(s)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, so sunos has MADV_FREE defined and yet no madvise, that's quite weird.

@gwr gwr Jun 12, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's in <sys/mman.h>

#if !defined(_STRICT_POSIX)
extern int mincore(caddr_t, size_t, char *);
extern int memcntl(void *, size_t, int, void *, int, int);
extern int madvise(void *, size_t, int);
[...]

Does the build supply -D_STRICT_POSIX or something?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's consistent once you see it's a namespace thing: madvise is a non-standard SVR4/BSD extension, posix_madvise is the standardized one, and we build with -D_XPG4_2 (strict X/Open). From the rootfs's sys/mman.h:

#if (_POSIX_C_SOURCE > 2) || defined(_XPG4_2)
extern void *mmap(void *, size_t, int, int, int, off_t);
...
#else   /* (_POSIX_C_SOURCE > 2) || defined(_XPG4_2) */
...
extern int madvise(caddr_t, size_t, int);
...
#endif

#if !defined(__XOPEN_OR_POSIX) || defined(_XPG6) || defined(__EXTENSIONS__)
extern int posix_madvise(void *, size_t, int);
#endif

#if (_POSIX_C_SOURCE <= 2) && !defined(_XPG4_2) || defined(__EXTENSIONS__)
...
#define MADV_FREE               5       /* contents can be freed */
...
#endif

So on illumos the posix-y path is the preferred one, and posix_madvise(POSIX_MADV_DONTNEED) is what they consider "modern".

Comment thread src/native/libs/System.Native/pal_process.c

@jakobbotsch jakobbotsch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JIT part LGTM

{
assert(origHandler->sa_handler);
origHandler->sa_handler(sig);
((void (*)(int))origHandler->sa_handler)(sig);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the sa_handler type on illumos?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C and C++ have different types:

struct sigaction {
	int sa_flags;
	union {
#ifdef	__cplusplus
		void (*_handler)(int);
#else
		void (*_handler)();
#endif
#if defined(__EXTENSIONS__) || defined(_KERNEL) || \
	(!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \
	(_POSIX_C_SOURCE > 2) || defined(_XPG4_2)
		void (*_sigaction)(int, siginfo_t *, void *);
#endif
	}	_funcptr;
	sigset_t sa_mask;
#ifndef _LP64
	int sa_resv[2];
#endif
};
#define	sa_handler	_funcptr._handler
#define	sa_sigaction	_funcptr._sigaction

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our rootfs has an older version of kernel. There is no new update from https://github.com/illumos/sysroot/ in a while.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you set sa_handler, the right type is (void (*)(int)), and if you
set sa_sigaction, the right type is (void (*)(int, siginfo_t *, void *))
Those are union arms. Here'e the relevant section of sys/signa.h


/*
 * The signal handler routine can have either one or three arguments.  With
 * K&R C code could use either form so not specifing the arguments neatly
 * finessed the problem.  Modern C and any C++ do not accept this.  To them
 * "(*sa_handler)()" indicates a routine with no arguments (what used to be
 * "(*sa_handler)(void)").  One or the other form must be used and the only
 * logical choice is "(*sa_handler)(int)" to allow the SIG_* defines to work.
 * "(*sa_sigaction)(int, siginfo_t *, void *)" can be used for the three
 * argument form.
 */

/*
 * Note: storage overlap by sa_handler and sa_sigaction
 */
struct sigaction {
	int sa_flags;
	union {
		void (*_handler)(int);
#if defined(__EXTENSIONS__) || defined(_KERNEL) || \
	(!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \
	(_POSIX_C_SOURCE > 2) || defined(_XPG4_2)
		void (*_sigaction)(int, siginfo_t *, void *);
#endif
	}	_funcptr;
	sigset_t sa_mask;
#ifndef _LP64
	int sa_resv[2];
#endif
};
#define	sa_handler	_funcptr._handler
#define	sa_sigaction	_funcptr._sigaction

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-PAL-coreclr only for closed issues community-contribution Indicates that the PR has been added by a community member os-SunOS SunOS, currently not officially supported

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants