Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ptrace.c
Go to the documentation of this file.
1 /*
2  * Kernel support for the ptrace() and syscall tracing interfaces.
3  *
4  * Copyright (C) 2000 Hewlett-Packard Co, Linuxcare Inc.
5  * Copyright (C) 2000 Matthew Wilcox <[email protected]>
6  * Copyright (C) 2000 David Huggins-Daines <[email protected]>
7  * Copyright (C) 2008 Helge Deller <[email protected]>
8  */
9 
10 #include <linux/kernel.h>
11 #include <linux/sched.h>
12 #include <linux/mm.h>
13 #include <linux/smp.h>
14 #include <linux/errno.h>
15 #include <linux/ptrace.h>
16 #include <linux/tracehook.h>
17 #include <linux/user.h>
18 #include <linux/personality.h>
19 #include <linux/security.h>
20 #include <linux/compat.h>
21 #include <linux/signal.h>
22 
23 #include <asm/uaccess.h>
24 #include <asm/pgtable.h>
25 #include <asm/processor.h>
26 #include <asm/asm-offsets.h>
27 
28 /* PSW bits we allow the debugger to modify */
29 #define USER_PSW_BITS (PSW_N | PSW_V | PSW_CB)
30 
31 /*
32  * Called by kernel/ptrace.c when detaching..
33  *
34  * Make sure single step bits etc are not set.
35  */
37 {
38  clear_tsk_thread_flag(task, TIF_SINGLESTEP);
39  clear_tsk_thread_flag(task, TIF_BLOCKSTEP);
40 
41  /* make sure the trap bits are not set */
42  pa_psw(task)->r = 0;
43  pa_psw(task)->t = 0;
44  pa_psw(task)->h = 0;
45  pa_psw(task)->l = 0;
46 }
47 
48 /*
49  * The following functions are called by ptrace_resume() when
50  * enabling or disabling single/block tracing.
51  */
53 {
54  ptrace_disable(task);
55 }
56 
58 {
59  clear_tsk_thread_flag(task, TIF_BLOCKSTEP);
60  set_tsk_thread_flag(task, TIF_SINGLESTEP);
61 
62  if (pa_psw(task)->n) {
63  struct siginfo si;
64 
65  /* Nullified, just crank over the queue. */
66  task_regs(task)->iaoq[0] = task_regs(task)->iaoq[1];
67  task_regs(task)->iasq[0] = task_regs(task)->iasq[1];
68  task_regs(task)->iaoq[1] = task_regs(task)->iaoq[0] + 4;
69  pa_psw(task)->n = 0;
70  pa_psw(task)->x = 0;
71  pa_psw(task)->y = 0;
72  pa_psw(task)->z = 0;
73  pa_psw(task)->b = 0;
74  ptrace_disable(task);
75  /* Don't wake up the task, but let the
76  parent know something happened. */
77  si.si_code = TRAP_TRACE;
78  si.si_addr = (void __user *) (task_regs(task)->iaoq[0] & ~3);
79  si.si_signo = SIGTRAP;
80  si.si_errno = 0;
81  force_sig_info(SIGTRAP, &si, task);
82  /* notify_parent(task, SIGCHLD); */
83  return;
84  }
85 
86  /* Enable recovery counter traps. The recovery counter
87  * itself will be set to zero on a task switch. If the
88  * task is suspended on a syscall then the syscall return
89  * path will overwrite the recovery counter with a suitable
90  * value such that it traps once back in user space. We
91  * disable interrupts in the tasks PSW here also, to avoid
92  * interrupts while the recovery counter is decrementing.
93  */
94  pa_psw(task)->r = 1;
95  pa_psw(task)->t = 0;
96  pa_psw(task)->h = 0;
97  pa_psw(task)->l = 0;
98 }
99 
101 {
102  clear_tsk_thread_flag(task, TIF_SINGLESTEP);
103  set_tsk_thread_flag(task, TIF_BLOCKSTEP);
104 
105  /* Enable taken branch trap. */
106  pa_psw(task)->r = 0;
107  pa_psw(task)->t = 1;
108  pa_psw(task)->h = 0;
109  pa_psw(task)->l = 0;
110 }
111 
113  unsigned long addr, unsigned long data)
114 {
115  unsigned long tmp;
116  long ret = -EIO;
117 
118  switch (request) {
119 
120  /* Read the word at location addr in the USER area. For ptraced
121  processes, the kernel saves all regs on a syscall. */
122  case PTRACE_PEEKUSR:
123  if ((addr & (sizeof(unsigned long)-1)) ||
124  addr >= sizeof(struct pt_regs))
125  break;
126  tmp = *(unsigned long *) ((char *) task_regs(child) + addr);
127  ret = put_user(tmp, (unsigned long __user *) data);
128  break;
129 
130  /* Write the word at location addr in the USER area. This will need
131  to change when the kernel no longer saves all regs on a syscall.
132  FIXME. There is a problem at the moment in that r3-r18 are only
133  saved if the process is ptraced on syscall entry, and even then
134  those values are overwritten by actual register values on syscall
135  exit. */
136  case PTRACE_POKEUSR:
137  /* Some register values written here may be ignored in
138  * entry.S:syscall_restore_rfi; e.g. iaoq is written with
139  * r31/r31+4, and not with the values in pt_regs.
140  */
141  if (addr == PT_PSW) {
142  /* Allow writing to Nullify, Divide-step-correction,
143  * and carry/borrow bits.
144  * BEWARE, if you set N, and then single step, it won't
145  * stop on the nullified instruction.
146  */
147  data &= USER_PSW_BITS;
148  task_regs(child)->gr[0] &= ~USER_PSW_BITS;
149  task_regs(child)->gr[0] |= data;
150  ret = 0;
151  break;
152  }
153 
154  if ((addr & (sizeof(unsigned long)-1)) ||
155  addr >= sizeof(struct pt_regs))
156  break;
157  if ((addr >= PT_GR1 && addr <= PT_GR31) ||
158  addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
159  (addr >= PT_FR0 && addr <= PT_FR31 + 4) ||
160  addr == PT_SAR) {
161  *(unsigned long *) ((char *) task_regs(child) + addr) = data;
162  ret = 0;
163  }
164  break;
165 
166  default:
167  ret = ptrace_request(child, request, addr, data);
168  break;
169  }
170 
171  return ret;
172 }
173 
174 
175 #ifdef CONFIG_COMPAT
176 
177 /* This function is needed to translate 32 bit pt_regs offsets in to
178  * 64 bit pt_regs offsets. For example, a 32 bit gdb under a 64 bit kernel
179  * will request offset 12 if it wants gr3, but the lower 32 bits of
180  * the 64 bit kernels view of gr3 will be at offset 28 (3*8 + 4).
181  * This code relies on a 32 bit pt_regs being comprised of 32 bit values
182  * except for the fp registers which (a) are 64 bits, and (b) follow
183  * the gr registers at the start of pt_regs. The 32 bit pt_regs should
184  * be half the size of the 64 bit pt_regs, plus 32*4 to allow for fr[]
185  * being 64 bit in both cases.
186  */
187 
188 static compat_ulong_t translate_usr_offset(compat_ulong_t offset)
189 {
190  if (offset < 0)
191  return sizeof(struct pt_regs);
192  else if (offset <= 32*4) /* gr[0..31] */
193  return offset * 2 + 4;
194  else if (offset <= 32*4+32*8) /* gr[0..31] + fr[0..31] */
195  return offset + 32*4;
196  else if (offset < sizeof(struct pt_regs)/2 + 32*4)
197  return offset * 2 + 4 - 32*8;
198  else
199  return sizeof(struct pt_regs);
200 }
201 
204 {
206  long ret = -EIO;
207 
208  switch (request) {
209 
210  case PTRACE_PEEKUSR:
211  if (addr & (sizeof(compat_uint_t)-1))
212  break;
213  addr = translate_usr_offset(addr);
214  if (addr >= sizeof(struct pt_regs))
215  break;
216 
217  tmp = *(compat_uint_t *) ((char *) task_regs(child) + addr);
218  ret = put_user(tmp, (compat_uint_t *) (unsigned long) data);
219  break;
220 
221  /* Write the word at location addr in the USER area. This will need
222  to change when the kernel no longer saves all regs on a syscall.
223  FIXME. There is a problem at the moment in that r3-r18 are only
224  saved if the process is ptraced on syscall entry, and even then
225  those values are overwritten by actual register values on syscall
226  exit. */
227  case PTRACE_POKEUSR:
228  /* Some register values written here may be ignored in
229  * entry.S:syscall_restore_rfi; e.g. iaoq is written with
230  * r31/r31+4, and not with the values in pt_regs.
231  */
232  if (addr == PT_PSW) {
233  /* Since PT_PSW==0, it is valid for 32 bit processes
234  * under 64 bit kernels as well.
235  */
236  ret = arch_ptrace(child, request, addr, data);
237  } else {
238  if (addr & (sizeof(compat_uint_t)-1))
239  break;
240  addr = translate_usr_offset(addr);
241  if (addr >= sizeof(struct pt_regs))
242  break;
243  if (addr >= PT_FR0 && addr <= PT_FR31 + 4) {
244  /* Special case, fp regs are 64 bits anyway */
245  *(__u64 *) ((char *) task_regs(child) + addr) = data;
246  ret = 0;
247  }
248  else if ((addr >= PT_GR1+4 && addr <= PT_GR31+4) ||
249  addr == PT_IAOQ0+4 || addr == PT_IAOQ1+4 ||
250  addr == PT_SAR+4) {
251  /* Zero the top 32 bits */
252  *(__u32 *) ((char *) task_regs(child) + addr - 4) = 0;
253  *(__u32 *) ((char *) task_regs(child) + addr) = data;
254  ret = 0;
255  }
256  }
257  break;
258 
259  default:
260  ret = compat_ptrace_request(child, request, addr, data);
261  break;
262  }
263 
264  return ret;
265 }
266 #endif
267 
269 {
270  if (test_thread_flag(TIF_SYSCALL_TRACE) &&
271  tracehook_report_syscall_entry(regs))
272  return -1L;
273 
274  return regs->gr[20];
275 }
276 
278 {
279  int stepping = test_thread_flag(TIF_SINGLESTEP) ||
280  test_thread_flag(TIF_BLOCKSTEP);
281 
282  if (stepping || test_thread_flag(TIF_SYSCALL_TRACE))
283  tracehook_report_syscall_exit(regs, stepping);
284 }