diff options
author | Guo Ren <ren_guo@c-sky.com> | 2019-12-17 14:57:22 +0800 |
---|---|---|
committer | Guo Ren <guoren@linux.alibaba.com> | 2020-03-08 20:55:14 +0800 |
commit | bfe47f358ad298a1efb9b8f8299a81541d90df87 (patch) | |
tree | 74753eeb05653cc8abd21004d4a4b71feaa85e66 /arch/csky/include | |
parent | 12879bda3c2a974b7e4fe199a9c21f0c5f6bca04 (diff) |
csky: Implement ptrace regs and stack API
Needed for kprobes support. Copied and adapted from Patrick's patch,
but it has been modified for csky's pt_regs.
ref:
https://lore.kernel.org/linux-riscv/1572919114-3886-2-git-send-email-vincent.chen@sifive.com/raw
Signed-off-by: Guo Ren <ren_guo@c-sky.com>
Cc: Patrick Staehlin <me@packi.ch>
Diffstat (limited to 'arch/csky/include')
-rw-r--r-- | arch/csky/include/asm/ptrace.h | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/arch/csky/include/asm/ptrace.h b/arch/csky/include/asm/ptrace.h index d0aba7b32417..f16ca256e007 100644 --- a/arch/csky/include/asm/ptrace.h +++ b/arch/csky/include/asm/ptrace.h @@ -7,6 +7,7 @@ #include <uapi/asm/ptrace.h> #include <asm/traps.h> #include <linux/types.h> +#include <linux/compiler.h> #ifndef __ASSEMBLY__ @@ -22,6 +23,18 @@ #define instruction_pointer(regs) ((regs)->pc) #define profile_pc(regs) instruction_pointer(regs) +static inline void instruction_pointer_set(struct pt_regs *regs, + unsigned long val) +{ + regs->pc = val; +} + +#if defined(__CSKYABIV2__) +#define MAX_REG_OFFSET offsetof(struct pt_regs, dcsr) +#else +#define MAX_REG_OFFSET offsetof(struct pt_regs, regs[9]) +#endif + static inline bool in_syscall(struct pt_regs const *regs) { return ((regs->sr >> 16) & 0xff) == VEC_TRAP0; @@ -37,5 +50,33 @@ static inline unsigned long regs_return_value(struct pt_regs *regs) return regs->a0; } +/* Valid only for Kernel mode traps. */ +static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) +{ + return regs->usp; +} + +extern int regs_query_register_offset(const char *name); +extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, + unsigned int n); + +/* + * regs_get_register() - get register value from its offset + * @regs: pt_regs from which register value is gotten + * @offset: offset of the register. + * + * regs_get_register returns the value of a register whose offset from @regs. + * The @offset is the offset of the register in struct pt_regs. + * If @offset is bigger than MAX_REG_OFFSET, this returns 0. + */ +static inline unsigned long regs_get_register(struct pt_regs *regs, + unsigned int offset) +{ + if (unlikely(offset > MAX_REG_OFFSET)) + return 0; + + return *(unsigned long *)((unsigned long)regs + offset); +} + #endif /* __ASSEMBLY__ */ #endif /* __ASM_CSKY_PTRACE_H */ |