Commit 3db3d3992d78 was aimed at making 'bt' work for dumpfiles saved
with fadump but it introduced a bit of unwarranted complexity in 'bt'
command processing. Rework 'bt' command processing for PPC64 arch to
make it a little less compilated and also, print symbols for NIP and
LR registers on exception frames.

Signed-off-by: Hari Bathini <hbath...@linux.ibm.com>
---
 ppc64.c |  140 +++++++++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 99 insertions(+), 41 deletions(-)

diff --git a/ppc64.c b/ppc64.c
index f5d0dac..03fecd3 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -2093,15 +2093,10 @@ ppc64_print_stack_entry(int frame,
                                        lr);
                                return;
                        }
-                       if (req->pc != lr) {
-                               fprintf(fp, "\n%s[Link Register] ", 
-                                       frame < 10 ? " " : "");
-                               fprintf(fp, "[%lx] %s at %lx",
-                                       req->sp, lrname, lr);
-                       }
                        req->ra = lr;
                }
-               if (!req->name || STREQ(req->name,lrname)) 
+               if (!req->name || STREQ(req->name, lrname) ||
+                   !is_kernel_text(req->pc))
                        fprintf(fp, "  (unreliable)");
                
                fprintf(fp, "\n"); 
@@ -2219,6 +2214,22 @@ ppc64_print_regs(struct ppc64_pt_regs *regs)
         fprintf(fp, "    Syscall Result: %016lx\n", regs->result);
 }
 
+static void ppc64_print_nip_lr(struct ppc64_pt_regs *regs, int print_lr)
+{
+       char buf[BUFSIZE];
+       char *sym_buf;
+
+       sym_buf = value_to_symstr(regs->nip, buf, 0);
+       if (sym_buf[0] != NULLCHAR)
+               fprintf(fp, " [NIP  : %s]\n", sym_buf);
+
+       if (print_lr) {
+               sym_buf = value_to_symstr(regs->link, buf, 0);
+               if (sym_buf[0] != NULLCHAR)
+                       fprintf(fp, " [LR   : %s]\n", sym_buf);
+       }
+}
+
 /*
  * Print the exception frame information
  */
@@ -2231,6 +2242,59 @@ ppc64_print_eframe(char *efrm_str, struct ppc64_pt_regs 
*regs,
 
        fprintf(fp, " %s [%lx] exception frame:\n", efrm_str, regs->trap);
        ppc64_print_regs(regs);
+       ppc64_print_nip_lr(regs, 1);
+}
+
+/*
+ * For vmcore typically saved with KDump or FADump, get SP and IP values
+ * from the saved ptregs.
+ */
+static int
+ppc64_vmcore_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
+{
+       struct ppc64_pt_regs *pt_regs;
+       unsigned long unip;
+
+       pt_regs = (struct ppc64_pt_regs *)bt_in->machdep;
+       if (!pt_regs || !pt_regs->gpr[1]) {
+               /*
+                * Not collected regs. May be the corresponding CPU not
+                * responded to an IPI in case of KDump OR f/w has not
+                * not provided the register info in case of FADump.
+                */
+               fprintf(fp, "%0lx: GPR1 register value (SP) was not saved\n",
+                       bt_in->task);
+               return FALSE;
+       }
+       *ksp = pt_regs->gpr[1];
+       if (IS_KVADDR(*ksp)) {
+               readmem(*ksp+16, KVADDR, &unip, sizeof(ulong), "Regs NIP value",
+                       FAULT_ON_ERROR);
+               *nip = unip;
+       } else {
+               if (IN_TASK_VMA(bt_in->task, *ksp))
+                       fprintf(fp, "%0lx: Task is running in user space\n",
+                               bt_in->task);
+               else
+                       fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n",
+                               bt_in->task, *ksp);
+               *nip = pt_regs->nip;
+       }
+
+       if (bt_in->flags &&
+       ((BT_TEXT_SYMBOLS|BT_TEXT_SYMBOLS_PRINT|BT_TEXT_SYMBOLS_NOPRINT)))
+               return TRUE;
+
+       /*
+        * Print the collected regs for the active task
+        */
+       ppc64_print_regs(pt_regs);
+       if (!IS_KVADDR(*ksp))
+               return FALSE;
+
+       ppc64_print_nip_lr(pt_regs, (unip != pt_regs->link) ? 1 : 0);
+
+       return TRUE;
 }
 
 /*
@@ -2239,7 +2303,7 @@ ppc64_print_eframe(char *efrm_str, struct ppc64_pt_regs 
*regs,
 static int
 ppc64_get_dumpfile_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
 {
-       int i;
+       int i, ret, panic_task;
        char *sym;
        ulong *up;
        struct bt_info bt_local, *bt;
@@ -2251,11 +2315,29 @@ ppc64_get_dumpfile_stack_frame(struct bt_info *bt_in, 
ulong *nip, ulong *ksp)
        struct ppc64_pt_regs *pt_regs;
        struct syment *sp;
 
-        bt = &bt_local;
-        BCOPY(bt_in, bt, sizeof(struct bt_info));
-        ms = machdep->machspec;
+       bt = &bt_local;
+       BCOPY(bt_in, bt, sizeof(struct bt_info));
+       ms = machdep->machspec;
+       ur_nip = ur_ksp = 0;
+
+       panic_task = tt->panic_task == bt->task ? TRUE : FALSE;
 
        check_hardirq = check_softirq = tt->flags & IRQSTACKS ? TRUE : FALSE;
+       if (panic_task && bt->machdep) {
+               pt_regs = (struct ppc64_pt_regs *)bt->machdep;
+               ur_nip = pt_regs->nip;
+               ur_ksp = pt_regs->gpr[1];
+       } else if ((pc->flags & KDUMP) ||
+                  ((pc->flags & DISKDUMP) &&
+                   (*diskdump_flags & KDUMP_CMPRS_LOCAL))) {
+               /*
+                * For the KDump or FADump vmcore, use SP and IP values
+                * that are saved in ptregs.
+                */
+               ret = ppc64_vmcore_stack_frame(bt_in, nip, ksp);
+               if (ret)
+                       return TRUE;
+       }
 
        if (bt->task != tt->panic_task) {
                char cpu_frozen = FALSE;
@@ -2385,38 +2467,14 @@ retry:
                check_intrstack = FALSE;
                goto retry;
        }
-
        /*
-        * We didn't find what we were looking for, so try to use
-        * the SP and IP values saved in ptregs.
+        *  We didn't find what we were looking for, so just use what was
+        *  passed in the ELF header.
         */
-       pt_regs = (struct ppc64_pt_regs *)bt_in->machdep;
-       if (!pt_regs || !pt_regs->gpr[1]) {
-               /*
-                * Not collected regs. May be the corresponding CPU did not
-                * respond to an IPI.
-                */
-               if (CRASHDEBUG(1))
-                       fprintf(fp, "%0lx: GPR1(SP) register value not saved\n",
-                               bt_in->task);
-       } else {
-               *ksp = pt_regs->gpr[1];
-               if (IS_KVADDR(*ksp)) {
-                       readmem(*ksp+16, KVADDR, nip, sizeof(ulong),
-                               "Regs NIP value", FAULT_ON_ERROR);
-                       ppc64_print_regs(pt_regs);
-                       return TRUE;
-               } else {
-                       if (IN_TASK_VMA(bt_in->task, *ksp))
-                               fprintf(fp, "%0lx: Task is running in user 
space\n",
-                                       bt_in->task);
-                       else
-                               fprintf(fp, "%0lx: Invalid Stack Pointer 
%0lx\n",
-                                       bt_in->task, *ksp);
-                       *nip = pt_regs->nip;
-                       ppc64_print_regs(pt_regs);
-                       return FALSE;
-               }
+       if (ur_nip && ur_ksp) {
+               *nip = ur_nip;
+               *ksp = ur_ksp;
+               return TRUE;
        }
 
         console("ppc64_get_dumpfile_stack_frame: cannot find SP for panic 
task\n");

--
Crash-utility mailing list
Crash-utility@redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility

Reply via email to