xref: /netbsd-src/sys/arch/sh3/sh3/process_machdep.c (revision 8e8fe15a7482795c20af5644062a8c10f18a10fa)
1 /*	$NetBSD: process_machdep.c,v 1.25 2020/10/19 17:47:37 christos Exp $	*/
2 
3 /*
4  * Copyright (c) 1993 The Regents of the University of California.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Jan-Simon Pendry.
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. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  * From:
35  *	Id: procfs_i386.c,v 4.1 1993/12/17 10:47:45 jsp Rel
36  */
37 
38 /*
39  * Copyright (c) 1995, 1996, 1997
40  *	Charles M. Hannum.  All rights reserved.
41  * Copyright (c) 1993 Jan-Simon Pendry
42  * All rights reserved.
43  *
44  * This code is derived from software contributed to Berkeley by
45  * Jan-Simon Pendry.
46  *
47  * Redistribution and use in source and binary forms, with or without
48  * modification, are permitted provided that the following conditions
49  * are met:
50  * 1. Redistributions of source code must retain the above copyright
51  *    notice, this list of conditions and the following disclaimer.
52  * 2. Redistributions in binary form must reproduce the above copyright
53  *    notice, this list of conditions and the following disclaimer in the
54  *    documentation and/or other materials provided with the distribution.
55  * 3. All advertising materials mentioning features or use of this software
56  *    must display the following acknowledgement:
57  *	This product includes software developed by the University of
58  *	California, Berkeley and its contributors.
59  * 4. Neither the name of the University nor the names of its contributors
60  *    may be used to endorse or promote products derived from this software
61  *    without specific prior written permission.
62  *
63  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
64  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
65  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
66  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
67  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
68  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
69  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
70  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
71  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
72  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
73  * SUCH DAMAGE.
74  *
75  * From:
76  *	Id: procfs_i386.c,v 4.1 1993/12/17 10:47:45 jsp Rel
77  */
78 
79 #include <sys/cdefs.h>
80 __KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.25 2020/10/19 17:47:37 christos Exp $");
81 
82 #ifdef _KERNEL_OPT
83 #include "opt_compat_netbsd.h"
84 #include "opt_ptrace.h"
85 #endif
86 
87 #include <sys/param.h>
88 #include <sys/systm.h>
89 #include <sys/time.h>
90 #include <sys/kernel.h>
91 #include <sys/proc.h>
92 #include <sys/vnode.h>
93 #include <sys/ptrace.h>
94 
95 #include <machine/psl.h>
96 #include <machine/reg.h>
97 
98 #ifdef COMPAT_40
99 static int process_machdep_doregs40(struct lwp *, struct lwp *, struct uio *);
100 static int process_machdep_read_regs40(struct lwp *l, struct __reg40 *);
101 static int process_machdep_write_regs40(struct lwp *l, struct __reg40 *);
102 #endif /* COMPAT_40 */
103 
104 
105 static inline struct trapframe *
process_frame(struct lwp * l)106 process_frame(struct lwp *l)
107 {
108 
109 	return (l->l_md.md_regs);
110 }
111 
112 int
process_read_regs(struct lwp * l,struct reg * regs)113 process_read_regs(struct lwp *l, struct reg *regs)
114 {
115 	struct trapframe *tf = process_frame(l);
116 
117 	regs->r_spc = tf->tf_spc;
118 	regs->r_ssr = tf->tf_ssr;
119 	regs->r_gbr = tf->tf_gbr;
120 	regs->r_macl = tf->tf_macl;
121 	regs->r_mach = tf->tf_mach;
122 	regs->r_pr = tf->tf_pr;
123 	regs->r_r14 = tf->tf_r14;
124 	regs->r_r13 = tf->tf_r13;
125 	regs->r_r12 = tf->tf_r12;
126 	regs->r_r11 = tf->tf_r11;
127 	regs->r_r10 = tf->tf_r10;
128 	regs->r_r9 = tf->tf_r9;
129 	regs->r_r8 = tf->tf_r8;
130 	regs->r_r7 = tf->tf_r7;
131 	regs->r_r6 = tf->tf_r6;
132 	regs->r_r5 = tf->tf_r5;
133 	regs->r_r4 = tf->tf_r4;
134 	regs->r_r3 = tf->tf_r3;
135 	regs->r_r2 = tf->tf_r2;
136 	regs->r_r1 = tf->tf_r1;
137 	regs->r_r0 = tf->tf_r0;
138 	regs->r_r15 = tf->tf_r15;
139 
140 	return (0);
141 }
142 
143 #ifdef PTRACE_HOOKS
144 
145 int
process_write_regs(struct lwp * l,const struct reg * regs)146 process_write_regs(struct lwp *l, const struct reg *regs)
147 {
148 	struct trapframe *tf = process_frame(l);
149 
150 	/*
151 	 * Check for security violations.
152 	 */
153 	if (((regs->r_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0) {
154 		return (EINVAL);
155 	}
156 
157 	tf->tf_spc = regs->r_spc;
158 	tf->tf_ssr = regs->r_ssr;
159 	tf->tf_pr = regs->r_pr;
160 
161 	tf->tf_gbr = regs->r_gbr;
162 	tf->tf_mach = regs->r_mach;
163 	tf->tf_macl = regs->r_macl;
164 	tf->tf_r14 = regs->r_r14;
165 	tf->tf_r13 = regs->r_r13;
166 	tf->tf_r12 = regs->r_r12;
167 	tf->tf_r11 = regs->r_r11;
168 	tf->tf_r10 = regs->r_r10;
169 	tf->tf_r9 = regs->r_r9;
170 	tf->tf_r8 = regs->r_r8;
171 	tf->tf_r7 = regs->r_r7;
172 	tf->tf_r6 = regs->r_r6;
173 	tf->tf_r5 = regs->r_r5;
174 	tf->tf_r4 = regs->r_r4;
175 	tf->tf_r3 = regs->r_r3;
176 	tf->tf_r2 = regs->r_r2;
177 	tf->tf_r1 = regs->r_r1;
178 	tf->tf_r0 = regs->r_r0;
179 	tf->tf_r15 = regs->r_r15;
180 
181 	return (0);
182 }
183 
184 
185 #ifdef __HAVE_PTRACE_MACHDEP
186 
187 int
ptrace_machdep_dorequest(struct lwp * l,struct lwp ** lt,int req,void * addr,int data)188 ptrace_machdep_dorequest(struct lwp *l, struct lwp **lt,
189 			 int req, void *addr, int data)
190 {
191 	struct uio uio;
192 	struct iovec iov;
193 	int write = 0, error;
194 
195 	switch (req) {
196 	default:
197 		return EINVAL;
198 
199 #ifdef COMPAT_40
200 	case PT___SETREGS40:
201 		write = 1;
202 		/* FALLTHROUGH*/
203 
204 	case PT___GETREGS40:
205 		if ((error = ptrace_update_lwp((*lt)->l_proc, lt, data)) != 0)
206 			return error;
207 		if (!process_validregs(*lt))
208 			return EINVAL;
209 		iov.iov_base = addr;
210 		iov.iov_len = sizeof(struct __reg40);
211 		uio.uio_iov = &iov;
212 		uio.uio_iovcnt = 1;
213 		uio.uio_offset = 0;
214 		uio.uio_resid = sizeof(struct __reg40);
215 		uio.uio_rw = write ? UIO_WRITE : UIO_READ;
216 		uio.uio_vmspace = l->l_proc->p_vmspace;
217 		return process_machdep_doregs40(l, *lt, &uio);
218 #endif	/* COMPAT_40 */
219 	}
220 }
221 
222 
223 #ifdef COMPAT_40
224 
225 static int
process_machdep_doregs40(struct lwp * curl,struct lwp * l,struct uio * uio)226 process_machdep_doregs40(struct lwp *curl, struct lwp *l, struct uio *uio)
227 {
228 	struct __reg40 r;
229 	int error;
230 	char *kv;
231 	int kl;
232 
233 	kl = sizeof(r);
234 	kv = (char *) &r;
235 
236 	kv += uio->uio_offset;
237 	kl -= uio->uio_offset;
238 	if (kl > uio->uio_resid)
239 		kl = uio->uio_resid;
240 
241 	if (kl < 0)
242 		error = EINVAL;
243 	else
244 		error = process_machdep_read_regs40(l, &r);
245 	if (error == 0)
246 		error = uiomove(kv, kl, uio);
247 	if (error == 0 && uio->uio_rw == UIO_WRITE) {
248 		if (l->l_proc->p_stat != SSTOP)
249 			error = EBUSY;
250 		else
251 			error = process_machdep_write_regs40(l, &r);
252 	}
253 
254 	uio->uio_offset = 0;
255 	return error;
256 }
257 
258 /*
259  * Like process_read_regs() but for old struct reg w/out r_gbr.
260  */
261 static int
process_machdep_read_regs40(struct lwp * l,struct __reg40 * regs)262 process_machdep_read_regs40(struct lwp *l, struct __reg40 *regs)
263 {
264 	struct trapframe *tf = process_frame(l);
265 
266 	regs->r_spc = tf->tf_spc;
267 	regs->r_ssr = tf->tf_ssr;
268 	/* no r_gbr in struct __reg40 */
269 	regs->r_macl = tf->tf_macl;
270 	regs->r_mach = tf->tf_mach;
271 	regs->r_pr = tf->tf_pr;
272 	regs->r_r14 = tf->tf_r14;
273 	regs->r_r13 = tf->tf_r13;
274 	regs->r_r12 = tf->tf_r12;
275 	regs->r_r11 = tf->tf_r11;
276 	regs->r_r10 = tf->tf_r10;
277 	regs->r_r9 = tf->tf_r9;
278 	regs->r_r8 = tf->tf_r8;
279 	regs->r_r7 = tf->tf_r7;
280 	regs->r_r6 = tf->tf_r6;
281 	regs->r_r5 = tf->tf_r5;
282 	regs->r_r4 = tf->tf_r4;
283 	regs->r_r3 = tf->tf_r3;
284 	regs->r_r2 = tf->tf_r2;
285 	regs->r_r1 = tf->tf_r1;
286 	regs->r_r0 = tf->tf_r0;
287 	regs->r_r15 = tf->tf_r15;
288 
289 	return 0;
290 }
291 
292 /*
293  * Like process_write_regs() but for old struct reg w/out r_gbr
294  */
295 static int
process_machdep_write_regs40(struct lwp * l,struct __reg40 * regs)296 process_machdep_write_regs40(struct lwp *l, struct __reg40 *regs)
297 {
298 	struct trapframe *tf = process_frame(l);
299 
300 	/*
301 	 * Check for security violations.
302 	 */
303 	if (((regs->r_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0) {
304 		return EINVAL;
305 	}
306 
307 	tf->tf_spc = regs->r_spc;
308 	tf->tf_ssr = regs->r_ssr;
309 	tf->tf_pr = regs->r_pr;
310 
311 	/* no r_gbr in struct __reg40 */
312 	tf->tf_mach = regs->r_mach;
313 	tf->tf_macl = regs->r_macl;
314 	tf->tf_r14 = regs->r_r14;
315 	tf->tf_r13 = regs->r_r13;
316 	tf->tf_r12 = regs->r_r12;
317 	tf->tf_r11 = regs->r_r11;
318 	tf->tf_r10 = regs->r_r10;
319 	tf->tf_r9 = regs->r_r9;
320 	tf->tf_r8 = regs->r_r8;
321 	tf->tf_r7 = regs->r_r7;
322 	tf->tf_r6 = regs->r_r6;
323 	tf->tf_r5 = regs->r_r5;
324 	tf->tf_r4 = regs->r_r4;
325 	tf->tf_r3 = regs->r_r3;
326 	tf->tf_r2 = regs->r_r2;
327 	tf->tf_r1 = regs->r_r1;
328 	tf->tf_r0 = regs->r_r0;
329 	tf->tf_r15 = regs->r_r15;
330 
331 	return 0;
332 }
333 
334 #endif /* COMPAT_40 */
335 
336 #endif /* __HAVE_PTRACE_MACHDEP  */
337 
338 
339 int
process_sstep(struct lwp * l,int sstep)340 process_sstep(struct lwp *l, int sstep)
341 {
342 
343 	if (sstep)
344 		l->l_md.md_flags |= MDL_SSTEP;
345 	else
346 		l->l_md.md_flags &= ~MDL_SSTEP;
347 
348 	return 0;
349 }
350 
351 int
process_set_pc(struct lwp * l,void * addr)352 process_set_pc(struct lwp *l, void *addr)
353 {
354 	struct trapframe *tf = process_frame(l);
355 
356 	tf->tf_spc = (int)addr;
357 
358 	return (0);
359 }
360 
361 #endif /* PTRACE_HOOKS */
362