[BACK]Return to linux_ptrace.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / compat / linux / arch / arm

Annotation of src/sys/compat/linux/arch/arm/linux_ptrace.c, Revision 1.7

1.7     ! ad          1: /*     $NetBSD: linux_ptrace.c,v 1.6 2006/09/01 21:20:46 matt Exp $    */
1.2       bjh21       2:
                      3: /*-
                      4:  * Copyright (c) 1999 The NetBSD Foundation, Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
                      8:  * by Matthias Scheler.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
                     20:  *     This product includes software developed by the NetBSD
                     21:  *     Foundation, Inc. and its contributors.
                     22:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     23:  *    contributors may be used to endorse or promote products derived
                     24:  *    from this software without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     27:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     28:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     29:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     30:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     31:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     32:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     33:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     34:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     35:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     36:  * POSSIBILITY OF SUCH DAMAGE.
                     37:  */
                     38:
                     39:
                     40: #include <sys/cdefs.h>
1.7     ! ad         41: __KERNEL_RCSID(0, "$NetBSD: linux_ptrace.c,v 1.6 2006/09/01 21:20:46 matt Exp $");
1.1       bjh21      42:
                     43: #include <sys/param.h>
1.2       bjh21      44: #include <sys/malloc.h>
                     45: #include <sys/mount.h>
                     46: #include <sys/proc.h>
                     47: #include <sys/ptrace.h>
                     48: #include <sys/systm.h>
                     49: #include <sys/syscallargs.h>
                     50: #include <uvm/uvm_extern.h>
                     51:
                     52: #include <machine/reg.h>
                     53:
                     54: #include <compat/linux/common/linux_types.h>
                     55: #include <compat/linux/common/linux_ptrace.h>
                     56: #include <compat/linux/common/linux_signal.h>
                     57:
                     58: #include <compat/linux/common/linux_util.h>
                     59: #include <compat/linux/common/linux_machdep.h>
                     60: #include <compat/linux/common/linux_emuldata.h>
                     61: #include <compat/linux/common/linux_exec.h>    /* for emul_linux */
                     62:
                     63: #include <compat/linux/linux_syscallargs.h>
1.1       bjh21      64:
1.2       bjh21      65: #include <lib/libkern/libkern.h>       /* for offsetof() */
1.1       bjh21      66:
1.2       bjh21      67: /*
                     68:  * On ARMv2, uregs contains R0--R15, orig_R0.
                     69:  * On ARMv3 and later, it's R0--R15, CPSR, orig_R0.
                     70:  * As far as I can see, Linux doesn't initialise orig_R0 on ARMv2, so we
                     71:  * just produce the ARMv3 version.
                     72:  */
                     73:
                     74: struct linux_reg {
                     75:        long uregs[18];
                     76: };
                     77:
                     78: #define LINUX_REG_R0   0
                     79: #define LINUX_REG_R1   1
                     80: #define LINUX_REG_R2   2
                     81: #define LINUX_REG_R3   3
                     82: #define LINUX_REG_R4   4
                     83: #define LINUX_REG_R5   5
                     84: #define LINUX_REG_R6   6
                     85: #define LINUX_REG_R7   7
                     86: #define LINUX_REG_R8   8
                     87: #define LINUX_REG_R9   9
                     88: #define LINUX_REG_R10  10
                     89: #define LINUX_REG_FP   11
                     90: #define LINUX_REG_IP   12
                     91: #define LINUX_REG_SP   13
                     92: #define LINUX_REG_LR   14
                     93: #define LINUX_REG_PC   15
                     94: #define LINUX_REG_CPSR 16
                     95: #define LINUX_REG_ORIG_R0 17
                     96:
1.1       bjh21      97: int
1.3       thorpej    98: linux_sys_ptrace_arch(l, v, retval)
                     99:        struct lwp *l;
1.1       bjh21     100:        void *v;
                    101:        register_t *retval;
                    102: {
1.2       bjh21     103:        struct linux_sys_ptrace_args /* {
                    104:                syscallarg(int) request;
                    105:                syscallarg(int) pid;
                    106:                syscallarg(int) addr;
                    107:                syscallarg(int) data;
                    108:        } */ *uap = v;
1.3       thorpej   109:        struct proc *p = l->l_proc;
1.2       bjh21     110:        int request, error;
                    111:        struct proc *t;                         /* target process */
1.3       thorpej   112:        struct lwp *lt;
1.2       bjh21     113:        struct reg *regs = NULL;
                    114:        struct fpreg *fpregs = NULL;
                    115:        struct linux_reg *linux_regs = NULL;
                    116:        struct linux_fpreg *linux_fpregs = NULL;
                    117:
                    118:        request = SCARG(uap, request);
                    119:
                    120:        if ((request != LINUX_PTRACE_GETREGS) &&
                    121:            (request != LINUX_PTRACE_SETREGS))
                    122:                return EIO;
                    123:
                    124:        /* Find the process we're supposed to be operating on. */
                    125:        if ((t = pfind(SCARG(uap, pid))) == NULL)
                    126:                return ESRCH;
                    127:
                    128:        /*
                    129:         * You can't do what you want to the process if:
                    130:         *      (1) It's not being traced at all,
                    131:         */
                    132:        if (!ISSET(t->p_flag, P_TRACED))
                    133:                return EPERM;
                    134:
                    135:        /*
                    136:         *      (2) it's being traced by procfs (which has
                    137:         *          different signal delivery semantics),
                    138:         */
                    139:        if (ISSET(t->p_flag, P_FSTRACE))
                    140:                return EBUSY;
                    141:
                    142:        /*
                    143:         *      (3) it's not being traced by _you_, or
                    144:         */
                    145:        if (t->p_pptr != p)
                    146:                return EBUSY;
                    147:
                    148:        /*
                    149:         *      (4) it's not currently stopped.
                    150:         */
                    151:        if (t->p_stat != SSTOP || !ISSET(t->p_flag, P_WAITED))
                    152:                return EBUSY;
                    153:
1.3       thorpej   154:        /* XXX NJWLWP
                    155:         * The entire ptrace interface needs work to be useful to
                    156:         * a process with multiple LWPs. For the moment, we'll
                    157:         * just kluge this and fail on others.
                    158:         */
                    159:
                    160:        if (p->p_nlwps > 1)
                    161:                return (ENOSYS);
                    162:
                    163:        lt = LIST_FIRST(&t->p_lwps);
                    164:
1.2       bjh21     165:        *retval = 0;
                    166:
                    167:        switch (request) {
                    168:        case  LINUX_PTRACE_GETREGS:
                    169:                MALLOC(regs, struct reg*, sizeof(struct reg), M_TEMP, M_WAITOK);
                    170:                MALLOC(linux_regs, struct linux_reg*, sizeof(struct linux_reg),
                    171:                        M_TEMP, M_WAITOK);
                    172:
1.3       thorpej   173:                error = process_read_regs(lt, regs);
1.2       bjh21     174:                if (error != 0)
                    175:                        goto out;
                    176:
                    177:                memcpy(linux_regs->uregs, regs->r, 13 * sizeof(register_t));
                    178:                linux_regs->uregs[LINUX_REG_SP] = regs->r_sp;
                    179:                linux_regs->uregs[LINUX_REG_LR] = regs->r_lr;
                    180:                linux_regs->uregs[LINUX_REG_PC] = regs->r_pc;
                    181:                linux_regs->uregs[LINUX_REG_CPSR] = regs->r_cpsr;
                    182:                linux_regs->uregs[LINUX_REG_ORIG_R0] = regs->r[0];
                    183:
                    184:                error = copyout(linux_regs, (caddr_t)SCARG(uap, data),
                    185:                    sizeof(struct linux_reg));
                    186:                goto out;
                    187:
                    188:        case  LINUX_PTRACE_SETREGS:
                    189:                MALLOC(regs, struct reg*, sizeof(struct reg), M_TEMP, M_WAITOK);
                    190:                MALLOC(linux_regs, struct linux_reg *, sizeof(struct linux_reg),
                    191:                        M_TEMP, M_WAITOK);
                    192:
                    193:                error = copyin((caddr_t)SCARG(uap, data), linux_regs,
                    194:                    sizeof(struct linux_reg));
                    195:                if (error != 0)
                    196:                        goto out;
                    197:
                    198:                memcpy(regs->r, linux_regs->uregs, 13 * sizeof(register_t));
                    199:                regs->r_sp = linux_regs->uregs[LINUX_REG_SP];
                    200:                regs->r_lr = linux_regs->uregs[LINUX_REG_LR];
                    201:                regs->r_pc = linux_regs->uregs[LINUX_REG_PC];
                    202:                regs->r_cpsr = linux_regs->uregs[LINUX_REG_CPSR];
                    203:
1.3       thorpej   204:                error = process_write_regs(lt, regs);
1.2       bjh21     205:                goto out;
                    206:
                    207:        default:
                    208:                /* never reached */
                    209:                break;
                    210:        }
                    211:
                    212:        return EIO;
                    213:
                    214:     out:
                    215:        if (regs)
                    216:                FREE(regs, M_TEMP);
                    217:        if (fpregs)
                    218:                FREE(fpregs, M_TEMP);
                    219:        if (linux_regs)
                    220:                FREE(linux_regs, M_TEMP);
                    221:        if (linux_fpregs)
                    222:                FREE(linux_fpregs, M_TEMP);
                    223:        return (error);
1.1       bjh21     224:
                    225: }

CVSweb <webmaster@jp.NetBSD.org>