ANDROID: arm64: process: dump memory around registers when displaying regs

A port of 8608d7c441 to ARM64.  Both the
original code and this port are limited to dumping kernel addresses, so
don't bother if the registers are from a userspace process.

Change-Id: Idc76804c54efaaeb70311cbb500c54db6dac4525
Signed-off-by: Greg Hackmann <ghackmann@google.com>
Signed-off-by: Tao Huang <huangtao@rock-chips.com>
This commit is contained in:
Greg Hackmann
2014-09-09 17:36:05 -07:00
committed by Tao Huang
parent 82db72bb71
commit 80018840e0
+68
View File
@@ -257,6 +257,71 @@ static void print_pstate(struct pt_regs *regs)
}
}
/*
* dump a block of kernel memory from around the given address
*/
static void show_data(unsigned long addr, int nbytes, const char *name)
{
int i, j;
int nlines;
u32 *p;
/*
* don't attempt to dump non-kernel addresses or
* values that are probably just small negative numbers
*/
if (addr < PAGE_OFFSET || addr > -256UL)
return;
printk("\n%s: %#lx:\n", name, addr);
/*
* round address down to a 32 bit boundary
* and always dump a multiple of 32 bytes
*/
p = (u32 *)(addr & ~(sizeof(u32) - 1));
nbytes += (addr & (sizeof(u32) - 1));
nlines = (nbytes + 31) / 32;
for (i = 0; i < nlines; i++) {
/*
* just display low 16 bits of address to keep
* each line of the dump < 80 characters
*/
printk("%04lx ", (unsigned long)p & 0xffff);
for (j = 0; j < 8; j++) {
u32 data;
if (aarch64_insn_read((void *)p, &data)) {
pr_cont(" ********");
} else {
pr_cont(" %08x", data);
}
++p;
}
pr_cont("\n");
}
}
static void show_extra_register_data(struct pt_regs *regs, int nbytes)
{
mm_segment_t fs;
unsigned int i;
fs = get_fs();
set_fs(KERNEL_DS);
show_data(regs->pc - nbytes, nbytes * 2, "PC");
show_data(regs->regs[30] - nbytes, nbytes * 2, "LR");
show_data(regs->sp - nbytes, nbytes * 2, "SP");
for (i = 0; i < 30; i++) {
char name[4];
snprintf(name, sizeof(name), "X%u", i);
show_data(regs->regs[i] - nbytes, nbytes * 2, name);
}
set_fs(fs);
}
void __show_regs(struct pt_regs *regs)
{
int i, top_reg;
@@ -301,6 +366,9 @@ void __show_regs(struct pt_regs *regs)
pr_cont("\n");
}
if (!user_mode(regs))
show_extra_register_data(regs, 256);
printk("\n");
}
void show_regs(struct pt_regs * regs)