Skip to content
Snippets Groups Projects
Commit 3861a7bf authored by ram's avatar ram
Browse files

Solaris patches.

parent 68d8faf0
No related branches found
No related tags found
No related merge requests found
/* $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
......@@ -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"
......
/*
* 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;
......
/* $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
......
/*
* $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. */
......
/* $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)
{
......
/* $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
/*
* 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
......
/* $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"
......
......@@ -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;
......
/*
* $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;
......
/* $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;
......
/*
* $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);
......
......@@ -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
......
#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()
......
#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
/* $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
#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
/*
* $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 */
#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 */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment