summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2024-03-12 13:32:54 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2024-03-12 13:32:54 +0000
commitf4f2ad97eccd16cc1a7bbbc0ab5f46d0c257f8a3 (patch)
tree055d75bac01cf1da4e8dc950f356157bf45e3b94 /sys
parent70b6b32721132a0f3420a633d299a047f734c401 (diff)
Fix the "fake" frame that we create alongside the trapframe. This fixes
backtraces through trap franes. Adjust the code that prints backtraces in ddb as the old code now tries to access a userland address. ok mpi@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/arm64/arm64/db_trace.c44
-rw-r--r--sys/arch/arm64/arm64/exception.S7
2 files changed, 36 insertions, 15 deletions
diff --git a/sys/arch/arm64/arm64/db_trace.c b/sys/arch/arm64/arm64/db_trace.c
index 0fcfa138f3e..cd460530a5a 100644
--- a/sys/arch/arm64/arm64/db_trace.c
+++ b/sys/arch/arm64/arm64/db_trace.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: db_trace.c,v 1.15 2023/06/17 08:13:56 kettenis Exp $ */
+/* $OpenBSD: db_trace.c,v 1.16 2024/03/12 13:32:53 kettenis Exp $ */
/* $NetBSD: db_trace.c,v 1.8 2003/01/17 22:28:48 thorpej Exp $ */
/*
@@ -97,8 +97,13 @@ db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count,
while (count-- && frame != 0) {
lastframe = frame;
- sym = db_search_symbol(lastlr, DB_STGY_ANY, &offset);
- db_symbol_values(sym, &name, NULL);
+ if (INKERNEL(frame)) {
+ sym = db_search_symbol(lastlr, DB_STGY_ANY, &offset);
+ db_symbol_values(sym, &name, NULL);
+ } else {
+ sym = NULL;
+ name = NULL;
+ }
if (name == NULL || strcmp(name, "end") == 0) {
(*pr)("%llx at 0x%lx", lastlr, lr - 4);
@@ -108,13 +113,6 @@ db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count,
}
(*pr)("\n");
- // can we detect traps ?
- db_read_bytes(frame, sizeof(vaddr_t), (char *)&frame);
- if (frame == 0)
- break;
- lastlr = lr;
- db_read_bytes(frame + 8, sizeof(vaddr_t), (char *)&lr);
-
if (name != NULL) {
if ((strcmp (name, "handle_el0_irq") == 0) ||
(strcmp (name, "handle_el1_irq") == 0)) {
@@ -125,15 +123,39 @@ db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count,
(*pr)("--- trap ---\n");
}
}
+
+ lastframe = frame;
+ db_read_bytes(frame, sizeof(vaddr_t), (char *)&frame);
+
+ if (frame == 0) {
+ /* end of chain */
+ break;
+ }
+
if (INKERNEL(frame)) {
+ /* staying in kernel */
if (frame <= lastframe) {
(*pr)("Bad frame pointer: 0x%lx\n", frame);
break;
}
+ } else if (INKERNEL(lastframe)) {
+ /* switch from user to kernel */
+ if (kernel_only) {
+ (*pr)("end of kernel\n");
+ break; /* kernel stack only */
+ }
} else {
- if (kernel_only)
+ /* in user */
+ if (frame <= lastframe) {
+ (*pr)("Bad user frame pointer: 0x%lx\n",
+ frame);
break;
+ }
}
+
+ lastlr = lr;
+ db_read_bytes(frame + 8, sizeof(vaddr_t), (char *)&lr);
+
--count;
}
}
diff --git a/sys/arch/arm64/arm64/exception.S b/sys/arch/arm64/arm64/exception.S
index 1a1ff5fb6d1..101de9ef803 100644
--- a/sys/arch/arm64/arm64/exception.S
+++ b/sys/arch/arm64/arm64/exception.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: exception.S,v 1.16 2023/12/26 09:19:15 kettenis Exp $ */
+/* $OpenBSD: exception.S,v 1.17 2024/03/12 13:32:53 kettenis Exp $ */
/*-
* Copyright (c) 2014 Andrew Turner
* All rights reserved.
@@ -38,7 +38,6 @@
sub sp, sp, #128
.endif
sub sp, sp, #(TF_SIZE + 16)
- stp x29, x30, [sp, #(TF_SIZE)]
stp x28, x29, [sp, #(TF_X + 28 * 8)]
stp x26, x27, [sp, #(TF_X + 26 * 8)]
stp x24, x25, [sp, #(TF_X + 24 * 8)]
@@ -59,11 +58,11 @@
.if \el == 0
mrs x18, sp_el0
.endif
- mov fp, x18
stp x10, x11, [sp, #(TF_ELR)]
stp x18, lr, [sp, #(TF_SP)]
+ stp fp, x10, [sp, #(TF_SIZE)]
mrs x18, tpidr_el1
- add x29, sp, #(TF_SIZE)
+ add fp, sp, #(TF_SIZE)
.endm
.macro restore_registers el