summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormpi <mpi@openbsd.org>2019-10-15 10:13:03 +0000
committermpi <mpi@openbsd.org>2019-10-15 10:13:03 +0000
commit19120e8f37ae8c3d69ee4ec889299229b3996b4d (patch)
tree3d6a1c11e6eaf477319db3486fb6ea0cdbda7e19 /sys
parentReduce the number of places where `p_priority' and `p_stat' are set. (diff)
downloadwireguard-openbsd-19120e8f37ae8c3d69ee4ec889299229b3996b4d.tar.xz
wireguard-openbsd-19120e8f37ae8c3d69ee4ec889299229b3996b4d.zip
Fix db_stack_dump() w/ custom addr & implement db_save_stack_trace().
Substract the BIAS from the `addr' argument since the unwinding algorithm assumes the given frame address doesn't include it. In other words, account for the BIAS added by __builtin_frame_address(). Inputs from and ok kettenis@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/sparc64/sparc64/db_trace.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/sys/arch/sparc64/sparc64/db_trace.c b/sys/arch/sparc64/sparc64/db_trace.c
index 03cab11e46b..4fe8ef619a1 100644
--- a/sys/arch/sparc64/sparc64/db_trace.c
+++ b/sys/arch/sparc64/sparc64/db_trace.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: db_trace.c,v 1.14 2017/11/03 11:29:47 jasper Exp $ */
+/* $OpenBSD: db_trace.c,v 1.15 2019/10/15 10:13:03 mpi Exp $ */
/* $NetBSD: db_trace.c,v 1.23 2001/07/10 06:06:16 eeh Exp $ */
/*
@@ -87,7 +87,7 @@ db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count,
frame = (vaddr_t)u->u_pcb.pcb_sp;
(*pr)("at %p\n", frame);
} else {
- frame = (vaddr_t)addr;
+ frame = (vaddr_t)addr - BIAS;
}
}
@@ -151,6 +151,33 @@ db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count,
}
}
+void
+db_save_stack_trace(struct db_stack_trace *st)
+{
+ struct frame64 *f64;
+ db_addr_t pc;
+ vaddr_t frame;
+
+ frame = (vaddr_t)__builtin_frame_address(0) - BIAS;
+ if ((frame & 1) == 0)
+ return;
+
+ st->st_count = 0;
+ while (st->st_count < DB_STACK_TRACE_MAX) {
+ f64 = (struct frame64 *)(frame + BIAS);
+ pc = (db_addr_t)KLOAD(f64->fr_pc);
+
+ st->st_pc[st->st_count++] = pc;
+ frame = KLOAD(f64->fr_fp);
+
+ if (pc < KERNBASE || pc >= KERNEND)
+ break;
+ if (frame < KERNBASE)
+ break;
+ if ((frame & 1) == 0)
+ break;
+ }
+}
void
db_dump_window(db_expr_t addr, int have_addr, db_expr_t count, char *modif)