----- Original Message -----
 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 <hbathini(a)linux.ibm.com> 
Thanks, Hari.  As we discussed in the related bugzilla, this looks good.
Queued for crash-7.2.4:
  
https://github.com/crash-utility/crash/commit/5fe78861ea1589084f6a2956a6f...
Dave
  
 ---
  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");