This patch to HEAD (along with Dick's great new io-layer) gets everything working under FreeBSD for 1.1.17. Here we add support for MONO_ARCH_USE_SIGACTION, fix libgc, support freebsd6, and clean up a nit that crept in from a bad archive patch.
Detailed descriptions follow, and the patch is attached. Thanks very much, Bill Index: libgc/include/private/gcconfig.h =================================================================== This patch redefines SIG_SUSPEND and SIG_THR_RESTART to SIGTSTP and SIGCONT. It has been submitted previously, but has not yet been committed. Source: bsd# patch archive. Index: libgc/configure.in =================================================================== Add support for freebsd6 to libgc/configure.in. Reuses the definition for freebsd5, but may be patched in the port to provide explicit compilation against libthr instead of libpthread. Index: libgc/os_dep.c =================================================================== Add necessary FREEBSD support to two os-dependent sigaction() calls which RESTART for SIGBUS and SIGSEGV. Source: bsd# patch archive. Index: libgc/dyn_load.c =================================================================== Clean up and add support for FREEBSD for ElfW. Source: bsd# patch archive. Index: configure.in =================================================================== - Support freebsd6 in configure with sigaltstack - Remove depracated with_nptl - Conditionally check for working ieeefp.h on FreeBSD - Support *bsd* in the AC_TRY_RUN test for sigaltstack(). Note that sigaltstack is default-enabled only for freebsd6 for now, where I have tested it thoroughly, but configure command-line enabling using with-sigaltstack=yes will now work for freebsd5, as well. - Fix --with-preview. (PREVIEW) Preview always builds even when disabled now. Index: ikvm-native/jni.c =================================================================== This is a re-submission of a bsd# archive patch which was committed by Zoltan recently, but did not fix the problem. We must completely forego the inclusion of alloca.h on *BSD*, as it is not available, and alloca() is defined in stdlib.h, which is always included. Index: mono/mini/exceptions-x86.c =================================================================== Add support for MONO_ARCH_USE_SIGACTION (sigaltstack) for FreeBSD. As mentioned in a previous mono-devel thread, FreeBSD does not provide the gregs[] array to access the register values in ucontext{} struct. This patch supports sigaltstack() via specific reference to the members, implemented in Zoltan's new mono_arch_sigctx_to_monoctx() routine, when enabled. Index: mono/mini/mini-x86.c =================================================================== Simply call pthread_attr_init() on the pthread_attr. This is required on FreeBSD even when using pthread_attr_get_np() as currently implemented. Index: mono/mini/mini-x86.h =================================================================== Redefine MAP_ANONYMOUS to MAP_ANON on FreeBSD to support sigaltstack()
Index: libgc/include/private/gcconfig.h =================================================================== --- libgc/include/private/gcconfig.h (revision 42774) +++ libgc/include/private/gcconfig.h (working copy) @@ -1186,8 +1186,8 @@ # ifndef GC_FREEBSD_THREADS # define MPROTECT_VDB # endif -# define SIG_SUSPEND SIGUSR1 -# define SIG_THR_RESTART SIGUSR2 +# define SIG_SUSPEND SIGTSTP +# define SIG_THR_RESTART SIGCONT # define FREEBSD_STACKBOTTOM # ifdef __ELF__ # define DYNAMIC_LOADING @@ -1501,8 +1501,8 @@ # ifdef FREEBSD # define OS_TYPE "FREEBSD" /* MPROTECT_VDB is not yet supported at all on FreeBSD/alpha. */ -# define SIG_SUSPEND SIGUSR1 -# define SIG_THR_RESTART SIGUSR2 +# define SIG_SUSPEND SIGTSTP +# define SIG_THR_RESTART SIGCONT # define FREEBSD_STACKBOTTOM # ifdef __ELF__ # define DYNAMIC_LOADING Index: libgc/configure.in =================================================================== --- libgc/configure.in (revision 42774) +++ libgc/configure.in (working copy) @@ -124,6 +124,17 @@ THREADLIBS="$PTHREAD_LIBS" fi ;; + *-*-freebsd6*) + AC_DEFINE(GC_FREEBSD_THREADS) + if test "x$PTHREAD_CFLAGS" != "x"; then + INCLUDES="$INCLUDES $PTHREAD_CFLAGS" + fi + if test "x$PTHREAD_LIBS" = "x"; then + THREADLIBS=-lpthread + else + THREADLIBS="$PTHREAD_LIBS" + fi + ;; *-*-solaris*) AC_DEFINE(GC_SOLARIS_THREADS) AC_DEFINE(GC_SOLARIS_PTHREADS) Index: libgc/os_dep.c =================================================================== --- libgc/os_dep.c (revision 42774) +++ libgc/os_dep.c (working copy) @@ -702,10 +702,10 @@ # endif # if defined(SUNOS5SIGS) || defined(IRIX5) || defined(OSF1) \ - || defined(HURD) || defined(NETBSD) + || defined(HURD) || defined(NETBSD) || defined(FREEBSD) static struct sigaction old_segv_act; # if defined(_sigargs) /* !Irix6.x */ || defined(HPUX) \ - || defined(HURD) || defined(NETBSD) + || defined(HURD) || defined(NETBSD) || defined(FREEBSD) static struct sigaction old_bus_act; # endif # else @@ -720,7 +720,7 @@ # endif { # if defined(SUNOS5SIGS) || defined(IRIX5) \ - || defined(OSF1) || defined(HURD) || defined(NETBSD) + || defined(OSF1) || defined(HURD) || defined(NETBSD) || defined(FREEBSD) struct sigaction act; act.sa_handler = h; @@ -740,7 +740,7 @@ # else (void) sigaction(SIGSEGV, &act, &old_segv_act); # if defined(IRIX5) && defined(_sigargs) /* Irix 5.x, not 6.x */ \ - || defined(HPUX) || defined(HURD) || defined(NETBSD) + || defined(HPUX) || defined(HURD) || defined(NETBSD) || defined(FREEBSD) /* Under Irix 5.x or HP/UX, we may get SIGBUS. */ /* Pthreads doesn't exist under Irix 5.x, so we */ /* don't have to worry in the threads case. */ @@ -776,10 +776,10 @@ void GC_reset_fault_handler() { # if defined(SUNOS5SIGS) || defined(IRIX5) \ - || defined(OSF1) || defined(HURD) || defined(NETBSD) + || defined(OSF1) || defined(HURD) || defined(NETBSD) || defined(FREEBSD) (void) sigaction(SIGSEGV, &old_segv_act, 0); # if defined(IRIX5) && defined(_sigargs) /* Irix 5.x, not 6.x */ \ - || defined(HPUX) || defined(HURD) || defined(NETBSD) + || defined(HPUX) || defined(HURD) || defined(NETBSD) || defined(FREEBSD) (void) sigaction(SIGBUS, &old_bus_act, 0); # endif # else Index: libgc/dyn_load.c =================================================================== --- libgc/dyn_load.c (revision 42774) +++ libgc/dyn_load.c (working copy) @@ -96,20 +96,28 @@ /* Newer versions of GNU/Linux define this macro. We * define it similarly for any ELF systems that don't. */ # ifndef ElfW -# ifdef NETBSD -# if ELFSIZE == 32 +# ifdef FREEBSD +# if __ELF_WORD_SIZE == 32 # define ElfW(type) Elf32_##type # else # define ElfW(type) Elf64_##type # endif # else -# if !defined(ELF_CLASS) || ELF_CLASS == ELFCLASS32 -# define ElfW(type) Elf32_##type +# ifdef NETBSD +# if ELFSIZE == 32 +# define ElfW(type) Elf32_##type +# else +# define ElfW(type) Elf64_##type +# endif # else -# define ElfW(type) Elf64_##type +# if !defined(ELF_CLASS) || ELF_CLASS == ELFCLASS32 +# define ElfW(type) Elf32_##type +# else +# define ElfW(type) Elf64_##type +# endif # endif # endif -# endif +# endif #if defined(SUNOS5DL) && !defined(USE_PROC_FOR_LIBRARIES) Index: configure.in =================================================================== --- configure.in (revision 42774) +++ configure.in (working copy) @@ -130,9 +130,34 @@ # TLS is only partially implemented on -CURRENT (compiler support # but NOT library support) # - with_nptl=no with_tls=pthread ;; + *-*-*freebsd6*) + platform_win32=no + if test "x$PTHREAD_CFLAGS" = "x"; then + CPPFLAGS="$CPPFLAGS -DGC_FREEBSD_THREADS" + libmono_cflags= + else + CPPFLAGS="$CPPFLAGS $PTHREAD_CFLAGS -DGC_FREEBSD_THREADS" + libmono_cflags="$PTHREAD_CFLAGS" + fi + if test "x$PTHREAD_LIBS" = "x"; then + LDFLAGS="$LDFLAGS -lpthread" + libmono_ldflags="-lpthread" + else + LDFLAGS="$LDFLAGS $PTHREAD_LIBS" + libmono_ldflags="$PTHREAD_LIBS" + fi + need_link_unlink=yes + AC_DEFINE(PTHREAD_POINTER_ID) + libdl= + libgc_threads=pthreads + with_sigaltstack=yes +# TLS is only partially implemented on -CURRENT (compiler support +# but NOT library support) +# + with_tls=pthread + ;; *-*-*openbsd*) platform_win32=no CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE -DGC_FREEBSD_THREADS" @@ -258,7 +283,17 @@ # for mono/dis AC_CHECK_HEADERS(wchar.h) -AC_CHECK_HEADERS(ieeefp.h) +case "$host" in + *-*-*freebsd6*) + AC_CHECK_HEADERS(ieeefp.h) + ;; + *-*-*freebsd*) + /* Only freebsd6 has a working ieeefp.h */ + ;; + *) + AC_CHECK_HEADERS(ieeefp.h) + ;; +esac AC_MSG_CHECKING(for isinf) AC_TRY_LINK([#include <math.h>], [ int f = isinf (1); @@ -837,7 +872,6 @@ else AC_TRY_RUN([ #include <pthread.h> - __thread int i; static int res1, res2; @@ -886,7 +920,9 @@ #include <signal.h> #include <pthread.h> #include <sys/wait.h> - + #if defined(__FreeBSD__) || defined(__NetBSD__) + #define SA_STACK SA_ONSTACK + #endif static void sigsegv_signal_handler (int _dummy, siginfo_t *info, void *context) { @@ -1547,8 +1583,8 @@ PREVIEW=yes AC_ARG_WITH(preview, [ --with-preview=yes,no If you want to install the 2.0 FX preview],[ - if test x$with_preview = xyes; then - PREVIEW=yes + if test x$with_preview = xno; then + PREVIEW=no fi ]) Index: ikvm-native/jni.c =================================================================== --- ikvm-native/jni.c (revision 42774) +++ ikvm-native/jni.c (working copy) @@ -28,9 +28,9 @@ #include <malloc.h> #define ALLOCA _alloca #else +#if !defined(__FreeBSD__) && !defined(__NetBSD__) #include <alloca.h> -/* alloca is in stdlib.h on freebsd */ -#include <stdlib.h> +#endif #define ALLOCA alloca #endif Index: mono/mini/exceptions-x86.c =================================================================== --- mono/mini/exceptions-x86.c (revision 42774) +++ mono/mini/exceptions-x86.c (working copy) @@ -25,6 +25,10 @@ #include "mini.h" #include "mini-x86.h" +#if defined(__FreeBSD__) +#include <ucontext.h> +#endif + #ifdef PLATFORM_WIN32 static MonoW32ExceptionHandler fpe_handler; static MonoW32ExceptionHandler ill_handler; @@ -549,6 +553,17 @@ #ifdef MONO_ARCH_USE_SIGACTION ucontext_t *ctx = (ucontext_t*)sigctx; +#if defined(__FreeBSD__) + mctx->eax = ctx->uc_mcontext.mc_eax; + mctx->ebx = ctx->uc_mcontext.mc_ebx; + mctx->ecx = ctx->uc_mcontext.mc_ecx; + mctx->edx = ctx->uc_mcontext.mc_edx; + mctx->ebp = ctx->uc_mcontext.mc_ebp; + mctx->esp = ctx->uc_mcontext.mc_esp; + mctx->esi = ctx->uc_mcontext.mc_esi; + mctx->edi = ctx->uc_mcontext.mc_edi; + mctx->eip = ctx->uc_mcontext.mc_eip; +#else mctx->eax = ctx->uc_mcontext.gregs [REG_EAX]; mctx->ebx = ctx->uc_mcontext.gregs [REG_EBX]; mctx->ecx = ctx->uc_mcontext.gregs [REG_ECX]; @@ -558,6 +573,7 @@ mctx->esi = ctx->uc_mcontext.gregs [REG_ESI]; mctx->edi = ctx->uc_mcontext.gregs [REG_EDI]; mctx->eip = ctx->uc_mcontext.gregs [REG_EIP]; +#endif #else struct sigcontext *ctx = (struct sigcontext *)sigctx; @@ -579,6 +595,18 @@ #ifdef MONO_ARCH_USE_SIGACTION ucontext_t *ctx = (ucontext_t*)sigctx; +#if def(__FreeBSD__) + ctx->uc_mcontext.mc_eax = mctx->eax; + ctx->uc_mcontext.mc_ebx = mctx->ebx; + ctx->uc_mcontext.mc_ecx = mctx->ecx; + ctx->uc_mcontext.mc_edx = mctx->edx; + ctx->uc_mcontext.mc_ebp = mctx->ebp; + ctx->uc_mcontext.mc_esp = mctx->esp; + ctx->uc_mcontext.mc_esi = mctx->esi; + ctx->uc_mcontext.mc_edi = mctx->edi; + ctx->uc_mcontext.mc_eip = mctx->eip; + +#else ctx->uc_mcontext.gregs [REG_EAX] = mctx->eax; ctx->uc_mcontext.gregs [REG_EBX] = mctx->ebx; ctx->uc_mcontext.gregs [REG_ECX] = mctx->ecx; @@ -588,6 +616,7 @@ ctx->uc_mcontext.gregs [REG_ESI] = mctx->esi; ctx->uc_mcontext.gregs [REG_EDI] = mctx->edi; ctx->uc_mcontext.gregs [REG_EIP] = mctx->eip; +#endif #else struct sigcontext *ctx = (struct sigcontext *)sigctx; @@ -608,7 +637,11 @@ { #ifdef MONO_ARCH_USE_SIGACTION ucontext_t *ctx = (ucontext_t*)sigctx; +#if def(__FreeBSD__) + return (gpointer)ctx->uc_mcontext.mc_eip; +#else return (gpointer)ctx->uc_mcontext.gregs [REG_EIP]; +#endif #else struct sigcontext *ctx = sigctx; return (gpointer)ctx->SC_EIP; Index: mono/mini/mini-x86.c =================================================================== --- mono/mini/mini-x86.c (revision 42774) +++ mono/mini/mini-x86.c (working copy) @@ -4691,6 +4691,9 @@ pthread_getattr_np( self, &attr ); #else #ifdef HAVE_PTHREAD_ATTR_GET_NP +#if defined(__FreeBSD__) + pthread_attr_init( &attr ); +#endif pthread_attr_get_np( self, &attr ); #elif defined(sun) pthread_attr_init( &attr ); Index: mono/mini/mini-x86.h =================================================================== --- mono/mini/mini-x86.h (revision 42774) +++ mono/mini/mini-x86.h (working copy) @@ -77,17 +77,21 @@ #ifndef PLATFORM_WIN32 #ifdef HAVE_WORKING_SIGALTSTACK - #define MONO_ARCH_SIGSEGV_ON_ALTSTACK #define MONO_ARCH_USE_SIGACTION -/* NetBSD doesn't define SA_STACK */ -#ifndef SA_STACK -#define SA_STACK SA_ONSTACK -#endif -#endif +/* FreeBSD and NetBSD need SA_STACK and MAP_ANON re-definitions */ +# if defined(__FreeBSD__) || defined(__NetBSD__) +# ifndef SA_STACK +# define SA_STACK SA_ONSTACK +# endif +# ifndef MAP_ANONYMOUS +# define MAP_ANONYMOUS MAP_ANON +# endif +# endif /* BSDs */ -#endif +#endif /* HAVE_WORKING_SIGALTSTACK */ +#endif /* !PLATFORM_WIN32 */ /* Enables OP_LSHL, OP_LSHL_IMM, OP_LSHR, OP_LSHR_IMM, OP_LSHR_UN, OP_LSHR_UN_IMM */ #define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS