Пример #1
0
void handle_breakpoint(os_context_t *context)
{
    lispobj code;
    DX_ALLOC_SAP(context_sap, context);

    fake_foreign_function_call(context);

#ifndef LISP_FEATURE_SB_SAFEPOINT
    unblock_gc_signals(0, 0);
#endif
    code = find_code(context);

#ifndef LISP_FEATURE_WIN32
    /* Don't disallow recursive breakpoint traps. Otherwise, we can't
     * use debugger breakpoints anywhere in here. */
    thread_sigmask(SIG_SETMASK, os_context_sigmask_addr(context), 0);
#endif

    funcall3(StaticSymbolFunction(HANDLE_BREAKPOINT),
             compute_offset(context, code),
             code,
             context_sap);

    undo_fake_foreign_function_call(context);
}
Пример #2
0
void
sigill_handler(int signal, siginfo_t *siginfo, os_context_t *context) {
    /* Triggering SIGTRAP using int3 is unreliable on OS X/x86, so
     * we need to use illegal instructions for traps.
     */
#if defined(LISP_FEATURE_UD2_BREAKPOINTS) && !defined(LISP_FEATURE_MACH_EXCEPTION_HANDLER)
    if (*((unsigned short *)*os_context_pc_addr(context)) == UD2_INST) {
        *os_context_pc_addr(context) += 2;
        return sigtrap_handler(signal, siginfo, context);
    }
#endif
    fake_foreign_function_call(context);
    lose("Unhandled SIGILL");
}
Пример #3
0
void
handle_single_step_trap (os_context_t *context, int kind, int register_offset)
{
    fake_foreign_function_call(context);

#ifndef LISP_FEATURE_WIN32
    thread_sigmask(SIG_SETMASK, os_context_sigmask_addr(context), 0);
#endif

    funcall2(StaticSymbolFunction(HANDLE_SINGLE_STEP_TRAP),
             make_fixnum(kind),
             make_fixnum(register_offset));

    undo_fake_foreign_function_call(context); /* blocks signals again */
}
Пример #4
0
void *handle_fun_end_breakpoint(os_context_t *context)
{
    lispobj code, lra;
    struct code *codeptr;
    DX_ALLOC_SAP(context_sap, context);

    fake_foreign_function_call(context);

#ifndef LISP_FEATURE_SB_SAFEPOINT
    unblock_gc_signals(0, 0);
#endif

    code = find_code(context);
    codeptr = (struct code *)native_pointer(code);

#ifndef LISP_FEATURE_WIN32
    /* Don't disallow recursive breakpoint traps. Otherwise, we can't
     * use debugger breakpoints anywhere in here. */
    thread_sigmask(SIG_SETMASK, os_context_sigmask_addr(context), 0);
#endif

    funcall3(StaticSymbolFunction(HANDLE_BREAKPOINT),
             compute_offset(context, code),
             code,
             context_sap);

    lra = codeptr->constants[REAL_LRA_SLOT];

#ifdef LISP_FEATURE_PPC
    /* PPC now passes LRA objects in reg_LRA during return.  Other
     * platforms should as well, but haven't been fixed yet. */
    *os_context_register_addr(context, reg_LRA) = lra;
#else
#ifdef reg_CODE
    *os_context_register_addr(context, reg_CODE) = lra;
#endif
#endif

    undo_fake_foreign_function_call(context);

#ifdef reg_LRA
    return (void *)(lra-OTHER_POINTER_LOWTAG+sizeof(lispobj));
#else
    return compute_pc(lra, fixnum_value(codeptr->constants[REAL_LRA_SLOT+1]));
#endif
}
Пример #5
0
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;
    }
}
Пример #6
0
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;
    }
}