Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7429c594 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "arm64: process: dump memory around registers when displaying regs"

parents b04c3dd9 075ca141
Loading
Loading
Loading
Loading
+69 −0
Original line number Diff line number Diff line
@@ -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)
{
	int i, top_reg;
@@ -244,6 +309,10 @@ void __show_regs(struct pt_regs *regs)

		pr_cont("\n");
	}

	if (!user_mode(regs))
		show_extra_register_data(regs, 128);

}

void show_regs(struct pt_regs * regs)