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>