0.8.21.49: Fixes for OS X 10.4 "Tiger"
[sbcl.git] / src / runtime / bsd-os.c
index 4f76233..eb07274 100644 (file)
@@ -21,6 +21,9 @@
 #include <stdio.h>
 #include <sys/param.h>
 #include <sys/file.h>
+#include <unistd.h>
+#include <assert.h>
+#include "sbcl.h"
 #include "./signal.h"
 #include "os.h"
 #include "arch.h"
 #include "interrupt.h"
 #include "interr.h"
 #include "lispregs.h"
-#include "sbcl.h"
 #include "thread.h"
+#include "runtime.h"
+#include "genesis/static-symbols.h"
+#include "genesis/fdefn.h"
 
 #include <sys/types.h>
 #include <signal.h>
 /* #include <sys/sysinfo.h> */
 #include "validate.h"
-
 \f
-vm_size_t os_vm_page_size;
+os_vm_size_t os_vm_page_size;
 
+#ifdef __NetBSD__
+#include <sys/resource.h>
+#include <sys/sysctl.h>
+#include <string.h>
+
+static void netbsd_init();
+#endif /* __NetBSD__ */
 void os_init(void)
 {
     os_vm_page_size = getpagesize();
+
+#ifdef __NetBSD__
+    netbsd_init();
+#endif /* __NetBSD__ */
 }
 
 int *os_context_pc_addr(os_context_t *context)
@@ -50,7 +66,9 @@ int *os_context_pc_addr(os_context_t *context)
     return CONTEXT_ADDR_FROM_STEM(eip);
 #elif defined __OpenBSD__
     return CONTEXT_ADDR_FROM_STEM(pc);
-#elif defined DARWIN
+#elif defined __NetBSD__
+    return CONTEXT_ADDR_FROM_STEM(EIP);
+#elif defined LISP_FEATURE_DARWIN
     return &context->uc_mcontext->ss.srr0;
 #else
 #error unsupported BSD variant
@@ -63,7 +81,7 @@ os_context_sigmask_addr(os_context_t *context)
     /* (Unlike most of the other context fields that we access, the
      * signal mask field is a field of the basic, outermost context
      * struct itself both in FreeBSD 4.0 and in OpenBSD 2.6.) */
-#if defined __FreeBSD__ || defined DARWIN
+#if defined __FreeBSD__  || __NetBSD__ || defined LISP_FEATURE_DARWIN
     return &context->uc_sigmask;
 #elif defined __OpenBSD__
     return &context->sc_mask;
@@ -162,21 +180,22 @@ memory_fault_handler(int signal, siginfo_t *siginfo, void *void_context)
 {
     /* The way that we extract low level information like the fault
      * address is not specified by POSIX. */
-#if defined __FreeBSD__
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
     void *fault_addr = siginfo->si_addr;
-#elif defined __OpenBSD__
-    void *fault_addr = siginfo->si_addr;
-#elif defined DARWIN
+#elif defined LISP_FEATURE_DARWIN
     void *fault_addr = siginfo->si_addr;
 #else
 #error unsupported BSD variant
 #endif
+
     os_context_t *context = arch_os_get_context(&void_context);
     if (!gencgc_handle_wp_violation(fault_addr)) 
-        if(!handle_control_stack_guard_triggered(context,fault_addr))
-           /* FIXME is this context or void_context?  not that it */
-           /* makes a difference currently except on linux/sparc */
-           interrupt_handle_now(signal, siginfo, void_context);
+        if(!handle_guard_page_triggered(context,fault_addr))
+#ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
+           arrange_return_to_lisp_function(context, SymbolFunction(MEMORY_FAULT_ERROR));
+#else
+           interrupt_handle_now(signal, siginfo, context);
+#endif
 }
 void
 os_install_interrupt_handlers(void)
@@ -198,8 +217,10 @@ sigsegv_handler(int signal, siginfo_t *info, void* void_context)
     
     addr = arch_get_bad_addr(signal,info,context);
     if(!interrupt_maybe_gc(signal, info, context))
-       if(!handle_control_stack_guard_triggered(context,addr))
+       if(!handle_guard_page_triggered(context,addr))
            interrupt_handle_now(signal, info, context);
+    /* Work around G5 bug; fix courtesy gbyers */
+    DARWIN_FIX_CONTEXT(context);
 }
 
 void
@@ -211,6 +232,44 @@ os_install_interrupt_handlers(void)
 }
 
 #endif /* defined GENCGC */
+
+#ifdef __NetBSD__
+static void netbsd_init()
+{
+    struct rlimit rl;
+    int mib[2], osrev;
+    size_t len;
+
+    /* Are we running on a sufficiently functional kernel? */
+    mib[0] = CTL_KERN;
+    mib[1] = KERN_OSREV;
+
+    len = sizeof(osrev);
+    sysctl(mib, 2, &osrev, &len, NULL, 0);
+
+    /* If we're older than 2.0... */
+    if (osrev < 200000000) {
+       fprintf(stderr, "osrev = %d (needed at least 200000000).\n", osrev);
+       lose("NetBSD kernel too old to run sbcl.\n");
+    }
+    
+    /* NetBSD counts mmap()ed space against the process's data size limit,
+     * so yank it up. This might be a nasty thing to do? */
+    getrlimit (RLIMIT_DATA, &rl);
+    /* Amazingly for such a new port, the provenance and meaning of
+       this number are unknown.  It might just mean REALLY_BIG_LIMIT,
+       or possibly it should be calculated from dynamic space size.
+       -- CSR, 2004-04-08 */
+    rl.rlim_cur = 1073741824;
+    if (setrlimit (RLIMIT_DATA, &rl) < 0) {
+       fprintf (stderr, 
+                "RUNTIME WARNING: unable to raise process data size limit:\n\
+  %s.\n\
+The system may fail to start.\n",
+                strerror(errno));
+    }
+}
+#endif /* __NetBSD__ */
 \f
 /* threads */
 
@@ -218,9 +277,6 @@ os_install_interrupt_handlers(void)
 #ifdef LISP_FEATURE_SB_THREAD
 #error "Define threading support functions"
 #else
-struct thread *arch_os_get_current_thread() {
-    return all_threads;
-}
 int arch_os_thread_init(struct thread *thread) {
   stack_t sigstack;
 #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK