summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2014-09-06 09:42:24 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2014-09-06 09:42:24 +0000
commit80c4a5e6590c3c153d2c40af7a931c334687251d (patch)
tree0b6e2b8c412de0865e66e9ed57847b8873173fe1
parentfc67eaa624ebcad11d73e46f431c766a22204e49 (diff)
Rewrite the PowerPC stack dump routine to delimit the trap & interrupt
contexts with markers (---like on x86---) and print the associated type or number when available. While here, gyp' the support for process tracing (tr /p). ok miod@
-rw-r--r--sys/arch/macppc/macppc/locore.S6
-rw-r--r--sys/arch/powerpc/ddb/db_trace.c148
-rw-r--r--sys/arch/powerpc/powerpc/trap.c17
-rw-r--r--sys/arch/socppc/socppc/locore.S6
4 files changed, 109 insertions, 68 deletions
diff --git a/sys/arch/macppc/macppc/locore.S b/sys/arch/macppc/macppc/locore.S
index b315f42a0c0..5c3717ebb9d 100644
--- a/sys/arch/macppc/macppc/locore.S
+++ b/sys/arch/macppc/macppc/locore.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.S,v 1.42 2013/12/29 21:06:37 miod Exp $ */
+/* $OpenBSD: locore.S,v 1.43 2014/09/06 09:42:22 mpi Exp $ */
/* $NetBSD: locore.S,v 1.2 1996/10/16 19:33:09 ws Exp $ */
/*
@@ -887,6 +887,7 @@ realtrap:
/*
* Now the common trap catching code.
*/
+ .globl s_trap
s_trap:
FRAME_SETUP(CI_TEMPSAVE)
/* Now we can recover interrupts again: */
@@ -901,6 +902,8 @@ s_trap:
trapagain:
addi %r3,%r1,8
bl _C_LABEL(trap)
+
+ .globl trapexit
trapexit:
/* Disable interrupts: */
mfmsr %r3
@@ -1180,6 +1183,7 @@ rfi3: rfi
/*
* Decrementer interrupt second level handler
*/
+ .globl decrintr
decrintr:
INTRENTER
addi %r3,%r1,8 /* intr frame */
diff --git a/sys/arch/powerpc/ddb/db_trace.c b/sys/arch/powerpc/ddb/db_trace.c
index e233eca7c0f..95db2e870f6 100644
--- a/sys/arch/powerpc/ddb/db_trace.c
+++ b/sys/arch/powerpc/ddb/db_trace.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: db_trace.c,v 1.5 2014/07/13 12:11:01 jasper Exp $ */
+/* $OpenBSD: db_trace.c,v 1.6 2014/09/06 09:42:23 mpi Exp $ */
/* $NetBSD: db_trace.c,v 1.15 1996/02/22 23:23:41 gwr Exp $ */
/*
@@ -30,10 +30,14 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
+#include <sys/user.h>
+
+#include <uvm/uvm_extern.h>
#include <machine/db_machdep.h>
#include <machine/signal.h>
#include <machine/pcb.h>
+#include <machine/pmap.h>
#include <ddb/db_access.h>
#include <ddb/db_sym.h>
@@ -41,8 +45,6 @@
#include <ddb/db_interface.h>
#include <ddb/db_output.h>
-int db_read32(u_int32_t paddr, u_int32_t *value);
-
db_regs_t ddb_regs;
struct db_variable db_regs[] = {
@@ -88,8 +90,6 @@ struct db_variable db_regs[] = {
struct db_variable *db_eregs = db_regs + nitems(db_regs);
-extern label_t *db_recover;
-
/*
* this is probably hackery.
*/
@@ -99,46 +99,16 @@ db_save_regs(struct trapframe *frame)
bcopy(frame, &(ddb_regs.tf), sizeof (struct trapframe));
}
-int
-db_read32(u_int32_t paddr, u_int32_t *value)
-{
- faultbuf env;
- faultbuf *old_onfault = curpcb->pcb_onfault;
- if (setfault(&env)) {
- curpcb->pcb_onfault = old_onfault;
- return EFAULT;
- }
- *value = *(u_int32_t *)paddr;
- curpcb->pcb_onfault = old_onfault;
- return 0;
-}
-
-db_expr_t
-db_dumpframe(u_int32_t pframe, int (*pr)(const char *, ...))
-{
- u_int32_t nextframe;
- u_int32_t lr;
- char *name;
- db_expr_t offset;
-
- if (db_read32(pframe, &nextframe) == EFAULT) {
- return 0;
- }
-
- if (db_read32(pframe+4, &lr) == EFAULT) {
- return 0;
- }
+/* from locore.S */
+extern db_addr_t trapexit;
+extern db_addr_t esym;
+#define INTSTK (8*1024) /* 8K interrupt stack */
- db_find_sym_and_offset(lr-4, &name, &offset);
- if (!name) {
- name = "0";
- offset = lr-4;
- }
- (*pr)("%08x: %s+0x%x fp %x nfp %x\n",
- lr-4, name, offset, pframe, nextframe);
+#define INKERNEL(va) (((vaddr_t)(va)) >= VM_MIN_KERNEL_ADDRESS && \
+ ((vaddr_t)(va)) < VM_MAX_KERNEL_ADDRESS)
- return nextframe;
-}
+#define ININTSTK(va) (((vaddr_t)(va)) >= round_page(esym) && \
+ ((vaddr_t)(va)) < (round_page(esym) + INTSTK))
/*
* Frame tracing.
@@ -147,14 +117,92 @@ void
db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count,
char *modif, int (*pr)(const char *, ...))
{
+ db_addr_t lr, sp, lastsp;
+ db_expr_t offset;
+ db_sym_t sym;
+ char *name;
+ char c, *cp = modif;
+ int trace_proc = 0;
+
+ while ((c = *cp++) != 0) {
+ if (c == 'p')
+ trace_proc = 1;
+ }
- if (count == 0 || count == -1)
- count = INT_MAX;
- if (have_addr == 0){
- addr = ddb_regs.tf.fixreg[1];
+ if (!have_addr) {
+ sp = ddb_regs.tf.fixreg[1];
+ lr = ddb_regs.tf.srr0;
+ } else {
+ if (trace_proc) {
+ struct proc *p = pfind((pid_t)addr);
+ if (p == NULL) {
+ (*pr) ("db_trace.c: process not found\n");
+ return;
+ }
+ addr = p->p_addr->u_pcb.pcb_sp;
+ }
+ sp = addr;
+ db_read_bytes(sp + 4, sizeof(db_addr_t), (char *)&lr);
}
- while (addr != 0 && count > 0) {
- addr = db_dumpframe(addr, pr);
- count --;
+
+ while (count && sp != 0) {
+ /*
+ * lr contains the return address, so adjust its value
+ * to display the offset of the calling address.
+ */
+ sym = db_search_symbol(lr - 4, DB_STGY_ANY, &offset);
+ db_symbol_values(sym, &name, NULL);
+
+ if (name == NULL || strcmp(name, "end") == 0) {
+ (*pr)("at 0x%lx", lr - 4);
+ } else {
+ (*pr)("%s() at ", name);
+ db_printsym(lr - 4, DB_STGY_PROC, pr);
+ }
+ (*pr)("\n");
+
+ lastsp = sp;
+
+ /*
+ * Abuse the fact that the return address of the trap()
+ * function is always 'trapexit'.
+ */
+ if (lr == (db_addr_t)&trapexit) {
+ struct trapframe *tf = (struct trapframe *)(sp + 8);
+ uint32_t code = tf->fixreg[0];
+ uint32_t type = tf->exc;
+
+ if (tf->srr1 & PSL_PR)
+ type |= EXC_USER;
+
+ if (type == (EXC_SC|EXC_USER))
+ (*pr)("--- syscall (number %d) ---\n", code);
+ else
+ (*pr)("--- trap (type 0x%x) ---\n", type);
+ }
+
+ db_read_bytes(sp, sizeof(db_addr_t), (char *)&sp);
+ if (sp == 0)
+ break;
+
+ db_read_bytes(sp + 4, sizeof(db_addr_t), (char *)&lr);
+
+ if (INKERNEL(sp)) {
+ if (sp <= lastsp) {
+ (*pr)("Bad frame pointer: 0x%lx\n", sp);
+ break;
+ }
+
+ if (ININTSTK(lastsp))
+ (*pr)("--- interrupt ---\n");
+
+ } else {
+ if (!ININTSTK(sp)) {
+ (*pr)("End of kernel: 0x%lx\n", sp);
+ break;
+ }
+ }
+ --count;
}
+ (*pr)("end trace frame: 0x%lx, count: %d\n", sp, count);
}
diff --git a/sys/arch/powerpc/powerpc/trap.c b/sys/arch/powerpc/powerpc/trap.c
index df85ef245be..6915c9c6121 100644
--- a/sys/arch/powerpc/powerpc/trap.c
+++ b/sys/arch/powerpc/powerpc/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.101 2014/07/09 08:32:57 deraadt Exp $ */
+/* $OpenBSD: trap.c,v 1.102 2014/09/06 09:42:23 mpi Exp $ */
/* $NetBSD: trap.c,v 1.3 1996/10/13 03:31:37 christos Exp $ */
/*
@@ -66,21 +66,6 @@ void trap(struct trapframe *frame);
#define NARGREG 8 /* 8 args are in registers */
#define MOREARGS(sp) ((caddr_t)((int)(sp) + 8)) /* more args go here */
-#ifdef DDB
-void ppc_dumpbt(struct trapframe *frame);
-
-void
-ppc_dumpbt(struct trapframe *frame)
-{
- u_int32_t addr;
- /* dumpframe is defined in db_trace.c */
- addr=frame->fixreg[1];
- while (addr != 0)
- addr = db_dumpframe(addr, db_printf);
- return;
-}
-#endif
-
#ifdef ALTIVEC
/*
* Save state of the vector processor, This is done lazily in the hope
diff --git a/sys/arch/socppc/socppc/locore.S b/sys/arch/socppc/socppc/locore.S
index d73fd2f5eda..b686a50f90c 100644
--- a/sys/arch/socppc/socppc/locore.S
+++ b/sys/arch/socppc/socppc/locore.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.S,v 1.9 2013/12/29 21:06:37 miod Exp $ */
+/* $OpenBSD: locore.S,v 1.10 2014/09/06 09:42:23 mpi Exp $ */
/* $NetBSD: locore.S,v 1.2 1996/10/16 19:33:09 ws Exp $ */
/*
@@ -906,6 +906,7 @@ realtrap:
/*
* Now the common trap catching code.
*/
+ .globl s_trap
s_trap:
FRAME_SETUP(CI_TEMPSAVE)
/* Now we can recover interrupts again: */
@@ -920,6 +921,8 @@ s_trap:
trapagain:
addi %r3,%r1,8
bl _C_LABEL(trap)
+
+ .globl trapexit
trapexit:
/* Disable interrupts: */
mfmsr %r3
@@ -1199,6 +1202,7 @@ rfi3: rfi
/*
* Decrementer interrupt second level handler
*/
+ .globl decrintr
decrintr:
INTRENTER
addi %r3,%r1,8 /* intr frame */