xref: /freebsd/sys/kern/sys_process.c (revision d2d3e8751c3b7831f7064ccf400978b75b696547)
14e68ceabSDavid Greenman /*
24e68ceabSDavid Greenman  * Copyright (c) 1994, Sean Eric Fagan
34e68ceabSDavid Greenman  * All rights reserved.
4df8bae1dSRodney W. Grimes  *
5df8bae1dSRodney W. Grimes  * Redistribution and use in source and binary forms, with or without
6df8bae1dSRodney W. Grimes  * modification, are permitted provided that the following conditions
7df8bae1dSRodney W. Grimes  * are met:
8df8bae1dSRodney W. Grimes  * 1. Redistributions of source code must retain the above copyright
9df8bae1dSRodney W. Grimes  *    notice, this list of conditions and the following disclaimer.
10df8bae1dSRodney W. Grimes  * 2. Redistributions in binary form must reproduce the above copyright
11df8bae1dSRodney W. Grimes  *    notice, this list of conditions and the following disclaimer in the
12df8bae1dSRodney W. Grimes  *    documentation and/or other materials provided with the distribution.
13df8bae1dSRodney W. Grimes  * 3. All advertising materials mentioning features or use of this software
14df8bae1dSRodney W. Grimes  *    must display the following acknowledgement:
154e68ceabSDavid Greenman  *	This product includes software developed by Sean Eric Fagan.
164e68ceabSDavid Greenman  * 4. The name of the author may not be used to endorse or promote products
174e68ceabSDavid Greenman  *    derived from this software without specific prior written permission.
18df8bae1dSRodney W. Grimes  *
194e68ceabSDavid Greenman  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20df8bae1dSRodney W. Grimes  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21df8bae1dSRodney W. Grimes  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
224e68ceabSDavid Greenman  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23df8bae1dSRodney W. Grimes  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24df8bae1dSRodney W. Grimes  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25df8bae1dSRodney W. Grimes  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26df8bae1dSRodney W. Grimes  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27df8bae1dSRodney W. Grimes  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28df8bae1dSRodney W. Grimes  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29df8bae1dSRodney W. Grimes  * SUCH DAMAGE.
30df8bae1dSRodney W. Grimes  *
31d2d3e875SBruce Evans  *	$Id: sys_process.c,v 1.14 1995/05/30 08:05:58 rgrimes Exp $
32df8bae1dSRodney W. Grimes  */
33df8bae1dSRodney W. Grimes 
34df8bae1dSRodney W. Grimes #include <sys/param.h>
35f23b4c91SGarrett Wollman #include <sys/systm.h>
36d2d3e875SBruce Evans #include <sys/sysproto.h>
37df8bae1dSRodney W. Grimes #include <sys/proc.h>
384e68ceabSDavid Greenman #include <sys/vnode.h>
394e68ceabSDavid Greenman #include <sys/ptrace.h>
40df8bae1dSRodney W. Grimes #include <sys/errno.h>
41df8bae1dSRodney W. Grimes 
424e68ceabSDavid Greenman #include <machine/reg.h>
434e68ceabSDavid Greenman #include <machine/psl.h>
444e68ceabSDavid Greenman #include <vm/vm.h>
454e68ceabSDavid Greenman #include <vm/vm_page.h>
464e68ceabSDavid Greenman #include <vm/vm_kern.h>
474e68ceabSDavid Greenman 
48f540b106SGarrett Wollman #include <sys/user.h>
494e68ceabSDavid Greenman 
50c4cf09ffSDavid Greenman static int
514e68ceabSDavid Greenman pread (struct proc *procp, unsigned int addr, unsigned int *retval) {
524e68ceabSDavid Greenman 	int		rv;
534e68ceabSDavid Greenman 	vm_map_t	map, tmap;
544e68ceabSDavid Greenman 	vm_object_t	object;
554e68ceabSDavid Greenman 	vm_offset_t	kva = 0;
564e68ceabSDavid Greenman 	int		page_offset;	/* offset into page */
574e68ceabSDavid Greenman 	vm_offset_t	pageno;		/* page number */
584e68ceabSDavid Greenman 	vm_map_entry_t	out_entry;
594e68ceabSDavid Greenman 	vm_prot_t	out_prot;
604e68ceabSDavid Greenman 	boolean_t	wired, single_use;
614e68ceabSDavid Greenman 	vm_offset_t	off;
624e68ceabSDavid Greenman 
634e68ceabSDavid Greenman 	/* Map page into kernel space */
644e68ceabSDavid Greenman 
654e68ceabSDavid Greenman 	map = &procp->p_vmspace->vm_map;
664e68ceabSDavid Greenman 
674e68ceabSDavid Greenman 	page_offset = addr - trunc_page(addr);
684e68ceabSDavid Greenman 	pageno = trunc_page(addr);
694e68ceabSDavid Greenman 
704e68ceabSDavid Greenman 	tmap = map;
714e68ceabSDavid Greenman 	rv = vm_map_lookup (&tmap, pageno, VM_PROT_READ, &out_entry,
724e68ceabSDavid Greenman 		&object, &off, &out_prot, &wired, &single_use);
734e68ceabSDavid Greenman 
744e68ceabSDavid Greenman 	if (rv != KERN_SUCCESS)
754e68ceabSDavid Greenman 		return EINVAL;
764e68ceabSDavid Greenman 
774e68ceabSDavid Greenman 	vm_map_lookup_done (tmap, out_entry);
784e68ceabSDavid Greenman 
794e68ceabSDavid Greenman 	/* Find space in kernel_map for the page we're interested in */
804e68ceabSDavid Greenman 	rv = vm_map_find (kernel_map, object, off, &kva, PAGE_SIZE, 1);
814e68ceabSDavid Greenman 
824e68ceabSDavid Greenman 	if (!rv) {
834e68ceabSDavid Greenman 		vm_object_reference (object);
844e68ceabSDavid Greenman 
854e68ceabSDavid Greenman 		rv = vm_map_pageable (kernel_map, kva, kva + PAGE_SIZE, 0);
864e68ceabSDavid Greenman 		if (!rv) {
874e68ceabSDavid Greenman 			*retval = 0;
88f23b4c91SGarrett Wollman 			bcopy ((caddr_t)kva + page_offset,
89f23b4c91SGarrett Wollman 			       retval, sizeof *retval);
904e68ceabSDavid Greenman 		}
914e68ceabSDavid Greenman 		vm_map_remove (kernel_map, kva, kva + PAGE_SIZE);
924e68ceabSDavid Greenman 	}
934e68ceabSDavid Greenman 
944e68ceabSDavid Greenman 	return rv;
954e68ceabSDavid Greenman }
964e68ceabSDavid Greenman 
97c4cf09ffSDavid Greenman static int
984e68ceabSDavid Greenman pwrite (struct proc *procp, unsigned int addr, unsigned int datum) {
994e68ceabSDavid Greenman 	int		rv;
1004e68ceabSDavid Greenman 	vm_map_t	map, tmap;
1014e68ceabSDavid Greenman 	vm_object_t	object;
1024e68ceabSDavid Greenman 	vm_offset_t	kva = 0;
1034e68ceabSDavid Greenman 	int		page_offset;	/* offset into page */
1044e68ceabSDavid Greenman 	vm_offset_t	pageno;		/* page number */
1054e68ceabSDavid Greenman 	vm_map_entry_t	out_entry;
1064e68ceabSDavid Greenman 	vm_prot_t	out_prot;
1074e68ceabSDavid Greenman 	boolean_t	wired, single_use;
1084e68ceabSDavid Greenman 	vm_offset_t	off;
1094e68ceabSDavid Greenman 	boolean_t	fix_prot = 0;
1104e68ceabSDavid Greenman 
1114e68ceabSDavid Greenman 	/* Map page into kernel space */
1124e68ceabSDavid Greenman 
1134e68ceabSDavid Greenman 	map = &procp->p_vmspace->vm_map;
1144e68ceabSDavid Greenman 
1154e68ceabSDavid Greenman 	page_offset = addr - trunc_page(addr);
1164e68ceabSDavid Greenman 	pageno = trunc_page(addr);
1174e68ceabSDavid Greenman 
1184e68ceabSDavid Greenman 	/*
1194e68ceabSDavid Greenman 	 * Check the permissions for the area we're interested in.
1204e68ceabSDavid Greenman 	 */
1214e68ceabSDavid Greenman 
1224e68ceabSDavid Greenman 	if (vm_map_check_protection (map, pageno, pageno + PAGE_SIZE,
1234e68ceabSDavid Greenman 		VM_PROT_WRITE) == FALSE) {
1244e68ceabSDavid Greenman 		/*
1254e68ceabSDavid Greenman 		 * If the page was not writable, we make it so.
1264e68ceabSDavid Greenman 		 * XXX It is possible a page may *not* be read/executable,
1274e68ceabSDavid Greenman 		 * if a process changes that!
1284e68ceabSDavid Greenman 		 */
1294e68ceabSDavid Greenman 		fix_prot = 1;
1304e68ceabSDavid Greenman 		/* The page isn't writable, so let's try making it so... */
1314e68ceabSDavid Greenman 		if ((rv = vm_map_protect (map, pageno, pageno + PAGE_SIZE,
1324e68ceabSDavid Greenman 			VM_PROT_ALL, 0)) != KERN_SUCCESS)
1334e68ceabSDavid Greenman 		  return EFAULT;	/* I guess... */
1344e68ceabSDavid Greenman 	}
1354e68ceabSDavid Greenman 
1364e68ceabSDavid Greenman 	/*
1374e68ceabSDavid Greenman 	 * Now we need to get the page.  out_entry, out_prot, wired, and
1384e68ceabSDavid Greenman 	 * single_use aren't used.  One would think the vm code would be
1394e68ceabSDavid Greenman 	 * a *bit* nicer...  We use tmap because vm_map_lookup() can
1404e68ceabSDavid Greenman 	 * change the map argument.
1414e68ceabSDavid Greenman 	 */
1424e68ceabSDavid Greenman 
1434e68ceabSDavid Greenman 	tmap = map;
1444e68ceabSDavid Greenman 	rv = vm_map_lookup (&tmap, pageno, VM_PROT_WRITE, &out_entry,
1454e68ceabSDavid Greenman 		&object, &off, &out_prot, &wired, &single_use);
1464e68ceabSDavid Greenman 	if (rv != KERN_SUCCESS) {
1474e68ceabSDavid Greenman 		return EINVAL;
1484e68ceabSDavid Greenman 	}
1494e68ceabSDavid Greenman 
1504e68ceabSDavid Greenman 	/*
1514e68ceabSDavid Greenman 	 * Okay, we've got the page.  Let's release tmap.
1524e68ceabSDavid Greenman 	 */
1534e68ceabSDavid Greenman 
1544e68ceabSDavid Greenman 	vm_map_lookup_done (tmap, out_entry);
1554e68ceabSDavid Greenman 
1564e68ceabSDavid Greenman 	/*
1574e68ceabSDavid Greenman 	 * Fault the page in...
1584e68ceabSDavid Greenman 	 */
1594e68ceabSDavid Greenman 
1609219d44eSDavid Greenman 	vm_map_pageable(map, trunc_page(vtopte(pageno)),
1619219d44eSDavid Greenman 		trunc_page(vtopte(pageno)) + PAGE_SIZE, FALSE);
162914a63ebSDavid Greenman 	rv = vm_fault(map, pageno, VM_PROT_WRITE|VM_PROT_READ, FALSE);
1639219d44eSDavid Greenman 	vm_map_pageable(map, trunc_page(vtopte(pageno)),
1649219d44eSDavid Greenman 		trunc_page(vtopte(pageno)) + PAGE_SIZE, TRUE);
1654e68ceabSDavid Greenman 	if (rv != KERN_SUCCESS)
1664e68ceabSDavid Greenman 		return EFAULT;
1674e68ceabSDavid Greenman 
1684e68ceabSDavid Greenman 	/* Find space in kernel_map for the page we're interested in */
1694e68ceabSDavid Greenman 	rv = vm_map_find (kernel_map, object, off, &kva, PAGE_SIZE, 1);
1704e68ceabSDavid Greenman 
1714e68ceabSDavid Greenman 	if (!rv) {
1724e68ceabSDavid Greenman 		vm_object_reference (object);
1734e68ceabSDavid Greenman 
1744e68ceabSDavid Greenman 		rv = vm_map_pageable (kernel_map, kva, kva + PAGE_SIZE, 0);
1754e68ceabSDavid Greenman 		if (!rv) {
176f23b4c91SGarrett Wollman 		  bcopy (&datum, (caddr_t)kva + page_offset, sizeof datum);
1774e68ceabSDavid Greenman 		}
1784e68ceabSDavid Greenman 		vm_map_remove (kernel_map, kva, kva + PAGE_SIZE);
1794e68ceabSDavid Greenman 	}
1804e68ceabSDavid Greenman 
1814e68ceabSDavid Greenman 	if (fix_prot)
1824e68ceabSDavid Greenman 		vm_map_protect (map, pageno, pageno + PAGE_SIZE,
1834e68ceabSDavid Greenman 			VM_PROT_READ|VM_PROT_EXECUTE, 0);
1844e68ceabSDavid Greenman 	return rv;
1854e68ceabSDavid Greenman }
1864e68ceabSDavid Greenman 
187df8bae1dSRodney W. Grimes /*
188df8bae1dSRodney W. Grimes  * Process debugging system call.
189df8bae1dSRodney W. Grimes  */
190d2d3e875SBruce Evans #ifndef _SYS_SYSPROTO_H_
191df8bae1dSRodney W. Grimes struct ptrace_args {
192df8bae1dSRodney W. Grimes 	int	req;
193df8bae1dSRodney W. Grimes 	pid_t	pid;
194df8bae1dSRodney W. Grimes 	caddr_t	addr;
195df8bae1dSRodney W. Grimes 	int	data;
196df8bae1dSRodney W. Grimes };
197d2d3e875SBruce Evans #endif
198df8bae1dSRodney W. Grimes 
1994e68ceabSDavid Greenman int
2004e68ceabSDavid Greenman ptrace(curp, uap, retval)
2014e68ceabSDavid Greenman 	struct proc *curp;
2024e68ceabSDavid Greenman 	struct ptrace_args *uap;
2034e68ceabSDavid Greenman 	int *retval;
2044e68ceabSDavid Greenman {
2054e68ceabSDavid Greenman 	struct proc *p;
206bb56ec4aSPoul-Henning Kamp 	int error = 0;
2074e68ceabSDavid Greenman 
2084e68ceabSDavid Greenman 	*retval = 0;
2094e68ceabSDavid Greenman 	if (uap->req == PT_TRACE_ME) {
2104e68ceabSDavid Greenman 		curp->p_flag |= P_TRACED;
2114e68ceabSDavid Greenman 		return 0;
2124e68ceabSDavid Greenman 	}
2134e68ceabSDavid Greenman 	if ((p = pfind(uap->pid)) == NULL) {
2144e68ceabSDavid Greenman 		return ESRCH;
2154e68ceabSDavid Greenman 	}
2164e68ceabSDavid Greenman 
2174e68ceabSDavid Greenman #ifdef PT_ATTACH
2184e68ceabSDavid Greenman 	if (uap->req != PT_ATTACH && (
2194e68ceabSDavid Greenman 			(p->p_flag & P_TRACED) == 0 ||
2204e68ceabSDavid Greenman 			(p->p_tptr && curp != p->p_tptr) ||
2214e68ceabSDavid Greenman 			(!p->p_tptr && curp != p->p_pptr)))
2224e68ceabSDavid Greenman 
2234e68ceabSDavid Greenman 		return ESRCH;
2244e68ceabSDavid Greenman #endif
2254e68ceabSDavid Greenman #ifdef PT_ATTACH
2264e68ceabSDavid Greenman 	if (uap->req != PT_ATTACH) {
2274e68ceabSDavid Greenman #endif
2284e68ceabSDavid Greenman 		if ((p->p_flag & P_TRACED) == 0)
2294e68ceabSDavid Greenman 			return EPERM;
2304e68ceabSDavid Greenman 		if (p->p_stat != SSTOP || (p->p_flag & P_WAITED) == 0)
2314e68ceabSDavid Greenman 			return EBUSY;
2324e68ceabSDavid Greenman #ifdef PT_ATTACH
2334e68ceabSDavid Greenman 	}
2344e68ceabSDavid Greenman #endif
235df8bae1dSRodney W. Grimes 	/*
2364e68ceabSDavid Greenman 	 * XXX The PT_ATTACH code is completely broken.  It will
2374e68ceabSDavid Greenman 	 * be obsoleted by a /proc filesystem, so is it worth it
2384e68ceabSDavid Greenman 	 * to fix it?  (Answer, probably.  So that'll be next,
2394e68ceabSDavid Greenman 	 * I guess.)
240df8bae1dSRodney W. Grimes 	 */
2414e68ceabSDavid Greenman 
2424e68ceabSDavid Greenman 	switch (uap->req) {
2434e68ceabSDavid Greenman #ifdef PT_ATTACH
2444e68ceabSDavid Greenman 	case PT_ATTACH:
2454e68ceabSDavid Greenman 		if (curp->p_ucred->cr_uid != 0 && (
2464e68ceabSDavid Greenman 			curp->p_ucred->cr_uid != p->p_ucred->cr_uid ||
2474e68ceabSDavid Greenman 			curp->p_ucred->cr_uid != p->p_cred->p_svuid))
2484e68ceabSDavid Greenman 			return EACCES;
2494e68ceabSDavid Greenman 
2504e68ceabSDavid Greenman 		p->p_tptr = curp;
2514e68ceabSDavid Greenman 		p->p_flag |= P_TRACED;
2524e68ceabSDavid Greenman 		psignal(p, SIGSTOP);
2534e68ceabSDavid Greenman 		return 0;
2544e68ceabSDavid Greenman 
2554e68ceabSDavid Greenman 	case PT_DETACH:
2564e68ceabSDavid Greenman 		if ((unsigned)uap->data >= NSIG)
2574e68ceabSDavid Greenman 			return EINVAL;
2584e68ceabSDavid Greenman 		p->p_flag &= ~P_TRACED;
2594e68ceabSDavid Greenman 		p->p_tptr = NULL;
2604e68ceabSDavid Greenman 		psignal(p->p_pptr, SIGCHLD);
2614e68ceabSDavid Greenman 		wakeup((caddr_t)p->p_pptr);
2624e68ceabSDavid Greenman 		s = splhigh();
2634e68ceabSDavid Greenman 		if (p->p_stat == SSTOP) {
2644e68ceabSDavid Greenman 			p->p_xstat = uap->data;
2654e68ceabSDavid Greenman 			setrunnable(p);
2664e68ceabSDavid Greenman 		} else if (uap->data) {
2674e68ceabSDavid Greenman 			psignal(p, uap->data);
2684e68ceabSDavid Greenman 		}
2694e68ceabSDavid Greenman 		splx(s);
2704e68ceabSDavid Greenman 		return 0;
2714e68ceabSDavid Greenman 
2724e68ceabSDavid Greenman # ifdef PT_INHERIT
2734e68ceabSDavid Greenman 	case PT_INHERIT:
2744e68ceabSDavid Greenman 		if ((p->p_flag & P_TRACED) == 0)
2754e68ceabSDavid Greenman 			return ESRCH;
2764e68ceabSDavid Greenman 		return 0;
2774e68ceabSDavid Greenman # endif	/* PT_INHERIT */
2784e68ceabSDavid Greenman #endif	/* PT_ATTACH */
2794e68ceabSDavid Greenman 
2804e68ceabSDavid Greenman 	case PT_READ_I:
2814e68ceabSDavid Greenman 	case PT_READ_D:
282bb56ec4aSPoul-Henning Kamp 		if ((error = pread (p, (unsigned int)uap->addr, retval)))
2834e68ceabSDavid Greenman 			return error;
2844e68ceabSDavid Greenman 		return 0;
2854e68ceabSDavid Greenman 	case PT_WRITE_I:
2864e68ceabSDavid Greenman 	case PT_WRITE_D:
287bb56ec4aSPoul-Henning Kamp 		if ((error = pwrite (p, (unsigned int)uap->addr,
288bb56ec4aSPoul-Henning Kamp 				    (unsigned int)uap->data)))
2894e68ceabSDavid Greenman 			return error;
2904e68ceabSDavid Greenman 		return 0;
2914e68ceabSDavid Greenman 	case PT_STEP:
292bb56ec4aSPoul-Henning Kamp 		if ((error = ptrace_single_step (p)))
2934e68ceabSDavid Greenman 			return error;
2944e68ceabSDavid Greenman 		/* fallthrough */
2954e68ceabSDavid Greenman 	case PT_CONTINUE:
2964e68ceabSDavid Greenman 		/*
2974e68ceabSDavid Greenman 		 * Continue at addr uap->addr with signal
2984e68ceabSDavid Greenman 		 * uap->data; if uap->addr is 1, then we just
2994e68ceabSDavid Greenman 		 * let the chips fall where they may.
3004e68ceabSDavid Greenman 		 *
3014e68ceabSDavid Greenman 		 * The only check I'll make right now is for
3024e68ceabSDavid Greenman 		 * uap->data to be larger than NSIG; if so, we return
3034e68ceabSDavid Greenman 		 * EINVAL.
3044e68ceabSDavid Greenman 		 */
3054e68ceabSDavid Greenman 		if (uap->data >= NSIG)
3064e68ceabSDavid Greenman 			return EINVAL;
3074e68ceabSDavid Greenman 
3084e68ceabSDavid Greenman 		if (uap->addr != (caddr_t)1) {
3094e68ceabSDavid Greenman 			fill_eproc (p, &p->p_addr->u_kproc.kp_eproc);
310b5e8ce9fSBruce Evans 			if ((error = ptrace_set_pc (p, (u_int)uap->addr)))
3114e68ceabSDavid Greenman 				return error;
3124e68ceabSDavid Greenman 		}
3134e68ceabSDavid Greenman 
3144e68ceabSDavid Greenman 		p->p_xstat = uap->data;
3154e68ceabSDavid Greenman 
3164e68ceabSDavid Greenman /*		if (p->p_stat == SSTOP) */
3174e68ceabSDavid Greenman 		setrunnable (p);
3184e68ceabSDavid Greenman 		return 0;
3194e68ceabSDavid Greenman 	case PT_READ_U:
3204e68ceabSDavid Greenman 		if ((u_int)uap->addr > (UPAGES * NBPG - sizeof(int))) {
3214e68ceabSDavid Greenman 			return EFAULT;
3224e68ceabSDavid Greenman 		}
3234e68ceabSDavid Greenman 		p->p_addr->u_kproc.kp_proc = *p;
3244e68ceabSDavid Greenman 		fill_eproc (p, &p->p_addr->u_kproc.kp_eproc);
3254e68ceabSDavid Greenman 		*retval = *(int*)((u_int)p->p_addr + (u_int)uap->addr);
3264e68ceabSDavid Greenman 		return 0;
3274e68ceabSDavid Greenman 	case PT_WRITE_U:
3284e68ceabSDavid Greenman 		p->p_addr->u_kproc.kp_proc = *p;
3294e68ceabSDavid Greenman 		fill_eproc (p, &p->p_addr->u_kproc.kp_eproc);
33020415301SBruce Evans 		return ptrace_write_u(p, (vm_offset_t)uap->addr, uap->data);
3314e68ceabSDavid Greenman 	case PT_KILL:
3324e68ceabSDavid Greenman 		p->p_xstat = SIGKILL;
3334e68ceabSDavid Greenman 		setrunnable(p);
3344e68ceabSDavid Greenman 		return 0;
3354e68ceabSDavid Greenman #ifdef PT_GETREGS
3364e68ceabSDavid Greenman 	case PT_GETREGS:
3374e68ceabSDavid Greenman 		/*
3384e68ceabSDavid Greenman 		 * copyout the registers into addr.  There's no
3394e68ceabSDavid Greenman 		 * size constraint!!! *GRRR*
3404e68ceabSDavid Greenman 		 */
3414e68ceabSDavid Greenman 		return ptrace_getregs(p, uap->addr);
3424e68ceabSDavid Greenman 	case PT_SETREGS:
3434e68ceabSDavid Greenman 		/*
3444e68ceabSDavid Greenman 		 * copyin the registers from addr.  Again, no
3454e68ceabSDavid Greenman 		 * size constraint!!! *GRRRR*
3464e68ceabSDavid Greenman 		 */
3474e68ceabSDavid Greenman 		return ptrace_setregs (p, uap->addr);
3484e68ceabSDavid Greenman #endif /* PT_GETREGS */
3494e68ceabSDavid Greenman 	default:
3504e68ceabSDavid Greenman 		break;
3514e68ceabSDavid Greenman 	}
3524e68ceabSDavid Greenman 
3534e68ceabSDavid Greenman 	return 0;
354df8bae1dSRodney W. Grimes }
355df8bae1dSRodney W. Grimes 
35626f9a767SRodney W. Grimes int
3574e68ceabSDavid Greenman trace_req(p)
3584e68ceabSDavid Greenman 	struct proc *p;
359df8bae1dSRodney W. Grimes {
3604e68ceabSDavid Greenman 	return 1;
361df8bae1dSRodney W. Grimes }
362