• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * This file is subject to the terms and conditions of the GNU General Public
3   * License.  See the file "COPYING" in the main directory of this archive
4   * for more details.
5   *
6   * Copyright (C) 1994, 95, 96, 97, 98, 99, 2000 by Ralf Baechle
7   * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8   */
9  #ifndef _ASM_PTRACE_H
10  #define _ASM_PTRACE_H
11  
12  
13  #include <linux/compiler.h>
14  #include <linux/linkage.h>
15  #include <linux/types.h>
16  #include <asm/isadep.h>
17  #include <asm/page.h>
18  #include <asm/thread_info.h>
19  #include <uapi/asm/ptrace.h>
20  
21  /*
22   * This struct defines the way the registers are stored on the stack during a
23   * system call/exception. As usual the registers k0/k1 aren't being saved.
24   *
25   * If you add a register here, also add it to regoffset_table[] in
26   * arch/mips/kernel/ptrace.c.
27   */
28  struct pt_regs {
29  #ifdef CONFIG_32BIT
30  	/* Pad bytes for argument save space on the stack. */
31  	unsigned long pad0[8];
32  #endif
33  
34  	/* Saved main processor registers. */
35  	unsigned long regs[32];
36  
37  	/* Saved special registers. */
38  	unsigned long cp0_status;
39  	unsigned long hi;
40  	unsigned long lo;
41  #ifdef CONFIG_CPU_HAS_SMARTMIPS
42  	unsigned long acx;
43  #endif
44  	unsigned long cp0_badvaddr;
45  	unsigned long cp0_cause;
46  	unsigned long cp0_epc;
47  #ifdef CONFIG_CPU_CAVIUM_OCTEON
48  	unsigned long long mpl[6];        /* MTM{0-5} */
49  	unsigned long long mtp[6];        /* MTP{0-5} */
50  #endif
51  	unsigned long __last[0];
52  } __aligned(8);
53  
kernel_stack_pointer(struct pt_regs * regs)54  static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
55  {
56  	return regs->regs[31];
57  }
58  
59  /*
60   * Don't use asm-generic/ptrace.h it defines FP accessors that don't make
61   * sense on MIPS.  We rather want an error if they get invoked.
62   */
63  
instruction_pointer_set(struct pt_regs * regs,unsigned long val)64  static inline void instruction_pointer_set(struct pt_regs *regs,
65                                             unsigned long val)
66  {
67  	regs->cp0_epc = val;
68  }
69  
70  /* Query offset/name of register from its name/offset */
71  extern int regs_query_register_offset(const char *name);
72  #define MAX_REG_OFFSET (offsetof(struct pt_regs, __last))
73  
74  /**
75   * regs_get_register() - get register value from its offset
76   * @regs:       pt_regs from which register value is gotten.
77   * @offset:     offset number of the register.
78   *
79   * regs_get_register returns the value of a register. The @offset is the
80   * offset of the register in struct pt_regs address which specified by @regs.
81   * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
82   */
regs_get_register(struct pt_regs * regs,unsigned int offset)83  static inline unsigned long regs_get_register(struct pt_regs *regs,
84                                                unsigned int offset)
85  {
86  	if (unlikely(offset > MAX_REG_OFFSET))
87  		return 0;
88  
89  	return *(unsigned long *)((unsigned long)regs + offset);
90  }
91  
92  /**
93   * regs_within_kernel_stack() - check the address in the stack
94   * @regs:       pt_regs which contains kernel stack pointer.
95   * @addr:       address which is checked.
96   *
97   * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
98   * If @addr is within the kernel stack, it returns true. If not, returns false.
99   */
regs_within_kernel_stack(struct pt_regs * regs,unsigned long addr)100  static inline int regs_within_kernel_stack(struct pt_regs *regs,
101                                             unsigned long addr)
102  {
103  	return ((addr & ~(THREAD_SIZE - 1))  ==
104  		(kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
105  }
106  
107  /**
108   * regs_get_kernel_stack_nth() - get Nth entry of the stack
109   * @regs:       pt_regs which contains kernel stack pointer.
110   * @n:          stack entry number.
111   *
112   * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
113   * is specified by @regs. If the @n th entry is NOT in the kernel stack,
114   * this returns 0.
115   */
regs_get_kernel_stack_nth(struct pt_regs * regs,unsigned int n)116  static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
117                                                        unsigned int n)
118  {
119  	unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
120  
121  	addr += n;
122  	if (regs_within_kernel_stack(regs, (unsigned long)addr))
123  		return *addr;
124  	else
125  		return 0;
126  }
127  
128  struct task_struct;
129  
130  extern int ptrace_getregs(struct task_struct *child,
131  	struct user_pt_regs __user *data);
132  extern int ptrace_setregs(struct task_struct *child,
133  	struct user_pt_regs __user *data);
134  
135  extern int ptrace_getfpregs(struct task_struct *child, __u32 __user *data);
136  extern int ptrace_setfpregs(struct task_struct *child, __u32 __user *data);
137  
138  extern int ptrace_get_watch_regs(struct task_struct *child,
139  	struct pt_watch_regs __user *addr);
140  extern int ptrace_set_watch_regs(struct task_struct *child,
141  	struct pt_watch_regs __user *addr);
142  
143  /*
144   * Does the process account for user or for system time?
145   */
146  #define user_mode(regs) (((regs)->cp0_status & KU_MASK) == KU_USER)
147  
is_syscall_success(struct pt_regs * regs)148  static inline int is_syscall_success(struct pt_regs *regs)
149  {
150  	return !regs->regs[7];
151  }
152  
regs_return_value(struct pt_regs * regs)153  static inline long regs_return_value(struct pt_regs *regs)
154  {
155  	if (is_syscall_success(regs) || !user_mode(regs))
156  		return regs->regs[2];
157  	else
158  		return -regs->regs[2];
159  }
160  
161  #define instruction_pointer(regs) ((regs)->cp0_epc)
162  #define profile_pc(regs) instruction_pointer(regs)
163  
164  extern asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall);
165  extern asmlinkage void syscall_trace_leave(struct pt_regs *regs);
166  
167  extern void die(const char *, struct pt_regs *) __noreturn;
168  
die_if_kernel(const char * str,struct pt_regs * regs)169  static inline void die_if_kernel(const char *str, struct pt_regs *regs)
170  {
171  	if (unlikely(!user_mode(regs)))
172  		die(str, regs);
173  }
174  
175  #define current_pt_regs()						\
176  ({									\
177  	unsigned long sp = (unsigned long)__builtin_frame_address(0);	\
178  	(struct pt_regs *)((sp | (THREAD_SIZE - 1)) + 1 - 32) - 1;	\
179  })
180  
181  /* Helpers for working with the user stack pointer */
182  
user_stack_pointer(struct pt_regs * regs)183  static inline unsigned long user_stack_pointer(struct pt_regs *regs)
184  {
185  	return regs->regs[29];
186  }
187  
user_stack_pointer_set(struct pt_regs * regs,unsigned long val)188  static inline void user_stack_pointer_set(struct pt_regs *regs,
189  	unsigned long val)
190  {
191  	regs->regs[29] = val;
192  }
193  
194  #endif /* _ASM_PTRACE_H */
195