Commit 00353423 authored by agoncharov's avatar agoncharov
Browse files

A more consistent treatment of signal handlers.

parent d4bc586c
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* Much hacked by Paul Werkowski * Much hacked by Paul Werkowski
* GENCGC support by Douglas Crosher, 1996, 1997. * GENCGC support by Douglas Crosher, 1996, 1997.
* *
* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/FreeBSD-os.c,v 1.28 2009/01/06 02:28:14 agoncharov Exp $ * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/FreeBSD-os.c,v 1.29 2009/01/20 04:45:18 agoncharov Exp $
* *
*/ */
...@@ -37,7 +37,6 @@ ...@@ -37,7 +37,6 @@
#endif #endif
vm_size_t os_vm_page_size; vm_size_t os_vm_page_size;
void void
os_init(void) os_init(void)
...@@ -49,39 +48,40 @@ unsigned long * ...@@ -49,39 +48,40 @@ unsigned long *
os_sigcontext_reg(ucontext_t *scp, int index) os_sigcontext_reg(ucontext_t *scp, int index)
{ {
__register_t *rv; __register_t *rv;
switch (index) { switch (index) {
case 0: case 0:
rv = &scp->uc_mcontext.mc_eax; rv = &scp->uc_mcontext.mc_eax;
break; break;
case 2: case 2:
rv = &scp->uc_mcontext.mc_ecx; rv = &scp->uc_mcontext.mc_ecx;
break; break;
case 4: case 4:
rv = &scp->uc_mcontext.mc_edx; rv = &scp->uc_mcontext.mc_edx;
break; break;
case 6: case 6:
rv = &scp->uc_mcontext.mc_ebx; rv = &scp->uc_mcontext.mc_ebx;
break; break;
case 8: case 8:
rv = &scp->uc_mcontext.mc_esp; rv = &scp->uc_mcontext.mc_esp;
break; break;
case 10: case 10:
rv = &scp->uc_mcontext.mc_ebp; rv = &scp->uc_mcontext.mc_ebp;
break; break;
case 12: case 12:
rv = &scp->uc_mcontext.mc_esi; rv = &scp->uc_mcontext.mc_esi;
break; break;
case 14: case 14:
rv = &scp->uc_mcontext.mc_edi; rv = &scp->uc_mcontext.mc_edi;
break; break;
default: default:
rv = NULL; rv = NULL;
} }
/* Pre-cast to (void *), to avoid the compiler warning: /* Pre-cast to (void *), to avoid the compiler warning:
* FreeBSD-os.c:72: warning: dereferencing type-punned pointer will break strict-aliasing rules * dereferencing type-punned pointer will break strict-aliasing rules
*/ */
return (unsigned long *) (void *) rv; return (unsigned long *) (void *) rv;
} }
unsigned long * unsigned long *
...@@ -98,15 +98,15 @@ os_sigcontext_fpu_reg(ucontext_t *scp, int index) ...@@ -98,15 +98,15 @@ os_sigcontext_fpu_reg(ucontext_t *scp, int index)
unsigned char *reg = NULL; unsigned char *reg = NULL;
switch (fpformat) { switch (fpformat) {
case _MC_FPFMT_XMM: case _MC_FPFMT_XMM:
reg = sv->sv_xmm.sv_fp[index].fp_acc.fp_bytes; reg = sv->sv_xmm.sv_fp[index].fp_acc.fp_bytes;
break; break;
case _MC_FPFMT_387: case _MC_FPFMT_387:
reg = sv->sv_87.sv_ac[index].fp_bytes; reg = sv->sv_87.sv_ac[index].fp_bytes;
break; break;
case _MC_FPFMT_NODEV: case _MC_FPFMT_NODEV:
reg = NULL; reg = NULL;
break; break;
} }
return reg; return reg;
} }
...@@ -115,7 +115,7 @@ unsigned int ...@@ -115,7 +115,7 @@ unsigned int
os_sigcontext_fpu_modes(ucontext_t *scp) os_sigcontext_fpu_modes(ucontext_t *scp)
{ {
unsigned int modes; unsigned int modes;
union savefpu *sv = (union savefpu *) scp->uc_mcontext.mc_fpstate; union savefpu *sv = (union savefpu *) scp->uc_mcontext.mc_fpstate;
int fpformat = scp->uc_mcontext.mc_fpformat; int fpformat = scp->uc_mcontext.mc_fpformat;
struct env87 *env_87 = &sv->sv_87.sv_env; struct env87 *env_87 = &sv->sv_87.sv_env;
...@@ -129,7 +129,7 @@ os_sigcontext_fpu_modes(ucontext_t *scp) ...@@ -129,7 +129,7 @@ os_sigcontext_fpu_modes(ucontext_t *scp)
} else if (fpformat == _MC_FPFMT_387) { } else if (fpformat == _MC_FPFMT_387) {
cw = env_87->en_cw & 0xffff; cw = env_87->en_cw & 0xffff;
sw = env_87->en_sw & 0xffff; sw = env_87->en_sw & 0xffff;
} else { /* _MC_FPFMT_NODEV */ } else { /* _MC_FPFMT_NODEV */
cw = 0; cw = 0;
sw = 0x3f; sw = 0x3f;
} }
...@@ -138,8 +138,9 @@ os_sigcontext_fpu_modes(ucontext_t *scp) ...@@ -138,8 +138,9 @@ os_sigcontext_fpu_modes(ucontext_t *scp)
#ifdef FEATURE_SSE2 #ifdef FEATURE_SSE2
if (fpu_mode == SSE2) { if (fpu_mode == SSE2) {
u_int32_t mxcsr = env_xmm->en_mxcsr; u_int32_t mxcsr = env_xmm->en_mxcsr;
DPRINTF(0, (stderr, "SSE2 modes = %08x\n", (int) mxcsr));
DPRINTF(0, (stderr, "SSE2 modes = %08x\n", (int)mxcsr));
modes |= mxcsr; modes |= mxcsr;
} }
#endif #endif
...@@ -147,7 +148,8 @@ os_sigcontext_fpu_modes(ucontext_t *scp) ...@@ -147,7 +148,8 @@ os_sigcontext_fpu_modes(ucontext_t *scp)
return modes; return modes;
} }
os_vm_address_t os_validate(os_vm_address_t addr, os_vm_size_t len) os_vm_address_t
os_validate(os_vm_address_t addr, os_vm_size_t len)
{ {
int flags = MAP_PRIVATE | MAP_ANON; int flags = MAP_PRIVATE | MAP_ANON;
...@@ -207,7 +209,8 @@ in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen) ...@@ -207,7 +209,8 @@ in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
return adr >= beg && adr < end; return adr >= beg && adr < end;
} }
boolean valid_addr(os_vm_address_t addr) boolean
valid_addr(os_vm_address_t addr)
{ {
os_vm_address_t newaddr; os_vm_address_t newaddr;
...@@ -227,22 +230,22 @@ boolean valid_addr(os_vm_address_t addr) ...@@ -227,22 +230,22 @@ boolean valid_addr(os_vm_address_t addr)
static void static void
sigbus_handler(int signal, siginfo_t *info, ucontext_t *context) protection_violation_handler(HANDLER_ARGS)
{ {
#ifdef RED_ZONE_HIT #ifdef RED_ZONE_HIT
if (os_control_stack_overflow(info->si_addr, context)) if (os_control_stack_overflow(code->si_addr, context))
return; return;
#endif #endif
#if defined GENCGC #if defined GENCGC
if (info->si_code == PROTECTION_VIOLATION_CODE) { if (code->si_code == PROTECTION_VIOLATION_CODE) {
if (gc_write_barrier(info->si_addr)) { if (gc_write_barrier(code->si_addr)) {
return; return;
} }
} }
#endif /* GENCGC */ #endif
interrupt_handle_now(signal, info, context); interrupt_handle_now(signal, code, context);
} }
/* /*
...@@ -253,46 +256,47 @@ sigbus_handler(int signal, siginfo_t *info, ucontext_t *context) ...@@ -253,46 +256,47 @@ sigbus_handler(int signal, siginfo_t *info, ucontext_t *context)
* if the subcode is FPE_FLTUND. * if the subcode is FPE_FLTUND.
*/ */
static void static void
sigfpe_handler(int signal, siginfo_t *info, ucontext_t *context) sigfpe_handler(HANDLER_ARGS)
{ {
union savefpu *sv = (union savefpu *) context->uc_mcontext.mc_fpstate; ucontext_t *ucontext = (ucontext_t *) context;
int fpformat = context->uc_mcontext.mc_fpformat; union savefpu *sv = (union savefpu *) ucontext->uc_mcontext.mc_fpstate;
int code = info->si_code; int fpformat = ucontext->uc_mcontext.mc_fpformat;
unsigned char trap = 0; unsigned char trap = 0;
switch (code) { switch (code->si_code) {
case FPE_FLTDIV: /* ZE */ case FPE_FLTDIV: /* ZE */
trap = 0x04; trap = 0x04;
break; break;
case FPE_FLTOVF: /* OE */ case FPE_FLTOVF: /* OE */
trap = 0x08; trap = 0x08;
break; break;
case FPE_FLTUND: /* DE or UE */ case FPE_FLTUND: /* DE or UE */
trap = 0x10; trap = 0x10;
break; break;
case FPE_FLTRES: /* PE */ case FPE_FLTRES: /* PE */
trap = 0x20; trap = 0x20;
break; break;
case FPE_FLTINV: /* IE */ case FPE_FLTINV: /* IE */
trap = 0x01; trap = 0x01;
break; break;
} }
switch (fpformat) {
case _MC_FPFMT_XMM: switch (fpformat) {
case _MC_FPFMT_XMM:
sv->sv_xmm.sv_env.en_sw |= trap; sv->sv_xmm.sv_env.en_sw |= trap;
break; break;
case _MC_FPFMT_387: case _MC_FPFMT_387:
sv->sv_87.sv_env.en_sw |= trap; sv->sv_87.sv_env.en_sw |= trap;
break; break;
} }
interrupt_handle_now(signal, info, context); interrupt_handle_now(signal, code, context);
} }
void void
os_install_interrupt_handlers(void) os_install_interrupt_handlers(void)
{ {
interrupt_install_low_level_handler interrupt_install_low_level_handler(PROTECTION_VIOLATION_SIGNAL,
(PROTECTION_VIOLATION_SIGNAL, sigbus_handler); protection_violation_handler);
interrupt_install_low_level_handler(SIGFPE, sigfpe_handler); interrupt_install_low_level_handler(SIGFPE, sigfpe_handler);
} }
...@@ -305,8 +309,8 @@ os_dlsym(const char *sym_name, lispobj lib_list) ...@@ -305,8 +309,8 @@ os_dlsym(const char *sym_name, lispobj lib_list)
for (lib_list_head = lib_list; for (lib_list_head = lib_list;
lib_list_head != NIL; lib_list_head = CONS(lib_list_head)->cdr) { lib_list_head != NIL; lib_list_head = CONS(lib_list_head)->cdr) {
struct cons *lib_cons = CONS(CONS(lib_list_head)->car); struct cons *lib_cons = CONS(CONS(lib_list_head)->car);
struct sap *dlhandle = (struct sap *) PTR(lib_cons->car); struct sap *dlhandle = (struct sap *)PTR(lib_cons->car);
void *sym_addr = dlsym((void *) dlhandle->pointer, sym_name); void *sym_addr = dlsym((void *)dlhandle->pointer, sym_name);
if (sym_addr) if (sym_addr)
return sym_addr; return sym_addr;
...@@ -329,16 +333,18 @@ restore_fpu(ucontext_t *scp) ...@@ -329,16 +333,18 @@ restore_fpu(ucontext_t *scp)
cw = env_xmm->en_cw; cw = env_xmm->en_cw;
} else if (fpformat == _MC_FPFMT_387) { } else if (fpformat == _MC_FPFMT_387) {
cw = env_87->en_cw & 0xffff; cw = env_87->en_cw & 0xffff;
} else { /* _MC_FPFMT_NODEV */ } else { /* _MC_FPFMT_NODEV */
return; return;
} }
DPRINTF(0, (stderr, "restore_fpu: cw = %08x\n", (int) cw)); DPRINTF(0, (stderr, "restore_fpu: cw = %08x\n", (int)cw));
__asm__ __volatile__ ("fldcw %0" : : "m" (*&cw)); __asm__ __volatile__ ("fldcw %0"::"m"(*&cw));
#ifdef FEATURE_SSE2 #ifdef FEATURE_SSE2
if (arch_support_sse2()) { if (arch_support_sse2()) {
u_int32_t mxcsr = env_xmm->en_mxcsr; u_int32_t mxcsr = env_xmm->en_mxcsr;
DPRINTF(0, (stderr, "restore_fpu: mxcsr (raw) = %04x\n", mxcsr));
__asm__ __volatile__ ("ldmxcsr %0" :: "m" (*&mxcsr)); DPRINTF(0, (stderr, "restore_fpu: mxcsr (raw) = %04x\n", mxcsr));
__asm__ __volatile__ ("ldmxcsr %0"::"m"(*&mxcsr));
} }
#endif #endif
} }
/* /*
$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/FreeBSD-os.h,v 1.22 2008/03/18 09:22:55 cshapiro Exp $ $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/FreeBSD-os.h,v 1.23 2009/01/20 04:45:18 agoncharov Rel $
This code was written as part of the CMU Common Lisp project at This code was written as part of the CMU Common Lisp project at
Carnegie Mellon University, and has been placed in the public domain. Carnegie Mellon University, and has been placed in the public domain.
...@@ -28,7 +28,9 @@ typedef int os_vm_prot_t; ...@@ -28,7 +28,9 @@ typedef int os_vm_prot_t;
#define OS_VM_DEFAULT_PAGESIZE 4096 #define OS_VM_DEFAULT_PAGESIZE 4096
#define HANDLER_ARGS int signal, siginfo_t *code, ucontext_t *context /* ucontext_t *context; using `void *' to compile without warning */
#define HANDLER_ARGS int signal, siginfo_t *code, void *context
#define CODE(code) ((code) ? code->si_code : 0) #define CODE(code) ((code) ? code->si_code : 0)
#define RESTORE_FPU(context) restore_fpu(context) #define RESTORE_FPU(context) restore_fpu(context)
......
/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/interrupt.c,v 1.56 2008/09/11 17:07:21 rtoy Exp $ */ /* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/interrupt.c,v 1.57 2009/01/20 04:45:19 agoncharov Exp $ */
/* Interrupt handling magic. */ /* Interrupt handling magic. */
...@@ -148,6 +148,7 @@ undo_fake_foreign_function_call(os_context_t * context) ...@@ -148,6 +148,7 @@ undo_fake_foreign_function_call(os_context_t * context)
void void
interrupt_internal_error(HANDLER_ARGS, boolean continuable) interrupt_internal_error(HANDLER_ARGS, boolean continuable)
{ {
ucontext_t *ucontext = (ucontext_t *) context;
lispobj context_sap = NIL; lispobj context_sap = NIL;
fake_foreign_function_call(context); fake_foreign_function_call(context);
...@@ -156,7 +157,7 @@ interrupt_internal_error(HANDLER_ARGS, boolean continuable) ...@@ -156,7 +157,7 @@ interrupt_internal_error(HANDLER_ARGS, boolean continuable)
if (internal_errors_enabled) if (internal_errors_enabled)
context_sap = alloc_sap(context); context_sap = alloc_sap(context);
sigprocmask(SIG_SETMASK, &context->uc_sigmask, 0); sigprocmask(SIG_SETMASK, &ucontext->uc_sigmask, 0);
if (internal_errors_enabled) if (internal_errors_enabled)
funcall2(SymbolFunction(INTERNAL_ERROR), context_sap, funcall2(SymbolFunction(INTERNAL_ERROR), context_sap,
...@@ -232,6 +233,7 @@ void ...@@ -232,6 +233,7 @@ void
interrupt_handle_now(HANDLER_ARGS) interrupt_handle_now(HANDLER_ARGS)
{ {
int were_in_lisp; int were_in_lisp;
ucontext_t *ucontext = (ucontext_t *) context;
union interrupt_handler handler; union interrupt_handler handler;
handler = interrupt_handlers[signal]; handler = interrupt_handlers[signal];
...@@ -259,7 +261,7 @@ interrupt_handle_now(HANDLER_ARGS) ...@@ -259,7 +261,7 @@ interrupt_handle_now(HANDLER_ARGS)
lispobj context_sap = alloc_sap(context); lispobj context_sap = alloc_sap(context);
/* Allow signals again. */ /* Allow signals again. */
sigprocmask(SIG_SETMASK, &context->uc_sigmask, 0); sigprocmask(SIG_SETMASK, &ucontext->uc_sigmask, 0);
#if 1 #if 1
funcall3(handler.lisp, make_fixnum(signal), make_fixnum(CODE(code)), funcall3(handler.lisp, make_fixnum(signal), make_fixnum(CODE(code)),
...@@ -270,7 +272,7 @@ interrupt_handle_now(HANDLER_ARGS) ...@@ -270,7 +272,7 @@ interrupt_handle_now(HANDLER_ARGS)
#endif #endif
} else { } else {
/* Allow signals again. */ /* Allow signals again. */
sigprocmask(SIG_SETMASK, &context->uc_sigmask, 0); sigprocmask(SIG_SETMASK, &ucontext->uc_sigmask, 0);
(*handler.c) (signal, code, context); (*handler.c) (signal, code, context);
} }
...@@ -284,6 +286,7 @@ interrupt_handle_now(HANDLER_ARGS) ...@@ -284,6 +286,7 @@ interrupt_handle_now(HANDLER_ARGS)
static void static void
setup_pending_signal(HANDLER_ARGS) setup_pending_signal(HANDLER_ARGS)
{ {
ucontext_t *ucontext = (ucontext_t *) context;
pending_signal = signal; pending_signal = signal;
/* /*
* Note: We used to set pending_code = *code. This doesn't work * Note: We used to set pending_code = *code. This doesn't work
...@@ -297,8 +300,8 @@ setup_pending_signal(HANDLER_ARGS) ...@@ -297,8 +300,8 @@ setup_pending_signal(HANDLER_ARGS)
* *
*/ */
pending_code.si_code = CODE(code); pending_code.si_code = CODE(code);
pending_mask = context->uc_sigmask; pending_mask = ucontext->uc_sigmask;
FILLBLOCKSET(&context->uc_sigmask); FILLBLOCKSET(&ucontext->uc_sigmask);
} }
static void static void
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment