#elif defined __OpenBSD__
return &context->sc_eflags;
#elif defined LISP_FEATURE_DARWIN
- return &context->uc_mcontext->ss.eflags;
+ return (int *)(&context->uc_mcontext->SS.EFLAGS);
#elif defined __NetBSD__
return &(context->uc_mcontext.__gregs[_REG_EFL]);
#elif defined LISP_FEATURE_WIN32
single_stepping = pc;
#ifdef CANNOT_GET_TO_SINGLE_STEP_FLAG
- *os_context_pc_addr(context) = (char *)pc - 9;
+ *os_context_pc_addr(context) = (os_context_register_t)((char *)pc - 9);
#endif
}
\f
#endif
/* Re-install the breakpoint if possible. */
if (*os_context_pc_addr(context) == (int)single_stepping + 1) {
- fprintf(stderr, "warning: couldn't reinstall breakpoint\n");
+ fprintf(stderr, "warning: couldn't reinstall breakpoint\n");
} else {
- *((char *)single_stepping) = BREAKPOINT_INST; /* x86 INT3 */
- *((char *)single_stepping+1) = trap_Breakpoint;
+ *((char *)single_stepping) = BREAKPOINT_INST; /* x86 INT3 */
+ *((char *)single_stepping+1) = trap_Breakpoint;
}
-
+
single_stepping = NULL;
return;
}
void
+arch_handle_breakpoint(os_context_t *context)
+{
+ --*os_context_pc_addr(context);
+ handle_breakpoint(context);
+}
+
+void
+arch_handle_fun_end_breakpoint(os_context_t *context)
+{
+ --*os_context_pc_addr(context);
+ *os_context_pc_addr(context) =
+ (int)handle_fun_end_breakpoint(context);
+}
+
+void
+arch_handle_single_step_trap(os_context_t *context, int trap)
+{
+ arch_skip_instruction(context);
+ /* On x86 the fdefn / function is always in EAX, so we pass 0
+ * as the register_offset. */
+ handle_single_step_trap(context, trap, 0);
+}
+
+#ifndef LISP_FEATURE_WIN32
+void
sigtrap_handler(int signal, siginfo_t *info, void *void_context)
{
os_context_t *context = (os_context_t*)void_context;
unsigned int trap;
-#ifndef LISP_FEATURE_WIN32
- /* On Windows this is done in the SE handler. */
if (single_stepping && (signal==SIGTRAP)) {
- restore_breakpoint_from_single_step(context);
- return;
+ restore_breakpoint_from_single_step(context);
+ return;
}
-#endif
/* This is just for info in case the monitor wants to print an
* approximation. */
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
* number of bytes will follow, the first is the length of the byte
* arguments to follow. */
trap = *(unsigned char *)(*os_context_pc_addr(context));
- /* FSHOW((stderr, "/<sigtrap trap %d at pc_addr: %p>\n", trap, *os_context_pc_addr(context))); */
- switch (trap) {
-
- case trap_PendingInterrupt:
- FSHOW((stderr, "/<trap pending interrupt>\n"));
- arch_skip_instruction(context);
- interrupt_handle_pending(context);
- break;
-
- case trap_Halt:
- /* Note: the old CMU CL code tried to save FPU state
- * here, and restore it after we do our thing, but there
- * seems to be no point in doing that, since we're just
- * going to lose(..) anyway. */
- fake_foreign_function_call(context);
- lose("%%PRIMITIVE HALT called; the party is over.\n");
-
- case trap_Error:
- case trap_Cerror:
- FSHOW((stderr, "<trap error/cerror %d>\n", trap));
- interrupt_internal_error(signal, info, context, trap==trap_Cerror);
- break;
-
- case trap_Breakpoint:
- --*os_context_pc_addr(context);
- handle_breakpoint(signal, info, context);
- break;
-
- case trap_FunEndBreakpoint:
- --*os_context_pc_addr(context);
- *os_context_pc_addr(context) =
- (int)handle_fun_end_breakpoint(signal, info, context);
- break;
-
- case trap_SingleStepAround:
- case trap_SingleStepBefore:
- arch_skip_instruction(context);
- /* On x86 the fdefn / function is always in EAX, so we pass 0
- * as the register_offset. */
- handle_single_step_trap(context, trap, 0);
- break;
-
- default:
- FSHOW((stderr,"/[C--trap default %d %d %x]\n",
- signal, trap, context));
- interrupt_handle_now(signal, info, context);
- break;
- }
+ handle_trap(context, trap);
}
-static void
+void
sigill_handler(int signal, siginfo_t *siginfo, void *void_context) {
os_context_t *context = (os_context_t*)void_context;
/* Triggering SIGTRAP using int3 is unreliable on OS X/x86, so
* we need to use illegal instructions for traps.
*/
-#if defined(LISP_FEATURE_DARWIN)
+#if defined(LISP_FEATURE_DARWIN) && !defined(LISP_FEATURE_MACH_EXCEPTION_HANDLER)
if (*((unsigned short *)*os_context_pc_addr(context)) == 0x0b0f) {
*os_context_pc_addr(context) += 2;
return sigtrap_handler(signal, siginfo, void_context);
}
#endif
-
fake_foreign_function_call(context);
- lose("fake_foreign_call fell through");
+ lose("Unhandled SIGILL");
}
+#endif /* not LISP_FEATURE_WIN32 */
void
arch_install_interrupt_handlers()
* OS I haven't tested on?) and we have to go back to the old CMU
* CL way, I hope there will at least be a comment to explain
* why.. -- WHN 2001-06-07 */
-#ifndef LISP_FEATURE_WIN32
+#if !defined(LISP_FEATURE_WIN32) && !defined(LISP_FEATURE_MACH_EXCEPTION_HANDLER)
undoably_install_low_level_interrupt_handler(SIGILL , sigill_handler);
undoably_install_low_level_interrupt_handler(SIGTRAP, sigtrap_handler);
#endif
-
SHOW("returning from arch_install_interrupt_handlers()");
}
\f
-/* This is implemented in assembly language and called from C: */
-extern lispobj
-call_into_lisp(lispobj fun, lispobj *args, int nargs);
-
-/* These functions are an interface to the Lisp call-in facility.
- * Since this is C we can know nothing about the calling environment.
- * The control stack might be the C stack if called from the monitor
- * or the Lisp stack if called as a result of an interrupt or maybe
- * even a separate stack. The args are most likely on that stack but
- * could be in registers depending on what the compiler likes. So we
- * copy the args into a portable vector and let the assembly language
- * call-in function figure it out. */
-
-lispobj
-funcall0(lispobj function)
-{
- lispobj *args = NULL;
-
- FSHOW((stderr, "/entering funcall0(0x%lx)\n", (long)function));
- return call_into_lisp(function, args, 0);
-}
-lispobj
-funcall1(lispobj function, lispobj arg0)
-{
- lispobj args[1];
- args[0] = arg0;
- return call_into_lisp(function, args, 1);
-}
-lispobj
-funcall2(lispobj function, lispobj arg0, lispobj arg1)
-{
- lispobj args[2];
- args[0] = arg0;
- args[1] = arg1;
- return call_into_lisp(function, args, 2);
-}
-lispobj
-funcall3(lispobj function, lispobj arg0, lispobj arg1, lispobj arg2)
-{
- lispobj args[3];
- args[0] = arg0;
- args[1] = arg1;
- args[2] = arg2;
- return call_into_lisp(function, args, 3);
-}
-
#ifdef LISP_FEATURE_LINKAGE_TABLE
/* FIXME: It might be cleaner to generate these from the lisp side of
* things.