summaryrefslogtreecommitdiff
path: root/os_dep.c
diff options
context:
space:
mode:
Diffstat (limited to 'os_dep.c')
-rw-r--r--os_dep.c84
1 files changed, 51 insertions, 33 deletions
diff --git a/os_dep.c b/os_dep.c
index cb32bdd..21d0563 100644
--- a/os_dep.c
+++ b/os_dep.c
@@ -129,7 +129,7 @@
#ifdef UNIX_LIKE
# include <fcntl.h>
-# ifdef SUNOS5SIGS
+# if defined(SUNOS5SIGS) && !defined(FREEBSD)
# include <sys/siginfo.h>
# endif
/* Define SETJMP and friends to be the version that restores */
@@ -2192,7 +2192,7 @@ GC_bool is_ptrfree;
/* Using vm_protect (mach syscall) over mprotect (BSD syscall) seems to
decrease the likelihood of some of the problems described below. */
#include <mach/vm_map.h>
- extern mach_port_t GC_task_self;
+ static mach_port_t GC_task_self;
#define PROTECT(addr,len) \
if(vm_protect(GC_task_self,(vm_address_t)(addr),(vm_size_t)(len), \
FALSE,VM_PROT_READ) != KERN_SUCCESS) { \
@@ -2225,9 +2225,9 @@ GC_bool is_ptrfree;
# endif /* !DARWIN */
# endif /* MSWIN32 || MSWINCE || DARWIN */
-#if defined(SUNOS4) || defined(FREEBSD)
+#if defined(SUNOS4) || (defined(FREEBSD) && !defined(SUNOS5SIGS))
typedef void (* SIG_PF)();
-#endif /* SUNOS4 || FREEBSD */
+#endif /* SUNOS4 || (FREEBSD && !SUNOS5SIGS) */
#if defined(SUNOS5SIGS) || defined(OSF1) || defined(LINUX) \
|| defined(HURD)
@@ -2254,13 +2254,13 @@ GC_bool is_ptrfree;
#endif /* IRIX5 || OSF1 || HURD */
#if defined(SUNOS5SIGS)
-# ifdef HPUX
-# define SIGINFO __siginfo
+# if defined(HPUX) || defined(FREEBSD)
+# define SIGINFO_T siginfo_t
# else
-# define SIGINFO siginfo
+# define SIGINFO_T struct siginfo
# endif
# ifdef __STDC__
- typedef void (* REAL_SIG_PF)(int, struct SIGINFO *, void *);
+ typedef void (* REAL_SIG_PF)(int, SIGINFO_T *, void *);
# else
typedef void (* REAL_SIG_PF)();
# endif
@@ -2280,8 +2280,11 @@ GC_bool is_ptrfree;
# if defined(ALPHA) || defined(M68K)
typedef void (* REAL_SIG_PF)(int, int, s_c *);
# else
-# if defined(IA64) || defined(HP_PA)
+# if defined(IA64) || defined(HP_PA) || defined(X86_64)
typedef void (* REAL_SIG_PF)(int, siginfo_t *, s_c *);
+ /* FIXME: */
+ /* According to SUSV3, the last argument should have type */
+ /* void * or ucontext_t * */
# else
typedef void (* REAL_SIG_PF)(int, s_c);
# endif
@@ -2356,7 +2359,7 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */
/*ARGSUSED*/
#if !defined(DARWIN)
-# if defined (SUNOS4) || defined(FREEBSD)
+# if defined (SUNOS4) || (defined(FREEBSD) && !defined(SUNOS5SIGS))
void GC_write_fault_handler(sig, code, scp, addr)
int sig, code;
struct sigcontext *scp;
@@ -2371,7 +2374,7 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */
# define SIG_OK (sig == SIGBUS)
# define CODE_OK (code == BUS_PAGE_FAULT)
# endif
-# endif /* SUNOS4 || FREEBSD */
+# endif /* SUNOS4 || (FREEBSD && !SUNOS5SIGS) */
# if defined(IRIX5) || defined(OSF1) || defined(HURD)
# include <errno.h>
@@ -2394,7 +2397,7 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */
# if defined(ALPHA) || defined(M68K)
void GC_write_fault_handler(int sig, int code, s_c * sc)
# else
-# if defined(IA64) || defined(HP_PA)
+# if defined(IA64) || defined(HP_PA) || defined(X86_64)
void GC_write_fault_handler(int sig, siginfo_t * si, s_c * scp)
# else
# if defined(ARM32)
@@ -2413,11 +2416,11 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */
# if defined(SUNOS5SIGS)
# ifdef __STDC__
- void GC_write_fault_handler(int sig, struct SIGINFO *scp, void * context)
+ void GC_write_fault_handler(int sig, SIGINFO_T *scp, void * context)
# else
void GC_write_fault_handler(sig, scp, context)
int sig;
- struct SIGINFO *scp;
+ SIGINFO_T *scp;
void * context;
# endif
# ifdef HPUX
@@ -2428,9 +2431,14 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */
|| (scp -> si_code == SEGV_UNKNOWN) \
|| (scp -> si_code == BUS_OBJERR)
# else
-# define SIG_OK (sig == SIGSEGV)
-# define CODE_OK (scp -> si_code == SEGV_ACCERR)
-# endif
+# ifdef FREEBSD
+# define SIG_OK (sig == SIGBUS)
+# define CODE_OK (scp -> si_code == BUS_PAGE_FAULT)
+# else
+# define SIG_OK (sig == SIGSEGV)
+# define CODE_OK (scp -> si_code == SEGV_ACCERR)
+# endif
+# endif
# endif /* SUNOS5SIGS */
# if defined(MSWIN32) || defined(MSWINCE)
@@ -2455,7 +2463,7 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */
char * addr = (char *) (scp -> si_addr);
# endif
# ifdef LINUX
-# if defined(I386) || defined (X86_64)
+# if defined(I386)
char * addr = (char *) (sc.cr2);
# else
# if defined(M68K)
@@ -2490,7 +2498,7 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */
# ifdef ALPHA
char * addr = get_fault_addr(sc);
# else
-# if defined(IA64) || defined(HP_PA)
+# if defined(IA64) || defined(HP_PA) || defined(X86_64)
char * addr = si -> si_addr;
/* I believe this is claimed to work on all platforms for */
/* Linux 2.3.47 and later. Hopefully we don't have to */
@@ -2533,6 +2541,10 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */
in_allocd_block = (HDR(addr) != 0);
# endif
if (!in_allocd_block) {
+ /* FIXME - We should make sure that we invoke the */
+ /* old handler with the appropriate calling */
+ /* sequence, which often depends on SA_SIGINFO. */
+
/* Heap blocks now begin and end on page boundaries */
SIG_PF old_handler;
@@ -2549,11 +2561,17 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */
return(EXCEPTION_CONTINUE_SEARCH);
# endif
} else {
-# if defined (SUNOS4) || defined(FREEBSD)
+# if defined (SUNOS4) \
+ || (defined(FREEBSD) && !defined(SUNOS5SIGS))
(*old_handler) (sig, code, scp, addr);
return;
# endif
# if defined (SUNOS5SIGS)
+ /*
+ * FIXME: For FreeBSD, this code should check if the
+ * old signal handler used the traditional BSD style and
+ * if so call it using that style.
+ */
(*(REAL_SIG_PF)old_handler) (sig, scp, context);
return;
# endif
@@ -2561,7 +2579,7 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */
# if defined(ALPHA) || defined(M68K)
(*(REAL_SIG_PF)old_handler) (sig, code, sc);
# else
-# if defined(IA64) || defined(HP_PA)
+# if defined(IA64) || defined(HP_PA) || defined(X86_64)
(*(REAL_SIG_PF)old_handler) (sig, si, scp);
# else
(*(REAL_SIG_PF)old_handler) (sig, sc);
@@ -2655,7 +2673,8 @@ void GC_dirty_init()
struct sigaction act, oldact;
/* We should probably specify SA_SIGINFO for Linux, and handle */
/* the different architectures more uniformly. */
-# if defined(IRIX5) || defined(LINUX) || defined(OSF1) || defined(HURD)
+# if defined(IRIX5) || defined(LINUX) && !defined(X86_64) \
+ || defined(OSF1) || defined(HURD)
act.sa_flags = SA_RESTART;
act.sa_handler = (SIG_PF)GC_write_fault_handler;
# else
@@ -2678,7 +2697,7 @@ void GC_dirty_init()
GC_err_printf0("Page size not multiple of HBLKSIZE\n");
ABORT("Page size not multiple of HBLKSIZE");
}
-# if defined(SUNOS4) || defined(FREEBSD)
+# if defined(SUNOS4) || (defined(FREEBSD) && !defined(SUNOS5SIGS))
GC_old_bus_handler = signal(SIGBUS, GC_write_fault_handler);
if (GC_old_bus_handler == SIG_IGN) {
GC_err_printf0("Previously ignored bus error!?");
@@ -2702,13 +2721,13 @@ void GC_dirty_init()
# endif
}
# endif
-# if defined(SUNOS5SIGS) || defined(IRIX5) || defined(LINUX) \
- || defined(OSF1) || defined(HURD)
+# if (defined(SUNOS5SIGS) && !defined(FREEBSD)) || defined(IRIX5) \
+ || defined(LINUX) || defined(OSF1) || defined(HURD)
/* SUNOS5SIGS includes HPUX */
# if defined(GC_IRIX_THREADS)
sigaction(SIGSEGV, 0, &oldact);
sigaction(SIGSEGV, &act, 0);
-# else
+# else
{
int res = sigaction(SIGSEGV, &act, &oldact);
if (res != 0) ABORT("Sigaction failed");
@@ -2734,8 +2753,9 @@ void GC_dirty_init()
GC_err_printf0("Replaced other SIGSEGV handler\n");
# endif
}
-# endif
-# if defined(HPUX) || defined(LINUX) || defined(HURD)
+# endif /* (SUNOS5SIGS && !FREEBSD) || IRIX5 || LINUX || OSF1 || HURD */
+# if defined(HPUX) || defined(LINUX) || defined(HURD) \
+ || (defined(FREEBSD) && defined(SUNOS5SIGS))
sigaction(SIGBUS, &act, &oldact);
GC_old_bus_handler = oldact.sa_handler;
if (GC_old_bus_handler == SIG_IGN) {
@@ -2747,7 +2767,7 @@ void GC_dirty_init()
GC_err_printf0("Replaced other SIGBUS handler\n");
# endif
}
-# endif /* HPUX || LINUX || HURD */
+# endif /* HPUX || LINUX || HURD || (FREEBSD && SUNOS5SIGS) */
# if defined(MSWIN32)
GC_old_segv_handler = SetUnhandledExceptionFilter(GC_write_fault_handler);
if (GC_old_segv_handler != NULL) {
@@ -3032,7 +3052,7 @@ word n;
#include <sys/procfs.h>
#include <sys/stat.h>
-#define INITIAL_BUF_SZ 4096
+#define INITIAL_BUF_SZ 16384
word GC_proc_buf_size = INITIAL_BUF_SZ;
char *GC_proc_buf;
@@ -3146,7 +3166,7 @@ int dummy;
GC_proc_buf = bufp = new_buf;
GC_proc_buf_size = new_size;
}
- if (syscall(SYS_read, GC_proc_fd, bufp, GC_proc_buf_size) <= 0) {
+ if (READ(GC_proc_fd, bufp, GC_proc_buf_size) <= 0) {
WARN("Insufficient space for /proc read\n", 0);
/* Punt: */
memset(GC_grungy_pages, 0xff, sizeof (page_hash_table));
@@ -3367,8 +3387,6 @@ extern kern_return_t exception_raise_state_identity(
#define MAX_EXCEPTION_PORTS 16
-static mach_port_t GC_task_self;
-
static struct {
mach_msg_type_number_t count;
exception_mask_t masks[MAX_EXCEPTION_PORTS];