예제 #1
0
파일: x86-arch.c 프로젝트: Distrotech/cmucl
void
arch_skip_instruction(os_context_t * context)
{
    int vlen, code;

    DPRINTF(0, (stderr, "[arch_skip_inst at %lx>]\n", SC_PC(context)));

    /* Get and skip the lisp error code. */
    code = *(char *) SC_PC(context)++;
    switch (code) {
      case trap_Error:
      case trap_Cerror:
	  /* Lisp error arg vector length */
	  vlen = *(char *) SC_PC(context)++;
	  /* Skip lisp error arg data bytes */
	  while (vlen-- > 0)
	      SC_PC(context)++;
	  break;

      case trap_Breakpoint:
      case trap_FunctionEndBreakpoint:
	  break;

      case trap_PendingInterrupt:
      case trap_Halt:
	  /* Only needed to skip the Code. */
	  break;

      default:
	  fprintf(stderr, "[arch_skip_inst invalid code %d\n]\n", code);
	  break;
    }

    DPRINTF(0, (stderr, "[arch_skip_inst resuming at %lx>]\n", SC_PC(context)));
}
예제 #2
0
파일: x86-arch.c 프로젝트: Distrotech/cmucl
void
arch_do_displaced_inst(os_context_t * context, unsigned long orig_inst)
{
    unsigned int *pc = (unsigned int *) SC_PC(context);

    /*
     * Put the original instruction back.
     */

    *((char *) pc) = orig_inst & 0xff;
    *((char *) pc + 1) = (orig_inst & 0xff00) >> 8;

#ifdef SC_EFLAGS
    /* Enable single-stepping */
    SC_EFLAGS(context) |= 0x100;
#else

    /*
     * Install helper instructions for the single step:
     *    nop; nop; nop; pushf; or [esp],0x100; popf.
     *
     * The or instruction enables the trap flag which enables
     * single-stepping.  So when the popf instruction is run, we start
     * single-stepping and stop on the next instruction.
     */

    DPRINTF(0, (stderr, "Installing helper instructions\n"));
    
    single_step_save1 = *(pc - 3);
    single_step_save2 = *(pc - 2);
    single_step_save3 = *(pc - 1);
    *(pc - 3) = 0x9c909090;
    *(pc - 2) = 0x00240c81;
    *(pc - 1) = 0x9d000001;
#endif

    single_stepping = (unsigned int *) pc;

#ifndef SC_EFLAGS
    /*
     * pc - 9 points to the pushf instruction that we installed for
     * the helper.
     */
    
    DPRINTF(0, (stderr, " Setting pc to pushf instruction at %p\n", (void*) ((char*) pc - 9)));
    SC_PC(context) = (int)((char *) pc - 9);
#endif
}
예제 #3
0
static void
info_from_sigcontext(struct call_info *info, os_context_t * csp)
{
    unsigned long pc;

    info->interrupted = 1;
    if (LowtagOf(SC_REG(csp, reg_CODE)) == type_FunctionPointer) {
	/* We tried to call a function, but crapped out before $CODE could be fixed up.  Probably an undefined function. */
	info->frame = (struct call_frame *) SC_REG(csp, reg_OCFP);
	info->lra = (lispobj) SC_REG(csp, reg_LRA);
	info->code = code_pointer(info->lra);
	pc = (unsigned long) PTR(info->lra);
    } else {
	info->frame = (struct call_frame *) SC_REG(csp, reg_CFP);
	info->code = code_pointer(SC_REG(csp, reg_CODE));
	info->lra = NIL;
	pc = SC_PC(csp);
    }
    if (info->code != NULL)
	info->pc = pc - (unsigned long) info->code -
#ifndef alpha
	    (HEADER_LENGTH(info->code->header) * sizeof(lispobj));
#else
	    (HEADER_LENGTH(((struct code *) info->code)->header) * sizeof(lispobj));
#endif
    else
예제 #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
파일: x86-arch.c 프로젝트: Distrotech/cmucl
unsigned char *
arch_internal_error_arguments(os_context_t * context)
{
    return (unsigned char *) (SC_PC(context) + 1);
}