summaryrefslogtreecommitdiffstats
path: root/sys/alpha
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2004-07-10 23:47:20 +0000
committermarcel <marcel@FreeBSD.org>2004-07-10 23:47:20 +0000
commitaae5483213805c645aad67985fa4f638d6e34915 (patch)
tree533bc344dcaf70d30b9a52c0dc5327488516647b /sys/alpha
parent1dca995d693b9df1e65a294b6385cc1d442233b1 (diff)
downloadFreeBSD-src-aae5483213805c645aad67985fa4f638d6e34915.zip
FreeBSD-src-aae5483213805c645aad67985fa4f638d6e34915.tar.gz
Mega update for the KDB framework: turn DDB into a KDB backend.
Most of the changes are a direct result of adding thread awareness. Typically, DDB_REGS is gone. All registers are taken from the trapframe and backtraces use the PCB based contexts. DDB_REGS was defined to be a trapframe on all platforms anyway. Thread awareness introduces the following new commands: thread X switch to thread X (where X is the TID), show threads list all threads. The backtrace code has been made more flexible so that one can create backtraces for any thread by giving the thread ID as an argument to trace. With this change, ia64 has support for breakpoints.
Diffstat (limited to 'sys/alpha')
-rw-r--r--sys/alpha/alpha/db_disasm.c38
-rw-r--r--sys/alpha/alpha/db_interface.c293
-rw-r--r--sys/alpha/alpha/db_trace.c168
-rw-r--r--sys/alpha/include/db_machdep.h49
4 files changed, 177 insertions, 371 deletions
diff --git a/sys/alpha/alpha/db_disasm.c b/sys/alpha/alpha/db_disasm.c
index c54ec21..8d98121 100644
--- a/sys/alpha/alpha/db_disasm.c
+++ b/sys/alpha/alpha/db_disasm.c
@@ -813,26 +813,9 @@ register_name (ireg)
* (optional) alternate format. Return address of start of
* next instruction.
*/
-int alpha_print_instruction(db_addr_t, alpha_instruction, boolean_t);
-db_addr_t
-db_disasm(loc, altfmt)
- db_addr_t loc;
- boolean_t altfmt;
-{
- alpha_instruction inst;
-
- inst.bits = db_get_value(loc, 4, 0);
-
- loc += alpha_print_instruction(loc, inst, altfmt);
- return (loc);
-}
-
-int
-alpha_print_instruction(iadr, i, showregs)
- db_addr_t iadr;
- alpha_instruction i;
- boolean_t showregs;
+static int
+alpha_print_instr(db_addr_t iadr, alpha_instruction i, boolean_t showregs)
{
const char *opcode;
int ireg;
@@ -1038,7 +1021,7 @@ loadstore_address:
if (i.mem_format.opcode == op_ldah)
signed_immediate <<= 16;
db_printf(" <0x%lx>", signed_immediate +
- db_register_value(DDB_REGS, i.mem_format.rs));
+ db_register_value(i.mem_format.rs));
}
break;
case op_br:
@@ -1084,10 +1067,23 @@ branch_displacement:
db_printf(",");
db_printf("%s=0x%lx",
name_of_register[regnum[ireg]],
- db_register_value(DDB_REGS, regnum[ireg]));
+ db_register_value(regnum[ireg]));
}
db_printf(">");
}
db_printf("\n");
return (sizeof(alpha_instruction));
}
+
+db_addr_t
+db_disasm(loc, altfmt)
+ db_addr_t loc;
+ boolean_t altfmt;
+{
+ alpha_instruction inst;
+
+ inst.bits = db_get_value(loc, 4, 0);
+
+ loc += alpha_print_instr(loc, inst, altfmt);
+ return (loc);
+}
diff --git a/sys/alpha/alpha/db_interface.c b/sys/alpha/alpha/db_interface.c
index d11ad8f..7a7553f 100644
--- a/sys/alpha/alpha/db_interface.c
+++ b/sys/alpha/alpha/db_interface.c
@@ -50,14 +50,12 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
-#include <sys/proc.h>
-#include <sys/reboot.h>
#include <sys/systm.h>
-#include <sys/kernel.h>
#include <sys/cons.h>
-#include <sys/ktr.h>
-#include <sys/lock.h>
+#include <sys/kdb.h>
+#include <sys/kernel.h>
#include <sys/pcpu.h>
+#include <sys/proc.h>
#include <sys/smp.h>
#include <vm/vm.h>
@@ -73,209 +71,104 @@ __FBSDID("$FreeBSD$");
#include <ddb/db_access.h>
#include <ddb/db_sym.h>
#include <ddb/db_variables.h>
-#include <machine/setjmp.h>
-
-static jmp_buf *db_nofault = 0;
-extern jmp_buf db_jmpbuf;
-extern void gdb_handle_exception(db_regs_t *, int, int);
-
-#if 0
-extern char *trap_type[];
-extern int trap_types;
-#endif
-
-int db_active;
-
-void ddbprinttrap(unsigned long, unsigned long, unsigned long,
- unsigned long);
+static db_varfcn_t db_frame;
struct db_variable db_regs[] = {
- { "v0", &ddb_regs.tf_regs[FRAME_V0], FCN_NULL },
- { "t0", &ddb_regs.tf_regs[FRAME_T0], FCN_NULL },
- { "t1", &ddb_regs.tf_regs[FRAME_T1], FCN_NULL },
- { "t2", &ddb_regs.tf_regs[FRAME_T2], FCN_NULL },
- { "t3", &ddb_regs.tf_regs[FRAME_T3], FCN_NULL },
- { "t4", &ddb_regs.tf_regs[FRAME_T4], FCN_NULL },
- { "t5", &ddb_regs.tf_regs[FRAME_T5], FCN_NULL },
- { "t6", &ddb_regs.tf_regs[FRAME_T6], FCN_NULL },
- { "t7", &ddb_regs.tf_regs[FRAME_T7], FCN_NULL },
- { "s0", &ddb_regs.tf_regs[FRAME_S0], FCN_NULL },
- { "s1", &ddb_regs.tf_regs[FRAME_S1], FCN_NULL },
- { "s2", &ddb_regs.tf_regs[FRAME_S2], FCN_NULL },
- { "s3", &ddb_regs.tf_regs[FRAME_S3], FCN_NULL },
- { "s4", &ddb_regs.tf_regs[FRAME_S4], FCN_NULL },
- { "s5", &ddb_regs.tf_regs[FRAME_S5], FCN_NULL },
- { "s6", &ddb_regs.tf_regs[FRAME_S6], FCN_NULL },
- { "a0", &ddb_regs.tf_regs[FRAME_A0], FCN_NULL },
- { "a1", &ddb_regs.tf_regs[FRAME_A1], FCN_NULL },
- { "a2", &ddb_regs.tf_regs[FRAME_A2], FCN_NULL },
- { "a3", &ddb_regs.tf_regs[FRAME_A3], FCN_NULL },
- { "a4", &ddb_regs.tf_regs[FRAME_A4], FCN_NULL },
- { "a5", &ddb_regs.tf_regs[FRAME_A5], FCN_NULL },
- { "t8", &ddb_regs.tf_regs[FRAME_T8], FCN_NULL },
- { "t9", &ddb_regs.tf_regs[FRAME_T9], FCN_NULL },
- { "t10", &ddb_regs.tf_regs[FRAME_T10], FCN_NULL },
- { "t11", &ddb_regs.tf_regs[FRAME_T11], FCN_NULL },
- { "ra", &ddb_regs.tf_regs[FRAME_RA], FCN_NULL },
- { "t12", &ddb_regs.tf_regs[FRAME_T12], FCN_NULL },
- { "at", &ddb_regs.tf_regs[FRAME_AT], FCN_NULL },
- { "gp", &ddb_regs.tf_regs[FRAME_GP], FCN_NULL },
- { "sp", &ddb_regs.tf_regs[FRAME_SP], FCN_NULL },
- { "pc", &ddb_regs.tf_regs[FRAME_PC], FCN_NULL },
- { "ps", &ddb_regs.tf_regs[FRAME_PS], FCN_NULL },
- { "ai", &ddb_regs.tf_regs[FRAME_T11], FCN_NULL },
- { "pv", &ddb_regs.tf_regs[FRAME_T12], FCN_NULL },
+ { "v0", (db_expr_t *)FRAME_V0, db_frame },
+ { "t0", (db_expr_t *)FRAME_T0, db_frame },
+ { "t1", (db_expr_t *)FRAME_T1, db_frame },
+ { "t2", (db_expr_t *)FRAME_T2, db_frame },
+ { "t3", (db_expr_t *)FRAME_T3, db_frame },
+ { "t4", (db_expr_t *)FRAME_T4, db_frame },
+ { "t5", (db_expr_t *)FRAME_T5, db_frame },
+ { "t6", (db_expr_t *)FRAME_T6, db_frame },
+ { "t7", (db_expr_t *)FRAME_T7, db_frame },
+ { "s0", (db_expr_t *)FRAME_S0, db_frame },
+ { "s1", (db_expr_t *)FRAME_S1, db_frame },
+ { "s2", (db_expr_t *)FRAME_S2, db_frame },
+ { "s3", (db_expr_t *)FRAME_S3, db_frame },
+ { "s4", (db_expr_t *)FRAME_S4, db_frame },
+ { "s5", (db_expr_t *)FRAME_S5, db_frame },
+ { "s6", (db_expr_t *)FRAME_S6, db_frame },
+ { "a0", (db_expr_t *)FRAME_A0, db_frame },
+ { "a1", (db_expr_t *)FRAME_A1, db_frame },
+ { "a2", (db_expr_t *)FRAME_A2, db_frame },
+ { "a3", (db_expr_t *)FRAME_A3, db_frame },
+ { "a4", (db_expr_t *)FRAME_A4, db_frame },
+ { "a5", (db_expr_t *)FRAME_A5, db_frame },
+ { "t8", (db_expr_t *)FRAME_T8, db_frame },
+ { "t9", (db_expr_t *)FRAME_T9, db_frame },
+ { "t10", (db_expr_t *)FRAME_T10, db_frame },
+ { "t11", (db_expr_t *)FRAME_T11, db_frame },
+ { "ra", (db_expr_t *)FRAME_RA, db_frame },
+ { "t12", (db_expr_t *)FRAME_T12, db_frame },
+ { "at", (db_expr_t *)FRAME_AT, db_frame },
+ { "gp", (db_expr_t *)FRAME_GP, db_frame },
+ { "sp", (db_expr_t *)FRAME_SP, db_frame },
+ { "pc", (db_expr_t *)FRAME_PC, db_frame },
+ { "ps", (db_expr_t *)FRAME_PS, db_frame },
+ { "ai", (db_expr_t *)FRAME_T11, db_frame },
+ { "pv", (db_expr_t *)FRAME_T12, db_frame },
};
struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
-/*
- * Print trap reason.
- */
-void
-ddbprinttrap(a0, a1, a2, entry)
- unsigned long a0, a1, a2, entry;
+static int
+db_frame(struct db_variable *vp, db_expr_t *valuep, int op)
{
- /* XXX Implement. */
-
- printf("ddbprinttrap(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", a0, a1, a2,
- entry);
-}
-
-/*
- * ddb_trap - field a kernel trap
- */
-int
-kdb_trap(a0, a1, a2, entry, regs)
- unsigned long a0, a1, a2, entry;
- db_regs_t *regs;
-{
- int ddb_mode = !(boothowto & RB_GDB);
- register_t s;
-
- /*
- * Don't bother checking for usermode, since a benign entry
- * by the kernel (call to Debugger() or a breakpoint) has
- * already checked for usermode. If neither of those
- * conditions exist, something Bad has happened.
- */
-
- if (entry != ALPHA_KENTRY_IF ||
- (a0 != ALPHA_IF_CODE_BUGCHK && a0 != ALPHA_IF_CODE_BPT
- && a0 != ALPHA_IF_CODE_GENTRAP)) {
-#if 0
- if (ddb_mode) {
- db_printf("ddbprinttrap from 0x%lx\n", /* XXX */
- regs->tf_regs[FRAME_PC]);
- ddbprinttrap(a0, a1, a2, entry);
- /*
- * Tell caller "We did NOT handle the trap."
- * Caller should panic, or whatever.
- */
- return (0);
- }
-#endif
- if (db_nofault) {
- jmp_buf *no_fault = db_nofault;
- db_nofault = 0;
- longjmp(*no_fault, 1);
- }
- }
-
- /*
- * XXX Should switch to DDB's own stack, here.
- */
-
- ddb_regs = *regs;
-
- s = intr_disable();
-
-#ifdef SMP
-#ifdef DIAGNOSTIC
- db_printf("stopping %x\n", PCPU_GET(other_cpus));
-#endif
- stop_cpus(PCPU_GET(other_cpus));
-#ifdef DIAGNOSTIC
- db_printf("stopped_cpus=%x\n", stopped_cpus);
-#endif
-#endif
-
- db_active++;
-
- if (ddb_mode) {
- cndbctl(TRUE); /* DDB active, unblank video */
- db_trap(entry, a0); /* Where the work happens */
- cndbctl(FALSE); /* DDB inactive */
- } else
- gdb_handle_exception(&ddb_regs, entry, a0);
-
- db_active--;
-
-#ifdef SMP
- restart_cpus(stopped_cpus);
-#endif
-
- intr_restore(s);
-
- *regs = ddb_regs;
-
- /*
- * Tell caller "We HAVE handled the trap."
- */
+ if (kdb_frame == NULL)
+ return (0);
+ if (op == DB_VAR_GET)
+ *valuep = kdb_frame->tf_regs[(uintptr_t)vp->valuep];
+ else
+ kdb_frame->tf_regs[(uintptr_t)vp->valuep] = *valuep;
return (1);
}
/*
* Read bytes from kernel address space for debugger.
*/
-void
-db_read_bytes(addr, size, data)
- vm_offset_t addr;
- register size_t size;
- register char *data;
+int
+db_read_bytes(vm_offset_t addr, size_t size, char *data)
{
- register char *src;
-
- db_nofault = &db_jmpbuf;
-
- src = (char *)addr;
- while (size-- > 0)
- *data++ = *src++;
-
- db_nofault = 0;
+ jmp_buf jb;
+ void *prev_jb;
+ char *src;
+ int ret;
+
+ prev_jb = kdb_jmpbuf(jb);
+ ret = setjmp(jb);
+ if (ret == 0) {
+ src = (char *)addr;
+ while (size-- > 0)
+ *data++ = *src++;
+ }
+ (void)kdb_jmpbuf(prev_jb);
+ return (ret);
}
/*
* Write bytes to kernel address space for debugger.
*/
-void
-db_write_bytes(addr, size, data)
- vm_offset_t addr;
- register size_t size;
- register char *data;
-{
- register char *dst;
-
- db_nofault = &db_jmpbuf;
-
- dst = (char *)addr;
- while (size-- > 0)
- *dst++ = *data++;
- alpha_pal_imb();
-
- db_nofault = 0;
-}
-
-void
-Debugger(const char* msg)
+int
+db_write_bytes(vm_offset_t addr, size_t size, char *data)
{
- u_int saveintr;
-
- printf("%s\n", msg);
- saveintr = alpha_pal_swpipl(ALPHA_PSL_IPL_HIGH);
- __asm("call_pal 0x81"); /* XXX bugchk */
- alpha_pal_swpipl(saveintr);
+ jmp_buf jb;
+ void *prev_jb;
+ char *dst;
+ int ret;
+
+ prev_jb = kdb_jmpbuf(jb);
+ ret = setjmp(jb);
+ if (ret == 0) {
+ dst = (char *)addr;
+ while (size-- > 0)
+ *dst++ = *data++;
+ alpha_pal_imb();
+ }
+ (void)kdb_jmpbuf(prev_jb);
+ return (ret);
}
/*
@@ -338,9 +231,7 @@ static int reg_to_frame[32] = {
};
u_long
-db_register_value(regs, regno)
- db_regs_t *regs;
- int regno;
+db_register_value(int regno)
{
if (regno > 31 || regno < 0) {
@@ -351,7 +242,7 @@ db_register_value(regs, regno)
if (regno == 31)
return (0);
- return (regs->tf_regs[reg_to_frame[regno]]);
+ return (kdb_frame->tf_regs[reg_to_frame[regno]]);
}
/*
@@ -446,19 +337,6 @@ db_inst_unconditional_flow_transfer(ins)
return (FALSE);
}
-#if 0
-boolean_t
-db_inst_spill(ins, regn)
- int ins, regn;
-{
- alpha_instruction insn;
-
- insn.bits = ins;
- return ((insn.mem_format.opcode == op_stq) &&
- (insn.mem_format.rd == regn));
-}
-#endif
-
boolean_t
db_inst_load(ins)
int ins;
@@ -520,10 +398,7 @@ db_inst_store(ins)
}
db_addr_t
-db_branch_taken(ins, pc, regs)
- int ins;
- db_addr_t pc;
- db_regs_t *regs;
+db_branch_taken(int ins, db_addr_t pc)
{
alpha_instruction insn;
db_addr_t newpc;
@@ -534,7 +409,7 @@ db_branch_taken(ins, pc, regs)
* Jump format: target PC is (contents of instruction's "RB") & ~3.
*/
case op_j:
- newpc = db_register_value(regs, insn.jump_format.rs) & ~3;
+ newpc = db_register_value(insn.jump_format.rs) & ~3;
break;
/*
diff --git a/sys/alpha/alpha/db_trace.c b/sys/alpha/alpha/db_trace.c
index 6eea6b1..79ed437 100644
--- a/sys/alpha/alpha/db_trace.c
+++ b/sys/alpha/alpha/db_trace.c
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/kdb.h>
#include <sys/proc.h>
#include <sys/user.h>
#include <sys/sysent.h>
@@ -60,11 +61,6 @@ __FBSDID("$FreeBSD$");
#include <ddb/db_output.h>
#include <alpha/alpha/db_instruction.h>
-struct trace_request {
- register_t ksp;
- register_t pc;
-};
-
/*
* Information about the `standard' Alpha function prologue.
*/
@@ -186,13 +182,15 @@ sym_is_trapsymbol(uintptr_t v)
}
static void
-decode_syscall(int number, struct proc *p)
+decode_syscall(int number, struct thread *td)
{
+ struct proc *p;
c_db_sym_t sym;
db_expr_t diff;
sy_call_t *f;
const char *symname;
+ p = (td != NULL) ? td->td_proc : NULL;
db_printf(" (%d", number);
if (p != NULL && 0 <= number && number < p->p_sysent->sv_size) {
f = p->p_sysent->sv_table[number].sy_call;
@@ -205,99 +203,34 @@ decode_syscall(int number, struct proc *p)
db_printf(")");
}
-void
-db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *modif)
+static int
+db_backtrace(struct thread *td, db_addr_t frame, db_addr_t pc, int count)
{
- db_addr_t callpc = 0, frame = 0, symval;
struct prologue_info pi;
- db_expr_t diff;
+ struct trapframe *tf;
+ const char *symname;
c_db_sym_t sym;
+ db_expr_t diff;
+ db_addr_t symval;
+ u_long last_ipl, tfps;
int i;
- u_long tfps;
- const char *symname;
- struct pcb *pcbp;
- struct trapframe *tf = NULL;
- boolean_t ra_from_tf = FALSE;
- boolean_t ra_from_pcb;
- u_long last_ipl = ~0L;
- struct proc *p = NULL;
- struct thread *td = NULL;
- boolean_t have_trapframe = FALSE;
- pid_t pid;
if (count == -1)
- count = 65535;
-
- if (!have_addr) {
- td = curthread;
- p = td->td_proc;
- addr = DDB_REGS->tf_regs[FRAME_SP] - FRAME_SIZE * 8;
- tf = (struct trapframe *)addr;
- have_trapframe = 1;
- } else if (addr < KERNBASE) {
- pid = (addr % 16) + ((addr >> 4) % 16) * 10 +
- ((addr >> 8) % 16) * 100 + ((addr >> 12) % 16) * 1000 +
- ((addr >> 16) % 16) * 10000;
- /*
- * The pcb for curproc is not valid at this point,
- * so fall back to the default case.
- */
- if (pid == curthread->td_proc->p_pid) {
- td = curthread;
- p = td->td_proc;
- addr = DDB_REGS->tf_regs[FRAME_SP] - FRAME_SIZE * 8;
- tf = (struct trapframe *)addr;
- have_trapframe = 1;
- } else {
- /* sx_slock(&allproc_lock); */
- LIST_FOREACH(p, &allproc, p_list) {
- if (p->p_pid == pid)
- break;
- }
- /* sx_sunlock(&allproc_lock); */
- if (p == NULL) {
- db_printf("pid %d not found\n", pid);
- return;
- }
- if ((p->p_sflag & PS_INMEM) == 0) {
- db_printf("pid %d swapped out\n", pid);
- return;
- }
- pcbp = FIRST_THREAD_IN_PROC(p)->td_pcb; /* XXXKSE */
- addr = (db_expr_t)pcbp->pcb_hw.apcb_ksp;
- callpc = pcbp->pcb_context[7];
- frame = addr;
- }
- } else {
- struct trace_request *tr;
-
- tr = (struct trace_request *)addr;
- if (tr->ksp < KERNBASE || tr->pc < KERNBASE) {
- db_printf("alpha trace requires known PC =eject=\n");
- return;
- }
- callpc = tr->pc;
- addr = tr->ksp;
- frame = addr;
- }
+ count = 1024;
+ last_ipl = ~0L;
+ tf = NULL;
while (count--) {
- if (have_trapframe) {
- frame = (db_addr_t)tf + FRAME_SIZE * 8;
- callpc = tf->tf_regs[FRAME_PC];
- ra_from_tf = TRUE;
- have_trapframe = 0;
- }
- sym = db_search_symbol(callpc, DB_STGY_ANY, &diff);
+ sym = db_search_symbol(pc, DB_STGY_ANY, &diff);
if (sym == DB_SYM_NULL)
- break;
+ return (ENOENT);
db_symbol_values(sym, &symname, (db_expr_t *)&symval);
- if (callpc < symval) {
- db_printf("symbol botch: callpc 0x%lx < "
- "func 0x%lx (%s)\n", callpc, symval, symname);
- return;
+ if (pc < symval) {
+ db_printf("symbol botch: pc 0x%lx < "
+ "func 0x%lx (%s)\n", pc, symval, symname);
+ return (0);
}
/*
@@ -328,7 +261,7 @@ db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *m
* debugger (for serious debugging).
*/
db_printf("%s() at ", symname);
- db_printsym(callpc, DB_STGY_PROC);
+ db_printsym(pc, DB_STGY_PROC);
db_printf("\n");
/*
@@ -337,7 +270,6 @@ db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *m
*/
if (sym_is_trapsymbol(symval)) {
tf = (struct trapframe *)frame;
-
for (i = 0; special_symbols[i].ss_val != 0; ++i)
if (symval == special_symbols[i].ss_val)
db_printf("--- %s",
@@ -345,7 +277,7 @@ db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *m
tfps = tf->tf_regs[FRAME_PS];
if (symval == (uintptr_t)&XentSys)
- decode_syscall(tf->tf_regs[FRAME_V0], p);
+ decode_syscall(tf->tf_regs[FRAME_V0], td);
if ((tfps & ALPHA_PSL_IPL_MASK) != last_ipl) {
last_ipl = tfps & ALPHA_PSL_IPL_MASK;
if (symval != (uintptr_t)&XentSys)
@@ -356,7 +288,8 @@ db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *m
db_printf("--- user mode ---\n");
break; /* Terminate search. */
}
- have_trapframe = 1;
+ frame = (db_addr_t)(tf + 1);
+ pc = tf->tf_regs[FRAME_PC];
continue;
}
@@ -366,8 +299,8 @@ db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *m
*
* XXX How does this interact w/ alloca()?!
*/
- if (decode_prologue(callpc, symval, &pi))
- return;
+ if (decode_prologue(pc, symval, &pi))
+ return (0);
if ((pi.pi_regmask & (1 << 26)) == 0) {
/*
* No saved RA found. We might have RA from
@@ -375,37 +308,56 @@ db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *m
* in a leaf call). If not, we've found the
* root of the call graph.
*/
- if (ra_from_tf)
- callpc = tf->tf_regs[FRAME_RA];
+ if (tf)
+ pc = tf->tf_regs[FRAME_RA];
else {
db_printf("--- root of call graph ---\n");
break;
}
} else
- callpc = *(u_long *)(frame + pi.pi_reg_offset[26]);
- ra_from_tf = ra_from_pcb = FALSE;
-#if 0
- /*
- * The call was actually made at RA - 4; the PC is
- * updated before being stored in RA.
- */
- callpc -= 4;
-#endif
+ pc = *(u_long *)(frame + pi.pi_reg_offset[26]);
frame += pi.pi_frame_size;
+ tf = NULL;
}
+
+ return (0);
}
void
-db_print_backtrace(void)
+db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count,
+ char *modif)
{
- struct trace_request tr;
+ struct thread *td;
+
+ td = (have_addr) ? kdb_thr_lookup(addr) : kdb_thread;
+ if (td == NULL) {
+ db_printf("Thread %d not found\n", (int)addr);
+ return;
+ }
+ db_trace_thread(td, count);
+}
+
+void
+db_trace_self(void)
+{
+ register_t pc, sp;
__asm __volatile(
" mov $30,%0 \n"
" lda %1,1f \n"
"1:\n"
- : "=r" (tr.ksp), "=r" (tr.pc));
- db_stack_trace_cmd((db_addr_t)&tr, 1, -1, NULL);
+ : "=r" (sp), "=r" (pc));
+ db_backtrace(curthread, sp, pc, -1);
+}
+
+int
+db_trace_thread(struct thread *thr, int count)
+{
+ struct pcb *ctx;
+
+ ctx = kdb_thr_ctx(thr);
+ return (db_backtrace(thr, ctx->pcb_hw.apcb_ksp, ctx->pcb_context[7],
+ count));
}
int
diff --git a/sys/alpha/include/db_machdep.h b/sys/alpha/include/db_machdep.h
index d2c4837..3f130ab 100644
--- a/sys/alpha/include/db_machdep.h
+++ b/sys/alpha/include/db_machdep.h
@@ -31,54 +31,40 @@
#ifndef _ALPHA_DB_MACHDEP_H_
#define _ALPHA_DB_MACHDEP_H_
-/*
- * Machine-dependent defines for new kernel debugger.
- */
-#ifndef KLD_MODULE
-#include "opt_ddb.h"
-#endif
-
#include <sys/param.h>
#include <vm/vm.h>
#include <machine/frame.h>
-#define DB_NO_AOUT
+#define DB_NO_AOUT
typedef vm_offset_t db_addr_t; /* address - unsigned */
typedef long db_expr_t; /* expression - signed */
-typedef struct trapframe db_regs_t;
-#ifdef DDB
-extern db_regs_t ddb_regs; /* register state */
-#endif
-#define DDB_REGS (&ddb_regs)
-
-#define PC_REGS(regs) ((db_addr_t)(regs)->tf_regs[FRAME_PC])
+#define PC_REGS() ((db_addr_t)kdb_thrctx->pcb_context[7])
#define BKPT_INST 0x00000080 /* breakpoint instruction */
#define BKPT_SIZE (4) /* size of breakpoint inst */
#define BKPT_SET(inst) (BKPT_INST)
-#define FIXUP_PC_AFTER_BREAK \
- (ddb_regs.tf_regs[FRAME_PC] -= BKPT_SIZE);
+#define FIXUP_PC_AFTER_BREAK (kdb_frame->tf_regs[FRAME_PC] -= BKPT_SIZE);
#define SOFTWARE_SSTEP 1 /* no hardware support */
-#define IS_BREAKPOINT_TRAP(type, code) ((type) == ALPHA_KENTRY_IF && \
- (code) == ALPHA_IF_CODE_BPT)
+
+#define IS_BREAKPOINT_TRAP(type, code) \
+ ((type) == ALPHA_KENTRY_IF && (code) == ALPHA_IF_CODE_BPT)
#define IS_WATCHPOINT_TRAP(type, code) 0
/*
* Functions needed for software single-stepping.
*/
-
-boolean_t db_inst_trap_return(int inst);
-boolean_t db_inst_return(int inst);
-boolean_t db_inst_call(int inst);
-boolean_t db_inst_branch(int inst);
-boolean_t db_inst_load(int inst);
-boolean_t db_inst_store(int inst);
-boolean_t db_inst_unconditional_flow_transfer(int inst);
-db_addr_t db_branch_taken(int inst, db_addr_t pc, db_regs_t *regs);
+boolean_t db_inst_trap_return(int inst);
+boolean_t db_inst_return(int inst);
+boolean_t db_inst_call(int inst);
+boolean_t db_inst_branch(int inst);
+boolean_t db_inst_load(int inst);
+boolean_t db_inst_store(int inst);
+boolean_t db_inst_unconditional_flow_transfer(int inst);
+db_addr_t db_branch_taken(int inst, db_addr_t pc);
#define inst_trap_return(ins) db_inst_trap_return(ins)
#define inst_return(ins) db_inst_return(ins)
@@ -88,15 +74,12 @@ db_addr_t db_branch_taken(int inst, db_addr_t pc, db_regs_t *regs);
#define inst_store(ins) db_inst_store(ins)
#define inst_unconditional_flow_transfer(ins) \
db_inst_unconditional_flow_transfer(ins)
-#define branch_taken(ins, pc, regs) \
- db_branch_taken((ins), (pc), (regs))
+#define branch_taken(ins, pc) db_branch_taken(ins, pc)
/* No delay slots on Alpha. */
#define next_instr_address(v, b) ((db_addr_t) ((b) ? (v) : ((v) + 4)))
-u_long db_register_value(db_regs_t *, int);
-int kdb_trap(unsigned long, unsigned long, unsigned long,
- unsigned long, struct trapframe *);
+u_long db_register_value(int);
/*
* Pretty arbitrary
OpenPOWER on IntegriCloud