arm64: process: dump memory around registers when displaying regs
A port of 8608d7c4418c75841c562a90cddd9beae5798a48 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> Git-commit: 081513b5f5f79f759beb2a542d89ca61c0967ac8 Git-repo: https://android.googlesource.com/kernel/common Signed-off-by: Venkata Narendra Kumar Gutta <vnkgutta@codeaurora.org>
This commit is contained in:
committed by
Venkata Narendra Kumar Gutta
parent
fee7e701fd
commit
075ca1414d
@@ -203,6 +203,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(KERN_DEBUG "\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(KERN_DEBUG "%04lx ", (unsigned long)p & 0xffff);
|
||||||
|
for (j = 0; j < 8; j++) {
|
||||||
|
u32 data;
|
||||||
|
|
||||||
|
if (probe_kernel_address(p, data))
|
||||||
|
printk(KERN_DEBUG " ********");
|
||||||
|
else
|
||||||
|
printk(KERN_DEBUG " %08x", data);
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
printk(KERN_DEBUG "\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)
|
void __show_regs(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
int i, top_reg;
|
int i, top_reg;
|
||||||
@@ -244,6 +309,10 @@ void __show_regs(struct pt_regs *regs)
|
|||||||
|
|
||||||
pr_cont("\n");
|
pr_cont("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!user_mode(regs))
|
||||||
|
show_extra_register_data(regs, 128);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void show_regs(struct pt_regs * regs)
|
void show_regs(struct pt_regs * regs)
|
||||||
|
|||||||
Reference in New Issue
Block a user