コード例 #1
0
ファイル: linux-os.c プロジェクト: angavrilov/sbcl
/*
 * The GC needs to be hooked into whatever signal is raised for
 * page fault on this OS.
 */
static void
sigsegv_handler(int signal, siginfo_t *info, os_context_t *context)
{
    os_vm_address_t addr = arch_get_bad_addr(signal, info, context);

#ifdef LISP_FEATURE_ALPHA
    /* Alpha stuff: This is the end of a pseudo-atomic section during
       which a signal was received.  We must deal with the pending
       interrupt (see also interrupt.c, ../code/interrupt.lisp)

       (how we got here: when interrupting, we set bit 63 in reg_ALLOC.
       At the end of the atomic section we tried to write to reg_ALLOC,
       got a SIGSEGV (there's nothing mapped there) so ended up here. */
    if (addr != NULL &&
        *os_context_register_addr(context, reg_ALLOC) & (1L<<63)) {
        *os_context_register_addr(context, reg_ALLOC) -= (1L<<63);
        interrupt_handle_pending(context);
        return;
    }
#endif

#ifdef LISP_FEATURE_GENCGC
    if (!gencgc_handle_wp_violation(addr))
#else
    if (!cheneygc_handle_wp_violation(context, addr))
#endif
        if (!handle_guard_page_triggered(context, addr))
            lisp_memory_fault_error(context, addr);
}
コード例 #2
0
ファイル: arm-arch.c プロジェクト: Ferada/sbcl
static void
sigtrap_handler(int signal, siginfo_t *siginfo, os_context_t *context)
{
    unsigned int code = *((unsigned char *)(4+*os_context_pc_addr(context)));
    u32 trap_instruction = *((u32 *)*os_context_pc_addr(context));
    int condition_bits = (trap_instruction >> 28) & 0x0f;

    /* Make sure that we're looking at an SWI instruction or that one
     * undefined instruction that the kernel recognizes as an explicit
     * trap. */
    if ((condition_bits == 15)
        || (((trap_instruction & 0x0f000000) != 0x0f000000)
            && (trap_instruction != 0xe7f001f0))) {
        lose("Unrecognized trap instruction %08lx in sigtrap_handler()",
             trap_instruction);
    }

    if (trap_instruction == 0xe7f001f0) {
        handle_trap(context, code);
    } else {
        arch_clear_pseudo_atomic_interrupted(context);
        arch_skip_instruction(context);
        interrupt_handle_pending(context);
    }
}
コード例 #3
0
ファイル: osf1-os.c プロジェクト: Distrotech/cmucl
static void
sigbus_handler(int signal, int code, struct sigcontext *context)
{
    context->sc_pc -= 4;	/* pc is +4 on bus error!?!!? */
    if (arch_get_bad_addr(signal, code, context) &&
	context->sc_regs[reg_ALLOC] & 2) {
	context->sc_regs[reg_ALLOC] -= 2;
	interrupt_handle_pending(context);
    } else
	interrupt_handle_now(signal, code, context);
}
コード例 #4
0
ファイル: x86-arch.c プロジェクト: Distrotech/cmucl
void
sigtrap_handler(HANDLER_ARGS)
{
    unsigned int trap;
    os_context_t* os_context = (os_context_t *) context;
#if 0
    fprintf(stderr, "x86sigtrap: %8x %x\n",
            SC_PC(os_os_context), *(unsigned char *) (SC_PC(os_context) - 1));
    fprintf(stderr, "sigtrap(%d %d %x)\n", signal, CODE(code), os_context);
#endif

    if (single_stepping && (signal == SIGTRAP)) {
#if 0
	fprintf(stderr, "* Single step trap %p\n", single_stepping);
#endif

#ifdef SC_EFLAGS
	/* Disable single-stepping */
	SC_EFLAGS(os_context) ^= 0x100;
#else
	/* Un-install single step helper instructions. */
	*(single_stepping - 3) = single_step_save1;
	*(single_stepping - 2) = single_step_save2;
	*(single_stepping - 1) = single_step_save3;
        DPRINTF(0, (stderr, "Uninstalling helper instructions\n"));
#endif

	/*
	 * Re-install the breakpoint if possible.
	 */
	if ((int) SC_PC(os_context) == (int) single_stepping + 1)
	    fprintf(stderr, "* Breakpoint not re-install\n");
	else {
	    char *ptr = (char *) single_stepping;

	    ptr[0] = BREAKPOINT_INST;	/* x86 INT3 */
	    ptr[1] = trap_Breakpoint;
	}

	single_stepping = NULL;
	return;
    }

    /* This is just for info in case monitor wants to print an approx */
    current_control_stack_pointer = (unsigned long *) SC_SP(os_context);

    RESTORE_FPU(os_context);

    /*
     * 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
     * arguments to follow.
     */

    trap = *(unsigned char *) SC_PC(os_context);

    switch (trap) {
      case trap_PendingInterrupt:
	  DPRINTF(0, (stderr, "<trap Pending Interrupt.>\n"));
	  arch_skip_instruction(os_context);
	  interrupt_handle_pending(os_context);
	  break;

      case trap_Halt:
	  {
              FPU_STATE(fpu_state);
              save_fpu_state(fpu_state);

	      fake_foreign_function_call(os_context);
	      lose("%%primitive halt called; the party is over.\n");
	      undo_fake_foreign_function_call(os_context);

              restore_fpu_state(fpu_state);
	      arch_skip_instruction(os_context);
	      break;
	  }

      case trap_Error:
      case trap_Cerror:
	  DPRINTF(0, (stderr, "<trap Error %x>\n", CODE(code)));
	  interrupt_internal_error(signal, code, os_context, CODE(code) == trap_Cerror);
	  break;

      case trap_Breakpoint:
#if 0
	  fprintf(stderr, "*C break\n");
#endif
	  SC_PC(os_context) -= 1;

	  handle_breakpoint(signal, CODE(code), os_context);
#if 0
	  fprintf(stderr, "*C break return\n");
#endif
	  break;

      case trap_FunctionEndBreakpoint:
	  SC_PC(os_context) -= 1;
	  SC_PC(os_context) =
	      (int) handle_function_end_breakpoint(signal, CODE(code), os_context);
	  break;

#ifdef trap_DynamicSpaceOverflowWarning
      case trap_DynamicSpaceOverflowWarning:
	  interrupt_handle_space_overflow(SymbolFunction
					  (DYNAMIC_SPACE_OVERFLOW_WARNING_HIT),
					  os_context);
	  break;
#endif
#ifdef trap_DynamicSpaceOverflowError
      case trap_DynamicSpaceOverflowError:
	  interrupt_handle_space_overflow(SymbolFunction
					  (DYNAMIC_SPACE_OVERFLOW_ERROR_HIT),
					  os_context);
	  break;
#endif
      default:
	  DPRINTF(0,
		  (stderr, "[C--trap default %d %d %p]\n", signal, CODE(code),
		   os_context));
	  interrupt_handle_now(signal, code, os_context);
	  break;
    }
}
コード例 #5
0
ファイル: amd64-arch.c プロジェクト: Distrotech/cmucl
void
sigtrap_handler(HANDLER_ARGS)
{
    unsigned int trap;

#ifdef __linux__
    GET_CONTEXT
#endif
#if 0
	fprintf(stderr, "x86sigtrap: %8x %x\n",
		context->sc_pc, *(unsigned char *) (context->sc_pc - 1));
    fprintf(stderr, "sigtrap(%d %d %x)\n", signal, code, context);
#endif

    if (single_stepping && (signal == SIGTRAP)) {
#if 0
	fprintf(stderr, "* Single step trap %x\n", single_stepping);
#endif

#ifndef __linux__
	/* Un-install single step helper instructions. */
	*(single_stepping - 3) = single_step_save1;
	*(single_stepping - 2) = single_step_save2;
	*(single_stepping - 1) = single_step_save3;
#else
	context->eflags ^= 0x100;
#endif

	/*
	 * Re-install the breakpoint if possible.
	 */

	if ((int) context->sc_pc == (int) single_stepping + 1)
	    fprintf(stderr, "* Breakpoint not re-install\n");
	else {
	    char *ptr = (char *) single_stepping;

	    ptr[0] = BREAKPOINT_INST;	/* x86 INT3 */
	    ptr[1] = trap_Breakpoint;
	}

	single_stepping = NULL;
	return;
    }

    /* This is just for info in case monitor wants to print an approx */
    current_control_stack_pointer = (unsigned long *) context->sc_sp;

#if defined(__linux__) && (defined(i386) || defined(__x86_64))
    /*
     * Restore the FPU control word, setting the rounding mode to nearest.
     */

    if (contextstruct.fpstate)
#if defined(__x86_64)
	setfpucw(contextstruct.fpstate->cwd & ~0xc00);
#else
	setfpucw(contextstruct.fpstate->cw & ~0xc00);
#endif
#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
     * arguments to follow.
     */

    trap = *(unsigned char *) (context->sc_pc);

    switch (trap) {
      case trap_PendingInterrupt:
	  DPRINTF(0, (stderr, "<trap Pending Interrupt.>\n"));
	  arch_skip_instruction(context);
	  interrupt_handle_pending(context);
	  break;

      case trap_Halt:
	  {
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
	      int fpu_state[27];

	      fpu_save(fpu_state);
#endif
	      fake_foreign_function_call(context);
	      lose("%%primitive halt called; the party is over.\n");
	      undo_fake_foreign_function_call(context);
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
	      fpu_restore(fpu_state);
#endif
	      arch_skip_instruction(context);
	      break;
	  }

      case trap_Error:
      case trap_Cerror:
	  DPRINTF(0, (stderr, "<trap Error %d>\n", code));
#ifdef __linux__
	  interrupt_internal_error(signal, contextstruct, code == trap_Cerror);
#else
	  interrupt_internal_error(signal, code, context, code == trap_Cerror);
#endif
	  break;

      case trap_Breakpoint:
#if 0
	  fprintf(stderr, "*C break\n");
#endif
	  (char *) context->sc_pc -= 1;
	  handle_breakpoint(signal, code, context);
#if 0
	  fprintf(stderr, "*C break return\n");
#endif
	  break;

      case trap_FunctionEndBreakpoint:
	  (char *) context->sc_pc -= 1;
	  context->sc_pc =
	      (int) handle_function_end_breakpoint(signal, code, context);
	  break;

#ifdef DYNAMIC_SPACE_OVERFLOW_WARNING_HIT
      case trap_DynamicSpaceOverflowWarning:
	  interrupt_handle_space_overflow(SymbolFunction
					  (DYNAMIC_SPACE_OVERFLOW_WARNING_HIT),
					  context);
	  break;
#endif
#ifdef DYNAMIC_SPACE_OVERFLOW_ERROR_HIT
      case trap_DynamicSpaceOverflowError:
	  interrupt_handle_space_overflow(SymbolFunction
					  (DYNAMIC_SPACE_OVERFLOW_ERROR_HIT),
					  context);
	  break;
#endif
      default:
	  DPRINTF(0,
		  (stderr, "[C--trap default %d %d %x]\n", signal, code,
		   context));
#ifdef __linux__
	  interrupt_handle_now(signal, contextstruct);
#else
	  interrupt_handle_now(signal, code, context);
#endif
	  break;
    }
}