Example #1
0
void
db_breakpoint_cmd(
	db_expr_t	addr,
	int		have_addr,
	db_expr_t	count,
	char *		modif)
{
	register int n;
	thread_act_t thr_act;
	boolean_t user_global = db_option(modif, 'U');
	boolean_t task_bpt = db_option(modif, 'T');
	boolean_t user_space;

	if (count == -1)
	    count = 1;

	if (task_bpt && user_global)
	    db_error("Cannot specify both 'T' and 'U'\n");
	user_space = (user_global)? TRUE: db_option(modif, 'u');
	if (user_space && db_access_level < DB_ACCESS_CURRENT)
	    db_error("User space break point is not supported\n");
	if ((!task_bpt || !user_space) &&
	    !DB_VALID_ADDRESS(addr, user_space)) {
	    /* if the user has explicitly specified user space,
	       do not insert a breakpoint into the kernel */
	    if (user_space)
	      db_error("Invalid user space address\n");
	    user_space = TRUE;
	    db_printf("%#X is in user space\n", addr);
	    db_printf("kernel is from %#X to %#x\n", VM_MIN_KERNEL_ADDRESS, VM_MAX_KERNEL_ADDRESS);
	}
	if (db_option(modif, 't') || task_bpt) {
	    for (n = 0; db_get_next_act(&thr_act, n); n++) {
		if (thr_act == THR_ACT_NULL)
		    db_error("No active thr_act\n");
		if (task_bpt && thr_act->task == TASK_NULL)
		    db_error("No task\n");
		if (db_access_level <= DB_ACCESS_CURRENT && user_space
			 && thr_act->task != db_current_space())
		    db_error("Cannot set break point in inactive user space\n");
		db_set_breakpoint(db_target_space(thr_act, user_space), 
					(db_addr_t)addr, count,
					(user_global)? THR_ACT_NULL: thr_act,
					task_bpt);
	    }
	} else {
	    db_set_breakpoint(db_target_space(THR_ACT_NULL, user_space),
				 (db_addr_t)addr,
				 count, THR_ACT_NULL, FALSE);
	}
}
Example #2
0
void
db_task_trap(
	int		type,
	int		code,
	boolean_t	user_space)
{
	jmp_buf_t db_jmpbuf;
	jmp_buf_t *prev;
	boolean_t	bkpt;
	boolean_t	watchpt;
	task_t		task;
	task_t		task_space;

	task = db_current_task();
	task_space = db_target_space(current_act(), user_space);
	bkpt = IS_BREAKPOINT_TRAP(type, code);
	watchpt = IS_WATCHPOINT_TRAP(type, code);

	/*
	 * Note:  we look up PC values in an address space (task_space),
	 * but print symbols using a (task-specific) symbol table, found
	 * using task.
	 */
	db_init_default_act();
	db_check_breakpoint_valid();
	if (db_stop_at_pc(&bkpt, task, task_space)) {
	    if (db_inst_count) {
		db_printf("After %d instructions (%d loads, %d stores),\n",
			  db_inst_count, db_load_count, db_store_count);
	    }
	    if (bkpt)
		db_printf("Breakpoint at  ");
	    else if (watchpt)
		db_printf("Watchpoint at  ");
	    else
		db_printf("Stopped at  ");
	    db_dot = PC_REGS(DDB_REGS);

	    prev = db_recover;
	    if (_setjmp(db_recover = &db_jmpbuf) == 0) {
#if defined(__alpha)
		db_print_loc(db_dot, task_space);
		db_printf("\n\t");
		db_print_inst(db_dot, task_space);
#else /* !defined(__alpha) */
#if defined(__powerpc__)
		db_print_loc_and_inst(db_dot, task_space);
#else	/* __powerpc__ */
		db_print_loc_and_inst(db_dot, task);
#endif	/* __powerpc__ */
#endif /* defined(__alpha) */
	    } else
		db_printf("Trouble printing location %#X.\n", db_dot);
	    db_recover = prev;

	    db_command_loop();
	}

	db_restart_at_pc(watchpt, task_space);
}
Example #3
0
/* Delete breakpoint */
void
db_delete_cmd(void)
{
	register int n;
	thread_act_t 	 thr_act;
	vm_offset_t task_thd;
	boolean_t user_global = FALSE;
	boolean_t task_bpt = FALSE;
	boolean_t user_space = FALSE;
	boolean_t thd_bpt = FALSE;
	db_expr_t addr;
	int t;
	
	t = db_read_token();
	if (t == tSLASH) {
	    t = db_read_token();
	    if (t != tIDENT) {
		db_printf("Bad modifier \"%s\"\n", db_tok_string);
		db_error(0);
	    }
	    user_global = db_option(db_tok_string, 'U');
	    user_space = (user_global)? TRUE: db_option(db_tok_string, 'u');
	    task_bpt = db_option(db_tok_string, 'T');
	    thd_bpt = db_option(db_tok_string, 't');
	    if (task_bpt && user_global)
		db_error("Cannot specify both 'T' and 'U' option\n");
	    t = db_read_token();
	}

	if ( t == tSTAR ) {
		db_printf("Delete ALL breakpoints\n");
    		db_delete_all_breakpoints( (task_t)task_bpt );
    		return;
	}

	if (t == tHASH) {
	    db_thread_breakpoint_t tbp;
	    db_breakpoint_t bkpt;

	    if (db_read_token() != tNUMBER) {
		db_printf("Bad break point number #%s\n", db_tok_string);
		db_error(0);
	    }
	    if ((tbp = db_find_breakpoint_number(db_tok_number, &bkpt)) == 0) {
	        db_printf("No such break point #%d\n", db_tok_number);
	        db_error(0);
	    }
	    db_delete_breakpoint(bkpt->task, bkpt->address, tbp->tb_task_thd);
	    return;
	}
	db_unread_token(t);
	if (!db_expression(&addr)) {
	    /*
	     *	We attempt to pick up the user_space indication from db_dot,
	     *	so that a plain "d" always works.
	     */
	    addr = (db_expr_t)db_dot;
	    if (!user_space && !DB_VALID_ADDRESS(addr, FALSE))
		user_space = TRUE;
	}
	if (!DB_VALID_ADDRESS(addr, user_space)) {
	    db_printf("Address %#X is not in %s space\n", addr, 
			(user_space)? "user": "******");
	    db_error(0);
	}
	if (thd_bpt || task_bpt) {
	    for (n = 0; db_get_next_act(&thr_act, n); n++) {
		if (thr_act == THR_ACT_NULL)
		    db_error("No active thr_act\n");
		if (task_bpt) {
		    if (thr_act->task == TASK_NULL)
			db_error("No task\n");
		    task_thd = (vm_offset_t) (thr_act->task);
		} else
		    task_thd = (user_global)? 0: (vm_offset_t) thr_act;
		db_delete_breakpoint(db_target_space(thr_act, user_space),
					(db_addr_t)addr, task_thd);
	    }
	} else {
	    db_delete_breakpoint(db_target_space(THR_ACT_NULL, user_space),
					 (db_addr_t)addr, 0);
	}
}
Example #4
0
/*
 *  kdb_trap - field a TRACE or BPT trap
 */
void
kdb_trap(
	int			type,
	struct savearea *regs)
{
	boolean_t	trap_from_user;
	int			previous_console_device;
	int			code=0;

	previous_console_device=switch_to_serial_console();

	switch (type) {
	    case T_TRACE:	/* single_step */
	    case T_PROGRAM:	/* breakpoint */
#if 0
	    case T_WATCHPOINT:	/* watchpoint */
#endif
	    case -1:	/* keyboard interrupt */
		break;

	    default:
		if (db_recover) {
		    ppc_nested_saved_state = *regs;
		    db_printf("Caught ");
		    if (type > TRAP_TYPES)
			db_printf("type %d", type);
		    else
			db_printf("%s", trap_type[type]);
		    db_printf(" trap, pc = %x\n",
			      regs->save_srr0);
		    db_error("");
		    /*NOTREACHED*/
		}
		kdbprinttrap(type, code, (int *)&regs->save_srr0, regs->save_r1);
	}

	saved_state[cpu_number()] = regs;

	ppc_last_saved_statep = regs;
	ppc_last_kdb_sp = (unsigned) &type;

	if (!IS_USER_TRAP(regs)) {
		bzero((char *)&ddb_regs, sizeof (ddb_regs));
		ddb_regs = *regs;
		trap_from_user = FALSE;	

	}
	else {
		ddb_regs = *regs;
		trap_from_user = TRUE;
	}

	db_task_trap(type, code, trap_from_user);

	*regs = ddb_regs;

	if ((type == T_PROGRAM) &&
	    (db_get_task_value(regs->save_srr0,
			       BKPT_SIZE,
			       FALSE,
			       db_target_space(current_act(),
					       trap_from_user))
	                      == BKPT_INST))
	    regs->save_srr0 += BKPT_SIZE;

kdb_exit:
	saved_state[cpu_number()] = 0;
	switch_to_old_console(previous_console_device);

}