sigtrap_handler(int signal, siginfo_t *siginfo, os_context_t *context)
{
unsigned int code;
-#ifdef LISP_FEATURE_LINUX
- os_restore_fp_control(context);
-#endif
/* this is different from how CMUCL does it. CMUCL used "call_pal
* PAL_gentrap", which doesn't do anything on Linux (unless NL0
#include "genesis/simple-fun.h"
#include "genesis/cons.h"
+/* Under Linux on some architectures, we appear to have to restore the
+ * FPU control word from the context, as after the signal is delivered
+ * we appear to have a null FPU control word. */
+#if defined(RESTORE_FP_CONTROL_FROM_CONTEXT)
+#define RESTORE_FP_CONTROL_WORD(context,void_context) \
+ os_context_t *context = arch_os_get_context(&void_context); \
+ os_restore_fp_control(context);
+#else
+#define RESTORE_FP_CONTROL_WORD(context,void_context) \
+ os_context_t *context = arch_os_get_context(&void_context);
+#endif
+
/* These are to be used in signal handlers. Currently all handlers are
* called from one of:
*
* low_level_maybe_now_maybe_later
* low_level_unblock_me_trampoline
*/
-#define SAVE_ERRNO() \
+#define SAVE_ERRNO(context,void_context) \
{ \
int _saved_errno = errno; \
+ RESTORE_FP_CONTROL_WORD(context,void_context); \
{
#define RESTORE_ERRNO \
check_interrupts_enabled_or_lose(context);
#endif
-#if defined(LISP_FEATURE_LINUX) || defined(RESTORE_FP_CONTROL_FROM_CONTEXT)
- /* Under Linux on some architectures, we appear to have to restore
- the FPU control word from the context, as after the signal is
- delivered we appear to have a null FPU control word. */
- os_restore_fp_control(context);
-#endif
-
handler = interrupt_handlers[signal];
if (ARE_SAME_HANDLER(handler.c, SIG_IGN)) {
static void
maybe_now_maybe_later(int signal, siginfo_t *info, void *void_context)
{
- SAVE_ERRNO();
- os_context_t *context = arch_os_get_context(&void_context);
+ SAVE_ERRNO(context,void_context);
struct thread *thread = arch_os_get_current_thread();
struct interrupt_data *data = thread->interrupt_data;
-#if defined(LISP_FEATURE_LINUX) || defined(RESTORE_FP_CONTROL_FROM_CONTEXT)
- os_restore_fp_control(context);
-#endif
-
if(!maybe_defer_handler(interrupt_handle_now,data,signal,info,context))
interrupt_handle_now(signal, info, context);
RESTORE_ERRNO;
static void
low_level_maybe_now_maybe_later(int signal, siginfo_t *info, void *void_context)
{
- SAVE_ERRNO();
- os_context_t *context = arch_os_get_context(&void_context);
+ SAVE_ERRNO(context,void_context);
struct thread *thread = arch_os_get_current_thread();
struct interrupt_data *data = thread->interrupt_data;
-#if defined(LISP_FEATURE_LINUX) || defined(RESTORE_FP_CONTROL_FROM_CONTEXT)
- os_restore_fp_control(context);
-#endif
-
if(!maybe_defer_handler(low_level_interrupt_handle_now,data,
signal,info,context))
low_level_interrupt_handle_now(signal, info, context);
void
interrupt_handle_now_handler(int signal, siginfo_t *info, void *void_context)
{
- SAVE_ERRNO();
- os_context_t *context = arch_os_get_context(&void_context);
-#if defined(LISP_FEATURE_LINUX) || defined(RESTORE_FP_CONTROL_FROM_CONTEXT)
- os_restore_fp_control(context);
+ SAVE_ERRNO(context,void_context);
#ifndef LISP_FEATURE_WIN32
if ((signal == SIGILL) || (signal == SIGBUS)
#ifndef LISP_FEATURE_LINUX
)
corruption_warning_and_maybe_lose("Signal %d recieved", signal);
#endif
-#endif
interrupt_handle_now(signal, info, context);
RESTORE_ERRNO;
}
/* Build a stack frame showing `interrupted' so that the
* user's backtrace makes (as much) sense (as usual) */
- /* FIXME: what about restoring fp state? */
+ /* fp state is saved and restored by call_into_lisp */
/* FIXME: errno is not restored, but since current uses of this
* function only call Lisp code that signals an error, it's not
* much of a problem. In other words, running out of the control
static void
unblock_me_trampoline(int signal, siginfo_t *info, void *void_context)
{
- SAVE_ERRNO();
- os_context_t *context = arch_os_get_context(&void_context);
+ SAVE_ERRNO(context,void_context);
sigset_t unblock;
sigemptyset(&unblock);
static void
low_level_unblock_me_trampoline(int signal, siginfo_t *info, void *void_context)
{
- SAVE_ERRNO();
+ SAVE_ERRNO(context,void_context);
sigset_t unblock;
sigemptyset(&unblock);
static void
low_level_handle_now_handler(int signal, siginfo_t *info, void *void_context)
{
- SAVE_ERRNO();
+ SAVE_ERRNO(context,void_context);
(*interrupt_low_level_handlers[signal])(signal, info, void_context);
RESTORE_ERRNO;
}
{
os_context_t *context = arch_os_get_context(&void_context);
unsigned int code = (os_context_insn(context) >> 6) & 0xfffff;
-#ifdef LISP_FEATURE_LINUX
- os_restore_fp_control(context);
-#endif
/* FIXME: This magic number is pseudo-atomic-trap from parms.lisp.
* Genesis should provide the proper #define, but it specialcases
* pseudo-atomic-trap to work around some oddity on SPARC.
unsigned int op, rs, rt, rd, funct, dest = 32;
int immed;
int result;
-#ifdef LISP_FEATURE_LINUX
- os_restore_fp_control(context);
-#endif
op = (bad_inst >> 26) & 0x3f;
rs = (bad_inst >> 21) & 0x1f;
unsigned int code;
os_context_t *context = void_context;
-#ifdef LISP_FEATURE_LINUX
- os_restore_fp_control(context);
-#endif
code=*((u32 *)(*os_context_pc_addr(context)));
if (code == ((3 << 26) | (0x18 << 21) | (reg_NL3 << 16))) {
arch_clear_pseudo_atomic_interrupted(context);
static void sigill_handler(int signal, siginfo_t *siginfo, void *void_context)
{
os_context_t *context = arch_os_get_context(&void_context);
-#ifdef LISP_FEATURE_LINUX
- /* FIXME: Check that this is necessary -- CSR, 2002-07-15 */
- os_restore_fp_control(context);
-#endif
if ((siginfo->si_code) == ILL_ILLOPC
#ifdef LISP_FEATURE_LINUX
boolean subtract, immed;
int rd, rs1, op1, rs2, op2, result;
os_context_t *context = arch_os_get_context(&void_context);
-#ifdef LISP_FEATURE_LINUX
- os_restore_fp_control(context);
-#endif
badinst = *(unsigned int *)os_context_pc_addr(context);
if ((badinst >> 30) != 2 || ((badinst >> 20) & 0x1f) != 0x11) {
current_control_stack_pointer =
(lispobj *)*os_context_sp_addr(context);
- /* FIXME: CMUCL puts the float control restoration code here.
- Thus, it seems to me that single-stepping won't restore the
- float control. Since SBCL currently doesn't support
- single-stepping (as far as I can tell) this is somewhat moot,
- but it might be worth either moving this code up or deleting
- the single-stepping code entirely. -- CSR, 2002-07-15 */
-#if defined(LISP_FEATURE_LINUX) || defined(RESTORE_FP_CONTROL_FROM_CONTEXT)
- os_restore_fp_control(context);
-#endif
-
/* On entry %eip points just after the INT3 byte and aims at the
* 'kind' value (eg trap_Cerror). For error-trap and Cerror-trap a
* number of bytes will follow, the first is the length of the byte
void
os_restore_fp_control(os_context_t *context)
{
- /* reset exception flags and restore control flags on SSE2 FPU */
- unsigned int temp = (context->uc_mcontext.fpregs->mxcsr) & ~0x3F;
- asm ("ldmxcsr %0" : : "m" (temp));
- /* same for x87 FPU. */
- asm ("fldcw %0" : : "m" (context->uc_mcontext.fpregs->cwd));
+ if (context->uc_mcontext.fpregs) {
+ /* reset exception flags and restore control flags on SSE2 FPU */
+ unsigned int temp = (context->uc_mcontext.fpregs->mxcsr) & ~0x3F;
+ asm ("ldmxcsr %0" : : "m" (temp));
+ /* same for x87 FPU. */
+ asm ("fldcw %0" : : "m" (context->uc_mcontext.fpregs->cwd));
+ }
}
void
}
unsigned long os_context_fp_control(os_context_t *context);
+#define RESTORE_FP_CONTROL_FROM_CONTEXT
void os_restore_fp_control(os_context_t *context);
#endif /* _X86_64_LINUX_OS_H */
current_control_stack_pointer =
(lispobj *)*os_context_sp_addr(context);
- /* FIXME: CMUCL puts the float control restoration code here.
- Thus, it seems to me that single-stepping won't restore the
- float control. Since SBCL currently doesn't support
- single-stepping (as far as I can tell) this is somewhat moot,
- but it might be worth either moving this code up or deleting
- the single-stepping code entirely. -- CSR, 2002-07-15 */
-#if defined(LISP_FEATURE_LINUX) || defined(RESTORE_FP_CONTROL_FROM_CONTEXT)
- os_restore_fp_control(context);
-#endif
-
#ifdef LISP_FEATURE_SUNOS
/* For some reason the breakpoints that :ENCAPSULATE NIL tracing sets up
* cause a trace trap (i.e. processor single-stepping trap) on the following
void
os_restore_fp_control(os_context_t *context)
{
- asm ("fldcw %0" : : "m" (context->uc_mcontext.fpregs->cw));
+ if (context->uc_mcontext.fpregs)
+ asm ("fldcw %0" : : "m" (context->uc_mcontext.fpregs->cw));
}
void
}
unsigned long os_context_fp_control(os_context_t *context);
+#define RESTORE_FP_CONTROL_FROM_CONTEXT
void os_restore_fp_control(os_context_t *context);
#endif /* _X86_LINUX_OS_H */
;;; checkins which aren't released. (And occasionally for internal
;;; versions, especially for internal versions off the main CVS
;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.25.46"
+"1.0.25.47"