Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/aarch64/aarch64 Functionalize frame pointer backtrace.
details: https://anonhg.NetBSD.org/src/rev/aabef033fc37
branches: trunk
changeset: 366684:aabef033fc37
user: ryo <ryo%NetBSD.org@localhost>
date: Tue Jun 07 23:55:25 2022 +0000
description:
Functionalize frame pointer backtrace.
diffstat:
sys/arch/aarch64/aarch64/db_trace.c | 161 +++++++++++++++++++----------------
1 files changed, 85 insertions(+), 76 deletions(-)
diffs (192 lines):
diff -r 320a1f6b4adc -r aabef033fc37 sys/arch/aarch64/aarch64/db_trace.c
--- a/sys/arch/aarch64/aarch64/db_trace.c Tue Jun 07 18:50:28 2022 +0000
+++ b/sys/arch/aarch64/aarch64/db_trace.c Tue Jun 07 23:55:25 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: db_trace.c,v 1.18 2022/06/07 08:08:31 ryo Exp $ */
+/* $NetBSD: db_trace.c,v 1.19 2022/06/07 23:55:25 ryo Exp $ */
/*
* Copyright (c) 2017 Ryo Shimizu <ryo%nerv.org@localhost>
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.18 2022/06/07 08:08:31 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.19 2022/06/07 23:55:25 ryo Exp $");
#include <sys/param.h>
#include <sys/bitops.h>
@@ -598,11 +598,90 @@
}
}
+static void
+db_fp_trace(struct trapframe *tf, db_addr_t fp, db_expr_t count, int flags,
+ void (*pr)(const char *, ...) __printflike(1, 2))
+{
+ uint64_t lr;
+ uint64_t lastlr, lastfp;
+
+ if (tf != NULL) {
+ pr_frame(tf, pr);
+ lastfp = lastlr = lr = fp = 0;
+
+ db_read_bytes((db_addr_t)&tf->tf_pc, sizeof(lr), (char *)&lr);
+ db_read_bytes((db_addr_t)&tf->tf_reg[29], sizeof(fp), (char *)&fp);
+ lr = aarch64_strip_pac(lr);
+
+ pr_traceaddr("fp", fp, lr - 4, flags, pr);
+ }
+
+ for (; (count > 0) && (fp != 0); count--) {
+
+ lastfp = fp;
+ fp = lr = 0;
+ /*
+ * normal stack frame
+ * fp[0] saved fp(x29) value
+ * fp[1] saved lr(x30) value
+ */
+ db_read_bytes(lastfp + 0, sizeof(fp), (char *)&fp);
+ db_read_bytes(lastfp + 8, sizeof(lr), (char *)&lr);
+ lr = aarch64_strip_pac(lr);
+
+ if (lr == 0 || ((flags & TRACEFLAG_USERSPACE) == 0 &&
+ IN_USER_VM_ADDRESS(lr)))
+ break;
+
+ if (((char *)(lr - 4) == (char *)el0_trap) ||
+ ((char *)(lr - 4) == (char *)el1_trap)) {
+
+ tf = (struct trapframe *)fp;
+
+ lastfp = (uint64_t)tf;
+ lastlr = lr;
+ lr = fp = 0;
+ db_read_bytes((db_addr_t)&tf->tf_pc, sizeof(lr),
+ (char *)&lr);
+ if (lr == 0) {
+ /*
+ * The exception may have been from a
+ * jump to null, so the null pc we
+ * would return to is useless. Try
+ * x[30] instead -- that will be the
+ * return address for the jump.
+ */
+ db_read_bytes((db_addr_t)&tf->tf_reg[30],
+ sizeof(lr), (char *)&lr);
+ }
+ db_read_bytes((db_addr_t)&tf->tf_reg[29], sizeof(fp),
+ (char *)&fp);
+ lr = aarch64_strip_pac(lr);
+
+ pr_traceaddr("tf", (db_addr_t)tf, lastlr - 4, flags, pr);
+
+ if (lr == 0)
+ break;
+
+ pr_frame(tf, pr);
+ tf = NULL;
+
+ if ((flags & TRACEFLAG_USERSPACE) == 0 &&
+ IN_USER_VM_ADDRESS(lr))
+ break;
+
+ pr_traceaddr("fp", fp, lr, flags, pr);
+ } else {
+ pr_traceaddr("fp", fp, lr - 4, flags, pr);
+ }
+ }
+}
+
void
db_stack_trace_print(db_expr_t addr, bool have_addr, db_expr_t count,
const char *modif, void (*pr)(const char *, ...) __printflike(1, 2))
{
- uint64_t lr, fp, lastlr, lastfp;
+ uint64_t fp;
struct trapframe *tf = NULL;
int flags = 0;
bool trace_thread = false;
@@ -734,78 +813,8 @@
if (trace_sp) {
/* trace $lr pushed to sp */
db_sp_trace(tf, fp, count, flags, pr);
- return;
- }
-
- /* trace $fp linked list */
- if (tf != NULL) {
- pr_frame(tf, pr);
- lastfp = lastlr = lr = fp = 0;
-
- db_read_bytes((db_addr_t)&tf->tf_pc, sizeof(lr), (char *)&lr);
- db_read_bytes((db_addr_t)&tf->tf_reg[29], sizeof(fp), (char *)&fp);
- lr = aarch64_strip_pac(lr);
-
- pr_traceaddr("fp", fp, lr - 4, flags, pr);
- }
-
- for (; (count > 0) && (fp != 0); count--) {
-
- lastfp = fp;
- fp = lr = 0;
- /*
- * normal stack frame
- * fp[0] saved fp(x29) value
- * fp[1] saved lr(x30) value
- */
- db_read_bytes(lastfp + 0, sizeof(fp), (char *)&fp);
- db_read_bytes(lastfp + 8, sizeof(lr), (char *)&lr);
- lr = aarch64_strip_pac(lr);
-
- if (lr == 0 || ((flags & TRACEFLAG_USERSPACE) == 0 &&
- IN_USER_VM_ADDRESS(lr)))
- break;
-
- if (((char *)(lr - 4) == (char *)el0_trap) ||
- ((char *)(lr - 4) == (char *)el1_trap)) {
-
- tf = (struct trapframe *)fp;
-
- lastfp = (uint64_t)tf;
- lastlr = lr;
- lr = fp = 0;
- db_read_bytes((db_addr_t)&tf->tf_pc, sizeof(lr),
- (char *)&lr);
- if (lr == 0) {
- /*
- * The exception may have been from a
- * jump to null, so the null pc we
- * would return to is useless. Try
- * x[30] instead -- that will be the
- * return address for the jump.
- */
- db_read_bytes((db_addr_t)&tf->tf_reg[30],
- sizeof(lr), (char *)&lr);
- }
- db_read_bytes((db_addr_t)&tf->tf_reg[29], sizeof(fp),
- (char *)&fp);
- lr = aarch64_strip_pac(lr);
-
- pr_traceaddr("tf", (db_addr_t)tf, lastlr - 4, flags, pr);
-
- if (lr == 0)
- break;
-
- pr_frame(tf, pr);
- tf = NULL;
-
- if ((flags & TRACEFLAG_USERSPACE) == 0 &&
- IN_USER_VM_ADDRESS(lr))
- break;
-
- pr_traceaddr("fp", fp, lr, flags, pr);
- } else {
- pr_traceaddr("fp", fp, lr - 4, flags, pr);
- }
+ } else {
+ /* trace $fp linked list */
+ db_fp_trace(tf, fp, count, flags, pr);
}
}
Home |
Main Index |
Thread Index |
Old Index