Skip to content

Commit

Permalink
Compile on amd64 Haiku (mono#4473)
Browse files Browse the repository at this point in the history
* Compile on amd64 Haiku

Use sigcontext (somewhat like win32, or x86) on Haiku amd64.

On amd64, Haiku doesn't have issues with marshalling 64-bit values,
but it currently does have issues with SGen either causing a stall
or a core dump. As such, while it can compile the stdlib (further
than x86 got), it's still a work in progress.

* Use set_real_time_clock for sys-time.c on Haiku

* Get mono-boehm compiling on Haiku again

It still doesn't work. Initialization will call GC_mark_from, which
will cause a segmentation fault as it decrements pointers. (Mono
will enter an infinite loop in mono_get_hazardous_pointer as a result.)

For now, mono-sgen will continue to be used by default.
  • Loading branch information
NattyNarwhal authored and luhenry committed Dec 6, 2017
1 parent b683e10 commit 5a581fb
Show file tree
Hide file tree
Showing 11 changed files with 150 additions and 23 deletions.
2 changes: 0 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -368,8 +368,6 @@ case "$host" in
AC_DEFINE(PTHREAD_POINTER_ID)
dnl Haiku does not support static TLS with __thread
with_tls=pthread
dnl Boehm is too much work to backport Haiku support for
support_boehm=no
libgc_threads=pthreads
use_sigposix=yes
;;
Expand Down
4 changes: 4 additions & 0 deletions libgc/configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ case "$THREADS" in
AC_DEFINE(GC_AIX_THREADS)
AC_DEFINE(_REENTRANT)
;;
*-*-haiku*)
AC_DEFINE(GC_HAIKU_THREADS)
AC_DEFINE(_REENTRANT)
;;
*-*-hpux*)
AC_MSG_WARN("Only HP/UX 11 threads are supported.")
AC_DEFINE(GC_HPUX_THREADS)
Expand Down
19 changes: 18 additions & 1 deletion libgc/dyn_load.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
!(defined(FREEBSD) && defined(__ELF__)) && \
!(defined(OPENBSD) && (defined(__ELF__) || defined(M68K))) && \
!(defined(NETBSD) && defined(__ELF__)) && !defined(HURD) && \
!defined(DARWIN)
!defined(DARWIN) && !defined(HAIKU)
--> We only know how to find data segments of dynamic libraries for the
--> above. Additional SVR4 variants might not be too
--> hard to add.
Expand Down Expand Up @@ -1258,6 +1258,23 @@ GC_bool GC_register_main_static_data()

#endif /* DARWIN */

#if defined(HAIKU)

#include <kernel/image.h>

void GC_register_dynamic_libraries()
{
image_info info;
int32 cookie = 0;
while (get_next_image_info(0, &cookie, &info) == B_OK)
{
void *data = info.data;
GC_add_roots_inner(data, data + info.data_size, TRUE);
}
}

#endif /* HAIKU */

#else /* !DYNAMIC_LOADING */

#ifdef PCR
Expand Down
2 changes: 1 addition & 1 deletion libgc/include/gc_config_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) || \
defined(GC_DGUX386_THREADS) || defined(GC_DARWIN_THREADS) || \
defined(GC_AIX_THREADS) || defined(GC_NETBSD_THREADS) || \
defined(GC_OPENBSD_THREADS) || \
defined(GC_OPENBSD_THREADS) || defined(GC_HAIKU_THREADS) ||\
(defined(GC_WIN32_THREADS) && defined(__CYGWIN32__))
# define GC_PTHREADS
# endif
Expand Down
33 changes: 32 additions & 1 deletion libgc/include/private/gcconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,16 @@
# define BEOS
# define mach_type_known
# endif
# if defined(__HAIKU__) && defined(_X86_)
# define I386
# define HAIKU
# define mach_type_known
# endif
# if defined(__HAIKU__) && defined(__amd64__)
# define X86_64
# define HAIKU
# define mach_type_known
# endif
# if defined(LINUX) && (defined(i386) || defined(__i386__))
# define I386
# define mach_type_known
Expand Down Expand Up @@ -1164,6 +1174,15 @@
extern int etext[];
# define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
# endif
# ifdef HAIKU
# define OS_TYPE "HAIKU"
# include <OS.h>
# define GETPAGESIZE() B_PAGE_SIZE
extern int etext[];
# define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
# define DYNAMIC_LOADING
# define MPROTECT_VDB
# endif
# ifdef SUNOS5
# define OS_TYPE "SUNOS5"
extern int _etext[], _end[];
Expand Down Expand Up @@ -2134,6 +2153,15 @@
/* There seems to be some issues with trylock hanging on darwin. This
should be looked into some more */
# endif
# ifdef HAIKU
# define OS_TYPE "HAIKU"
# include <OS.h>
# define GETPAGESIZE() B_PAGE_SIZE
extern int etext[];
# define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
# define DYNAMIC_LOADING
# define MPROTECT_VDB
# endif
# ifdef FREEBSD
# define OS_TYPE "FREEBSD"
# ifndef GC_FREEBSD_THREADS
Expand Down Expand Up @@ -2251,7 +2279,7 @@
# if defined(SVR4) || defined(LINUX) || defined(IRIX5) || defined(HPUX) \
|| defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \
|| defined(DGUX) || defined(BSD) || defined(SUNOS4) \
|| defined(_AIX) || defined(DARWIN) || defined(OSF1)
|| defined(_AIX) || defined(DARWIN) || defined(OSF1) || defined(HAIKU)
# define UNIX_LIKE /* Basic Unix-like system calls work. */
# endif

Expand Down Expand Up @@ -2507,6 +2535,9 @@
# if defined(SN_TARGET_PS3)
extern void *ps3_get_mem (size_t size);
# define GET_MEM(bytes) (struct hblk*) ps3_get_mem (bytes)
# elif defined(HAIKU)
ptr_t GC_haiku_get_mem(GC_word bytes);
# define GET_MEM(bytes) (struct hblk*)GC_haiku_get_mem(bytes)
# else
extern ptr_t GC_unix_get_mem(word size);
# define GET_MEM(bytes) (struct hblk *)GC_unix_get_mem(bytes)
Expand Down
40 changes: 31 additions & 9 deletions libgc/os_dep.c
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ void GC_enable_signals(void)
&& !defined(MACOS) && !defined(DJGPP) && !defined(DOS4GW) \
&& !defined(NOSYS) && !defined(ECOS) && !defined(SN_TARGET_PS3)

# if defined(sigmask) && !defined(UTS4) && !defined(HURD)
# if defined(sigmask) && !defined(UTS4) && !defined(HURD) && !defined(HAIKU)
/* Use the traditional BSD interface */
# define SIGSET_T int
# define SIG_DEL(set, signal) (set) &= ~(sigmask(signal))
Expand Down Expand Up @@ -764,14 +764,14 @@ ptr_t GC_get_stack_base()

# endif /* MS Windows */

# ifdef BEOS
# ifdef HAIKU
# include <kernel/OS.h>
ptr_t GC_get_stack_base(){
thread_info th;
get_thread_info(find_thread(NULL),&th);
return th.stack_end;
}
# endif /* BEOS */
# endif /* HAIKU */


# ifdef OS2
Expand Down Expand Up @@ -1122,7 +1122,7 @@ void *GC_set_stackbottom = NULL;

#endif /* FREEBSD_STACKBOTTOM */

#if !defined(BEOS) && !defined(AMIGA) && !defined(MSWIN32) \
#if !defined(HAIKU) && !defined(AMIGA) && !defined(MSWIN32) \
&& !defined(MSWINCE) && !defined(OS2) && !defined(NOSYS) && !defined(ECOS) \
&& !defined(GC_OPENBSD_THREADS)

Expand Down Expand Up @@ -1182,7 +1182,7 @@ ptr_t GC_get_stack_base()
# endif /* STACKBOTTOM */
}

# endif /* ! AMIGA, !OS 2, ! MS Windows, !BEOS, !NOSYS, !ECOS */
# endif /* ! AMIGA, !OS 2, ! MS Windows, !HAIKU, !NOSYS, !ECOS */

#if defined(GC_OPENBSD_THREADS)

Expand Down Expand Up @@ -1957,6 +1957,19 @@ word bytes;
}
# endif

#if defined(HAIKU)
#include <stdlib.h>

ptr_t GC_haiku_get_mem(word bytes)
{
void* mem;
if (posix_memalign(&mem, GC_page_size, bytes) == 0)
return mem;
else
return NULL;
}
#endif

#ifdef USE_MUNMAP

/* For now, this only works on Win32/WinCE and some Unix-like */
Expand Down Expand Up @@ -2393,7 +2406,9 @@ GC_bool is_ptrfree;

# include <sys/mman.h>
# include <signal.h>
# include <sys/syscall.h>
# if !defined(HAIKU)
# include <sys/syscall.h>
# endif

# define PROTECT(addr, len) \
if (mprotect((caddr_t)(addr), (size_t)(len), \
Expand Down Expand Up @@ -2450,13 +2465,13 @@ GC_bool is_ptrfree;
#endif /* SUNOS4 || (FREEBSD && !SUNOS5SIGS) */

#if defined(SUNOS5SIGS) || defined(OSF1) || defined(LINUX) \
|| defined(HURD)
|| defined(HURD) || defined(HAIKU)
# ifdef __STDC__
typedef void (* SIG_PF)(int);
# else
typedef void (* SIG_PF)();
# endif
#endif /* SUNOS5SIGS || OSF1 || LINUX || HURD */
#endif /* SUNOS5SIGS || OSF1 || LINUX || HURD || HAIKU */

#if defined(MSWIN32)
typedef LPTOP_LEVEL_EXCEPTION_FILTER SIG_PF;
Expand Down Expand Up @@ -2634,6 +2649,13 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */
/* architectures. */
# endif /* LINUX */

# if defined(HAIKU)
# include <errno.h>
# define CODE_OK TRUE
# define SIG_OK (sig == SIGSEGV)
void GC_write_failt_handler(int sig, siginfo_t *scp, void * context)
#endif /* HAIKU */

# if defined(SUNOS5SIGS)
# ifdef __STDC__
void GC_write_fault_handler(int sig, SIGINFO_T *scp, void * context)
Expand Down Expand Up @@ -2679,7 +2701,7 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */
# if defined(OSF1) && defined(ALPHA)
char * addr = (char *) (scp -> sc_traparg_a0);
# endif
# ifdef SUNOS5SIGS
# if defined(SUNOS5SIGS) || defined(HAIKU)
char * addr = (char *) (scp -> si_addr);
# endif
# ifdef LINUX
Expand Down
2 changes: 1 addition & 1 deletion libgc/pthread_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -1135,7 +1135,7 @@ void GC_thr_init()
# if defined(GC_HPUX_THREADS)
GC_nprocs = pthread_num_processors_np();
# endif
# if defined(GC_OSF1_THREADS) || defined(GC_AIX_THREADS)
# if defined(GC_OSF1_THREADS) || defined(GC_AIX_THREADS) || defined(GC_HAIKU_THREADS)
GC_nprocs = sysconf(_SC_NPROCESSORS_ONLN);
if (GC_nprocs <= 0) GC_nprocs = 1;
# endif
Expand Down
2 changes: 1 addition & 1 deletion mono/mini/mini-amd64.h
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ typedef struct {
*/
#define MONO_ARCH_VARARG_ICALLS 1

#if !defined( HOST_WIN32 ) && defined (HAVE_SIGACTION)
#if !defined( HOST_WIN32 ) && !defined(__HAIKU__) && defined (HAVE_SIGACTION)

#define MONO_ARCH_USE_SIGACTION 1

Expand Down
42 changes: 42 additions & 0 deletions mono/utils/mono-context.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,27 @@ mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
mctx->gregs [AMD64_R13] = context->R13;
mctx->gregs [AMD64_R14] = context->R14;
mctx->gregs [AMD64_R15] = context->R15;
#elif defined(__HAIKU__)
// Haiku uses sigcontext because there's no ucontext
struct sigcontext *ctx = (struct sigcontext *)sigctx;

mctx->gregs [AMD64_RIP] = ctx->regs.rip;
mctx->gregs [AMD64_RAX] = ctx->regs.rax;
mctx->gregs [AMD64_RCX] = ctx->regs.rcx;
mctx->gregs [AMD64_RDX] = ctx->regs.rdx;
mctx->gregs [AMD64_RBX] = ctx->regs.rbx;
mctx->gregs [AMD64_RSP] = ctx->regs.rsp;
mctx->gregs [AMD64_RBP] = ctx->regs.rbp;
mctx->gregs [AMD64_RSI] = ctx->regs.rsi;
mctx->gregs [AMD64_RDI] = ctx->regs.rdi;
mctx->gregs [AMD64_R8] = ctx->regs.r8;
mctx->gregs [AMD64_R9] = ctx->regs.r9;
mctx->gregs [AMD64_R10] = ctx->regs.r10;
mctx->gregs [AMD64_R11] = ctx->regs.r11;
mctx->gregs [AMD64_R12] = ctx->regs.r12;
mctx->gregs [AMD64_R13] = ctx->regs.r13;
mctx->gregs [AMD64_R14] = ctx->regs.r14;
mctx->gregs [AMD64_R15] = ctx->regs.r15;
#else
g_assert_not_reached ();
#endif
Expand Down Expand Up @@ -305,6 +326,27 @@ mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
context->R13 = mctx->gregs [AMD64_R13];
context->R14 = mctx->gregs [AMD64_R14];
context->R15 = mctx->gregs [AMD64_R15];
#elif defined(__HAIKU__)
// Haiku uses sigcontext because there's no ucontext
struct sigcontext *ctx = (struct sigcontext *)sigctx;

ctx->regs.rip = mctx->gregs [AMD64_RIP];
ctx->regs.rax = mctx->gregs [AMD64_RAX];
ctx->regs.rcx = mctx->gregs [AMD64_RCX];
ctx->regs.rdx = mctx->gregs [AMD64_RDX];
ctx->regs.rbx = mctx->gregs [AMD64_RBX];
ctx->regs.rsp = mctx->gregs [AMD64_RSP];
ctx->regs.rbp = mctx->gregs [AMD64_RBP];
ctx->regs.rsi = mctx->gregs [AMD64_RSI];
ctx->regs.rdi = mctx->gregs [AMD64_RDI];
ctx->regs.r8 = mctx->gregs [AMD64_R8];
ctx->regs.r9 = mctx->gregs [AMD64_R9];
ctx->regs.r10 = mctx->gregs [AMD64_R10];
ctx->regs.r11 = mctx->gregs [AMD64_R11];
ctx->regs.r12 = mctx->gregs [AMD64_R12];
ctx->regs.r13 = mctx->gregs [AMD64_R13];
ctx->regs.r14 = mctx->gregs [AMD64_R14];
ctx->regs.r15 = mctx->gregs [AMD64_R15];
#else
g_assert_not_reached ();
#endif
Expand Down
13 changes: 12 additions & 1 deletion mono/utils/mono-context.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,23 @@ typedef struct {

#if !defined( HOST_WIN32 )

#if defined(HAVE_SIGACTION) || defined(__APPLE__) // the __APPLE__ check is required for the tvos simulator, which has ucontext_t but not sigaction
// the __APPLE__ check is required for the tvos simulator, which has ucontext_t but not sigaction
#if defined(HAVE_SIGACTION) || defined(__APPLE__)
#define MONO_SIGNAL_USE_UCONTEXT_T 1
#endif

#endif

#ifdef __HAIKU__
/* sigcontext surrogate */
struct sigcontext {
vregs regs;
};

// Haiku doesn't support this
#undef MONO_SIGNAL_USE_UCONTEXT_T
#endif

typedef struct {
mgreg_t gregs [AMD64_NREG];
#if defined(__APPLE__) || (defined(__linux__) && defined(__GLIBC__)) || defined(HOST_WIN32)
Expand Down
14 changes: 8 additions & 6 deletions support/sys-time.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
#include <sys/types.h>
#include <sys/time.h>
#include <string.h>
#ifdef __HAIKU__
#include <os/kernel/OS.h>
#endif

#include "map.h"
#include "mph.h"
Expand Down Expand Up @@ -47,11 +50,6 @@ Mono_Posix_Syscall_settimeofday (
struct Mono_Posix_Timeval *tv,
struct Mono_Posix_Timezone *tz)
{
#if defined(__HAIKU__)
/* FIXME: Haiku doesn't support this either, consider
using set_real_time_clock instead? */
return -1;
#else
struct timeval _tv = {0};
struct timeval *ptv = NULL;
struct timezone _tz = {0};
Expand All @@ -69,10 +67,14 @@ Mono_Posix_Syscall_settimeofday (
ptz = &_tz;
}

#ifdef __HAIKU__
set_real_time_clock(ptv->tv_sec);
r = 0;
#else
r = settimeofday (ptv, ptz);
#endif

return r;
#endif
}

static inline struct timeval*
Expand Down

0 comments on commit 5a581fb

Please sign in to comment.