diff options
Diffstat (limited to 'arch/s390/kernel/ptrace.c')
| -rw-r--r-- | arch/s390/kernel/ptrace.c | 58 | 
1 files changed, 58 insertions, 0 deletions
| diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 7cf464234419..33fdc5a79764 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -992,3 +992,61 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)  #endif  	return &user_s390_view;  } + +static const char *gpr_names[NUM_GPRS] = { +	"r0", "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7", +	"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", +}; + +unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset) +{ +	if (offset >= NUM_GPRS) +		return 0; +	return regs->gprs[offset]; +} + +int regs_query_register_offset(const char *name) +{ +	unsigned long offset; + +	if (!name || *name != 'r') +		return -EINVAL; +	if (strict_strtoul(name + 1, 10, &offset)) +		return -EINVAL; +	if (offset >= NUM_GPRS) +		return -EINVAL; +	return offset; +} + +const char *regs_query_register_name(unsigned int offset) +{ +	if (offset >= NUM_GPRS) +		return NULL; +	return gpr_names[offset]; +} + +static int regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr) +{ +	unsigned long ksp = kernel_stack_pointer(regs); + +	return (addr & ~(THREAD_SIZE - 1)) == (ksp & ~(THREAD_SIZE - 1)); +} + +/** + * regs_get_kernel_stack_nth() - get Nth entry of the stack + * @regs:pt_regs which contains kernel stack pointer. + * @n:stack entry number. + * + * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which + * is specifined by @regs. If the @n th entry is NOT in the kernel stack, + * this returns 0. + */ +unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n) +{ +	unsigned long addr; + +	addr = kernel_stack_pointer(regs) + n * sizeof(long); +	if (!regs_within_kernel_stack(regs, addr)) +		return 0; +	return *(unsigned long *)addr; +} | 
