diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2024-03-12 13:32:54 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2024-03-12 13:32:54 +0000 |
commit | f4f2ad97eccd16cc1a7bbbc0ab5f46d0c257f8a3 (patch) | |
tree | 055d75bac01cf1da4e8dc950f356157bf45e3b94 /sys | |
parent | 70b6b32721132a0f3420a633d299a047f734c401 (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.c | 44 | ||||
-rw-r--r-- | sys/arch/arm64/arm64/exception.S | 7 |
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 |