X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fbsd-os.c;h=f31f5fc9ed7ddce6557b4d23387369bcaff21b91;hb=c3699db2053ff3b5ac6a98d4431c3789496002d8;hp=44b5a05b459ece20c31ca029f7f6265e6281226c;hpb=8fc5fda05f92d69c95b47e4ad7561d91dab18c3e;p=sbcl.git diff --git a/src/runtime/bsd-os.c b/src/runtime/bsd-os.c index 44b5a05..f31f5fc 100644 --- a/src/runtime/bsd-os.c +++ b/src/runtime/bsd-os.c @@ -18,10 +18,6 @@ * files for more information. */ -/* - * $Header$ - */ - #include #include #include @@ -30,94 +26,44 @@ #include "arch.h" #include "globals.h" #include "interrupt.h" +#include "interr.h" #include "lispregs.h" #include "sbcl.h" +#include "thread.h" #include #include /* #include */ -#include #include "validate.h" -vm_size_t os_vm_page_size; - -#if defined GENCGC -#include "gencgc.h" -#endif -/* The different BSD variants have diverged in exactly where they - * store signal context information, but at least they tend to use the - * same stems to name the structure fields, so by using this macro we - * can share a fair amount of code between different variants. */ -#if defined __FreeBSD__ -#define CONTEXT_ADDR_FROM_STEM(stem) &context->uc_mcontext.mc_ ## stem -#elif defined __OpenBSD__ -#define CONTEXT_ADDR_FROM_STEM(stem) &context->sc_ ## stem -#else -#error unsupported BSD variant -#endif -void -os_init(void) -{ - os_vm_page_size = getpagesize(); -} +vm_size_t os_vm_page_size; -/* KLUDGE: There is strong family resemblance in the signal context - * stuff in FreeBSD and OpenBSD, but in detail they're different in - * almost every line of code. It would be nice to find some way to - * factor out the commonality better; failing that, it might be best - * just to split this generic-BSD code into one variant for each BSD. */ - -int * -os_context_register_addr(os_context_t *context, int offset) +void os_init(void) { - switch(offset) { - case 0: - return CONTEXT_ADDR_FROM_STEM(eax); - case 2: - return CONTEXT_ADDR_FROM_STEM(ecx); - case 4: - return CONTEXT_ADDR_FROM_STEM(edx); - case 6: - return CONTEXT_ADDR_FROM_STEM(ebx); - case 8: - return CONTEXT_ADDR_FROM_STEM(esp); - case 10: - return CONTEXT_ADDR_FROM_STEM(ebp); - case 12: - return CONTEXT_ADDR_FROM_STEM(esi); - case 14: - return CONTEXT_ADDR_FROM_STEM(edi); - default: - return 0; - } + os_vm_page_size = getpagesize(); } -int * -os_context_pc_addr(os_context_t *context) +int *os_context_pc_addr(os_context_t *context) { #if defined __FreeBSD__ return CONTEXT_ADDR_FROM_STEM(eip); #elif defined __OpenBSD__ return CONTEXT_ADDR_FROM_STEM(pc); +#elif defined DARWIN + return &context->uc_mcontext->ss.srr0; #else #error unsupported BSD variant #endif } -int * -os_context_sp_addr(os_context_t *context) -{ - return CONTEXT_ADDR_FROM_STEM(esp); -} - sigset_t * 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__ +#if defined __FreeBSD__ || defined DARWIN return &context->uc_sigmask; #elif defined __OpenBSD__ return &context->sc_mask; @@ -168,11 +114,6 @@ os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len) } void -os_flush_icache(os_vm_address_t address, os_vm_size_t length) -{ -} - -void os_protect(os_vm_address_t address, os_vm_size_t length, os_vm_prot_t prot) { if (mprotect(address, length, prot) == -1) { @@ -192,25 +133,25 @@ in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen) boolean is_valid_lisp_addr(os_vm_address_t addr) { - return in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE) - || in_range_p(addr, STATIC_SPACE_START , STATIC_SPACE_SIZE ) - || in_range_p(addr, DYNAMIC_0_SPACE_START, DYNAMIC_SPACE_SIZE ) - || in_range_p(addr, DYNAMIC_1_SPACE_START, DYNAMIC_SPACE_SIZE ) - || in_range_p(addr, CONTROL_STACK_START , CONTROL_STACK_SIZE ) - || in_range_p(addr, BINDING_STACK_START , BINDING_STACK_SIZE ); + struct thread *th; + if(in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE) || + in_range_p(addr, STATIC_SPACE_START , STATIC_SPACE_SIZE) || + in_range_p(addr, DYNAMIC_SPACE_START , DYNAMIC_SPACE_SIZE)) + return 1; + for_each_thread(th) { + if((th->control_stack_start <= addr) && (addr < th->control_stack_end)) + return 1; + if(in_range_p(addr, th->binding_stack_start, BINDING_STACK_SIZE)) + return 1; + } + return 0; } /* * any OS-dependent special low-level handling for signals */ -#if !defined GENCGC - -void -os_install_interrupt_handlers(void) -{} - -#else +#if defined LISP_FEATURE_GENCGC /* * The GENCGC needs to be hooked into whatever signal is raised for @@ -225,291 +166,72 @@ memory_fault_handler(int signal, siginfo_t *siginfo, void *void_context) void *fault_addr = siginfo->si_addr; #elif defined __OpenBSD__ void *fault_addr = siginfo->si_addr; +#elif defined DARWIN + void *fault_addr = siginfo->si_addr; #else #error unsupported BSD variant #endif - if (!gencgc_handle_wp_violation(fault_addr)) { - interrupt_handle_now(signal, siginfo, void_context); - } + 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); } void os_install_interrupt_handlers(void) { -#if defined __FreeBSD__ - interrupt_install_low_level_handler(SIGBUS, memory_fault_handler); -#elif defined __OpenBSD__ - interrupt_install_low_level_handler(SIGSEGV, memory_fault_handler); -#else -#error unsupported BSD variant -#endif -} - -#endif /* !defined GENCGC */ - -/* feh! - * - * DL_WORKAROUND enables "stubbing" of various functions from libc et - * al. This is necessary when using dynamic linking in FreeBSD, as the - * symbols in the dynamic libraries will not have known addresses (in - * sbcl.nm). - * - * FIXME: This flag should be set in Config.bsd */ -#define DL_WORKAROUND 1 - -#if DL_WORKAROUND -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void *ldso_stub__dlopen(const char *path, int mode) -{ - return dlopen(path, mode); -} - -void *ldso_stub__dlsym(void *handle, const char *symbol) -{ - return dlsym(handle, symbol); -} - -const char *ldso_stub__dlerror(void) -{ - return dlerror(); -} -int ldso_stub__access(const char *path, int mode) -{ - return access(path, mode); -} - -double ldso_stub__acos(double x) -{ - return acos(x); -} - -double ldso_stub__acosh(double x) -{ - return acosh(x); -} - -double ldso_stub__asin(double x) -{ - return asin(x); -} - -double ldso_stub__asinh(double x) -{ - return asin(x); -} - -double ldso_stub__atanh(double x) -{ - return atanh(x); -} - - -int ldso_stub__chdir(const char *path) -{ - return chdir(path); -} - -int ldso_stub__close(int d) -{ - return close(d); -} - -int ldso_stub__closedir(DIR *dirp) -{ - return closedir(dirp); -} - -double ldso_stub__cosh(double x) -{ - return cosh(x); -} - -void ldso_stub__exit(int status) -{ - exit(status); -} - -void ldso_stub__free(void *ptr) -{ - free(ptr); -} - -int ldso_stub__fstat(int fd, struct stat *sb) -{ - return fstat(fd, sb); + SHOW("os_install_interrupt_handlers()/bsd-os/defined(GENCGC)"); + undoably_install_low_level_interrupt_handler(SIG_MEMORY_FAULT, + memory_fault_handler); + SHOW("leaving os_install_interrupt_handlers()"); } -int ldso_stub__fsync(int fd) -{ - return fsync(fd); -} - -char *ldso_stub__getenv(const char *name) -{ - return getenv(name); -} - -int ldso_stub__gethostname(char *name, int namelen) -{ - return gethostname(name, namelen); -} - -pid_t ldso_stub__getpid(void) -{ - return getpid(); -} - -int ldso_stub__getrusage(int who, struct rusage *rusage) -{ - return getrusage(who, rusage); -} - -int ldso_stub__gettimeofday(struct timeval *tp, struct timezone *tzp) -{ - return gettimeofday(tp, tzp); -} - -uid_t ldso_stub__getuid(void) -{ - return getuid(); -} - -char *ldso_stub__getwd(char *buf) -{ - return getwd(buf); -} - -double ldso_stub__hypot(double x, double y) -{ - return hypot(x, y); -} - -int ldso_stub__kill(pid_t pid, int sig) -{ - return kill(pid, sig); -} - -int ldso_stub__killpg(pid_t pgrp, int sig) -{ - return killpg(pgrp, sig); -} - -off_t ldso_stub__lseek(int fildes, off_t offset, int whence) -{ - return lseek(fildes, offset, whence); -} - -int ldso_stub__lstat(const char *path, struct stat *sb) -{ - return lstat(path, sb); -} - -void *ldso_stub__malloc(size_t size) -{ - return malloc(size); -} - -int ldso_stub__mkdir(const char *path, mode_t mode) -{ - return mkdir(path, mode); -} - -int ldso_stub__open(const char *path, int flags, mode_t mode) -{ - return open(path, flags, mode); -} +#else /* Currently Darwin only */ -DIR *ldso_stub__opendir(const char *filename) -{ - return opendir(filename); -} - -double ldso_stub__pow(double x, double y) -{ - return pow(x, y); -} - -ssize_t ldso_stub__read(int d, void *buf, size_t nbytes) -{ - return read(d, buf, nbytes); -} - -struct dirent *ldso_stub__readdir(DIR *dirp) -{ - return readdir(dirp); -} - -int ldso_stub__readlink(const char *path, char *buf, int bufsiz) -{ - return readlink(path, buf, bufsiz); -} - -int ldso_stub__rename(const char *from, const char *to) -{ - return rename(from, to); -} - -int ldso_stub__select(int nfds, fd_set *readfs, fd_set *writefds, - fd_set *exceptfds, struct timeval *timeout) -{ - return select(nfds, readfs, writefds, exceptfds, timeout); -} - -int ldso_stub__sigblock(int mask) -{ - return sigblock(mask); -} - -int ldso_stub__sigpause(int sigmask) -{ - return sigpause(sigmask); -} - -int ldso_stub__sigsetmask(int mask) -{ - return sigsetmask(mask); -} - -double ldso_stub__sinh(double x) -{ - return sin(x); -} - -int ldso_stub__stat(const char *path, struct stat *sb) +static void +sigsegv_handler(int signal, siginfo_t *info, void* void_context) { - return stat(path, sb); + os_context_t *context = arch_os_get_context(&void_context); + unsigned int pc = (unsigned int *)(*os_context_pc_addr(context)); + os_vm_address_t addr; + + addr = arch_get_bad_addr(signal,info,context); + if(!interrupt_maybe_gc(signal, info, context)) + if(!handle_control_stack_guard_triggered(context,addr)) + interrupt_handle_now(signal, info, context); } -double ldso_stub__tanh(double x) +void +os_install_interrupt_handlers(void) { - return tanh(x); + SHOW("os_install_interrupt_handlers()/bsd-os/!defined(GENCGC)"); + undoably_install_low_level_interrupt_handler(SIG_MEMORY_FAULT, + sigsegv_handler); } -/* tzname */ - -int ldso_stub__unlink(const char *path) -{ - return unlink(path); -} +#endif /* defined GENCGC */ + +/* threads */ -ssize_t ldso_stub__write(int d, const void *buf, size_t nbytes) -{ - return write(d, buf, nbytes); +/* no threading in any *BSD variant on any CPU (yet? in sbcl-0.8.0 anyway) */ +#ifdef LISP_FEATURE_SB_THREAD +#error "Define threading support functions" +#else +int arch_os_thread_init(struct thread *thread) { + stack_t sigstack; +#ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK + /* Signal handlers are run on the control stack, so if it is exhausted + * we had better use an alternate stack for whatever signal tells us + * we've exhausted it */ + sigstack.ss_sp=((void *) thread)+dynamic_values_bytes; + sigstack.ss_flags=0; + sigstack.ss_size = 32*SIGSTKSZ; + sigaltstack(&sigstack,0); +#endif + return 1; /* success */ } - -pid_t ldso_stub__wait3(int *status, int options, struct rusage *rusage) -{ - return wait3(status, options, rusage); +int arch_os_thread_cleanup(struct thread *thread) { + return 1; /* success */ } - -#endif /* DL_WORKAROUND */ +#endif