OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [powerpc/] [kernel/] [ptrace.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 *  PowerPC version
3
 *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
4
 *
5
 *  Derived from "arch/m68k/kernel/ptrace.c"
6
 *  Copyright (C) 1994 by Hamish Macdonald
7
 *  Taken from linux/kernel/ptrace.c and modified for M680x0.
8
 *  linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
9
 *
10
 * Modified by Cort Dougan (cort@hq.fsmlabs.com)
11
 * and Paul Mackerras (paulus@samba.org).
12
 *
13
 * This file is subject to the terms and conditions of the GNU General
14
 * Public License.  See the file README.legal in the main directory of
15
 * this archive for more details.
16
 */
17
 
18
#include <linux/kernel.h>
19
#include <linux/sched.h>
20
#include <linux/mm.h>
21
#include <linux/smp.h>
22
#include <linux/errno.h>
23
#include <linux/ptrace.h>
24
#include <linux/user.h>
25
#include <linux/security.h>
26
#include <linux/signal.h>
27
#include <linux/seccomp.h>
28
#include <linux/audit.h>
29
#ifdef CONFIG_PPC32
30
#include <linux/module.h>
31
#endif
32
 
33
#include <asm/uaccess.h>
34
#include <asm/page.h>
35
#include <asm/pgtable.h>
36
#include <asm/system.h>
37
 
38
/*
39
 * does not yet catch signals sent when the child dies.
40
 * in exit.c or in signal.c.
41
 */
42
 
43
/*
44
 * Set of msr bits that gdb can change on behalf of a process.
45
 */
46
#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
47
#define MSR_DEBUGCHANGE 0
48
#else
49
#define MSR_DEBUGCHANGE (MSR_SE | MSR_BE)
50
#endif
51
 
52
/*
53
 * Max register writeable via put_reg
54
 */
55
#ifdef CONFIG_PPC32
56
#define PT_MAX_PUT_REG  PT_MQ
57
#else
58
#define PT_MAX_PUT_REG  PT_CCR
59
#endif
60
 
61
/*
62
 * Get contents of register REGNO in task TASK.
63
 */
64
unsigned long ptrace_get_reg(struct task_struct *task, int regno)
65
{
66
        unsigned long tmp = 0;
67
 
68
        if (task->thread.regs == NULL)
69
                return -EIO;
70
 
71
        if (regno == PT_MSR) {
72
                tmp = ((unsigned long *)task->thread.regs)[PT_MSR];
73
                return tmp | task->thread.fpexc_mode;
74
        }
75
 
76
        if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long)))
77
                return ((unsigned long *)task->thread.regs)[regno];
78
 
79
        return -EIO;
80
}
81
 
82
/*
83
 * Write contents of register REGNO in task TASK.
84
 */
85
int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data)
86
{
87
        if (task->thread.regs == NULL)
88
                return -EIO;
89
 
90
        if (regno <= PT_MAX_PUT_REG || regno == PT_TRAP) {
91
                if (regno == PT_MSR)
92
                        data = (data & MSR_DEBUGCHANGE)
93
                                | (task->thread.regs->msr & ~MSR_DEBUGCHANGE);
94
                /* We prevent mucking around with the reserved area of trap
95
                 * which are used internally by the kernel
96
                 */
97
                if (regno == PT_TRAP)
98
                        data &= 0xfff0;
99
                ((unsigned long *)task->thread.regs)[regno] = data;
100
                return 0;
101
        }
102
        return -EIO;
103
}
104
 
105
 
106
static int get_fpregs(void __user *data, struct task_struct *task,
107
                      int has_fpscr)
108
{
109
        unsigned int count = has_fpscr ? 33 : 32;
110
 
111
        if (copy_to_user(data, task->thread.fpr, count * sizeof(double)))
112
                return -EFAULT;
113
        return 0;
114
}
115
 
116
static int set_fpregs(void __user *data, struct task_struct *task,
117
                      int has_fpscr)
118
{
119
        unsigned int count = has_fpscr ? 33 : 32;
120
 
121
        if (copy_from_user(task->thread.fpr, data, count * sizeof(double)))
122
                return -EFAULT;
123
        return 0;
124
}
125
 
126
 
127
#ifdef CONFIG_ALTIVEC
128
/*
129
 * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
130
 * The transfer totals 34 quadword.  Quadwords 0-31 contain the
131
 * corresponding vector registers.  Quadword 32 contains the vscr as the
132
 * last word (offset 12) within that quadword.  Quadword 33 contains the
133
 * vrsave as the first word (offset 0) within the quadword.
134
 *
135
 * This definition of the VMX state is compatible with the current PPC32
136
 * ptrace interface.  This allows signal handling and ptrace to use the
137
 * same structures.  This also simplifies the implementation of a bi-arch
138
 * (combined (32- and 64-bit) gdb.
139
 */
140
 
141
/*
142
 * Get contents of AltiVec register state in task TASK
143
 */
144
static int get_vrregs(unsigned long __user *data, struct task_struct *task)
145
{
146
        unsigned long regsize;
147
 
148
        /* copy AltiVec registers VR[0] .. VR[31] */
149
        regsize = 32 * sizeof(vector128);
150
        if (copy_to_user(data, task->thread.vr, regsize))
151
                return -EFAULT;
152
        data += (regsize / sizeof(unsigned long));
153
 
154
        /* copy VSCR */
155
        regsize = 1 * sizeof(vector128);
156
        if (copy_to_user(data, &task->thread.vscr, regsize))
157
                return -EFAULT;
158
        data += (regsize / sizeof(unsigned long));
159
 
160
        /* copy VRSAVE */
161
        if (put_user(task->thread.vrsave, (u32 __user *)data))
162
                return -EFAULT;
163
 
164
        return 0;
165
}
166
 
167
/*
168
 * Write contents of AltiVec register state into task TASK.
169
 */
170
static int set_vrregs(struct task_struct *task, unsigned long __user *data)
171
{
172
        unsigned long regsize;
173
 
174
        /* copy AltiVec registers VR[0] .. VR[31] */
175
        regsize = 32 * sizeof(vector128);
176
        if (copy_from_user(task->thread.vr, data, regsize))
177
                return -EFAULT;
178
        data += (regsize / sizeof(unsigned long));
179
 
180
        /* copy VSCR */
181
        regsize = 1 * sizeof(vector128);
182
        if (copy_from_user(&task->thread.vscr, data, regsize))
183
                return -EFAULT;
184
        data += (regsize / sizeof(unsigned long));
185
 
186
        /* copy VRSAVE */
187
        if (get_user(task->thread.vrsave, (u32 __user *)data))
188
                return -EFAULT;
189
 
190
        return 0;
191
}
192
#endif /* CONFIG_ALTIVEC */
193
 
194
#ifdef CONFIG_SPE
195
 
196
/*
197
 * For get_evrregs/set_evrregs functions 'data' has the following layout:
198
 *
199
 * struct {
200
 *   u32 evr[32];
201
 *   u64 acc;
202
 *   u32 spefscr;
203
 * }
204
 */
205
 
206
/*
207
 * Get contents of SPE register state in task TASK.
208
 */
209
static int get_evrregs(unsigned long *data, struct task_struct *task)
210
{
211
        int i;
212
 
213
        if (!access_ok(VERIFY_WRITE, data, 35 * sizeof(unsigned long)))
214
                return -EFAULT;
215
 
216
        /* copy SPEFSCR */
217
        if (__put_user(task->thread.spefscr, &data[34]))
218
                return -EFAULT;
219
 
220
        /* copy SPE registers EVR[0] .. EVR[31] */
221
        for (i = 0; i < 32; i++, data++)
222
                if (__put_user(task->thread.evr[i], data))
223
                        return -EFAULT;
224
 
225
        /* copy ACC */
226
        if (__put_user64(task->thread.acc, (unsigned long long *)data))
227
                return -EFAULT;
228
 
229
        return 0;
230
}
231
 
232
/*
233
 * Write contents of SPE register state into task TASK.
234
 */
235
static int set_evrregs(struct task_struct *task, unsigned long *data)
236
{
237
        int i;
238
 
239
        if (!access_ok(VERIFY_READ, data, 35 * sizeof(unsigned long)))
240
                return -EFAULT;
241
 
242
        /* copy SPEFSCR */
243
        if (__get_user(task->thread.spefscr, &data[34]))
244
                return -EFAULT;
245
 
246
        /* copy SPE registers EVR[0] .. EVR[31] */
247
        for (i = 0; i < 32; i++, data++)
248
                if (__get_user(task->thread.evr[i], data))
249
                        return -EFAULT;
250
        /* copy ACC */
251
        if (__get_user64(task->thread.acc, (unsigned long long*)data))
252
                return -EFAULT;
253
 
254
        return 0;
255
}
256
#endif /* CONFIG_SPE */
257
 
258
 
259
static void set_single_step(struct task_struct *task)
260
{
261
        struct pt_regs *regs = task->thread.regs;
262
 
263
        if (regs != NULL) {
264
#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
265
                task->thread.dbcr0 = DBCR0_IDM | DBCR0_IC;
266
                regs->msr |= MSR_DE;
267
#else
268
                regs->msr |= MSR_SE;
269
#endif
270
        }
271
        set_tsk_thread_flag(task, TIF_SINGLESTEP);
272
}
273
 
274
static void clear_single_step(struct task_struct *task)
275
{
276
        struct pt_regs *regs = task->thread.regs;
277
 
278
        if (regs != NULL) {
279
#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
280
                task->thread.dbcr0 = 0;
281
                regs->msr &= ~MSR_DE;
282
#else
283
                regs->msr &= ~MSR_SE;
284
#endif
285
        }
286
        clear_tsk_thread_flag(task, TIF_SINGLESTEP);
287
}
288
 
289
static int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
290
                               unsigned long data)
291
{
292
        /* We only support one DABR and no IABRS at the moment */
293
        if (addr > 0)
294
                return -EINVAL;
295
 
296
        /* The bottom 3 bits are flags */
297
        if ((data & ~0x7UL) >= TASK_SIZE)
298
                return -EIO;
299
 
300
        /* Ensure translation is on */
301
        if (data && !(data & DABR_TRANSLATION))
302
                return -EIO;
303
 
304
        task->thread.dabr = data;
305
        return 0;
306
}
307
 
308
/*
309
 * Called by kernel/ptrace.c when detaching..
310
 *
311
 * Make sure single step bits etc are not set.
312
 */
313
void ptrace_disable(struct task_struct *child)
314
{
315
        /* make sure the single step bit is not set. */
316
        clear_single_step(child);
317
}
318
 
319
/*
320
 * Here are the old "legacy" powerpc specific getregs/setregs ptrace calls,
321
 * we mark them as obsolete now, they will be removed in a future version
322
 */
323
static long arch_ptrace_old(struct task_struct *child, long request, long addr,
324
                            long data)
325
{
326
        int ret = -EPERM;
327
 
328
        switch(request) {
329
        case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
330
                int i;
331
                unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
332
                unsigned long __user *tmp = (unsigned long __user *)addr;
333
 
334
                CHECK_FULL_REGS(child->thread.regs);
335
                for (i = 0; i < 32; i++) {
336
                        ret = put_user(*reg, tmp);
337
                        if (ret)
338
                                break;
339
                        reg++;
340
                        tmp++;
341
                }
342
                break;
343
        }
344
 
345
        case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
346
                int i;
347
                unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
348
                unsigned long __user *tmp = (unsigned long __user *)addr;
349
 
350
                CHECK_FULL_REGS(child->thread.regs);
351
                for (i = 0; i < 32; i++) {
352
                        ret = get_user(*reg, tmp);
353
                        if (ret)
354
                                break;
355
                        reg++;
356
                        tmp++;
357
                }
358
                break;
359
        }
360
 
361
        case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
362
                flush_fp_to_thread(child);
363
                ret = get_fpregs((void __user *)addr, child, 0);
364
                break;
365
        }
366
 
367
        case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
368
                flush_fp_to_thread(child);
369
                ret = set_fpregs((void __user *)addr, child, 0);
370
                break;
371
        }
372
 
373
        }
374
        return ret;
375
}
376
 
377
long arch_ptrace(struct task_struct *child, long request, long addr, long data)
378
{
379
        int ret = -EPERM;
380
 
381
        switch (request) {
382
        /* when I and D space are separate, these will need to be fixed. */
383
        case PTRACE_PEEKTEXT: /* read word at location addr. */
384
        case PTRACE_PEEKDATA:
385
                ret = generic_ptrace_peekdata(child, addr, data);
386
                break;
387
 
388
        /* read the word at location addr in the USER area. */
389
        case PTRACE_PEEKUSR: {
390
                unsigned long index, tmp;
391
 
392
                ret = -EIO;
393
                /* convert to index and check */
394
#ifdef CONFIG_PPC32
395
                index = (unsigned long) addr >> 2;
396
                if ((addr & 3) || (index > PT_FPSCR)
397
                    || (child->thread.regs == NULL))
398
#else
399
                index = (unsigned long) addr >> 3;
400
                if ((addr & 7) || (index > PT_FPSCR))
401
#endif
402
                        break;
403
 
404
                CHECK_FULL_REGS(child->thread.regs);
405
                if (index < PT_FPR0) {
406
                        tmp = ptrace_get_reg(child, (int) index);
407
                } else {
408
                        flush_fp_to_thread(child);
409
                        tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
410
                }
411
                ret = put_user(tmp,(unsigned long __user *) data);
412
                break;
413
        }
414
 
415
        /* If I and D space are separate, this will have to be fixed. */
416
        case PTRACE_POKETEXT: /* write the word at location addr. */
417
        case PTRACE_POKEDATA:
418
                ret = generic_ptrace_pokedata(child, addr, data);
419
                break;
420
 
421
        /* write the word at location addr in the USER area */
422
        case PTRACE_POKEUSR: {
423
                unsigned long index;
424
 
425
                ret = -EIO;
426
                /* convert to index and check */
427
#ifdef CONFIG_PPC32
428
                index = (unsigned long) addr >> 2;
429
                if ((addr & 3) || (index > PT_FPSCR)
430
                    || (child->thread.regs == NULL))
431
#else
432
                index = (unsigned long) addr >> 3;
433
                if ((addr & 7) || (index > PT_FPSCR))
434
#endif
435
                        break;
436
 
437
                CHECK_FULL_REGS(child->thread.regs);
438
                if (index < PT_FPR0) {
439
                        ret = ptrace_put_reg(child, index, data);
440
                } else {
441
                        flush_fp_to_thread(child);
442
                        ((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
443
                        ret = 0;
444
                }
445
                break;
446
        }
447
 
448
        case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
449
        case PTRACE_CONT: { /* restart after signal. */
450
                ret = -EIO;
451
                if (!valid_signal(data))
452
                        break;
453
                if (request == PTRACE_SYSCALL)
454
                        set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
455
                else
456
                        clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
457
                child->exit_code = data;
458
                /* make sure the single step bit is not set. */
459
                clear_single_step(child);
460
                wake_up_process(child);
461
                ret = 0;
462
                break;
463
        }
464
 
465
/*
466
 * make the child exit.  Best I can do is send it a sigkill.
467
 * perhaps it should be put in the status that it wants to
468
 * exit.
469
 */
470
        case PTRACE_KILL: {
471
                ret = 0;
472
                if (child->exit_state == EXIT_ZOMBIE)   /* already dead */
473
                        break;
474
                child->exit_code = SIGKILL;
475
                /* make sure the single step bit is not set. */
476
                clear_single_step(child);
477
                wake_up_process(child);
478
                break;
479
        }
480
 
481
        case PTRACE_SINGLESTEP: {  /* set the trap flag. */
482
                ret = -EIO;
483
                if (!valid_signal(data))
484
                        break;
485
                clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
486
                set_single_step(child);
487
                child->exit_code = data;
488
                /* give it a chance to run. */
489
                wake_up_process(child);
490
                ret = 0;
491
                break;
492
        }
493
 
494
        case PTRACE_GET_DEBUGREG: {
495
                ret = -EINVAL;
496
                /* We only support one DABR and no IABRS at the moment */
497
                if (addr > 0)
498
                        break;
499
                ret = put_user(child->thread.dabr,
500
                               (unsigned long __user *)data);
501
                break;
502
        }
503
 
504
        case PTRACE_SET_DEBUGREG:
505
                ret = ptrace_set_debugreg(child, addr, data);
506
                break;
507
 
508
#ifdef CONFIG_PPC64
509
        case PTRACE_GETREGS64:
510
#endif
511
        case PTRACE_GETREGS: { /* Get all pt_regs from the child. */
512
                int ui;
513
                if (!access_ok(VERIFY_WRITE, (void __user *)data,
514
                               sizeof(struct pt_regs))) {
515
                        ret = -EIO;
516
                        break;
517
                }
518
                CHECK_FULL_REGS(child->thread.regs);
519
                ret = 0;
520
                for (ui = 0; ui < PT_REGS_COUNT; ui ++) {
521
                        ret |= __put_user(ptrace_get_reg(child, ui),
522
                                          (unsigned long __user *) data);
523
                        data += sizeof(long);
524
                }
525
                break;
526
        }
527
 
528
#ifdef CONFIG_PPC64
529
        case PTRACE_SETREGS64:
530
#endif
531
        case PTRACE_SETREGS: { /* Set all gp regs in the child. */
532
                unsigned long tmp;
533
                int ui;
534
                if (!access_ok(VERIFY_READ, (void __user *)data,
535
                               sizeof(struct pt_regs))) {
536
                        ret = -EIO;
537
                        break;
538
                }
539
                CHECK_FULL_REGS(child->thread.regs);
540
                ret = 0;
541
                for (ui = 0; ui < PT_REGS_COUNT; ui ++) {
542
                        ret = __get_user(tmp, (unsigned long __user *) data);
543
                        if (ret)
544
                                break;
545
                        ptrace_put_reg(child, ui, tmp);
546
                        data += sizeof(long);
547
                }
548
                break;
549
        }
550
 
551
        case PTRACE_GETFPREGS: { /* Get the child FPU state (FPR0...31 + FPSCR) */
552
                flush_fp_to_thread(child);
553
                ret = get_fpregs((void __user *)data, child, 1);
554
                break;
555
        }
556
 
557
        case PTRACE_SETFPREGS: { /* Set the child FPU state (FPR0...31 + FPSCR) */
558
                flush_fp_to_thread(child);
559
                ret = set_fpregs((void __user *)data, child, 1);
560
                break;
561
        }
562
 
563
#ifdef CONFIG_ALTIVEC
564
        case PTRACE_GETVRREGS:
565
                /* Get the child altivec register state. */
566
                flush_altivec_to_thread(child);
567
                ret = get_vrregs((unsigned long __user *)data, child);
568
                break;
569
 
570
        case PTRACE_SETVRREGS:
571
                /* Set the child altivec register state. */
572
                flush_altivec_to_thread(child);
573
                ret = set_vrregs(child, (unsigned long __user *)data);
574
                break;
575
#endif
576
#ifdef CONFIG_SPE
577
        case PTRACE_GETEVRREGS:
578
                /* Get the child spe register state. */
579
                flush_spe_to_thread(child);
580
                ret = get_evrregs((unsigned long __user *)data, child);
581
                break;
582
 
583
        case PTRACE_SETEVRREGS:
584
                /* Set the child spe register state. */
585
                /* this is to clear the MSR_SPE bit to force a reload
586
                 * of register state from memory */
587
                flush_spe_to_thread(child);
588
                ret = set_evrregs(child, (unsigned long __user *)data);
589
                break;
590
#endif
591
 
592
        /* Old reverse args ptrace callss */
593
        case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */
594
        case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */
595
        case PPC_PTRACE_GETFPREGS: /* Get FPRs 0 - 31. */
596
        case PPC_PTRACE_SETFPREGS: /* Get FPRs 0 - 31. */
597
                ret = arch_ptrace_old(child, request, addr, data);
598
                break;
599
 
600
        default:
601
                ret = ptrace_request(child, request, addr, data);
602
                break;
603
        }
604
        return ret;
605
}
606
 
607
static void do_syscall_trace(void)
608
{
609
        /* the 0x80 provides a way for the tracing parent to distinguish
610
           between a syscall stop and SIGTRAP delivery */
611
        ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
612
                                 ? 0x80 : 0));
613
 
614
        /*
615
         * this isn't the same as continuing with a signal, but it will do
616
         * for normal use.  strace only continues with a signal if the
617
         * stopping signal is not SIGTRAP.  -brl
618
         */
619
        if (current->exit_code) {
620
                send_sig(current->exit_code, current, 1);
621
                current->exit_code = 0;
622
        }
623
}
624
 
625
void do_syscall_trace_enter(struct pt_regs *regs)
626
{
627
        secure_computing(regs->gpr[0]);
628
 
629
        if (test_thread_flag(TIF_SYSCALL_TRACE)
630
            && (current->ptrace & PT_PTRACED))
631
                do_syscall_trace();
632
 
633
        if (unlikely(current->audit_context)) {
634
#ifdef CONFIG_PPC64
635
                if (!test_thread_flag(TIF_32BIT))
636
                        audit_syscall_entry(AUDIT_ARCH_PPC64,
637
                                            regs->gpr[0],
638
                                            regs->gpr[3], regs->gpr[4],
639
                                            regs->gpr[5], regs->gpr[6]);
640
                else
641
#endif
642
                        audit_syscall_entry(AUDIT_ARCH_PPC,
643
                                            regs->gpr[0],
644
                                            regs->gpr[3] & 0xffffffff,
645
                                            regs->gpr[4] & 0xffffffff,
646
                                            regs->gpr[5] & 0xffffffff,
647
                                            regs->gpr[6] & 0xffffffff);
648
        }
649
}
650
 
651
void do_syscall_trace_leave(struct pt_regs *regs)
652
{
653
        if (unlikely(current->audit_context))
654
                audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
655
                                   regs->result);
656
 
657
        if ((test_thread_flag(TIF_SYSCALL_TRACE)
658
             || test_thread_flag(TIF_SINGLESTEP))
659
            && (current->ptrace & PT_PTRACED))
660
                do_syscall_trace();
661
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.