+#endif
+}
+
+#ifndef LISP_FEATURE_WIN32
+int
+siginfo_code(siginfo_t *info)
+{
+ return info->si_code;
+}
+os_vm_address_t current_memory_fault_address;
+
+void
+lisp_memory_fault_error(os_context_t *context, os_vm_address_t addr)
+{
+ /* FIXME: This is lossy: if we get another memory fault (eg. from
+ * another thread) before lisp has read this, we lose the information.
+ * However, since this is mostly informative, we'll live with that for
+ * now -- some address is better then no address in this case.
+ */
+ current_memory_fault_address = addr;
+ /* To allow debugging memory faults in signal handlers and such. */
+ corruption_warning_and_maybe_lose("Memory fault at %x (pc=%p, sp=%p)",
+ addr,
+ *os_context_pc_addr(context),
+#ifdef ARCH_HAS_STACK_POINTER
+ *os_context_sp_addr(context)
+#else
+ 0
+#endif
+ );
+ unblock_signals_in_context_and_maybe_warn(context);
+#ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
+ arrange_return_to_lisp_function(context,
+ StaticSymbolFunction(MEMORY_FAULT_ERROR));
+#else
+ funcall0(StaticSymbolFunction(MEMORY_FAULT_ERROR));
+#endif
+}
+#endif
+
+static void
+unhandled_trap_error(os_context_t *context)
+{
+ lispobj context_sap;
+ fake_foreign_function_call(context);
+ unblock_gc_signals(0, 0);
+ context_sap = alloc_sap(context);
+#ifndef LISP_FEATURE_WIN32
+ thread_sigmask(SIG_SETMASK, os_context_sigmask_addr(context), 0);
+#endif
+ funcall1(StaticSymbolFunction(UNHANDLED_TRAP_ERROR), context_sap);
+ lose("UNHANDLED-TRAP-ERROR fell through");
+}
+
+/* Common logic for trapping instructions. How we actually handle each
+ * case is highly architecture dependent, but the overall shape is
+ * this. */
+void
+handle_trap(os_context_t *context, int trap)
+{
+ switch(trap) {
+ case trap_PendingInterrupt:
+ FSHOW((stderr, "/<trap pending interrupt>\n"));
+ arch_skip_instruction(context);
+ interrupt_handle_pending(context);
+ break;
+ case trap_Error:
+ case trap_Cerror:
+ FSHOW((stderr, "/<trap error/cerror %d>\n", trap));
+ interrupt_internal_error(context, trap==trap_Cerror);
+ break;
+ case trap_Breakpoint:
+ arch_handle_breakpoint(context);
+ break;
+ case trap_FunEndBreakpoint:
+ arch_handle_fun_end_breakpoint(context);
+ break;
+#ifdef trap_AfterBreakpoint
+ case trap_AfterBreakpoint:
+ arch_handle_after_breakpoint(context);
+ break;
+#endif
+#ifdef trap_SingleStepAround
+ case trap_SingleStepAround:
+ case trap_SingleStepBefore:
+ arch_handle_single_step_trap(context, trap);
+ break;
+#endif
+ case trap_Halt:
+ fake_foreign_function_call(context);
+ lose("%%PRIMITIVE HALT called; the party is over.\n");
+ default:
+ unhandled_trap_error(context);
+ }