Module Name:    src
Committed By:   ryo
Date:           Thu Jun  2 05:09:01 UTC 2022

Modified Files:
        src/sys/arch/aarch64/aarch64: db_trace.c
Added Files:
        src/usr.sbin/crash/arch: aarch64.c

Log Message:
tidy up backtrace from crash(9) on aarch64

- fix to dump trapframe when backtracing from crash(8).
- use db_read_bytes() when reading kernel memory.


To generate a diff of this commit:
cvs rdiff -u -r1.16 -r1.17 src/sys/arch/aarch64/aarch64/db_trace.c
cvs rdiff -u -r0 -r1.1 src/usr.sbin/crash/arch/aarch64.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/aarch64/aarch64/db_trace.c
diff -u src/sys/arch/aarch64/aarch64/db_trace.c:1.16 src/sys/arch/aarch64/aarch64/db_trace.c:1.17
--- src/sys/arch/aarch64/aarch64/db_trace.c:1.16	Sun May 29 23:43:49 2022
+++ src/sys/arch/aarch64/aarch64/db_trace.c	Thu Jun  2 05:09:01 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: db_trace.c,v 1.16 2022/05/29 23:43:49 ryo Exp $ */
+/* $NetBSD: db_trace.c,v 1.17 2022/06/02 05:09:01 ryo Exp $ */
 
 /*
  * Copyright (c) 2017 Ryo Shimizu <r...@nerv.org>
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.16 2022/05/29 23:43:49 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.17 2022/06/02 05:09:01 ryo Exp $");
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -52,6 +52,15 @@ __KERNEL_RCSID(0, "$NetBSD: db_trace.c,v
 #include <ddb/db_extern.h>
 #include <ddb/db_interface.h>
 
+#ifdef _KERNEL
+extern char el0_trap[];
+extern char el1_trap[];
+#else
+/* see also usr.sbin/crash/arch/aarch64.c */
+extern vaddr_t el0_trap;
+extern vaddr_t el1_trap;
+#endif
+
 #define MAXBACKTRACE	128	/* against infinite loop */
 
 
@@ -61,6 +70,31 @@ __CTASSERT(VM_MIN_ADDRESS == 0);
 #define IN_KERNEL_VM_ADDRESS(addr)	\
 	((VM_MIN_KERNEL_ADDRESS <= (addr)) && ((addr) < VM_MAX_KERNEL_ADDRESS))
 
+static void
+pr_frame(struct trapframe *tf, void (*pr)(const char *, ...) __printflike(1, 2))
+{
+	struct trapframe tf_buf;
+
+	db_read_bytes((db_addr_t)tf, sizeof(tf_buf), (char *)&tf_buf);
+
+	if (tf_buf.tf_sp == 0) {
+		(*pr)("---- switchframe %p (%zu bytes) ----\n",
+		    tf, sizeof(*tf));
+		dump_switchframe(tf, pr);
+	} else {
+#ifdef _KERNEL
+		(*pr)("---- %s: trapframe %p (%zu bytes) ----\n",
+		    (tf_buf.tf_esr == (uint64_t)-1) ? "Interrupt" :
+		    eclass_trapname(__SHIFTOUT(tf_buf.tf_esr, ESR_EC)),
+		    tf, sizeof(*tf));
+#else
+		(*pr)("---- trapframe %p (%zu bytes) ----\n", tf, sizeof(*tf));
+#endif
+		dump_trapframe(tf, pr);
+	}
+	(*pr)("------------------------"
+	      "------------------------\n");
+}
 
 static bool __unused
 is_lwp(void *p)
@@ -74,19 +108,44 @@ is_lwp(void *p)
 	return false;
 }
 
+static vaddr_t
+db_lwp_getuarea(lwp_t *l)
+{
+	void *laddr;
+	db_read_bytes((db_addr_t)&l->l_addr, sizeof(laddr), (char *)&laddr);
+	if (laddr == 0)
+		return 0;
+	return (vaddr_t)((char *)laddr - UAREA_PCB_OFFSET);
+}
+
 static const char *
 getlwpnamebysp(uint64_t sp)
 {
-#if defined(_KERNEL)
+	static char c_name[MAXCOMLEN];
 	lwp_t *lwp;
+	struct proc *pp;
+	char *lname;
 
 	for (lwp = db_lwp_first(); lwp != NULL; lwp = db_lwp_next(lwp)) {
-		uint64_t uarea = uvm_lwp_getuarea(lwp);
+		uint64_t uarea = db_lwp_getuarea(lwp);
 		if ((uarea <= sp) && (sp < (uarea + USPACE))) {
-			return lwp->l_name;
+			db_read_bytes((db_addr_t)&lwp->l_name, sizeof(lname),
+			    (char *)&lname);
+			if (lname != NULL) {
+				db_read_bytes((db_addr_t)lname, sizeof(c_name),
+			    c_name);
+				return c_name;
+			}
+			db_read_bytes((db_addr_t)&lwp->l_proc, sizeof(pp),
+			    (char *)&pp);
+			if (pp != NULL) {
+				db_read_bytes((db_addr_t)&pp->p_comm,
+				    sizeof(c_name), c_name);
+				return c_name;
+			}
+			break;
 		}
 	}
-#endif
 	return "unknown";
 }
 
@@ -253,22 +312,7 @@ db_stack_trace_print(db_expr_t addr, boo
 		count = MAXBACKTRACE;
 
 	if (tf != NULL) {
-#if defined(_KERNEL)
-		if (tf->tf_sp == 0) {
-			(*pr)("---- switchframe %p (%zu bytes) ----\n",
-			    tf, sizeof(*tf));
-			dump_switchframe(tf, pr);
-		} else {
-			(*pr)("---- %s: trapframe %p (%zu bytes) ----\n",
-			    (tf->tf_esr == -1) ? "Interrupt" :
-			    eclass_trapname(__SHIFTOUT(tf->tf_esr, ESR_EC)),
-			    tf, sizeof(*tf));
-			dump_trapframe(tf, pr);
-		}
-		(*pr)("------------------------"
-		      "------------------------\n");
-
-#endif
+		pr_frame(tf, pr);
 		lastfp = lastlr = lr = fp = 0;
 
 		db_read_bytes((db_addr_t)&tf->tf_pc, sizeof(lr), (char *)&lr);
@@ -294,9 +338,6 @@ db_stack_trace_print(db_expr_t addr, boo
 		if (lr == 0 || (!trace_user && IN_USER_VM_ADDRESS(lr)))
 			break;
 
-#if defined(_KERNEL)
-		extern char el1_trap[];	/* XXX */
-		extern char el0_trap[];	/* XXX */
 		if (((char *)(lr - 4) == (char *)el0_trap) ||
 		    ((char *)(lr - 4) == (char *)el1_trap)) {
 
@@ -327,13 +368,7 @@ db_stack_trace_print(db_expr_t addr, boo
 			if (lr == 0)
 				break;
 
-			(*pr)("---- %s: trapframe %p (%zu bytes) ----\n",
-			    (tf->tf_esr == -1) ? "Interrupt" :
-			    eclass_trapname(__SHIFTOUT(tf->tf_esr, ESR_EC)),
-			    tf, sizeof(*tf));
-			dump_trapframe(tf, pr);
-			(*pr)("------------------------"
-			      "------------------------\n");
+			pr_frame(tf, pr);
 			tf = NULL;
 
 			if (!trace_user && IN_USER_VM_ADDRESS(lr))
@@ -341,9 +376,7 @@ db_stack_trace_print(db_expr_t addr, boo
 
 			pr_traceaddr("fp", fp, lr, flags, pr);
 
-		} else
-#endif
-		{
+		} else {
 			pr_traceaddr("fp", fp, lr - 4, flags, pr);
 		}
 	}

Added files:

Index: src/usr.sbin/crash/arch/aarch64.c
diff -u /dev/null src/usr.sbin/crash/arch/aarch64.c:1.1
--- /dev/null	Thu Jun  2 05:09:01 2022
+++ src/usr.sbin/crash/arch/aarch64.c	Thu Jun  2 05:09:01 2022
@@ -0,0 +1,61 @@
+/*	$NetBSD: aarch64.c,v 1.1 2022/06/02 05:09:01 ryo Exp $	*/
+
+/*-
+ * Copyright (c) 2022 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Ryo Shimizu.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: aarch64.c,v 1.1 2022/06/02 05:09:01 ryo Exp $");
+#endif /* not lint */
+
+#include <kvm.h>
+#include <nlist.h>
+#include <err.h>
+#include <stdlib.h>
+
+#include "extern.h"
+
+vaddr_t el0_trap;
+vaddr_t el1_trap;
+
+static struct nlist nl[] = {
+	{ .n_name = "el0_trap" },	/* 0 */
+	{ .n_name = "el1_trap" },	/* 1 */
+	{ .n_name = NULL },
+};
+
+void
+db_mach_init(kvm_t *kd)
+{
+	if (kvm_nlist(kd, nl) == -1)
+		errx(EXIT_FAILURE, "kvm_nlist: %s", kvm_geterr(kd));
+
+	el0_trap = nl[0].n_value;
+	el1_trap = nl[1].n_value;
+}

Reply via email to