Fix the "fake" frame that we create alongside the trapframe. This fixes
authorkettenis <kettenis@openbsd.org>
Tue, 12 Mar 2024 13:32:53 +0000 (13:32 +0000)
committerkettenis <kettenis@openbsd.org>
Tue, 12 Mar 2024 13:32:53 +0000 (13:32 +0000)
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@

sys/arch/arm64/arm64/db_trace.c
sys/arch/arm64/arm64/exception.S

index 0fcfa13..cd46053 100644 (file)
@@ -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;
        }
 }
index 1a1ff5f..101de9e 100644 (file)
@@ -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)]
 .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