11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1999, 2000  Niibe Yutaka
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
40a9426df1858f71ac84eb7eef500b4247de5e3bbDavid Howells#ifndef __ASM_SH_PTRACE_H
50a9426df1858f71ac84eb7eef500b4247de5e3bbDavid Howells#define __ASM_SH_PTRACE_H
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7da28c597996a964a195529595c37f7aacd6dad09Paul Mundt
8da28c597996a964a195529595c37f7aacd6dad09Paul Mundt#include <linux/stringify.h>
9da28c597996a964a195529595c37f7aacd6dad09Paul Mundt#include <linux/stddef.h>
10da28c597996a964a195529595c37f7aacd6dad09Paul Mundt#include <linux/thread_info.h>
1133f242ed11ce6b5fbe73fe4ece7ef4bc2f4e2851Paul Mundt#include <asm/addrspace.h>
12b0f3ae03aca0f331b851ae94bc066124e7f104dfPaul Mundt#include <asm/page.h>
130a9426df1858f71ac84eb7eef500b4247de5e3bbDavid Howells#include <uapi/asm/ptrace.h>
1433f242ed11ce6b5fbe73fe4ece7ef4bc2f4e2851Paul Mundt
1533f242ed11ce6b5fbe73fe4ece7ef4bc2f4e2851Paul Mundt#define user_mode(regs)			(((regs)->sr & 0x40000000)==0)
16eac676e531214f1e276645613acae7d7c4529035Roel Kluin#define kernel_stack_pointer(_regs)	((unsigned long)(_regs)->regs[15])
17db7eba292e913390fa881272bfbc3da0a5380513Paul Mundt
18db7eba292e913390fa881272bfbc3da0a5380513Paul Mundt#define GET_FP(regs)	((regs)->regs[14])
19db7eba292e913390fa881272bfbc3da0a5380513Paul Mundt#define GET_USP(regs)	((regs)->regs[15])
2033f242ed11ce6b5fbe73fe4ece7ef4bc2f4e2851Paul Mundt
21eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt#define arch_has_single_step()	(1)
22eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt
23c459dbf294b4a3d70490a468a7ca3907fb2c2f57Paul Mundt/*
24eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * kprobe-based event tracer support
25c459dbf294b4a3d70490a468a7ca3907fb2c2f57Paul Mundt */
26eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundtstruct pt_regs_offset {
27eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt	const char *name;
28eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt	int offset;
29eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt};
30eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt
31eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt#define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)}
32eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt#define REGS_OFFSET_NAME(num)	\
33eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt	{.name = __stringify(r##num), .offset = offsetof(struct pt_regs, regs[num])}
34da28c597996a964a195529595c37f7aacd6dad09Paul Mundt#define TREGS_OFFSET_NAME(num)	\
35da28c597996a964a195529595c37f7aacd6dad09Paul Mundt	{.name = __stringify(tr##num), .offset = offsetof(struct pt_regs, tregs[num])}
36eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt#define REG_OFFSET_END {.name = NULL, .offset = 0}
37eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt
38eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt/* Query offset/name of register from its name/offset */
39eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundtextern int regs_query_register_offset(const char *name);
40eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundtextern const char *regs_query_register_name(unsigned int offset);
41eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt
42eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundtextern const struct pt_regs_offset regoffset_table[];
43eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt
44eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt/**
45eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * regs_get_register() - get register value from its offset
46eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * @regs:	pt_regs from which register value is gotten.
47eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * @offset:	offset number of the register.
48eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt *
49eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * regs_get_register returns the value of a register. The @offset is the
50eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * offset of the register in struct pt_regs address which specified by @regs.
51eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
52eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt */
53eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundtstatic inline unsigned long regs_get_register(struct pt_regs *regs,
54eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt					      unsigned int offset)
55eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt{
56eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt	if (unlikely(offset > MAX_REG_OFFSET))
57eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt		return 0;
58eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt	return *(unsigned long *)((unsigned long)regs + offset);
59eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt}
60eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt
61eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt/**
62eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * regs_within_kernel_stack() - check the address in the stack
63eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * @regs:	pt_regs which contains kernel stack pointer.
64eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * @addr:	address which is checked.
65eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt *
66eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
67eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * If @addr is within the kernel stack, it returns true. If not, returns false.
68eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt */
69eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundtstatic inline int regs_within_kernel_stack(struct pt_regs *regs,
70eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt					   unsigned long addr)
71eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt{
72eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt	return ((addr & ~(THREAD_SIZE - 1))  ==
73eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt		(kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
74eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt}
75eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt
76eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt/**
77eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * regs_get_kernel_stack_nth() - get Nth entry of the stack
78eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * @regs:	pt_regs which contains kernel stack pointer.
79eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * @n:		stack entry number.
80eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt *
81eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
82eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * is specified by @regs. If the @n th entry is NOT in the kernel stack,
83eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * this returns 0.
84eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt */
85eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundtstatic inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
86eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt						      unsigned int n)
87eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt{
88eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt	unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
89eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt	addr += n;
90eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt	if (regs_within_kernel_stack(regs, (unsigned long)addr))
91eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt		return *addr;
92eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt	else
93eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt		return 0;
94eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt}
95c459dbf294b4a3d70490a468a7ca3907fb2c2f57Paul Mundt
9634d0b5af50a063cded842716633501b38ff815fbPaul Mundtstruct perf_event;
9734d0b5af50a063cded842716633501b38ff815fbPaul Mundtstruct perf_sample_data;
9834d0b5af50a063cded842716633501b38ff815fbPaul Mundt
99c84b51e65ea2f256353c339bd87e991b7e64630fPaul Gortmakerextern void ptrace_triggered(struct perf_event *bp,
10034d0b5af50a063cded842716633501b38ff815fbPaul Mundt		      struct perf_sample_data *data, struct pt_regs *regs);
10134d0b5af50a063cded842716633501b38ff815fbPaul Mundt
1023cf0f4ece9f1680e54b154b1e38baaf6ace20a62Al Viro#define task_pt_regs(task) \
1034f099ebb27211d378304ddcfa507097f5128f5b9Magnus Damm	((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE) - 1)
1043cf0f4ece9f1680e54b154b1e38baaf6ace20a62Al Viro
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline unsigned long profile_pc(struct pt_regs *regs)
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
107db7eba292e913390fa881272bfbc3da0a5380513Paul Mundt	unsigned long pc = regs->pc;
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1099edef28653a519bf0a48250f36cce96b1736ec4ePaul Mundt	if (virt_addr_uncached(pc))
1109edef28653a519bf0a48250f36cce96b1736ec4ePaul Mundt		return CAC_ADDR(pc);
11133f242ed11ce6b5fbe73fe4ece7ef4bc2f4e2851Paul Mundt
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return pc;
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1143cea45c6ef459b776123a4855eba6dafd506f3ceMike Frysinger#define profile_pc profile_pc
1153cea45c6ef459b776123a4855eba6dafd506f3ceMike Frysinger
1163cea45c6ef459b776123a4855eba6dafd506f3ceMike Frysinger#include <asm-generic/ptrace.h>
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* __ASM_SH_PTRACE_H */
118