92b4ca0b5af6744e4afc84991c8b2084c0344e2c
[linux-2.6.git] / arch / blackfin / kernel / ptrace.c
1 /*
2  * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
3  * these modifications are Copyright 2004-2009 Analog Devices Inc.
4  *
5  * Licensed under the GPL-2
6  */
7
8 #include <linux/kernel.h>
9 #include <linux/sched.h>
10 #include <linux/mm.h>
11 #include <linux/smp.h>
12 #include <linux/elf.h>
13 #include <linux/errno.h>
14 #include <linux/ptrace.h>
15 #include <linux/user.h>
16 #include <linux/regset.h>
17 #include <linux/signal.h>
18 #include <linux/uaccess.h>
19
20 #include <asm/page.h>
21 #include <asm/pgtable.h>
22 #include <asm/system.h>
23 #include <asm/processor.h>
24 #include <asm/asm-offsets.h>
25 #include <asm/dma.h>
26 #include <asm/fixed_code.h>
27 #include <asm/cacheflush.h>
28 #include <asm/mem_map.h>
29
30 /*
31  * does not yet catch signals sent when the child dies.
32  * in exit.c or in signal.c.
33  */
34
35 /* Find the stack offset for a register, relative to thread.esp0. */
36 #define PT_REG(reg)     ((long)&((struct pt_regs *)0)->reg)
37
38 /*
39  * Get the address of the live pt_regs for the specified task.
40  * These are saved onto the top kernel stack when the process
41  * is not running.
42  *
43  * Note: if a user thread is execve'd from kernel space, the
44  * kernel stack will not be empty on entry to the kernel, so
45  * ptracing these tasks will fail.
46  */
47 static inline struct pt_regs *task_pt_regs(struct task_struct *task)
48 {
49         return (struct pt_regs *)
50             ((unsigned long)task_stack_page(task) +
51              (THREAD_SIZE - sizeof(struct pt_regs)));
52 }
53
54 /*
55  * Get contents of register REGNO in task TASK.
56  */
57 static inline long
58 get_reg(struct task_struct *task, long regno, unsigned long __user *datap)
59 {
60         long tmp;
61         struct pt_regs *regs = task_pt_regs(task);
62
63         if (regno & 3 || regno > PT_LAST_PSEUDO || regno < 0)
64                 return -EIO;
65
66         switch (regno) {
67         case PT_TEXT_ADDR:
68                 tmp = task->mm->start_code;
69                 break;
70         case PT_TEXT_END_ADDR:
71                 tmp = task->mm->end_code;
72                 break;
73         case PT_DATA_ADDR:
74                 tmp = task->mm->start_data;
75                 break;
76         case PT_USP:
77                 tmp = task->thread.usp;
78                 break;
79         default:
80                 if (regno < sizeof(*regs)) {
81                         void *reg_ptr = regs;
82                         tmp = *(long *)(reg_ptr + regno);
83                 } else
84                         return -EIO;
85         }
86
87         return put_user(tmp, datap);
88 }
89
90 /*
91  * Write contents of register REGNO in task TASK.
92  */
93 static inline int
94 put_reg(struct task_struct *task, long regno, unsigned long data)
95 {
96         struct pt_regs *regs = task_pt_regs(task);
97
98         if (regno & 3 || regno > PT_LAST_PSEUDO || regno < 0)
99                 return -EIO;
100
101         switch (regno) {
102         case PT_PC:
103                 /*********************************************************************/
104                 /* At this point the kernel is most likely in exception.             */
105                 /* The RETX register will be used to populate the pc of the process. */
106                 /*********************************************************************/
107                 regs->retx = data;
108                 regs->pc = data;
109                 break;
110         case PT_RETX:
111                 break;          /* regs->retx = data; break; */
112         case PT_USP:
113                 regs->usp = data;
114                 task->thread.usp = data;
115                 break;
116         case PT_SYSCFG: /* don't let userspace screw with this */
117                 if ((data & ~1) != 0x6)
118                         pr_warning("ptrace: ignore syscfg write of %#lx\n", data);
119                 break;          /* regs->syscfg = data; break; */
120         default:
121                 if (regno < sizeof(*regs)) {
122                         void *reg_offset = regs;
123                         *(long *)(reg_offset + regno) = data;
124                 }
125                 /* Ignore writes to pseudo registers */
126         }
127
128         return 0;
129 }
130
131 /*
132  * check that an address falls within the bounds of the target process's memory mappings
133  */
134 static inline int is_user_addr_valid(struct task_struct *child,
135                                      unsigned long start, unsigned long len)
136 {
137         struct vm_area_struct *vma;
138         struct sram_list_struct *sraml;
139
140         /* overflow */
141         if (start + len < start)
142                 return -EIO;
143
144         vma = find_vma(child->mm, start);
145         if (vma && start >= vma->vm_start && start + len <= vma->vm_end)
146                         return 0;
147
148         for (sraml = child->mm->context.sram_list; sraml; sraml = sraml->next)
149                 if (start >= (unsigned long)sraml->addr
150                     && start + len < (unsigned long)sraml->addr + sraml->length)
151                         return 0;
152
153         if (start >= FIXED_CODE_START && start + len < FIXED_CODE_END)
154                 return 0;
155
156         return -EIO;
157 }
158
159 /*
160  * retrieve the contents of Blackfin userspace general registers
161  */
162 static int genregs_get(struct task_struct *target,
163                        const struct user_regset *regset,
164                        unsigned int pos, unsigned int count,
165                        void *kbuf, void __user *ubuf)
166 {
167         struct pt_regs *regs = task_pt_regs(target);
168         int ret;
169
170         /* This sucks ... */
171         regs->usp = target->thread.usp;
172
173         ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
174                                   regs, 0, sizeof(*regs));
175         if (ret < 0)
176                 return ret;
177
178         return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
179                                         sizeof(*regs), -1);
180 }
181
182 /*
183  * update the contents of the Blackfin userspace general registers
184  */
185 static int genregs_set(struct task_struct *target,
186                        const struct user_regset *regset,
187                        unsigned int pos, unsigned int count,
188                        const void *kbuf, const void __user *ubuf)
189 {
190         struct pt_regs *regs = task_pt_regs(target);
191         int ret;
192
193         /* Don't let people set SYSCFG (it's at the end of pt_regs) */
194         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
195                                  regs, 0, PT_SYSCFG);
196         if (ret < 0)
197                 return ret;
198
199         /* This sucks ... */
200         target->thread.usp = regs->usp;
201         /* regs->retx = regs->pc; */
202
203         return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
204                                         PT_SYSCFG, -1);
205 }
206
207 /*
208  * Define the register sets available on the Blackfin under Linux
209  */
210 enum bfin_regset {
211         REGSET_GENERAL,
212 };
213
214 static const struct user_regset bfin_regsets[] = {
215         [REGSET_GENERAL] = {
216                 .core_note_type = NT_PRSTATUS,
217                 .n              = sizeof(struct pt_regs) / sizeof(long),
218                 .size           = sizeof(long),
219                 .align          = sizeof(long),
220                 .get            = genregs_get,
221                 .set            = genregs_set,
222         },
223 };
224
225 static const struct user_regset_view user_bfin_native_view = {
226         .name      = "Blackfin",
227         .e_machine = EM_BLACKFIN,
228         .regsets   = bfin_regsets,
229         .n         = ARRAY_SIZE(bfin_regsets),
230 };
231
232 const struct user_regset_view *task_user_regset_view(struct task_struct *task)
233 {
234         return &user_bfin_native_view;
235 }
236
237 void ptrace_enable(struct task_struct *child)
238 {
239         struct pt_regs *regs = task_pt_regs(child);
240         regs->syscfg |= SYSCFG_SSSTEP;
241 }
242
243 /*
244  * Called by kernel/ptrace.c when detaching..
245  *
246  * Make sure the single step bit is not set.
247  */
248 void ptrace_disable(struct task_struct *child)
249 {
250         struct pt_regs *regs = task_pt_regs(child);
251         regs->syscfg &= ~SYSCFG_SSSTEP;
252 }
253
254 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
255 {
256         int ret;
257         unsigned long __user *datap = (unsigned long __user *)data;
258         void *paddr = (void *)addr;
259
260         switch (request) {
261                 /* when I and D space are separate, these will need to be fixed. */
262         case PTRACE_PEEKDATA:
263                 pr_debug("ptrace: PEEKDATA\n");
264                 /* fall through */
265         case PTRACE_PEEKTEXT:   /* read word at location addr. */
266                 {
267                         unsigned long tmp = 0;
268                         int copied = 0, to_copy = sizeof(tmp);
269
270                         ret = -EIO;
271                         pr_debug("ptrace: PEEKTEXT at addr 0x%08lx + %i\n", addr, to_copy);
272                         if (is_user_addr_valid(child, addr, to_copy) < 0)
273                                 break;
274                         pr_debug("ptrace: user address is valid\n");
275
276                         switch (bfin_mem_access_type(addr, to_copy)) {
277                         case BFIN_MEM_ACCESS_CORE:
278                         case BFIN_MEM_ACCESS_CORE_ONLY:
279                                 copied = access_process_vm(child, addr, &tmp,
280                                                            to_copy, 0);
281                                 if (copied)
282                                         break;
283
284                                 /* hrm, why didn't that work ... maybe no mapping */
285                                 if (addr >= FIXED_CODE_START &&
286                                     addr + to_copy <= FIXED_CODE_END) {
287                                         copy_from_user_page(0, 0, 0, &tmp, paddr, to_copy);
288                                         copied = to_copy;
289                                 } else if (addr >= BOOT_ROM_START) {
290                                         memcpy(&tmp, paddr, to_copy);
291                                         copied = to_copy;
292                                 }
293
294                                 break;
295                         case BFIN_MEM_ACCESS_DMA:
296                                 if (safe_dma_memcpy(&tmp, paddr, to_copy))
297                                         copied = to_copy;
298                                 break;
299                         case BFIN_MEM_ACCESS_ITEST:
300                                 if (isram_memcpy(&tmp, paddr, to_copy))
301                                         copied = to_copy;
302                                 break;
303                         default:
304                                 copied = 0;
305                                 break;
306                         }
307
308                         pr_debug("ptrace: copied size %d [0x%08lx]\n", copied, tmp);
309                         if (copied == to_copy)
310                                 ret = put_user(tmp, datap);
311                         break;
312                 }
313
314 #ifdef CONFIG_BINFMT_ELF_FDPIC
315         case PTRACE_GETFDPIC: {
316                 unsigned long tmp = 0;
317
318                 switch (addr) {
319                 case_PTRACE_GETFDPIC_EXEC:
320                 case PTRACE_GETFDPIC_EXEC:
321                         tmp = child->mm->context.exec_fdpic_loadmap;
322                         break;
323                 case_PTRACE_GETFDPIC_INTERP:
324                 case PTRACE_GETFDPIC_INTERP:
325                         tmp = child->mm->context.interp_fdpic_loadmap;
326                         break;
327                 default:
328                         break;
329                 }
330
331                 ret = put_user(tmp, datap);
332                 break;
333         }
334 #endif
335
336                 /* when I and D space are separate, this will have to be fixed. */
337         case PTRACE_POKEDATA:
338                 pr_debug("ptrace: PTRACE_PEEKDATA\n");
339                 /* fall through */
340         case PTRACE_POKETEXT:   /* write the word at location addr. */
341                 {
342                         int copied = 0, to_copy = sizeof(data);
343
344                         ret = -EIO;
345                         pr_debug("ptrace: POKETEXT at addr 0x%08lx + %i bytes %lx\n",
346                                  addr, to_copy, data);
347                         if (is_user_addr_valid(child, addr, to_copy) < 0)
348                                 break;
349                         pr_debug("ptrace: user address is valid\n");
350
351                         switch (bfin_mem_access_type(addr, to_copy)) {
352                         case BFIN_MEM_ACCESS_CORE:
353                         case BFIN_MEM_ACCESS_CORE_ONLY:
354                                 copied = access_process_vm(child, addr, &data,
355                                                            to_copy, 1);
356                                 break;
357                         case BFIN_MEM_ACCESS_DMA:
358                                 if (safe_dma_memcpy(paddr, &data, to_copy))
359                                         copied = to_copy;
360                                 break;
361                         case BFIN_MEM_ACCESS_ITEST:
362                                 if (isram_memcpy(paddr, &data, to_copy))
363                                         copied = to_copy;
364                                 break;
365                         default:
366                                 copied = 0;
367                                 break;
368                         }
369
370                         pr_debug("ptrace: copied size %d\n", copied);
371                         if (copied == to_copy)
372                                 ret = 0;
373                         break;
374                 }
375
376         case PTRACE_PEEKUSR:
377                 switch (addr) {
378 #ifdef CONFIG_BINFMT_ELF_FDPIC  /* backwards compat */
379                 case PT_FDPIC_EXEC:   goto case_PTRACE_GETFDPIC_EXEC;
380                 case PT_FDPIC_INTERP: goto case_PTRACE_GETFDPIC_INTERP;
381 #endif
382                 default:
383                         ret = get_reg(child, addr, datap);
384                 }
385                 pr_debug("ptrace: PEEKUSR reg %li with %#lx = %i\n", addr, data, ret);
386                 break;
387
388         case PTRACE_POKEUSR:
389                 ret = put_reg(child, addr, data);
390                 pr_debug("ptrace: POKEUSR reg %li with %li = %i\n", addr, data, ret);
391                 break;
392
393         case PTRACE_GETREGS:
394                 pr_debug("ptrace: PTRACE_GETREGS\n");
395                 return copy_regset_to_user(child, &user_bfin_native_view,
396                                            REGSET_GENERAL,
397                                            0, sizeof(struct pt_regs),
398                                            (void __user *)data);
399
400         case PTRACE_SETREGS:
401                 pr_debug("ptrace: PTRACE_SETREGS\n");
402                 return copy_regset_from_user(child, &user_bfin_native_view,
403                                              REGSET_GENERAL,
404                                              0, sizeof(struct pt_regs),
405                                              (const void __user *)data);
406
407         default:
408                 ret = ptrace_request(child, request, addr, data);
409                 break;
410         }
411
412         return ret;
413 }
414
415 asmlinkage void syscall_trace(void)
416 {
417         if (!test_thread_flag(TIF_SYSCALL_TRACE))
418                 return;
419
420         if (!(current->ptrace & PT_PTRACED))
421                 return;
422
423         /* the 0x80 provides a way for the tracing parent to distinguish
424          * between a syscall stop and SIGTRAP delivery
425          */
426         ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
427                                  ? 0x80 : 0));
428
429         /*
430          * this isn't the same as continuing with a signal, but it will do
431          * for normal use.  strace only continues with a signal if the
432          * stopping signal is not SIGTRAP.  -brl
433          */
434         if (current->exit_code) {
435                 send_sig(current->exit_code, current, 1);
436                 current->exit_code = 0;
437         }
438 }