blob: 33b3f37dcdbb0cdb0487b0b1e84bcba985e62878 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001#ifndef __ASM_SH_PTRACE_H
2#define __ASM_SH_PTRACE_H
3
Paul Mundteaaaeef2010-06-14 15:16:53 +09004#include <linux/stringify.h>
5
Linus Torvalds1da177e2005-04-16 15:20:36 -07006/*
7 * Copyright (C) 1999, 2000 Niibe Yutaka
8 *
9 */
Adrian Bunkf22ab812008-07-25 01:47:34 -070010#if defined(__SH5__)
Paul Mundt33f242e2007-11-09 16:57:27 +090011struct pt_regs {
12 unsigned long long pc;
13 unsigned long long sr;
Paul Mundtecd4ca52009-04-27 17:05:38 +090014 long long syscall_nr;
Paul Mundt33f242e2007-11-09 16:57:27 +090015 unsigned long long regs[63];
16 unsigned long long tregs[8];
17 unsigned long long pad[2];
18};
Paul Mundteaaaeef2010-06-14 15:16:53 +090019
20#define MAX_REG_OFFSET offsetof(struct pt_regs, tregs[7])
21#define regs_return_value(regs) ((regs)->regs[3])
22
23#define TREGS_OFFSET_NAME(num) \
24 {.name = __stringify(tr##num), .offset = offsetof(struct pt_regs, tregs[num])}
25
Paul Mundt33f242e2007-11-09 16:57:27 +090026#else
Linus Torvalds1da177e2005-04-16 15:20:36 -070027/*
28 * GCC defines register number like this:
29 * -----------------------------
30 * 0 - 15 are integer registers
31 * 17 - 22 are control/special registers
32 * 24 - 39 fp registers
33 * 40 - 47 xd registers
34 * 48 - fpscr register
35 * -----------------------------
36 *
37 * We follows above, except:
38 * 16 --- program counter (PC)
39 * 22 --- syscall #
40 * 23 --- floating point communication register
41 */
42#define REG_REG0 0
43#define REG_REG15 15
44
45#define REG_PC 16
46
47#define REG_PR 17
48#define REG_SR 18
Paul Mundt33f242e2007-11-09 16:57:27 +090049#define REG_GBR 19
Linus Torvalds1da177e2005-04-16 15:20:36 -070050#define REG_MACH 20
51#define REG_MACL 21
52
53#define REG_SYSCALL 22
54
55#define REG_FPREG0 23
56#define REG_FPREG15 38
57#define REG_XFREG0 39
58#define REG_XFREG15 54
59
60#define REG_FPSCR 55
61#define REG_FPUL 56
62
Linus Torvalds1da177e2005-04-16 15:20:36 -070063/*
64 * This struct defines the way the registers are stored on the
65 * kernel stack during a system call or other kernel entry.
66 */
67struct pt_regs {
68 unsigned long regs[16];
69 unsigned long pc;
70 unsigned long pr;
71 unsigned long sr;
72 unsigned long gbr;
73 unsigned long mach;
74 unsigned long macl;
75 long tra;
76};
77
Paul Mundteaaaeef2010-06-14 15:16:53 +090078#define MAX_REG_OFFSET offsetof(struct pt_regs, tra)
79#define regs_return_value(regs) ((regs)->regs[0])
80
Linus Torvalds1da177e2005-04-16 15:20:36 -070081/*
82 * This struct defines the way the DSP registers are stored on the
83 * kernel stack during a system call or other kernel entry.
84 */
85struct pt_dspregs {
86 unsigned long a1;
87 unsigned long a0g;
88 unsigned long a1g;
89 unsigned long m0;
90 unsigned long m1;
91 unsigned long a0;
92 unsigned long x0;
93 unsigned long x1;
94 unsigned long y0;
95 unsigned long y1;
96 unsigned long dsr;
97 unsigned long rs;
98 unsigned long re;
99 unsigned long mod;
100};
Paul Mundtdd762792008-12-10 20:14:15 +0900101#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
Paul Mundt934135c2008-09-12 19:52:36 +0900103#define PTRACE_GETREGS 12 /* General registers */
104#define PTRACE_SETREGS 13
105
106#define PTRACE_GETFPREGS 14 /* FPU registers */
107#define PTRACE_SETFPREGS 15
108
Paul Mundt3bc24a12008-05-19 13:40:12 +0900109#define PTRACE_GETFDPIC 31 /* get the ELF fdpic loadmap address */
110
111#define PTRACE_GETFDPIC_EXEC 0 /* [addr] request the executable loadmap */
112#define PTRACE_GETFDPIC_INTERP 1 /* [addr] request the interpreter loadmap */
113
Paul Mundt934135c2008-09-12 19:52:36 +0900114#define PTRACE_GETDSPREGS 55 /* DSP registers */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115#define PTRACE_SETDSPREGS 56
116
Paul Mundtb0f3ae02010-02-12 15:40:00 +0900117#define PT_TEXT_END_ADDR 240
118#define PT_TEXT_ADDR 244 /* &(struct user)->start_code */
119#define PT_DATA_ADDR 248 /* &(struct user)->start_data */
Kieran Binghambe6514c2009-05-08 15:48:15 +0100120#define PT_TEXT_LEN 252
121
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122#ifdef __KERNEL__
Paul Mundt33f242e2007-11-09 16:57:27 +0900123#include <asm/addrspace.h>
Paul Mundtb0f3ae02010-02-12 15:40:00 +0900124#include <asm/page.h>
125#include <asm/system.h>
Paul Mundt33f242e2007-11-09 16:57:27 +0900126
127#define user_mode(regs) (((regs)->sr & 0x40000000)==0)
Paul Mundteaaaeef2010-06-14 15:16:53 +0900128#define user_stack_pointer(regs) ((unsigned long)(regs)->regs[15])
129#define kernel_stack_pointer(regs) ((unsigned long)(regs)->regs[15])
Paul Mundt5a4f7c62007-11-20 18:08:06 +0900130#define instruction_pointer(regs) ((unsigned long)(regs)->pc)
Paul Mundt33f242e2007-11-09 16:57:27 +0900131
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132extern void show_regs(struct pt_regs *);
133
Paul Mundtc459dbf2008-07-30 19:09:31 +0900134#define arch_has_single_step() (1)
Paul Mundtc459dbf2008-07-30 19:09:31 +0900135
Paul Mundteaaaeef2010-06-14 15:16:53 +0900136/*
137 * kprobe-based event tracer support
138 */
139#include <linux/stddef.h>
140#include <linux/thread_info.h>
141
142struct pt_regs_offset {
143 const char *name;
144 int offset;
145};
146
147#define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)}
148#define REGS_OFFSET_NAME(num) \
149 {.name = __stringify(r##num), .offset = offsetof(struct pt_regs, regs[num])}
150#define REG_OFFSET_END {.name = NULL, .offset = 0}
151
152/* Query offset/name of register from its name/offset */
153extern int regs_query_register_offset(const char *name);
154extern const char *regs_query_register_name(unsigned int offset);
155
156extern const struct pt_regs_offset regoffset_table[];
157
158/**
159 * regs_get_register() - get register value from its offset
160 * @regs: pt_regs from which register value is gotten.
161 * @offset: offset number of the register.
162 *
163 * regs_get_register returns the value of a register. The @offset is the
164 * offset of the register in struct pt_regs address which specified by @regs.
165 * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
166 */
167static inline unsigned long regs_get_register(struct pt_regs *regs,
168 unsigned int offset)
169{
170 if (unlikely(offset > MAX_REG_OFFSET))
171 return 0;
172 return *(unsigned long *)((unsigned long)regs + offset);
173}
174
175/**
176 * regs_within_kernel_stack() - check the address in the stack
177 * @regs: pt_regs which contains kernel stack pointer.
178 * @addr: address which is checked.
179 *
180 * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
181 * If @addr is within the kernel stack, it returns true. If not, returns false.
182 */
183static inline int regs_within_kernel_stack(struct pt_regs *regs,
184 unsigned long addr)
185{
186 return ((addr & ~(THREAD_SIZE - 1)) ==
187 (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
188}
189
190/**
191 * regs_get_kernel_stack_nth() - get Nth entry of the stack
192 * @regs: pt_regs which contains kernel stack pointer.
193 * @n: stack entry number.
194 *
195 * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
196 * is specified by @regs. If the @n th entry is NOT in the kernel stack,
197 * this returns 0.
198 */
199static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
200 unsigned int n)
201{
202 unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
203 addr += n;
204 if (regs_within_kernel_stack(regs, (unsigned long)addr))
205 return *addr;
206 else
207 return 0;
208}
209
Paul Mundt34d0b5a2009-12-28 17:53:47 +0900210struct perf_event;
211struct perf_sample_data;
212
213extern void ptrace_triggered(struct perf_event *bp, int nmi,
214 struct perf_sample_data *data, struct pt_regs *regs);
215
Al Viro3cf0f4e2006-01-12 01:05:44 -0800216#define task_pt_regs(task) \
Magnus Damm4f099eb2009-02-23 07:16:34 +0000217 ((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE) - 1)
Al Viro3cf0f4e2006-01-12 01:05:44 -0800218
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219static inline unsigned long profile_pc(struct pt_regs *regs)
220{
221 unsigned long pc = instruction_pointer(regs);
222
Paul Mundt9edef282010-02-17 16:28:00 +0900223 if (virt_addr_uncached(pc))
224 return CAC_ADDR(pc);
Paul Mundt33f242e2007-11-09 16:57:27 +0900225
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226 return pc;
227}
Paul Mundt33f242e2007-11-09 16:57:27 +0900228#endif /* __KERNEL__ */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229
230#endif /* __ASM_SH_PTRACE_H */