From 3861a7bf88ef9bfa801e82fffa4a446bd041e919 Mon Sep 17 00:00:00 2001 From: ram <ram> Date: Mon, 24 Oct 1994 19:53:01 +0000 Subject: [PATCH] Solaris patches. --- lisp/backtrace.c | 13 +- lisp/breakpoint.c | 1 + lisp/gc.c | 22 ++- lisp/globals.h | 6 +- lisp/interr.c | 4 +- lisp/interrupt.c | 153 +++++++++++++++--- lisp/interrupt.h | 28 ++-- lisp/lisp.c | 19 ++- lisp/monitor.c | 4 +- lisp/os-common.c | 8 + lisp/os.h | 15 +- lisp/parse.c | 6 +- lisp/runprog.c | 17 +- lisp/socket.c | 4 + lisp/sparc-arch.c | 139 ++++++++++------- lisp/sparc-assem.S | 57 +++++++ lisp/sparc-lispregs.h | 45 +++++- lisp/sparc-validate.h | 26 ++-- lisp/sunos-os.c | 350 ++++++++++++++++++++++++++++++++++++------ lisp/sunos-os.h | 35 +++++ lisp/undefineds.c | 4 +- lisp/undefineds.h | 58 +++++-- lisp/vars.c | 3 +- 23 files changed, 827 insertions(+), 190 deletions(-) diff --git a/lisp/backtrace.c b/lisp/backtrace.c index 7d3e24086..436654a58 100644 --- a/lisp/backtrace.c +++ b/lisp/backtrace.c @@ -1,4 +1,4 @@ -/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/backtrace.c,v 1.2 1993/01/10 17:22:33 wlott Exp $ +/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/backtrace.c,v 1.2.1.1 1994/10/24 19:45:21 ram Exp $ * * Simple backtrace facility. More or less from Rob's lisp version. */ @@ -8,10 +8,11 @@ #include "lisp.h" #include "internals.h" #include "globals.h" +#include "os.h" #include "interrupt.h" #include "lispregs.h" -#ifndef i386 +#if !defined(i386) /* && !defined(SVR4) */ /* Sigh ... I know what the call frame looks like and it had better not change. */ @@ -194,9 +195,9 @@ backtrace(int nframes) string = (struct vector *) object; printf("%s, ", (char *) string->data); } else - printf("(Not simple string???), "); + printf("(Not simple string??\?), "); } else - printf("(Not other pointer???), "); + printf("(Not other pointer??\?), "); function = header->next; @@ -213,7 +214,7 @@ backtrace(int nframes) if (info.pc) printf("PC: 0x%x>\n", info.pc); else - printf("PC: ???>\n"); + printf("PC: ??\?>\n"); } while (--nframes > 0 && previous_info(&info)); } @@ -224,7 +225,7 @@ void backtrace(nframes) int nframes; { - printf("Can't backtrace on the x86.\n"); + printf("Can't backtrace on this hardware platform.\n"); } #endif diff --git a/lisp/breakpoint.c b/lisp/breakpoint.c index 1e3979ff4..f989775fc 100644 --- a/lisp/breakpoint.c +++ b/lisp/breakpoint.c @@ -4,6 +4,7 @@ #include "lisp.h" #include "os.h" #include "internals.h" +#include "interrupt.h" #include "arch.h" #include "lispregs.h" #include "globals.h" diff --git a/lisp/gc.c b/lisp/gc.c index 191dc19ee..052d4eae2 100644 --- a/lisp/gc.c +++ b/lisp/gc.c @@ -1,7 +1,7 @@ /* * Stop and Copy GC based on Cheney's algorithm. * - * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/gc.c,v 1.6 1993/07/27 15:00:59 hallgren Exp $ + * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/gc.c,v 1.6.1.1 1994/10/24 19:45:48 ram Exp $ * * Written by Christopher Hoover. */ @@ -173,8 +173,14 @@ void collect_garbage(void) lispobj *current_static_space_free_pointer; unsigned long static_space_size; unsigned long control_stack_size, binding_stack_size; +#ifdef POSIX_SIGS + sigset_t tmp, old; +#else int oldmask; +#endif + SAVE_CONTEXT(); + #ifdef PRINTNOISE printf("[Collecting garbage ... \n"); @@ -182,7 +188,13 @@ void collect_garbage(void) gettimeofday(&start_tv, (struct timezone *) 0); #endif +#ifdef POSIX_SIGS + sigemptyset(&tmp); + FILLBLOCKSET(&tmp); + sigprocmask(SIG_BLOCK, &tmp, &old); +#else oldmask = sigblock(BLOCKABLE); +#endif current_static_space_free_pointer = (lispobj *) SymbolValue(STATIC_SPACE_FREE_POINTER); @@ -296,7 +308,11 @@ void collect_garbage(void) #endif zero_stack(); +#ifdef POSIX_SIGS + sigprocmask(SIG_SETMASK, &old, 0); +#else (void) sigsetmask(oldmask); +#endif #ifdef PRINTNOISE @@ -1827,7 +1843,7 @@ void set_auto_gc_trigger(os_vm_size_t dynamic_usage) addr=os_round_up_to_page(addr); length=os_trunc_size_to_page(length); -#ifdef SUNOS +#if defined(SUNOS) || defined(SOLARIS) os_invalidate(addr,length); #else os_protect(addr, length, 0); @@ -1839,7 +1855,7 @@ void set_auto_gc_trigger(os_vm_size_t dynamic_usage) void clear_auto_gc_trigger(void) { if(current_auto_gc_trigger!=NULL){ -#ifdef SUNOS /* don't want to force whole space into swapping mode... */ +#if defined(SUNOS) || defined(SOLARIS)/* don't want to force whole space into swapping mode... */ os_vm_address_t addr=(os_vm_address_t)current_auto_gc_trigger; os_vm_size_t length= DYNAMIC_SPACE_SIZE + (os_vm_address_t)current_dynamic_space - addr; diff --git a/lisp/globals.h b/lisp/globals.h index 3167d57a8..f82b2f593 100644 --- a/lisp/globals.h +++ b/lisp/globals.h @@ -1,4 +1,4 @@ -/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/globals.h,v 1.2 1992/09/08 20:18:32 wlott Exp $ */ +/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/globals.h,v 1.2.1.1 1994/10/24 19:46:05 ram Exp $ */ #if !defined(_INCLUDE_GLOBALS_H_) #define _INCLUDED_GLOBALS_H_ @@ -38,8 +38,12 @@ extern void globals_init(void); #define EXTERN(name,bytes) .extern name bytes #endif #ifdef sparc +#ifdef SVR4 +#define EXTERN(name,bytes) .global name +#else #define EXTERN(name,bytes) .global _ ## name #endif +#endif #ifdef ibmrt #define EXTERN(name,bytes) .globl _/**/name #endif diff --git a/lisp/interr.c b/lisp/interr.c index 46773b374..d5ef6e6be 100644 --- a/lisp/interr.c +++ b/lisp/interr.c @@ -1,5 +1,5 @@ /* - * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/interr.c,v 1.1 1992/07/28 20:14:32 wlott Exp $ + * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/interr.c,v 1.1.1.1 1994/10/24 19:47:21 ram Exp $ * * Stuff to handle internal errors. * @@ -8,6 +8,7 @@ #include <stdio.h> #include <stdarg.h> +#include "arch.h" #include "signal.h" #include "lisp.h" @@ -15,7 +16,6 @@ #include "interr.h" #include "print.h" #include "lispregs.h" -#include "arch.h" /* Lossage handler. */ diff --git a/lisp/interrupt.c b/lisp/interrupt.c index dc698c1cf..170cc4487 100644 --- a/lisp/interrupt.c +++ b/lisp/interrupt.c @@ -1,4 +1,4 @@ -/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/interrupt.c,v 1.2 1992/09/08 20:25:46 wlott Exp $ */ +/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/interrupt.c,v 1.2.1.1 1994/10/24 19:47:36 ram Exp $ */ /* Interrupt handing magic. */ @@ -10,12 +10,12 @@ #endif #include "lisp.h" +#include "arch.h" #include "internals.h" #include "os.h" -#include "arch.h" +#include "interrupt.h" #include "globals.h" #include "lispregs.h" -#include "interrupt.h" #include "validate.h" #include "monitor.h" #include "gc.h" @@ -28,10 +28,25 @@ boolean internal_errors_enabled = 0; struct sigcontext *lisp_interrupt_contexts[MAX_INTERRUPTS]; union interrupt_handler interrupt_handlers[NSIG]; -void (*interrupt_low_level_handlers[NSIG])(int signal, int code, - struct sigcontext *scp) = {0}; +void (*interrupt_low_level_handlers[NSIG]) (HANDLER_ARGS) = {0}; + +static int pending_signal = 0; + +#ifdef SOLARIS +static siginfo_t *pending_code; +#define PASSCODE(code) ((code)) +#define DEREFCODE(code) ((code)) +#else +static int pending_code = 0; +#define PASSCODE(code) (code) +#define DEREFCODE(code) (code) +#endif -static int pending_signal = 0, pending_code = 0, pending_mask = 0; +#ifdef POSIX_SIGS +static sigset_t pending_mask; +#else +static int pending_mask = 0; +#endif static boolean maybe_gc_pending = FALSE; @@ -110,7 +125,14 @@ void fake_foreign_function_call(struct sigcontext *context) void undo_fake_foreign_function_call(struct sigcontext *context) { /* Block all blockable signals */ +#ifdef POSIX_SIGS + sigset_t block; + sigemptyset(&block); + FILLBLOCKSET(&block); + sigprocmask(SIG_BLOCK, &block, 0); +#else sigblock(BLOCKABLE); +#endif /* Going back into lisp. */ foreign_function_call_active = 0; @@ -126,10 +148,14 @@ void undo_fake_foreign_function_call(struct sigcontext *context) #endif } -void interrupt_internal_error(int signal, int code, struct sigcontext *context, +void interrupt_internal_error(HANDLER_ARGS, boolean continuable) { +#ifdef POSIX_SIGS + sigprocmask(SIG_SETMASK,&context->uc_sigmask, 0); +#else sigsetmask(context->sc_mask); +#endif fake_foreign_function_call(context); if (internal_errors_enabled) funcall2(SymbolFunction(INTERNAL_ERROR), alloc_sap(context), @@ -156,16 +182,25 @@ void interrupt_handle_pending(struct sigcontext *context) undo_fake_foreign_function_call(context); } if (pending_signal) { - int signal, code; - + int signal; +#ifdef SOLARIS + siginfo_t *code; +#else + int code; +#endif signal = pending_signal; code = pending_code; pending_signal = 0; - pending_code = 0; - interrupt_handle_now(signal, code, context); + /* pending_code = 0; /**/ + interrupt_handle_now(signal, PASSCODE(code), context); } +#ifdef POSIX_SIGS + context->uc_sigmask = pending_mask; + sigemptyset(&pending_mask); +#else context->sc_mask = pending_mask; pending_mask = 0; +#endif } @@ -174,7 +209,7 @@ void interrupt_handle_pending(struct sigcontext *context) * the two main signal handlers. * \****************************************************************/ -void interrupt_handle_now(int signal, int code, struct sigcontext *context) +void interrupt_handle_now(HANDLER_ARGS) { int were_in_lisp; union interrupt_handler handler; @@ -184,12 +219,18 @@ void interrupt_handle_now(int signal, int code, struct sigcontext *context) if(handler.c==SIG_IGN) return; + SAVE_CONTEXT(); /**/ + were_in_lisp = !foreign_function_call_active; if (were_in_lisp) fake_foreign_function_call(context); /* Allow signals again. */ +#ifdef POSIX_SIGS + sigprocmask(SIG_SETMASK, &context->uc_sigmask, 0); +#else sigsetmask(context->sc_mask); +#endif if (handler.c==SIG_DFL) /* This can happen if someone tries to ignore or default on of the */ @@ -197,8 +238,13 @@ void interrupt_handle_now(int signal, int code, struct sigcontext *context) /* decides to pass on it. */ lose("interrupt_handle_now: No handler for signal %d?\n", signal); else if (LowtagOf(handler.lisp) == type_FunctionPointer) - funcall3(handler.lisp, make_fixnum(signal), make_fixnum(code), +#if 1 + funcall3(handler.lisp, make_fixnum(signal), make_fixnum(CODE(code)), + alloc_sap(context)); +#else + funcall3(handler.lisp, make_fixnum(signal), alloc_sap(code), alloc_sap(context)); +#endif else (*handler.c)(signal, code, context); @@ -206,21 +252,32 @@ void interrupt_handle_now(int signal, int code, struct sigcontext *context) undo_fake_foreign_function_call(context); } -static void maybe_now_maybe_later(int signal, int code, - struct sigcontext *context) +static void maybe_now_maybe_later(HANDLER_ARGS) { + SAVE_CONTEXT(); /**/ + if (SymbolValue(INTERRUPTS_ENABLED) == NIL) { pending_signal = signal; - pending_code = code; + pending_code = DEREFCODE(code); +#ifdef POSIX_SIGS + pending_mask = context->uc_sigmask; + FILLBLOCKSET(&context->uc_sigmask); +#else pending_mask = context->sc_mask; context->sc_mask |= BLOCKABLE; +#endif SetSymbolValue(INTERRUPT_PENDING, T); } else if ((!foreign_function_call_active) && arch_pseudo_atomic_atomic(context)) { pending_signal = signal; - pending_code = code; + pending_code = DEREFCODE(code); +#ifdef POSIX_SIGS + pending_mask = context->uc_sigmask; + FILLBLOCKSET(&context->uc_sigmask); +#else pending_mask = context->sc_mask; context->sc_mask |= BLOCKABLE; +#endif arch_set_pseudo_atomic_interrupted(context); } else interrupt_handle_now(signal, code, context); @@ -231,7 +288,7 @@ static void maybe_now_maybe_later(int signal, int code, \****************************************************************/ #ifndef INTERNAL_GC_TRIGGER -static boolean gc_trigger_hit(int signal, int code, struct sigcontext *context) +static boolean gc_trigger_hit(HANDLER_ARGS) { if (current_auto_gc_trigger == NULL) return FALSE; @@ -245,7 +302,7 @@ static boolean gc_trigger_hit(int signal, int code, struct sigcontext *context) #endif -boolean interrupt_maybe_gc(int signal, int code, struct sigcontext *context) +boolean interrupt_maybe_gc(HANDLER_ARGS) { if (!foreign_function_call_active #ifndef INTERNAL_GC_TRIGGER @@ -259,8 +316,13 @@ boolean interrupt_maybe_gc(int signal, int code, struct sigcontext *context) if (arch_pseudo_atomic_atomic(context)) { maybe_gc_pending = TRUE; if (pending_signal == 0) { +#ifdef POSIX_SIGS + pending_mask = context->uc_sigmask; + FILLBLOCKSET(&context->uc_sigmask); +#else pending_mask = context->sc_mask; context->sc_mask |= BLOCKABLE; +#endif } arch_set_pseudo_atomic_interrupted(context); } @@ -281,8 +343,18 @@ boolean interrupt_maybe_gc(int signal, int code, struct sigcontext *context) void interrupt_install_low_level_handler (int signal, - void handler(int signal, int code, struct sigcontext *handler)) + void handler(HANDLER_ARGS)) { +#ifdef POSIX_SIGS + struct sigaction sa; + + sa.sa_sigaction=handler; + sigemptyset(&sa.sa_mask); + FILLBLOCKSET(&sa.sa_mask); + sa.sa_flags = SA_RESTART | SA_SIGINFO; + + sigaction(signal, &sa, NULL); +#else struct sigvec sv; sv.sv_handler=handler; @@ -290,13 +362,49 @@ void interrupt_install_low_level_handler sv.sv_flags=0; sigvec(signal,&sv,NULL); +#endif interrupt_low_level_handlers[signal]=(handler==SIG_DFL ? 0 : handler); } unsigned long install_handler(int signal, - void handler(int signal, int code, - struct sigcontext *handler)) + void handler(HANDLER_ARGS)) +#ifdef POSIX_SIGS +{ + struct sigaction sa; + sigset_t old,new; + union interrupt_handler oldhandler; + + sigemptyset(&new); + sigaddset(&new, signal); + sigprocmask(SIG_BLOCK, &new, &old); + + sigemptyset(&new); + FILLBLOCKSET(&new); + + if(interrupt_low_level_handlers[signal]==0){ + if(handler==SIG_DFL || handler==SIG_IGN) + sa.sa_sigaction = handler; + else if (sigismember(&new, signal)) + sa.sa_sigaction = maybe_now_maybe_later; + else + sa.sa_sigaction = interrupt_handle_now; + + sigemptyset(&sa.sa_mask); + FILLBLOCKSET(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO | SA_RESTART; + + sigaction(signal, &sa, NULL); + } + + oldhandler = interrupt_handlers[signal]; + interrupt_handlers[signal].c = handler; + + sigprocmask(SIG_SETMASK, &old, 0); + + return (unsigned long)oldhandler.lisp; +} +#else { struct sigvec sv; int oldmask; @@ -325,6 +433,7 @@ unsigned long install_handler(int signal, return (unsigned long)oldhandler.lisp; } +#endif void interrupt_init(void) { diff --git a/lisp/interrupt.h b/lisp/interrupt.h index 21058120c..d2a6d13a8 100644 --- a/lisp/interrupt.h +++ b/lisp/interrupt.h @@ -1,4 +1,4 @@ -/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/interrupt.h,v 1.3 1993/07/27 15:08:44 hallgren Exp $ */ +/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/interrupt.h,v 1.3.1.1 1994/10/24 19:47:46 ram Exp $ */ #if !defined(_INCLUDE_INTERRUPT_H_) #define _INCLUDE_INTERRUPT_H_ @@ -11,24 +11,21 @@ extern struct sigcontext *lisp_interrupt_contexts[MAX_INTERRUPTS]; union interrupt_handler { lispobj lisp; - void (*c)(int signal, int code, struct sigcontext *scp); + void (*c)(HANDLER_ARGS); }; extern void interrupt_init(void); extern void fake_foreign_function_call(struct sigcontext *context); extern void undo_fake_foreign_function_call(struct sigcontext *context); -extern void interrupt_handle_now(int signal, int code, struct sigcontext *scp); +extern void interrupt_handle_now(HANDLER_ARGS); extern void interrupt_handle_pending(struct sigcontext *scp); -extern void interrupt_internal_error(int signal, int code, - struct sigcontext *scp, - boolean continuable); -extern boolean interrupt_maybe_gc(int sig, int code, struct sigcontext *scp); +extern void interrupt_internal_error(HANDLER_ARGS, boolean continuable); +extern boolean interrupt_maybe_gc(HANDLER_ARGS); extern void interrupt_install_low_level_handler (int signal, - void handler(int signal, int code, struct sigcontext *scp)); + void handler(HANDLER_ARGS)); extern unsigned long install_handler(int signal, - void handler(int signal, int code, - struct sigcontext *handler)); + void handler(HANDLER_ARGS)); extern union interrupt_handler interrupt_handlers[NSIG]; @@ -41,6 +38,16 @@ extern union interrupt_handler interrupt_handlers[NSIG]; sigmask(SIGPROF) | sigmask(SIGWINCH) | \ sigmask(SIGUSR1) | sigmask(SIGUSR2)) #else +#ifdef POSIX_SIGS +#define FILLBLOCKSET(s) (sigaddset(s,SIGHUP), sigaddset(s,SIGINT), \ + sigaddset(s,SIGQUIT), sigaddset(s,SIGPIPE), \ + sigaddset(s,SIGALRM), sigaddset(s,SIGURG), \ + sigaddset(s,SIGTSTP), sigaddset(s,SIGCHLD), \ + sigaddset(s,SIGIO), sigaddset(s,SIGXCPU), \ + sigaddset(s,SIGXFSZ), sigaddset(s,SIGVTALRM), \ + sigaddset(s,SIGPROF), sigaddset(s,SIGWINCH), \ + sigaddset(s,SIGUSR1), sigaddset(s,SIGUSR2)) +#else #define BLOCKABLE (sigmask(SIGHUP) | sigmask(SIGINT) | \ sigmask(SIGQUIT) | sigmask(SIGPIPE) | \ sigmask(SIGALRM) | sigmask(SIGURG) | \ @@ -51,3 +58,4 @@ extern union interrupt_handler interrupt_handlers[NSIG]; sigmask(SIGUSR1) | sigmask(SIGUSR2)) #endif #endif +#endif diff --git a/lisp/lisp.c b/lisp/lisp.c index a6f8a8dfb..84efef7db 100644 --- a/lisp/lisp.c +++ b/lisp/lisp.c @@ -1,7 +1,7 @@ /* * main() entry point for a stand alone lisp image. * - * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/lisp.c,v 1.5 1994/01/28 17:22:29 wlott Exp $ + * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/lisp.c,v 1.5.1.1 1994/10/24 19:48:01 ram Exp $ * */ @@ -20,11 +20,11 @@ #include "vars.h" #include "globals.h" #include "os.h" +#include "interrupt.h" #include "arch.h" #include "gc.h" #include "monitor.h" #include "validate.h" -#include "interrupt.h" #include "core.h" #include "save.h" #include "lispregs.h" @@ -32,8 +32,10 @@ /* SIGINT handler that invokes the monitor. */ -static void sigint_handler(int signal, int code, struct sigcontext *context) +static void sigint_handler(HANDLER_ARGS) { + SAVE_CONTEXT(); + printf("\nSIGINT hit at 0x%08X\n", SC_PC(context)); ldb_monitor(); } @@ -80,6 +82,9 @@ void main(int argc, char *argv[], char *envp[]) #ifdef MACH mach_init(); #endif +#ifdef SVR4 + tzset(); +#endif set_lossage_handler(ldb_monitor); @@ -109,11 +114,7 @@ void main(int argc, char *argv[], char *envp[]) if (default_core == NULL) default_core = "lisp.core"; - /* Note: the /usr/misc/.cmucl/lib/ default path is also wired into */ - /* the lisp code in .../code/save.lisp. */ - if (core == NULL) { - extern char *getenv(char *var); static char buf[MAXPATHLEN]; char *lib = getenv("CMUCLLIB"); @@ -135,8 +136,10 @@ void main(int argc, char *argv[], char *envp[]) } while (*lib++ == ':'); } if (core == NULL) { + /* Note: the /usr/misc/.cmucl/lib/ default path is also wired + /* into the lisp code in .../code/save.lisp. */ #ifdef hpux - strcpy(buf, "/usr/local/cmucl/lib/"); + strcpy(buf, "/usr/local/lib/cmucl/lib/"); #else strcpy(buf, "/usr/misc/.cmucl/lib/"); #endif diff --git a/lisp/monitor.c b/lisp/monitor.c index e752f9cfb..20dddd197 100644 --- a/lisp/monitor.c +++ b/lisp/monitor.c @@ -1,4 +1,4 @@ -/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/monitor.c,v 1.3 1993/04/28 01:59:00 wlott Exp $ */ +/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/monitor.c,v 1.3.1.1 1994/10/24 19:48:49 ram Exp $ */ #include <stdio.h> #include <sys/types.h> @@ -13,9 +13,9 @@ #include "globals.h" #include "vars.h" #include "parse.h" +#include "os.h" #include "interrupt.h" #include "lispregs.h" -#include "os.h" #include "monitor.h" #include "print.h" #include "arch.h" diff --git a/lisp/os-common.c b/lisp/os-common.c index 2a9377015..f6174f4f7 100644 --- a/lisp/os-common.c +++ b/lisp/os-common.c @@ -68,7 +68,11 @@ os_vm_address_t os_reallocate(os_vm_address_t addr, os_vm_size_t old_len, if(len_diff<0) os_invalidate(addr+len,-len_diff); else if(len_diff!=0){ +#if 1 + os_vm_address_t new= NULL; +#else os_vm_address_t new=os_validate(addr+old_len,len_diff); +#endif if(new==NULL || new!=addr+old_len){ if(new!=NULL) @@ -84,6 +88,10 @@ os_vm_address_t os_reallocate(os_vm_address_t addr, os_vm_size_t old_len, addr=new; } +#if 0 + else + fprintf(stderr,"Map grow: [0x%08x] %x -> %x\n", addr, old_len,len); +#endif } return addr; diff --git a/lisp/os.h b/lisp/os.h index d0d16c693..59c2126e9 100644 --- a/lisp/os.h +++ b/lisp/os.h @@ -1,5 +1,5 @@ /* - * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/os.h,v 1.2 1993/07/27 15:40:17 hallgren Exp $ + * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/os.h,v 1.2.1.1 1994/10/24 19:49:34 ram Exp $ * * Common interface for os-dependent functions. * @@ -23,6 +23,19 @@ #endif #endif +#ifndef HANDLER_ARGS +#define HANDLER_ARGS int signal, int code, struct sigcontext *context +#endif +#ifndef CODE +#define CODE(code) code +#endif +#ifndef CTXT_SIGMASK +#define CTXT_SIGMASK(context) context->sc_mask +#endif +#ifndef SAVE_CONTEXT +#define SAVE_CONTEXT() do {} while(0) +#endif + #define OS_VM_PROT_ALL (OS_VM_PROT_READ|OS_VM_PROT_WRITE|OS_VM_PROT_EXECUTE) extern os_vm_size_t os_vm_page_size; diff --git a/lisp/parse.c b/lisp/parse.c index d89ecac5a..5fde13f7c 100644 --- a/lisp/parse.c +++ b/lisp/parse.c @@ -1,4 +1,4 @@ -/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/parse.c,v 1.1 1992/07/28 20:15:14 wlott Exp $ */ +/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/parse.c,v 1.1.1.1 1994/10/24 19:49:55 ram Exp $ */ #include <stdio.h> #include <ctype.h> #include <signal.h> @@ -8,14 +8,14 @@ #include "globals.h" #include "vars.h" #include "parse.h" +#include "os.h" #include "interrupt.h" #include "lispregs.h" #include "monitor.h" #include "arch.h" -#include "os.h" #include "search.h" -#ifndef MACH +#if !defined(MACH) && !defined(SVR4) static int strcasecmp(s1,s2) char *s1,*s2; diff --git a/lisp/runprog.c b/lisp/runprog.c index 3ecd58bc0..ed122a7b1 100644 --- a/lisp/runprog.c +++ b/lisp/runprog.c @@ -1,12 +1,16 @@ /* - * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/runprog.c,v 1.1 1993/08/04 11:25:08 wlott Exp $ + * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/runprog.c,v 1.1.1.1 1994/10/24 19:50:05 ram Exp $ * * Support for run-program. * */ #include <sys/file.h> +#include <sys/fcntl.h> #include <sys/ioctl.h> +#ifdef SVR4 +#include <unistd.h> +#endif int spawn(char *program, char *argv[], char *envp[], char *pty_name, int stdin, int stdout, int stderr) @@ -18,15 +22,17 @@ int spawn(char *program, char *argv[], char *envp[], char *pty_name, return pid; /* Put us in our own process group. */ -#ifdef hpux +#if defined(hpux) setsid(); +#elif defined(SVR4) + setpgrp(); #else setpgrp(0, getpid()); #endif /* If we are supposed to be part of some other pty, go for it. */ if (pty_name) { -#ifndef hpux +#if !defined(hpux) && !defined(SVR4) fd = open("/dev/tty", O_RDWR, 0); if (fd >= 0) { ioctl(fd, TIOCNOTTY, 0); @@ -50,8 +56,13 @@ int spawn(char *program, char *argv[], char *envp[], char *pty_name, dup2(stderr, 2); /* Close all other fds. */ +#ifdef SVR4 + for (fd = sysconf(_SC_OPEN_MAX)-1; fd >= 3; fd--) + close(fd); +#else for (fd = getdtablesize()-1; fd >= 3; fd--) close(fd); +#endif /* Exec the program. */ execve(program, argv, envp); diff --git a/lisp/socket.c b/lisp/socket.c index f8c843ebc..9a21aceed 100644 --- a/lisp/socket.c +++ b/lisp/socket.c @@ -20,6 +20,8 @@ #include <netinet/tcp.h> #endif +#include "os.h" + extern int errno; /* Certain (broken) OS's don't have this */ /* decl in errno.h */ @@ -34,7 +36,9 @@ extern int errno; /* Certain (broken) OS's don't have this */ #endif /* hpux */ #endif /* X_UNIX_PATH */ #endif /* UNIXCONN */ +#ifndef bcopy void bcopy(); +#endif /* * Attempts to connect to server, given host and display. Returns file diff --git a/lisp/sparc-arch.c b/lisp/sparc-arch.c index 70f39d979..05709dd20 100644 --- a/lisp/sparc-arch.c +++ b/lisp/sparc-arch.c @@ -1,23 +1,26 @@ #include <stdio.h> +#ifdef SOLARIS +#include <sys/trap.h> +#else #include <machine/trap.h> +#endif +#include "arch.h" #include "lisp.h" #include "internals.h" #include "globals.h" #include "validate.h" #include "os.h" -#include "arch.h" #include "lispregs.h" #include "signal.h" #include "interrupt.h" char *arch_init() { - return NULL; + return 0; } -os_vm_address_t arch_get_bad_addr(int signal, int code, - struct sigcontext *context) +os_vm_address_t arch_get_bad_addr(HANDLER_ARGS) { unsigned long badinst; int rs1; @@ -26,19 +29,19 @@ os_vm_address_t arch_get_bad_addr(int signal, int code, /* Make sure it's not the pc thats bogus, and that it was lisp code */ /* that caused the fault. */ - if ((context->sc_pc & 3) != 0 || - ((context->sc_pc < READ_ONLY_SPACE_START || - context->sc_pc >= READ_ONLY_SPACE_START+READ_ONLY_SPACE_SIZE) && - ((lispobj *)context->sc_pc < current_dynamic_space && - (lispobj *)context->sc_pc >= + if ((SC_PC(context) & 3) != 0 || + ((SC_PC(context) < READ_ONLY_SPACE_START || + SC_PC(context) >= READ_ONLY_SPACE_START+READ_ONLY_SPACE_SIZE) && + ((lispobj *)SC_PC(context) < current_dynamic_space && + (lispobj *)SC_PC(context) >= current_dynamic_space + DYNAMIC_SPACE_SIZE))) - return NULL; + return 0; - badinst = *(unsigned long *)context->sc_pc; + badinst = *(unsigned long *)SC_PC(context); if ((badinst >> 30) != 3) /* All load/store instructions have op = 11 (binary) */ - return NULL; + return 0; rs1 = (badinst>>14)&0x1f; @@ -64,13 +67,13 @@ void arch_skip_instruction(context) struct sigcontext *context; { /* Skip the offending instruction */ - context->sc_pc = context->sc_npc; - context->sc_npc += 4; + SC_PC(context) = SC_NPC(context); + SC_NPC(context) += 4; } unsigned char *arch_internal_error_arguments(struct sigcontext *scp) { - return (unsigned char *)(scp->sc_pc+4); + return (unsigned char *)(SC_PC(scp)+4); } boolean arch_pseudo_atomic_atomic(struct sigcontext *scp) @@ -97,99 +100,129 @@ void arch_remove_breakpoint(void *pc, unsigned long orig_inst) } static unsigned long *skipped_break_addr, displaced_after_inst; +#ifdef POSIX_SIGS +static sigset_t orig_sigmask; +#else static int orig_sigmask; +#endif void arch_do_displaced_inst(struct sigcontext *scp, unsigned long orig_inst) { - unsigned long *pc = (unsigned long *)scp->sc_pc; - unsigned long *npc = (unsigned long *)scp->sc_npc; - + unsigned long *pc = (unsigned long *)SC_PC(scp); + unsigned long *npc = (unsigned long *)SC_NPC(scp); + +#ifdef POSIX_SIGS + orig_sigmask = scp->uc_sigmask; + sigemptyset(&scp->uc_sigmask); + FILLBLOCKSET(&scp->uc_sigmask); +#else orig_sigmask = scp->sc_mask; scp->sc_mask = BLOCKABLE; +#endif *pc = orig_inst; skipped_break_addr = pc; displaced_after_inst = *npc; *npc = trap_AfterBreakpoint; +#ifdef SOLARIS + /* XXX never tested */ + setcontext(scp); +#else sigreturn(scp); +#endif } -static void sigill_handler(signal, code, scp) -int signal, code; -struct sigcontext *scp; +static void sigill_handler(HANDLER_ARGS) { int badinst; - sigsetmask(scp->sc_mask); + SAVE_CONTEXT(); + +#ifdef POSIX_SIGS + sigprocmask(SIG_SETMASK, &context->uc_sigmask, 0); +#else + sigsetmask(context->sc_mask); +#endif - if (code == T_UNIMP_INSTR) { +#ifdef SOLARIS + if (CODE(code) == ILL_ILLOPC) +#else + if (CODE(code) == T_UNIMP_INSTR) +#endif + { int trap; - trap = *(unsigned long *)(scp->sc_pc) & 0x3fffff; + trap = *(unsigned long *)(SC_PC(context)) & 0x3fffff; switch (trap) { case trap_PendingInterrupt: - arch_skip_instruction(scp); - interrupt_handle_pending(scp); + arch_skip_instruction(context); + interrupt_handle_pending(context); break; case trap_Halt: - fake_foreign_function_call(scp); + fake_foreign_function_call(context); lose("%%primitive halt called; the party is over.\n"); case trap_Error: case trap_Cerror: - interrupt_internal_error(signal, code, scp, trap == trap_Cerror); + interrupt_internal_error(signal, code, context, trap == trap_Cerror); break; case trap_Breakpoint: - handle_breakpoint(signal, code, scp); + handle_breakpoint(signal, code, context); break; case trap_FunctionEndBreakpoint: - scp->sc_pc=(int)handle_function_end_breakpoint(signal, code, scp); - scp->sc_npc=scp->sc_pc + 4; + SC_PC(context)=(int)handle_function_end_breakpoint(signal, code, context); + SC_NPC(context)=SC_PC(context) + 4; break; case trap_AfterBreakpoint: *skipped_break_addr = trap_Breakpoint; skipped_break_addr = NULL; - *(unsigned long *)scp->sc_pc = displaced_after_inst; - scp->sc_mask = orig_sigmask; + *(unsigned long *)SC_PC(context) = displaced_after_inst; +#ifdef POSIX_SIGS + context->uc_sigmask = orig_sigmask; +#else + context->sc_mask = orig_sigmask; +#endif break; default: - interrupt_handle_now(signal, code, scp); + interrupt_handle_now(signal, code, context); break; } } - else if (code >= T_SOFTWARE_TRAP + 16 & code < T_SOFTWARE_TRAP + 32) - interrupt_internal_error(signal, code, scp, FALSE); +#ifdef SOLARIS + else if (CODE(code) == ILL_ILLTRP) +#else + else if (CODE(code) >= T_SOFTWARE_TRAP + 16 & CODE(code) < T_SOFTWARE_TRAP + 32) +#endif + interrupt_internal_error(signal, code, context, FALSE); else - interrupt_handle_now(signal, code, scp); + interrupt_handle_now(signal, code, context); } -static void sigemt_handler(signal, code, scp) - int signal, code; - struct sigcontext *scp; +static void sigemt_handler(HANDLER_ARGS) { unsigned long badinst; boolean subtract, immed; int rd, rs1, op1, rs2, op2, result; - badinst = *(unsigned long *)scp->sc_pc; + badinst = *(unsigned long *)SC_PC(context); if ((badinst >> 30) != 2 || ((badinst >> 20) & 0x1f) != 0x11) { /* It wasn't a tagged add. Pass the signal into lisp. */ - interrupt_handle_now(signal, code, scp); + interrupt_handle_now(signal, code, context); return; } /* Extract the parts of the inst. */ subtract = badinst & (1<<19); rs1 = (badinst>>14) & 0x1f; - op1 = SC_REG(scp, rs1); + op1 = SC_REG(context, rs1); /* If the first arg is $ALLOC then it is really a signal-pending note */ /* for the pseudo-atomic noise. */ @@ -202,15 +235,15 @@ static void sigemt_handler(signal, code, scp) result = op1 - op2; else result = op1 + op2; - SC_REG(scp, reg_ALLOC) = result & ~7; - arch_skip_instruction(scp); - interrupt_handle_pending(scp); + SC_REG(context, reg_ALLOC) = result & ~7; + arch_skip_instruction(context); + interrupt_handle_pending(context); return; } if ((op1 & 3) != 0) { /* The first arg wan't a fixnum. */ - interrupt_internal_error(signal, code, scp, FALSE); + interrupt_internal_error(signal, code, context, FALSE); return; } @@ -221,12 +254,12 @@ static void sigemt_handler(signal, code, scp) } else { rs2 = badinst & 0x1f; - op2 = SC_REG(scp, rs2); + op2 = SC_REG(context, rs2); } if ((op2 & 3) != 0) { /* The second arg wan't a fixnum. */ - interrupt_internal_error(signal, code, scp, FALSE); + interrupt_internal_error(signal, code, context, FALSE); return; } @@ -239,15 +272,15 @@ static void sigemt_handler(signal, code, scp) result = (op1>>2) + (op2>>2); current_dynamic_space_free_pointer = - (lispobj *) SC_REG(scp, reg_ALLOC); + (lispobj *) SC_REG(context, reg_ALLOC); - SC_REG(scp, rd) = alloc_number(result); + SC_REG(context, rd) = alloc_number(result); - SC_REG(scp, reg_ALLOC) = + SC_REG(context, reg_ALLOC) = (unsigned long) current_dynamic_space_free_pointer; } - arch_skip_instruction(scp); + arch_skip_instruction(context); } void arch_install_interrupt_handlers() diff --git a/lisp/sparc-assem.S b/lisp/sparc-assem.S index 4e22039bf..3f13eb572 100644 --- a/lisp/sparc-assem.S +++ b/lisp/sparc-assem.S @@ -1,7 +1,34 @@ +#ifdef SOLARIS +#define _ASM +#include <sys/asm_linkage.h> +#include <sys/psw.h> +#include <sys/trap.h> +#define _current_binding_stack_pointer current_binding_stack_pointer +#define _current_control_stack_pointer current_control_stack_pointer +#define _current_dynamic_space_free_pointer current_dynamic_space_free_pointer +#define _foreign_function_call_active foreign_function_call_active +#define _current_control_frame_pointer current_control_frame_pointer +#define _call_into_lisp call_into_lisp +#define _function_end_breakpoint_end function_end_breakpoint_end +#define _closure_tramp closure_tramp +#define _undefined_tramp undefined_tramp +#define _function_end_breakpoint_trap function_end_breakpoint_trap +#define _function_end_breakpoint_guts function_end_breakpoint_guts +#define _call_into_c call_into_c +#define _flush_icache flush_icache +#ifdef __STDC__ +#define FUNCDEF(x) .type x, \#function +#else +#define FUNCDEF(x) .type x, #function +#endif +#else #include <machine/asm_linkage.h> #include <machine/psl.h> #include <machine/trap.h> +#define FUNCDEF(x) /* nothing */ +#define SET_SIZE(x) /* nothing */ +#endif #define LANGUAGE_ASSEMBLY #include "lispregs.h" @@ -18,6 +45,7 @@ .seg "text" .global _call_into_lisp + FUNCDEF(_call_into_lisp) _call_into_lisp: save %sp, -FRAMESIZE, %sp @@ -110,10 +138,12 @@ lra: ld [%sp+FRAMESIZE-4], %i7 ret restore %sp, FRAMESIZE, %sp + SET_SIZE(_call_into_lisp) .global _call_into_c + FUNCDEF(_call_into_c) _call_into_c: /* Build a lisp stack frame */ mov reg_CFP, reg_OCFP @@ -182,9 +212,11 @@ _call_into_c: ret nop + SET_SIZE(_call_into_c) .global _undefined_tramp + FUNCDEF(_undefined_tramp) .align 8 .byte 0 _undefined_tramp: @@ -203,8 +235,10 @@ _undefined_tramp: ld [reg_FDEFN+FDEFN_RAW_ADDR_OFFSET], reg_CODE jmp reg_CODE+FUNCTION_CODE_OFFSET nop + SET_SIZE(_undefined_tramp) .global _closure_tramp + FUNCDEF(_closure_tramp) .align 8 .byte 0 _closure_tramp: @@ -219,6 +253,7 @@ _closure_tramp: ld [reg_LEXENV+CLOSURE_FUNCTION_OFFSET], reg_CODE jmp reg_CODE+FUNCTION_CODE_OFFSET nop + SET_SIZE(_closure_tramp) @@ -252,10 +287,21 @@ _function_end_breakpoint_trap: .global _function_end_breakpoint_end _function_end_breakpoint_end: + .global _flush_icache + FUNCDEF(_flush_icache) +_flush_icache: + iflush %i0 ! flush instruction cache + retl ! return from leaf routine + nop + SET_SIZE(_flush_icache) + +#ifndef SOLARIS + /****************************************************************\ * State saving and restoring. \****************************************************************/ + .global _call_on_stack _call_on_stack: call %o0 @@ -295,6 +341,7 @@ _restore_state: mov %o0, %i0 + /****************************************************************\ We need our own version of sigtramp. @@ -493,3 +540,13 @@ _sigreturn: unimp 0 ! just in case it returns /*NOTREACHED*/ +#else /* SOLARIS */ + .global save_context + FUNCDEF(save_context) +save_context: + ta ST_FLUSH_WINDOWS ! flush register windows + retl ! return from leaf routine + nop + SET_SIZE(save_context) + +#endif diff --git a/lisp/sparc-lispregs.h b/lisp/sparc-lispregs.h index d85d9f095..ca031e593 100644 --- a/lisp/sparc-lispregs.h +++ b/lisp/sparc-lispregs.h @@ -1,11 +1,27 @@ -/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/sparc-lispregs.h,v 1.1 1992/09/08 20:21:10 wlott Exp $ */ +/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/sparc-lispregs.h,v 1.1.1.1 1994/10/24 19:51:49 ram Exp $ */ + + #ifdef LANGUAGE_ASSEMBLY -#define GREG(num) %g ## num -#define OREG(num) %o ## num -#define LREG(num) %l ## num -#define IREG(num) %i ## num +#ifdef __STDC__ + /* Standard C token concatenation */ +#define CAT(a,b) a ## b + +#else + /* Reisser CPP token concatenation */ +#define CAT(a,b) a/**/b + +#endif + +/* + * Note: concatenation to non preprocessor symbols is not defined, + * SunPRO C 2.0.1 yields % g0, perfectly valid according to ANSI + */ +#define GREG(num) CAT(%g,num) +#define OREG(num) CAT(%o,num) +#define LREG(num) CAT(%l,num) +#define IREG(num) CAT(%i,num) #else @@ -65,13 +81,30 @@ #define BOXED_REGISTERS { \ reg_A0, reg_A1, reg_A2, reg_A3, reg_A4, reg_A5, reg_FDEFN, reg_LEXENV, \ - reg_NFP, reg_OCFP, reg_LRA, reg_L0, reg_L1, reg_CODE \ + reg_NFP, reg_OCFP, reg_LRA, reg_L0, reg_L1, reg_L2, reg_CODE \ } #ifndef LANGUAGE_ASSEMBLY +#ifdef SOLARIS + +#include <ucontext.h> + +extern int * solaris_register_address(struct ucontext *, int); + +#define SC_REG(sc, reg) (*solaris_register_address(sc,reg)) + +/* short cuts */ + +#define SC_PC(sc) ((sc)->uc_mcontext.gregs[REG_PC]) +#define SC_NPC(sc) ((sc)->uc_mcontext.gregs[REG_nPC]) + +#else + #define SC_REG(sc, n) (((int *)((sc)->sc_g1))[n]) #define SC_PC(sc) ((sc)->sc_pc) #define SC_NPC(sc) ((sc)->sc_npc) +#endif /* SOLARIS */ + #endif diff --git a/lisp/sparc-validate.h b/lisp/sparc-validate.h index c46e7d11f..2e6ff973d 100644 --- a/lisp/sparc-validate.h +++ b/lisp/sparc-validate.h @@ -1,19 +1,19 @@ -#define READ_ONLY_SPACE_START (0x00200000) -#define READ_ONLY_SPACE_SIZE (0x0bdf8000) +#define READ_ONLY_SPACE_START (0x01000000) +#define READ_ONLY_SPACE_SIZE (0x03ff8000) + +#define STATIC_SPACE_START (0x05000000) +#define STATIC_SPACE_SIZE (0x01ff8000) -#define STATIC_SPACE_START (0x0c000000) -#define STATIC_SPACE_SIZE (0x03ff8000) +#define DYNAMIC_0_SPACE_START (0x07000000) +#define DYNAMIC_1_SPACE_START (0x0b000000) +#define DYNAMIC_SPACE_SIZE (0x03ff8000) -#define DYNAMIC_0_SPACE_START (0x10000000) -#define DYNAMIC_1_SPACE_START (0x18000000) -#define DYNAMIC_SPACE_SIZE (0x07ff8000) +#define CONTROL_STACK_START (0x00900000) +#define CONTROL_STACK_SIZE (0x00078000) -#define CONTROL_STACK_START (0x00100000) -#define CONTROL_STACK_SIZE (0x00078000) +#define BINDING_STACK_START (0x00980000) +#define BINDING_STACK_SIZE (0x00078000) -#define BINDING_STACK_START (0x00180000) -#define BINDING_STACK_SIZE (0x00078000) - -#define HOLES {0x0bff8000, 0x0fff8000, 0x17ff8000, 0x1fff8000} +#define HOLES {0x04ff8000, 0x06ff8000, 0x0aff8000, 0x1fff8000} #define HOLE_SIZE 0x2000 diff --git a/lisp/sunos-os.c b/lisp/sunos-os.c index c33547470..b7bd8d480 100644 --- a/lisp/sunos-os.c +++ b/lisp/sunos-os.c @@ -1,5 +1,5 @@ /* - * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/sunos-os.c,v 1.1 1992/09/08 20:32:23 wlott Exp $ + * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/sunos-os.c,v 1.1.1.1 1994/10/24 19:52:19 ram Exp $ * * OS-dependent routines. This file (along with os.h) exports an * OS-independent interface to the operating system VM facilities. @@ -19,6 +19,22 @@ #include <signal.h> #include <sys/file.h> +#ifdef SOLARIS +#include <unistd.h> +#include <errno.h> +#include <sys/param.h> +#define OS_PROTERR SEGV_ACCERR +#define OS_MAPERR SEGV_MAPERR +#define OS_HASERRNO(code) ((code)->si_errno != 0) +#define OS_ERRNO(code) ((code)->si_errno) +#else +#define OS_PROTERR SEGV_PROT +#define OS_MAPERR SEGV_NOMAP +#define OS_HASERRNO(code) (SEGV_CODE(code)==SEGV_OBJERR) +#define OS_ERRNO(code) SEGV_ERRNO(code) +extern int errno; +#endif /* SOLARIS */ + #include "os.h" /* block size must be larger than the system page size */ @@ -32,7 +48,8 @@ #define EMPTYFILE "/tmp/empty" #define ZEROFILE "/dev/zero" -#define MAX_SEGS 64 +#define INITIAL_MAX_SEGS 32 +#define GROW_MAX_SEGS 16 extern char *getenv(); @@ -41,6 +58,7 @@ extern char *getenv(); #define ADJ_OFFSET(off,adj) (((off)==OFFSET_NONE) ? OFFSET_NONE : ((off)+(adj))) long os_vm_page_size=(-1); +static long os_real_page_size=(-1); static struct segment { os_vm_address_t start; /* note: start & length are expected to be on page */ @@ -48,15 +66,24 @@ static struct segment { long file_offset; short mapped_fd; short protection; -} addr_map[MAX_SEGS]; +} *segments; -static int n_segments=0; +static int n_segments=0, max_segments=0; static int zero_fd=(-1), empty_fd=(-1); static os_vm_address_t last_fault=0; static os_vm_size_t real_page_size_difference=0; +static void os_init_bailout(arg) +char *arg; +{ + char buf[500]; + sprintf(buf,"os_init: %s",arg); + perror(buf); + exit(1); +} + void os_init() { char *empty_file=getenv("CMUCL_EMPTYFILE"); @@ -65,11 +92,28 @@ void os_init() empty_file=EMPTYFILE; empty_fd=open(empty_file,O_RDONLY|O_CREAT); + if(empty_fd<0) + os_init_bailout(empty_file); unlink(empty_file); zero_fd=open(ZEROFILE,O_RDONLY); + if(zero_fd<0) + os_init_bailout(ZEROFILE); - os_vm_page_size=getpagesize(); + +#ifdef SOLARIS + os_vm_page_size = os_real_page_size = sysconf(_SC_PAGESIZE); +#else + os_vm_page_size = os_real_page_size = getpagesize(); +#endif + + max_segments=INITIAL_MAX_SEGS; + segments=(struct segment *)malloc(sizeof(struct segment)*max_segments); + if(segments==NULL){ + fprintf(stderr,"os_init: Couldn't allocate %d segment descriptors\n", + max_segments); + exit(1); + } if(os_vm_page_size>OS_VM_DEFAULT_PAGESIZE){ fprintf(stderr,"os_init: Pagesize too large (%d > %d)\n", @@ -120,14 +164,28 @@ int mapped_fd; if(len==0) return NULL; - if(n_segments==MAX_SEGS){ - fprintf(stderr,"seg_create_nomerge: Out of segments\n"); - return NULL; + if(n_segments==max_segments){ + struct segment *new_segs; + + max_segments+=GROW_MAX_SEGS; + + new_segs=(struct segment *) + realloc(segments,max_segments*sizeof(struct segment)); + + if(new_segs==NULL){ + fprintf(stderr, + "seg_create_nomerge: Couldn't grow segment descriptor table to %s segments\n", + max_segments); + max_segments-=GROW_MAX_SEGS; + return NULL; + } + + segments=new_segs; } - for(n=n_segments, seg=addr_map; n>0; n--, seg++) + for(n=n_segments, seg=segments; n>0; n--, seg++) if(addr<seg->start){ - seg=(&addr_map[n_segments]); + seg=(&segments[n_segments]); while(n-->0){ seg[0]=seg[-1]; seg--; @@ -146,6 +204,7 @@ int mapped_fd; return seg; } +#if 1 /* returns the first segment containing addr */ static struct segment *seg_find(addr) os_vm_address_t addr; @@ -153,12 +212,35 @@ os_vm_address_t addr; int n; struct segment *seg; - for(n=n_segments, seg=addr_map; n>0; n--, seg++) + for(n=n_segments, seg=segments; n>0; n--, seg++) if(seg->start<=addr && seg->start+seg->length>addr) return seg; return NULL; } +#else +/* returns the first segment containing addr */ +static struct segment *seg_find(addr) +os_vm_address_t addr; +{ + /* does a binary search */ + struct segment *lo=segments, *hi=segments+n_segments; + + while(hi>lo){ + struct segment *mid=lo+((hi-lo)>>1); + os_vm_address_t start=mid->start; + + if(addr>=start && addr<start+mid->length) + return mid; + else if(addr<start) + hi=mid; + else + lo=mid+1; + } + + return NULL; +} +#endif /* returns TRUE if the range from addr to addr+len intersects with any segment */ static boolean collides_with_seg_p(addr,len) @@ -169,7 +251,7 @@ os_vm_size_t len; struct segment *seg; os_vm_address_t end=addr+len; - for(n=n_segments, seg=addr_map; n>0; n--, seg++) + for(n=n_segments, seg=segments; n>0; n--, seg++) if(seg->start>=end) return FALSE; else if(seg->start+seg->length>addr) @@ -178,7 +260,26 @@ os_vm_size_t len; return FALSE; } -#define seg_last_p(seg) (((seg)-addr_map)>=n_segments-1) +#if 0 /* WAY to SLOW */ +/* returns TRUE if the range from addr to addr+len is a valid mapping + * (that we don't know about) */ +static boolean mem_in_use(addr,len) +os_vm_address_t addr; +os_vm_size_t len; +{ + os_vm_address_t p; + + for (p = addr; addr < addr + len; p += os_real_page_size) { + char c; + + if (mincore((caddr_t)p, os_real_page_size, &c) == 0 || errno != ENOMEM) + return TRUE; + } + return FALSE; +} +#endif + +#define seg_last_p(seg) (((seg)-segments)>=n_segments-1) static void seg_destroy(seg) struct segment *seg; @@ -186,7 +287,7 @@ struct segment *seg; if(seg!=NULL){ int n; - for(n=seg-addr_map+1; n<n_segments; n++){ + for(n=seg-segments+1; n<n_segments; n++){ seg[0]=seg[1]; seg++; } @@ -236,7 +337,7 @@ struct segment *seg; { if(!seg_last_p(seg)) seg_try_merge_next(seg); - if(seg>addr_map) + if(seg>segments) seg_try_merge_next(seg-1); } @@ -401,11 +502,11 @@ int is_readable; addr=os_round_up_to_page(real); if(addr!=real) - munmap(real,addr-real); + munmap((caddr_t)real,addr-real); overflow=real_page_size_difference-(addr-real); if(overflow!=0) - munmap(addr+len-real_page_size_difference,overflow); + munmap((caddr_t)(addr+len-real_page_size_difference),overflow); real=addr; } @@ -433,7 +534,7 @@ int is_readable; seg=seg_create(real,len,protection,map_fd,offset); if(seg==NULL){ - munmap(real,len); + munmap((caddr_t)real,len); return NULL; } } @@ -486,7 +587,7 @@ os_vm_size_t len; seg_destroy(seg); last_fault=0; - if(munmap(addr,len)!=0) + if(munmap((caddr_t)addr,len)!=0) perror("os_invalidate: munmap"); } } @@ -565,9 +666,7 @@ os_vm_address_t test; /* ---------------------------------------------------------------- */ -static boolean maybe_gc(sig, code, context) -int sig, code; -struct sigcontext *context; +static boolean maybe_gc(HANDLER_ARGS) { /* * It's necessary to enable recursive SEGVs, since the handle is @@ -581,10 +680,16 @@ struct sigcontext *context; if(already_trying) return FALSE; + SAVE_CONTEXT(); + +#ifdef POSIX_SIGS + sigprocmask(SIG_SETMASK, &context->uc_sigmask,0); +#else sigsetmask(context->sc_mask); +#endif already_trying=TRUE; - did_gc=interrupt_maybe_gc(sig, code, context); + did_gc=interrupt_maybe_gc(signal, code, context); already_trying=FALSE; return did_gc; @@ -598,16 +703,23 @@ struct sigcontext *context; * * Running into the gc trigger page will also end up here... */ -void segv_handler(sig, code, context, addr) -int sig, code; -struct sigcontext *context; -caddr_t addr; +#ifndef SOLARIS +void segv_handler(HANDLER_ARGS, caddr_t addr) +#else +void segv_handler(HANDLER_ARGS) +#endif /* SOLARIS */ { - if (code == SEGV_PROT) { /* allow writes to this chunk */ +#ifdef SOLARIS + caddr_t addr = code->si_addr; +#endif + + SAVE_CONTEXT(); + + if (CODE(code) == OS_PROTERR) { /* allow writes to this chunk */ struct segment *seg=seg_find(addr); - if(last_fault==addr){ - if(seg!=NULL && maybe_gc(sig, code, context)) + if((caddr_t)last_fault==addr){ + if(seg!=NULL && maybe_gc(signal, code, context)) /* we just garbage collected */ return; else{ @@ -615,10 +727,10 @@ caddr_t addr; fprintf(stderr, "segv_handler: Real protection violation: 0x%08x\n", addr); - interrupt_handle_now(sig,code,context); + interrupt_handle_now(signal,code,context); } }else - last_fault=addr; + last_fault=(os_vm_address_t) addr; if(seg!=NULL){ int err; @@ -635,13 +747,13 @@ caddr_t addr; #if 0 /* unmap it. probably redundant. */ - if(munmap(block,length) == -1) + if(munmap((caddr_t)block,length) == -1) perror("segv_handler: munmap"); #endif /* and remap it with more permissions */ err=(int) - mmap(block, + mmap((caddr_t)block, length, seg->protection, MAP_PRIVATE|MAP_FIXED, @@ -652,21 +764,21 @@ caddr_t addr; if (err == -1) { perror("segv_handler: mmap"); - interrupt_handle_now(sig,code,context); + interrupt_handle_now(signal,code,context); } } else{ fprintf(stderr, "segv_handler: 0x%08x not in any segment\n",addr); - interrupt_handle_now(sig,code,context); + interrupt_handle_now(signal,code,context); } } /* * note that we check for a gc-trigger hit even if it's not a PROT error */ - else if(!maybe_gc(sig, code, context)){ + else if(!maybe_gc(signal, code, context)){ static int nomap_count=0; - if(code==SEGV_NOMAP){ + if(CODE(code)==OS_MAPERR){ if(nomap_count==0){ fprintf(stderr, "segv_handler: No mapping fault: 0x%08x\n",addr); @@ -681,15 +793,14 @@ caddr_t addr; "segv_handler: Recursive no mapping fault (stack overflow?)\n"); exit(-1); } - }else if(SEGV_CODE(code)==SEGV_OBJERR){ - extern int errno; - errno=SEGV_ERRNO(code); + } else if(OS_HASERRNO(code)) { + errno=OS_ERRNO(code); perror("segv_handler: Object error"); } - interrupt_handle_now(sig,code,context); + interrupt_handle_now(signal,code,context); - if(code==SEGV_NOMAP) + if(CODE(code)==OS_MAPERR) nomap_count--; } } @@ -698,3 +809,156 @@ void os_install_interrupt_handlers() { interrupt_install_low_level_handler(SIGSEGV,segv_handler); } + + +#ifdef SOLARIS + + +/* function defintions for register lvalues */ + +int * solaris_register_address(struct ucontext *context, int reg) +{ + if (reg == 0) { + static int zero; + + zero = 0; + + return &zero; + } else if (reg < 16) { + return &context->uc_mcontext.gregs[reg+3]; + } else if (reg < 32) { + int *sp = (int*) context->uc_mcontext.gregs[REG_SP]; + return &sp[reg-16]; + } else + return 0; +} +/* function defintions for backward compatibilty and static linking */ + +#if 0 +void * dlopen(const char * file, int flag) { return 0; } +void * dlsym(void *obj, const char *sym) { return 0; } +int dlclose(void *obj) { return 0; } +char * dlerror(void) { return "no dynamic linking"; } +#endif + +/* For now we put in some porting functions */ + +int +getdtablesize(void) +{ + return sysconf(_SC_OPEN_MAX); +} + +char * +getwd(char *path) +{ + return getcwd(path, MAXPATHLEN); +} + +int +getpagesize(void) +{ + return sysconf(_SC_PAGESIZE); +} + + +#include <sys/procfs.h> +/* Old rusage definition */ +struct rusage { + struct timeval ru_utime; /* user time used */ + struct timeval ru_stime; /* system time used */ + long ru_maxrss; +#define ru_first ru_ixrss + long ru_ixrss; /* XXX: 0 */ + long ru_idrss; /* XXX: sum of rm_asrss */ + long ru_isrss; /* XXX: 0 */ + long ru_minflt; /* any page faults not requiring I/O */ + long ru_majflt; /* any page faults requiring I/O */ + long ru_nswap; /* swaps */ + long ru_inblock; /* block input operations */ + long ru_oublock; /* block output operations */ + long ru_msgsnd; /* messages sent */ + long ru_msgrcv; /* messages received */ + long ru_nsignals; /* signals received */ + long ru_nvcsw; /* voluntary context switches */ + long ru_nivcsw; /* involuntary " */ +#define ru_last ru_nivcsw +}; + + +int +getrusage(int who, struct rusage *rp) +{ + memset(rp, 0, sizeof(struct rusage)); + return 0; +} + +int +setreuid() +{ + fprintf(stderr,"setreuid unimplemented\n"); + errno = ENOSYS; + return -1; +} + +int +setregid() +{ + fprintf(stderr,"setregid unimplemented\n"); + errno = ENOSYS; + return -1; +} + +int +gethostid() +{ + fprintf(stderr,"gethostid unimplemented\n"); + errno = ENOSYS; + return -1; +} + +int +killpg(int pgrp, int sig) +{ + if (pgrp < 0) { + errno = ESRCH; + return -1; + } + return kill(-pgrp, sig); +} + +int +sigblock(int mask) +{ + sigset_t old, new; + + sigemptyset(&new); + new.__sigbits[0] = mask; + + sigprocmask(SIG_BLOCK, &new, &old); + + return old.__sigbits[0]; +} + +int +wait3(int *status, int options, struct rusage *rp) +{ + if (rp) + memset(rp, 0, sizeof(struct rusage)); + return waitpid(-1, status, options); +} + +int +sigsetmask(int mask) +{ + sigset_t old, new; + + sigemptyset(&new); + new.__sigbits[0] = mask; + + sigprocmask(SIG_SETMASK, &new, &old); + + return old.__sigbits[0]; + +} +#endif /* SOLARIS */ diff --git a/lisp/sunos-os.h b/lisp/sunos-os.h index 8d2eb79c3..0f17acc3b 100644 --- a/lisp/sunos-os.h +++ b/lisp/sunos-os.h @@ -1,6 +1,26 @@ +#ifdef SOLARIS +#undef boolean +#endif /* SOLARIS */ + #include <sys/types.h> + +#ifdef SOLARIS +#define boolean int +#include <signal.h> +#include <unistd.h> +#include <sys/fcntl.h> +#endif /* SOLARIS */ + #include <sys/mman.h> +#ifdef SOLARIS +#include <ucontext.h> +#define sigcontext ucontext + +#define POSIX_SIGS + +#endif /* SOLARIS */ + typedef unsigned long os_vm_address_t; typedef long os_vm_size_t; typedef off_t os_vm_offset_t; @@ -11,3 +31,18 @@ typedef int os_vm_prot_t; #define OS_VM_PROT_EXECUTE PROT_EXEC #define OS_VM_DEFAULT_PAGESIZE 8192 + +#ifdef SOLARIS +#include <ucontext.h> +#define HANDLER_ARGS int signal, siginfo_t *code, struct ucontext *context +#define CODE(code) ((code) ? code->si_code : 0) +#define SAVE_CONTEXT() save_context() + +#ifdef NULL +#undef NULL +#define NULL 0 +#endif + +#define bcopy(a,b,n) memmove(b,a,n) +#define bzero(a,n) memset(a,0,n) +#endif /* SOLARIS */ diff --git a/lisp/undefineds.c b/lisp/undefineds.c index 0cf5f9f50..897e50309 100644 --- a/lisp/undefineds.c +++ b/lisp/undefineds.c @@ -1,11 +1,13 @@ /* Routines that must be linked into the core for lisp to work. */ -/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/undefineds.c,v 1.2 1993/08/18 22:14:34 wlott Exp $ */ +/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/undefineds.c,v 1.2.1.1 1994/10/24 19:52:41 ram Exp $ */ #ifdef sun #ifndef MACH +#if !defined(SUNOS) && !defined(SOLARIS) #define SUNOS #endif #endif +#endif typedef int func(); diff --git a/lisp/undefineds.h b/lisp/undefineds.h index c6fab8e2f..5b3dd3b42 100644 --- a/lisp/undefineds.h +++ b/lisp/undefineds.h @@ -1,5 +1,5 @@ /* Routines that must be linked into the core for lisp to work. */ -/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/undefineds.h,v 1.2 1993/07/27 15:11:19 hallgren Exp $ */ +/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/undefineds.h,v 1.2.1.1 1994/10/24 19:52:44 ram Exp $ */ /* Pick up all the syscalls. */ accept, @@ -24,33 +24,37 @@ exit, fchmod, fchown, fcntl, -#ifndef hpux +#if !defined(hpux) && !defined(SVR4) flock, #endif fork, fstat, fsync, ftruncate, -#ifndef hpux +#if !defined(hpux) && !defined(SVR4) getdtablesize, #endif getegid, geteuid, getgid, getgroups, +#ifndef SVR4 gethostid, +#endif gethostname, getitimer, -#ifndef hpux +#if !defined(hpux) && !defined(SVR4) getpagesize, #endif getpeername, getpgrp, getpid, getppid, +#ifndef SVR4 getpriority, +#endif getrlimit, -#ifndef hpux +#if !defined(hpux) && !defined(SVR4) getrusage, #endif getsockname, @@ -59,7 +63,9 @@ gettimeofday, getuid, ioctl, kill, +#ifndef SVR4 killpg, +#endif link, listen, lseek, @@ -71,13 +77,15 @@ open, pipe, profil, ptrace, -#if !defined(SUNOS) && !defined(parisc) +#if !defined(SUNOS) && !defined(parisc) && !defined(SOLARIS) quota, #endif read, readlink, readv, +#ifndef SVR4 reboot, +#endif recv, recvfrom, recvmsg, @@ -89,17 +97,21 @@ send, sendmsg, sendto, setgroups, -#ifndef SUNOS +#if !defined(SUNOS) && !defined(SOLARIS) sethostid, #endif +#ifndef SVR4 sethostname, +#endif setitimer, setpgrp, +#ifndef SVR4 setpriority, -#if !defined(SUNOS) && !defined(parisc) +#endif +#if !defined(SUNOS) && !defined(parisc) && !defined(SOLARIS) setquota, #endif -#ifndef hpux +#if !defined(hpux) && !defined(SVR4) setregid, setreuid, #endif @@ -107,22 +119,28 @@ setrlimit, setsockopt, settimeofday, shutdown, +#ifndef SVR4 sigblock, +#endif sigpause, -#if !defined(ibmrt) && !defined(hpux) +#if !defined(ibmrt) && !defined(hpux) && !defined(SVR4) sigreturn, #endif +#ifndef SVR4 sigsetmask, sigstack, sigvec, +#endif socket, socketpair, stat, +#ifndef SVR4 swapon, +#endif symlink, sync, syscall, -#ifdef hpux +#if defined(hpux) || defined(SVR4) closedir, opendir, readdir, @@ -131,7 +149,7 @@ tcsetattr, #endif truncate, umask, -#if !defined(SUNOS) && !defined(parisc) +#if !defined(SUNOS) && !defined(parisc) && !defined(SOLARIS) umount, #endif unlink, @@ -141,7 +159,9 @@ utimes, vfork, vhangup, wait, +#ifndef SVR4 wait3, +#endif write, writev, @@ -182,5 +202,19 @@ gethostbyname, gethostbyaddr, /* Other random things. */ +#ifdef SVR4 +setpgid, +getpgid, +timezone, +altzone, +daylight, +tzname, +dlopen, +dlsym, +dlclose, +dlerror, +#endif +#ifndef SVR4 getwd, +#endif ttyname diff --git a/lisp/vars.c b/lisp/vars.c index 09aacbd76..dfe39c1b3 100644 --- a/lisp/vars.c +++ b/lisp/vars.c @@ -1,10 +1,11 @@ -/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/vars.c,v 1.1 1992/07/28 20:15:38 wlott Exp $ */ +/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/vars.c,v 1.1.1.1 1994/10/24 19:53:01 ram Exp $ */ #include <stdio.h> #include <sys/types.h> #include <stdlib.h> #include "lisp.h" #include "vars.h" +#include "os.h" #define NAME_BUCKETS 31 #define OBJ_BUCKETS 31 -- GitLab