Ejemplo n.º 1
0
void
db_restart_at_pc(
	boolean_t	watchpt,
	task_t	  	task)
{
	db_addr_t pc = PC_REGS(DDB_REGS);
#ifdef	SOFTWARE_SSTEP
	db_addr_t brpc;
#endif


	if ((db_run_mode == STEP_COUNT) ||
	    (db_run_mode == STEP_RETURN) ||
	    (db_run_mode == STEP_CALLT)) {
	    db_expr_t		ins;

	    /*
	     * We are about to execute this instruction,
	     * so count it now.
	     */

	    ins = db_get_task_value(pc, sizeof(int), FALSE, task);
	    db_inst_count++;
	    db_load_count += db_inst_load(ins);
	    db_store_count += db_inst_store(ins);
#ifdef	SOFTWARE_SSTEP
	    /* Account for instructions in delay slots */
	    brpc = next_instr_address(pc,1,task);
	    if ((brpc != pc) && (inst_branch(ins) || inst_call(ins))) {
		/* Note: this ~assumes an instruction <= sizeof(int) */
		ins = db_get_task_value(brpc, sizeof(int), FALSE, task);
		db_inst_count++;
		db_load_count += db_inst_load(ins);
		db_store_count += db_inst_store(ins);
	    }
#endif	/* SOFTWARE_SSTEP */
	}

	if (db_run_mode == STEP_CONTINUE) {
	    if (watchpt || db_find_breakpoint_here(task, pc)) {
		/*
		 * Step over breakpoint/watchpoint.
		 */
		db_run_mode = STEP_INVISIBLE;
		db_set_task_single_step(DDB_REGS, task);
	    } else {
		db_set_breakpoints();
		db_set_watchpoints();
	    }
	} else {
	    db_set_task_single_step(DDB_REGS, task);
	}
}
Ejemplo n.º 2
0
/*
 * Set a temporary breakpoint.
 * The instruction is changed immediately,
 * so the breakpoint does not have to be on the breakpoint list.
 */
db_breakpoint_t
db_set_temp_breakpoint(
	task_t		task,
	db_addr_t	addr)
{
	register db_breakpoint_t	bkpt;

	bkpt = db_breakpoint_alloc();
	if (bkpt == 0) {
	    db_printf("Too many breakpoints.\n");
	    return 0;
	}
	bkpt->task = task;
	bkpt->address = addr;
	bkpt->flags = BKPT_TEMP;
	bkpt->threads = 0;
	if (db_add_thread_breakpoint(bkpt, 0, 1, FALSE) < 0) {
	    if (bkpt)
		db_breakpoint_free(bkpt);
	    db_printf("Too many thread_breakpoints.\n");
	    return 0;
	}
	bkpt->bkpt_inst = db_get_task_value(bkpt->address, BKPT_SIZE, 
						FALSE, task);
	db_put_task_value(bkpt->address, BKPT_SIZE, 
				BKPT_SET(bkpt->bkpt_inst), task);
	return bkpt;
}
Ejemplo n.º 3
0
db_expr_t
db_get_value(
	db_addr_t	addr,
	int		size,
	boolean_t	is_signed)
{
	return(db_get_task_value(addr, size, is_signed, TASK_NULL));
}
Ejemplo n.º 4
0
/*
 * Write to file.
 */
void
db_write_cmd(
	db_expr_t	address,
	boolean_t	have_addr,
	db_expr_t	count,
	char *		modif)
{
	register db_addr_t	addr;
	register db_expr_t	old_value;
	db_expr_t	new_value;
	register int	size;
	boolean_t	wrote_one = FALSE;
	boolean_t	t_opt, u_opt;
	thread_act_t	thr_act;
	task_t		task;

	addr = (db_addr_t) address;

	size = db_size_option(modif, &u_opt, &t_opt);

	if (t_opt) 
	  {
	    if (!db_get_next_act(&thr_act, 0))
	      return;
	    task = thr_act->task;
	  }
	else
	  task = db_current_space();

	/* if user space is not explicitly specified, 
	   look in the kernel */
	if (!u_opt)
	  task = TASK_NULL;

	if (!DB_VALID_ADDRESS(addr, u_opt)) {
	  db_printf("Bad address 0x%x\n", addr);
	  return;
	}

	while (db_expression(&new_value)) {
	    old_value = db_get_task_value(addr, size, FALSE, task);
	    db_task_printsym(addr, DB_STGY_ANY, task);
	    db_printf("\t\t%#8n\t=\t%#8n\n", old_value, new_value);
	    db_put_task_value(addr, size, new_value, task);
	    addr += size;

	    wrote_one = TRUE;
	}

	if (!wrote_one)
	    db_error("Nothing written.\n");

	db_next = addr;
	db_prev = addr - size;
}
Ejemplo n.º 5
0
int
db_xcdump(
    db_addr_t	addr,
    int		size,
    int		count,
    task_t		task)
{
    register int 	i, n;
    db_expr_t	value;
    int		bcount;
    db_addr_t	off;
    char		*name;
    char		data[DB_XCDUMP_NC];

    db_find_task_sym_and_offset(addr, &name, &off, task);
    for (n = count*size; n > 0; n -= bcount) {
        db_prev = addr;
        if (off == 0) {
            db_printf("%s:\n", name);
            off = -1;
        }
        db_printf("%0*X:%s", 2*sizeof(db_addr_t), addr,
                  (size != 1) ? " " : "" );
        bcount = ((n > DB_XCDUMP_NC)? DB_XCDUMP_NC: n);
        if (trunc_page(addr) != trunc_page(addr+bcount-1)) {
            db_addr_t next_page_addr = trunc_page(addr+bcount-1);
            if (!DB_CHECK_ACCESS(next_page_addr, sizeof(int), task))
                bcount = next_page_addr - addr;
        }
        db_read_bytes((vm_offset_t)addr, bcount, data, task);
        for (i = 0; i < bcount && off != 0; i += size) {
            if (i % 4 == 0)
                db_printf(" ");
            value = db_get_task_value(addr, size, FALSE, task);
            db_printf("%0*x ", size*2, value);
            addr += size;
            db_find_task_sym_and_offset(addr, &name, &off, task);
        }
        db_printf("%*s",
                  ((DB_XCDUMP_NC-i)/size)*(size*2+1)+(DB_XCDUMP_NC-i)/4,
                  "");
        bcount = i;
        db_printf("%s*", (size != 1)? " ": "");
        for (i = 0; i < bcount; i++) {
            value = data[i];
            db_printf("%c", (value >= ' ' && value <= '~')? value: '.');
        }
        db_printf("*\n");
    }
    return(addr);
}
Ejemplo n.º 6
0
int
db_numargs(
	struct i386_frame *fp,
	task_t task)
{
	long	*argp;
	long	inst;
	long	args;
	extern char	etext[];

	argp = (long *)db_get_task_value((long)&fp->f_retaddr, sizeof(long), FALSE, task);
	if (argp < (long *)VM_MIN_KERNEL_ADDRESS || argp > (long *)etext)
	    args = db_numargs_default;
	else if (!DB_CHECK_ACCESS((long)argp, sizeof(long), task))
	    args = db_numargs_default;
	else {
	    inst = db_get_task_value((long)argp, sizeof(long), FALSE, task);
	    if ((inst & 0xff) == 0x59)	/* popl %ecx */
		args = 1;
	    else if ((inst & 0xffff) == 0xc483)	/* addl %n, %esp */
		args = ((inst >> 16) & 0xff) / 4;
	    else
		args = db_numargs_default;
	}
Ejemplo n.º 7
0
void
db_set_task_single_step(
	register db_regs_t	*regs,
	task_t		   	task)
{
	db_addr_t pc = PC_REGS(regs), brpc;
	register unsigned int	 inst;
	register boolean_t       unconditional;

	/*
	 *	User was stopped at pc, e.g. the instruction
	 *	at pc was not executed.
	 */
	inst = db_get_task_value(pc, sizeof(int), FALSE, task);
	if (inst_branch(inst) || inst_call(inst)) {
	    extern db_expr_t getreg_val();	/* XXX -- need prototype! */

	    brpc = branch_taken(inst, pc, getreg_val, (unsigned char*)regs);
	    if (brpc != pc) {	/* self-branches are hopeless */
		db_taken_bkpt = db_set_temp_breakpoint(task, brpc);
	    } else
	        db_taken_bkpt = 0;
	    pc = next_instr_address(pc,1,task);
	} else 
	    pc = next_instr_address(pc,0,task);
	
	/* 
	 * check if this control flow instruction is an
	 * unconditional transfer
	 */

	unconditional = inst_unconditional_flow_transfer(inst);

	/* 
	  We only set the sequential breakpoint if previous instruction was not
	  an unconditional change of flow of control. If the previous instruction
	  is an unconditional change of flow of control, setting a breakpoint in the
	  next sequential location may set a breakpoint in data or in another routine,
	  which could screw up either the program or the debugger. 
	  (Consider, for instance, that the next sequential instruction is the 
	  start of a routine needed by the debugger.)
	*/
	if (!unconditional && db_find_breakpoint_here(task, pc) == 0 &&
	    (db_taken_bkpt == 0 || db_taken_bkpt->address != pc)) {
	    	db_not_taken_bkpt = db_set_temp_breakpoint(task, pc);
	} else
	    	db_not_taken_bkpt = 0;
}
Ejemplo n.º 8
0
void
db_search(
    db_addr_t	addr,
    int		size,
    db_expr_t	value,
    db_expr_t	mask,
    unsigned int	count,
    task_t		task)
{
    while (count-- != 0) {
        db_prev = addr;
        if ((db_get_task_value(addr,size,FALSE,task) & mask) == value)
            break;
        addr += size;
    }
    db_printf("0x%x: ", addr);
    db_next = addr;
}
Ejemplo n.º 9
0
void
db_clear_breakpoints(void)
{
	register db_breakpoint_t bkpt, *bkptp;
	register task_t	 task;
	db_expr_t inst;
	thread_act_t	 cur_act = current_act();
	task_t	 cur_task = (cur_act && !cur_act->kernel_loaded) ?
			cur_act->task: TASK_NULL;

	if (db_breakpoints_inserted) {
	    bkptp = &db_breakpoint_list;
	    for (bkpt = *bkptp; bkpt; bkpt = *bkptp) {
		task = bkpt->task;
		if (bkpt->flags & BKPT_USR_GLOBAL) {
		    if (cur_task == TASK_NULL) {
			bkptp = &bkpt->link;
			continue;
		    }
		    task = cur_task;
		}
		if ((bkpt->flags & BKPT_SET_IN_MEM)
		    && DB_CHECK_ACCESS(bkpt->address, BKPT_SIZE, task)) {
		    inst = db_get_task_value(bkpt->address, BKPT_SIZE, FALSE, 
								task);
		    if (inst != BKPT_SET(inst)) {
			if (bkpt->flags & BKPT_USR_GLOBAL) {
			    bkptp = &bkpt->link;
			    continue;
			}
			db_force_delete_breakpoint(bkpt, 0, FALSE);
			*bkptp = bkpt->link;
		        db_breakpoint_free(bkpt);
			continue;
		    }
		    db_put_task_value(bkpt->address, BKPT_SIZE,
				 bkpt->bkpt_inst, task);
		    bkpt->flags &= ~BKPT_SET_IN_MEM;
		}
		bkptp = &bkpt->link;
	    }
	    db_breakpoints_inserted = FALSE;
	}
}
Ejemplo n.º 10
0
void
db_set_breakpoints(void)
{
	register db_breakpoint_t bkpt;
	register task_t	task;
	db_expr_t	inst;
	thread_act_t	cur_act = current_act();
	task_t		cur_task =
				(cur_act && !cur_act->kernel_loaded) ?
					cur_act->task : TASK_NULL;
	boolean_t	inserted = TRUE;

	if (!db_breakpoints_inserted) {
	    for (bkpt = db_breakpoint_list; bkpt != 0; bkpt = bkpt->link) {
		if (bkpt->flags & BKPT_SET_IN_MEM)
		    continue;
		task = bkpt->task;
		if (bkpt->flags & BKPT_USR_GLOBAL) {
		    if ((bkpt->flags & BKPT_1ST_SET) == 0) {
		        if (cur_task == TASK_NULL)
			    continue;
		        task = cur_task;
		    } else
			bkpt->flags &= ~BKPT_1ST_SET;
		}
		if (DB_CHECK_ACCESS(bkpt->address, BKPT_SIZE, task)) {
		    inst = db_get_task_value(bkpt->address, BKPT_SIZE, FALSE,
								task);
		    if (inst == BKPT_SET(inst))
			continue;
		    bkpt->bkpt_inst = inst;
		    db_put_task_value(bkpt->address,
				BKPT_SIZE,
				BKPT_SET(bkpt->bkpt_inst), task);
		    bkpt->flags |= BKPT_SET_IN_MEM;
		} else {
		    inserted = FALSE;
		}
	    }
	    db_breakpoints_inserted = inserted;
	}
}
Ejemplo n.º 11
0
/*
 * Disassemble instruction at 'loc'.  'altfmt' specifies an
 * (optional) alternate format.  Return address of start of
 * next instruction.
 */
db_addr_t
db_disasm(
	db_addr_t	loc,
	boolean_t	altfmt,
	task_t		task)
{
	int inst;
	char *p;

	inst = db_get_task_value(loc, 4, FALSE, task);
	db_disasm_pc = loc;
	db_disasm_print_symaddr = FALSE;
	p = in(inst);
	db_printf("%s", p);
	if (db_disasm_print_symaddr) {
		db_printf(" <");
		db_task_printsym(db_disasm_symaddr, DB_STGY_ANY, task);
		db_printf(">");
	}
	dis_done();
	return (loc+4);
}
Ejemplo n.º 12
0
/*
 * Disassemble instruction at 'loc'.  'altfmt' specifies an
 * (optional) alternate format.  Return address of start of
 * next instruction.
 */
db_addr_t
db_disasm(
	db_addr_t	loc,
	boolean_t	altfmt,
	task_t		task)
{
	int inst;
	char *p;

	inst = db_get_task_value(loc, 4, FALSE, task);
	db_disasm_pc = loc;
	db_disasm_print_symaddr = FALSE;
	p = in(inst);
	db_printf("%s", p);
	if (db_disasm_print_symaddr) {
		db_printf(" <");
		db_task_printsym(db_disasm_symaddr, DB_STGY_ANY, task);
		db_printf(">");
	}
	db_printf("\n");		/* Make sure we have a new line for multiline displays */
	dis_done();
	return (loc+4);
}
Ejemplo n.º 13
0
boolean_t
kdb_trap(
	int	type,
	int	code,
	struct i386_saved_state *regs)
{
	spl_t	s;

	s = splhigh();
	saved_ipl[cpu_number()] = s;

	switch (type) {
	    case T_DEBUG:	/* single_step */
	    {
		int addr;
	    	int status = get_dr6();

		if (status & 0xf) {	/* hmm hdw break */
			addr =	status & 0x8 ? get_dr3() :
				status & 0x4 ? get_dr2() :
				status & 0x2 ? get_dr1() :
					       get_dr0();
			regs->efl |= EFL_RF;
			db_single_step_cmd(addr, 0, 1, "p");
		}
	    }
	    case T_INT3:	/* breakpoint */
	    case T_WATCHPOINT:	/* watchpoint */
	    case -1:	/* keyboard interrupt */
		break;

	    default:
		if (db_recover) {
		    i386_nested_saved_state = *regs;
		    db_printf("Caught %s (%d), code = %x, pc = %x\n",
			trap_name(type), type, code, regs->eip);
		    db_error("");
		    /*NOTREACHED*/
		}
		kdbprinttrap(type, code);
	}

#if	NCPUS > 1
	if (db_enter())
#endif	/* NCPUS > 1 */
	{
	    i386_last_saved_statep = regs;
	    i386_last_kdb_sp = (unsigned) &type;

	    /* XXX Should switch to ddb`s own stack here. */

	    ddb_regs = *regs;
	    if ((regs->cs & 0x3) == KERNEL_RING) {
		/*
		 * Kernel mode - esp and ss not saved
		 */
		ddb_regs.uesp = (int)&regs->uesp;   /* kernel stack pointer */
		ddb_regs.ss   = KERNEL_DS;
	    }

	    cnpollc(TRUE);
	    db_task_trap(type, code, (regs->cs & 0x3) != 0);
	    cnpollc(FALSE);

	    regs->eip    = ddb_regs.eip;
	    regs->efl    = ddb_regs.efl;
	    regs->eax    = ddb_regs.eax;
	    regs->ecx    = ddb_regs.ecx;
	    regs->edx    = ddb_regs.edx;
	    regs->ebx    = ddb_regs.ebx;
	    if ((regs->cs & 0x3) != KERNEL_RING) {
		/*
		 * user mode - saved esp and ss valid
		 */
		regs->uesp = ddb_regs.uesp;		/* user stack pointer */
		regs->ss   = ddb_regs.ss & 0xffff;	/* user stack segment */
	    }
	    regs->ebp    = ddb_regs.ebp;
	    regs->esi    = ddb_regs.esi;
	    regs->edi    = ddb_regs.edi;
	    regs->es     = ddb_regs.es & 0xffff;
	    regs->cs     = ddb_regs.cs & 0xffff;
	    regs->ds     = ddb_regs.ds & 0xffff;
	    regs->fs     = ddb_regs.fs & 0xffff;
	    regs->gs     = ddb_regs.gs & 0xffff;

	    if ((type == T_INT3) &&
		(db_get_task_value(regs->eip, BKPT_SIZE, FALSE, TASK_NULL)
								 == BKPT_INST))
		regs->eip += BKPT_SIZE;
	}
#if	NCPUS > 1
	db_leave();
#endif	/* NCPUS > 1 */

	splx(s);
	return 1;
}
Ejemplo n.º 14
0
boolean_t
db_stop_at_pc(
	boolean_t	*is_breakpoint,
	task_t		task,
	task_t		space)
{
	register  db_thread_breakpoint_t bkpt;

	db_clear_task_single_step(DDB_REGS, space);
	db_clear_breakpoints();
	db_clear_watchpoints();
	db_stop_pc = PC_REGS(DDB_REGS);

#ifdef	FIXUP_PC_AFTER_BREAK
	if (*is_breakpoint) {
	    /*
	     * Breakpoint trap.  Fix up the PC if the
	     * machine requires it.
	     */
	    FIXUP_PC_AFTER_BREAK
	    db_stop_pc = PC_REGS(DDB_REGS);
	}
#endif

	/*
	 * Now check for a breakpoint at this address.
	 */
	bkpt = db_find_thread_breakpoint_here(space, db_stop_pc);
	if (bkpt) {
	    if (db_cond_check(bkpt)) {
		*is_breakpoint = TRUE;
		return (TRUE);	/* stop here */
	    }
	}
	*is_breakpoint = FALSE;

	if (db_run_mode == STEP_INVISIBLE) {
	    db_run_mode = STEP_CONTINUE;
	    return (FALSE);	/* continue */
	}
	if (db_run_mode == STEP_COUNT) {
	    return (FALSE); /* continue */
	}
	if (db_run_mode == STEP_ONCE) {
	    if (--db_loop_count > 0) {
		if (db_sstep_print) {
		    db_print_loc_and_inst(db_stop_pc, task);
		}
		return (FALSE);	/* continue */
	    }
	}
	if (db_run_mode == STEP_RETURN) {
	    jmp_buf_t *prev;
	    jmp_buf_t db_jmpbuf;
	    /* WARNING: the following assumes an instruction fits an int */
		db_expr_t ins;
	   
		ins = db_get_task_value(db_stop_pc, sizeof(int), FALSE, space);

	    /* continue until matching return */

	    prev = db_recover;
	    if (_setjmp(db_recover = &db_jmpbuf) == 0) {
	    	if (!inst_trap_return(ins) &&
		    (!inst_return(ins) || --db_call_depth != 0)) {
			if (db_sstep_print) {
		    	    if (inst_call(ins) || inst_return(ins)) {
				register int i;

				db_printf("[after %6d /%4d] ",
					  db_inst_count,
					  db_inst_count - db_last_inst_count);
				db_last_inst_count = db_inst_count;
				for (i = db_call_depth; --i > 0; )
				    db_printf("  ");
				db_print_loc_and_inst(db_stop_pc, task);
				db_printf("\n");
		    	    }
		        }
			if (inst_call(ins))
			    db_call_depth++;
			db_recover = prev;
			if (db_step_again())
				return (FALSE);	/* continue */
	        }
	    }
	    db_recover = prev;
	}
	if (db_run_mode == STEP_CALLT) {
	    /* WARNING: the following assumes an instruction fits an int */
		db_expr_t ins;
		ins = db_get_task_value(db_stop_pc, sizeof(int), FALSE, space);

	    /* continue until call or return */

	    if (!inst_call(ins) &&
		!inst_return(ins) &&
		!inst_trap_return(ins)) {
			if (db_step_again())
				return (FALSE);	/* continue */
	    }
	}
	if (db_find_breakpoint_here(space, db_stop_pc))
		return(FALSE);
	db_run_mode = STEP_NONE;
	return (TRUE);
}
Ejemplo n.º 15
0
void
db_examine(
    db_addr_t	addr,
    char *		fmt,	/* format string */
    int		count,	/* repeat count */
    task_t		task)
{
    int		c;
    db_expr_t	value;
    int		size;
    int		width;
    int		leader;
    int		items;
    int		nitems;
    char *		fp;
    db_addr_t	next_addr;
    int		sz;

    db_examine_prev_addr = addr;
    while (--count >= 0) {
        fp = fmt;
        size = sizeof(int);
        width = db_examine_width(size, &items, &leader);
        while ((c = *fp++) != 0) {
            switch (c) {
            case 'b':
                size = sizeof(char);
                width = db_examine_width(size, &items, &leader);
                break;
            case 'h':
                size = sizeof(short);
                width = db_examine_width(size, &items, &leader);
                break;
            case 'l':
                size = sizeof(int);
                width = db_examine_width(size, &items, &leader);
                break;
            case 'q':
                size = sizeof(long);
                width = db_examine_width(size, &items, &leader);
                break;
            case 'a':	/* address */
            case 'A':   /* function address */
                /* always forces a new line */
                if (db_print_position() != 0)
                    db_printf("\n");
                db_prev = addr;
                next_addr = addr + 4;
                db_task_printsym(addr,
                                 (c == 'a')?DB_STGY_ANY:DB_STGY_PROC,
                                 task);
                db_printf(":\t");
                break;
            case 'm':
                db_next = db_xcdump(addr, size, count+1, task);
                return;
            case 't':
            case 'u':
                break;
            default:
restart:
                /* Reset next_addr in case we are printing in
                   multiple formats.  */
                next_addr = addr;
                if (db_print_position() == 0) {
                    /* If we hit a new symbol, print it */
                    char *	name;
                    db_addr_t	off;

                    db_find_task_sym_and_offset(addr,&name,&off,task);
                    if (off == 0)
                        db_printf("\r%s:\n", name);
                    db_printf("%#n: ", addr);
                    for (sz = 0; sz < leader; sz++)
                        db_putchar(' ');
                    db_prev = addr;
                    nitems = items;
                }

                switch (c) {
                case 'p':	/* Addrs rendered symbolically. */
                    if( size == sizeof(void *) )  {
                        char       *symName;
                        db_addr_t	offset;

                        items = 1;
                        value = db_get_task_value( next_addr,
                                                   sizeof(db_expr_t), FALSE, task );
                        db_find_task_sym_and_offset( value,
                                                     &symName, &offset, task);
                        db_printf("\n\t*%8x(%8X) = %s",
                                  next_addr, value, symName );
                        if( offset )  {
                            db_printf("+%X", offset );
                        }
                        next_addr += size;
                    }
                    break;
                case 'r':	/* signed, current radix */
                    for (sz = size, next_addr = addr;
                            sz >= sizeof (db_expr_t);
                            sz -= sizeof (db_expr_t)) {
                        if (nitems-- == 0) {
                            db_putchar('\n');
                            goto restart;
                        }
                        value = db_get_task_value(next_addr,
                                                  sizeof (db_expr_t),
                                                  TRUE,task);
                        db_printf("%-*r", width, value);
                        next_addr += sizeof (db_expr_t);
                    }
                    if (sz > 0) {
                        if (nitems-- == 0) {
                            db_putchar('\n');
                            goto restart;
                        }
                        value = db_get_task_value(next_addr, sz,
                                                  TRUE, task);
                        db_printf("%-*R", width, value);
                        next_addr += sz;
                    }
                    break;
                case 'x':	/* unsigned hex */
                    for (sz = size, next_addr = addr;
                            sz >= sizeof (db_expr_t);
                            sz -= sizeof (db_expr_t)) {
                        if (nitems-- == 0) {
                            db_putchar('\n');
                            goto restart;
                        }
                        value = db_get_task_value(next_addr,
                                                  sizeof (db_expr_t),
                                                  FALSE,task);
                        db_printf("%-*x", width, value);
                        next_addr += sizeof (db_expr_t);
                    }
                    if (sz > 0) {
                        if (nitems-- == 0) {
                            db_putchar('\n');
                            goto restart;
                        }
                        value = db_get_task_value(next_addr, sz,
                                                  FALSE, task);
                        db_printf("%-*X", width, value);
                        next_addr += sz;
                    }
                    break;
                case 'z':	/* signed hex */
                    for (sz = size, next_addr = addr;
                            sz >= sizeof (db_expr_t);
                            sz -= sizeof (db_expr_t)) {
                        if (nitems-- == 0) {
                            db_putchar('\n');
                            goto restart;
                        }
                        value = db_get_task_value(next_addr,
                                                  sizeof (db_expr_t),
                                                  TRUE, task);
                        db_printf("%-*z", width, value);
                        next_addr += sizeof (db_expr_t);
                    }
                    if (sz > 0) {
                        if (nitems-- == 0) {
                            db_putchar('\n');
                            goto restart;
                        }
                        value = db_get_task_value(next_addr,sz,
                                                  TRUE,task);
                        db_printf("%-*Z", width, value);
                        next_addr += sz;
                    }
                    break;
                case 'd':	/* signed decimal */
                    for (sz = size, next_addr = addr;
                            sz >= sizeof (db_expr_t);
                            sz -= sizeof (db_expr_t)) {
                        if (nitems-- == 0) {
                            db_putchar('\n');
                            goto restart;
                        }
                        value = db_get_task_value(next_addr,
                                                  sizeof (db_expr_t),
                                                  TRUE,task);
                        db_printf("%-*d", width, value);
                        next_addr += sizeof (db_expr_t);
                    }
                    if (sz > 0) {
                        if (nitems-- == 0) {
                            db_putchar('\n');
                            goto restart;
                        }
                        value = db_get_task_value(next_addr, sz,
                                                  TRUE, task);
                        db_printf("%-*D", width, value);
                        next_addr += sz;
                    }
                    break;
                case 'U':	/* unsigned decimal */
                case 'u':
                    for (sz = size, next_addr = addr;
                            sz >= sizeof (db_expr_t);
                            sz -= sizeof (db_expr_t)) {
                        if (nitems-- == 0) {
                            db_putchar('\n');
                            goto restart;
                        }
                        value = db_get_task_value(next_addr,
                                                  sizeof (db_expr_t),
                                                  FALSE,task);
                        db_printf("%-*u", width, value);
                        next_addr += sizeof (db_expr_t);
                    }
                    if (sz > 0) {
                        if (nitems-- == 0) {
                            db_putchar('\n');
                            goto restart;
                        }
                        value = db_get_task_value(next_addr, sz,
                                                  FALSE, task);
                        db_printf("%-*U", width, value);
                        next_addr += sz;
                    }
                    break;
                case 'o':	/* unsigned octal */
                    for (sz = size, next_addr = addr;
                            sz >= sizeof (db_expr_t);
                            sz -= sizeof (db_expr_t)) {
                        if (nitems-- == 0) {
                            db_putchar('\n');
                            goto restart;
                        }
                        value = db_get_task_value(next_addr,
                                                  sizeof (db_expr_t),
                                                  FALSE,task);
                        db_printf("%-*o", width, value);
                        next_addr += sizeof (db_expr_t);
                    }
                    if (sz > 0) {
                        if (nitems-- == 0) {
                            db_putchar('\n');
                            goto restart;
                        }
                        value = db_get_task_value(next_addr, sz,
                                                  FALSE, task);
                        db_printf("%-*o", width, value);
                        next_addr += sz;
                    }
                    break;
                case 'c':	/* character */
                    for (sz = 0, next_addr = addr;
                            sz < size;
                            sz++, next_addr++) {
                        value = db_get_task_value(next_addr,1,
                                                  FALSE,task);
                        if ((value >= ' ' && value <= '~') ||
                                value == '\n' ||
                                value == '\t')
                            db_printf("%c", value);
                        else
                            db_printf("\\%03o", value);
                    }
                    break;
                case 's':	/* null-terminated string */
                    size = 0;
                    for (;;) {
                        value = db_get_task_value(next_addr,1,
                                                  FALSE,task);
                        next_addr += 1;
                        size++;
                        if (value == 0)
                            break;
                        if (value >= ' ' && value <= '~')
                            db_printf("%c", value);
                        else
                            db_printf("\\%03o", value);
                    }
                    break;
                case 'i':	/* instruction */
                    next_addr = db_disasm(addr, FALSE, task);
                    size = next_addr - addr;
                    break;
                case 'I':	/* instruction, alternate form */
                    next_addr = db_disasm(addr, TRUE, task);
                    size = next_addr - addr;
                    break;
                default:
                    break;
                }
                if (db_print_position() != 0)
                    db_end_line();
                break;
            }
        }
        addr = next_addr;
    }
    db_next = addr;
}
Ejemplo n.º 16
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);

}