No empty .Rs/.Re
[netbsd-mini2440.git] / sys / kern / sys_process.c
blob197ab0d207fc213fe53fdb013f3e6abae5fcd70b
1 /* $NetBSD: sys_process.c,v 1.152 2009/12/14 00:48:35 matt Exp $ */
3 /*-
4 * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran.
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.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 /*-
33 * Copyright (c) 1982, 1986, 1989, 1993
34 * The Regents of the University of California. All rights reserved.
35 * (c) UNIX System Laboratories, Inc.
36 * All or some portions of this file are derived from material licensed
37 * to the University of California by American Telephone and Telegraph
38 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
39 * the permission of UNIX System Laboratories, Inc.
41 * This code is derived from software contributed to Berkeley by
42 * Jan-Simon Pendry.
44 * Redistribution and use in source and binary forms, with or without
45 * modification, are permitted provided that the following conditions
46 * are met:
47 * 1. Redistributions of source code must retain the above copyright
48 * notice, this list of conditions and the following disclaimer.
49 * 2. Redistributions in binary form must reproduce the above copyright
50 * notice, this list of conditions and the following disclaimer in the
51 * documentation and/or other materials provided with the distribution.
52 * 3. Neither the name of the University nor the names of its contributors
53 * may be used to endorse or promote products derived from this software
54 * without specific prior written permission.
56 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66 * SUCH DAMAGE.
68 * from: @(#)sys_process.c 8.1 (Berkeley) 6/10/93
71 /*-
72 * Copyright (c) 1993 Jan-Simon Pendry.
73 * Copyright (c) 1994 Christopher G. Demetriou. All rights reserved.
75 * This code is derived from software contributed to Berkeley by
76 * Jan-Simon Pendry.
78 * Redistribution and use in source and binary forms, with or without
79 * modification, are permitted provided that the following conditions
80 * are met:
81 * 1. Redistributions of source code must retain the above copyright
82 * notice, this list of conditions and the following disclaimer.
83 * 2. Redistributions in binary form must reproduce the above copyright
84 * notice, this list of conditions and the following disclaimer in the
85 * documentation and/or other materials provided with the distribution.
86 * 3. All advertising materials mentioning features or use of this software
87 * must display the following acknowledgement:
88 * This product includes software developed by the University of
89 * California, Berkeley and its contributors.
90 * 4. Neither the name of the University nor the names of its contributors
91 * may be used to endorse or promote products derived from this software
92 * without specific prior written permission.
94 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
95 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
96 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
97 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
98 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
99 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
100 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
101 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
102 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
103 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
104 * SUCH DAMAGE.
106 * from: @(#)sys_process.c 8.1 (Berkeley) 6/10/93
110 * References:
111 * (1) Bach's "The Design of the UNIX Operating System",
112 * (2) sys/miscfs/procfs from UCB's 4.4BSD-Lite distribution,
113 * (3) the "4.4BSD Programmer's Reference Manual" published
114 * by USENIX and O'Reilly & Associates.
115 * The 4.4BSD PRM does a reasonably good job of documenting what the various
116 * ptrace() requests should actually do, and its text is quoted several times
117 * in this file.
120 #include <sys/cdefs.h>
121 __KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.152 2009/12/14 00:48:35 matt Exp $");
123 #include "opt_ptrace.h"
124 #include "opt_ktrace.h"
126 #include <sys/param.h>
127 #include <sys/systm.h>
128 #include <sys/proc.h>
129 #include <sys/errno.h>
130 #include <sys/ptrace.h>
131 #include <sys/uio.h>
132 #include <sys/ras.h>
133 #include <sys/kmem.h>
134 #include <sys/kauth.h>
135 #include <sys/mount.h>
136 #include <sys/syscallargs.h>
138 #include <uvm/uvm_extern.h>
140 #include <machine/reg.h>
142 #ifdef PTRACE
143 static kauth_listener_t ptrace_listener;
145 static int
146 ptrace_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,
147 void *arg0, void *arg1, void *arg2, void *arg3)
149 struct proc *p;
150 int result;
152 result = KAUTH_RESULT_DEFER;
153 p = arg0;
155 if (action != KAUTH_PROCESS_PTRACE)
156 return result;
158 switch ((u_long)arg1) {
159 case PT_TRACE_ME:
160 case PT_ATTACH:
161 case PT_WRITE_I:
162 case PT_WRITE_D:
163 case PT_READ_I:
164 case PT_READ_D:
165 case PT_IO:
166 #ifdef PT_GETREGS
167 case PT_GETREGS:
168 #endif
169 #ifdef PT_SETREGS
170 case PT_SETREGS:
171 #endif
172 #ifdef PT_GETFPREGS
173 case PT_GETFPREGS:
174 #endif
175 #ifdef PT_SETFPREGS
176 case PT_SETFPREGS:
177 #endif
178 #ifdef __HAVE_PTRACE_MACHDEP
179 PTRACE_MACHDEP_REQUEST_CASES
180 #endif
181 if (kauth_cred_getuid(cred) != kauth_cred_getuid(p->p_cred) ||
182 ISSET(p->p_flag, PK_SUGID)) {
183 break;
186 result = KAUTH_RESULT_ALLOW;
188 break;
190 #ifdef PT_STEP
191 case PT_STEP:
192 #endif
193 case PT_CONTINUE:
194 case PT_KILL:
195 case PT_DETACH:
196 case PT_LWPINFO:
197 case PT_SYSCALL:
198 case PT_DUMPCORE:
199 result = KAUTH_RESULT_ALLOW;
200 break;
202 default:
203 break;
206 return result;
209 void
210 ptrace_init(void)
213 ptrace_listener = kauth_listen_scope(KAUTH_SCOPE_PROCESS,
214 ptrace_listener_cb, NULL);
218 * Process debugging system call.
221 sys_ptrace(struct lwp *l, const struct sys_ptrace_args *uap, register_t *retval)
223 /* {
224 syscallarg(int) req;
225 syscallarg(pid_t) pid;
226 syscallarg(void *) addr;
227 syscallarg(int) data;
228 } */
229 struct proc *p = l->l_proc;
230 struct lwp *lt;
231 struct proc *t; /* target process */
232 struct uio uio;
233 struct iovec iov;
234 struct ptrace_io_desc piod;
235 struct ptrace_lwpinfo pl;
236 struct vmspace *vm;
237 int error, write, tmp, req, pheld;
238 int signo;
239 ksiginfo_t ksi;
240 char *path;
241 int len;
243 error = 0;
244 req = SCARG(uap, req);
247 * If attaching or detaching, we need to get a write hold on the
248 * proclist lock so that we can re-parent the target process.
250 mutex_enter(proc_lock);
252 /* "A foolish consistency..." XXX */
253 if (req == PT_TRACE_ME) {
254 t = p;
255 mutex_enter(t->p_lock);
256 } else {
257 /* Find the process we're supposed to be operating on. */
258 if ((t = p_find(SCARG(uap, pid), PFIND_LOCKED)) == NULL) {
259 mutex_exit(proc_lock);
260 return (ESRCH);
263 /* XXX-elad */
264 mutex_enter(t->p_lock);
265 error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANSEE,
266 t, KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL);
267 if (error) {
268 mutex_exit(proc_lock);
269 mutex_exit(t->p_lock);
270 return (ESRCH);
275 * Grab a reference on the process to prevent it from execing or
276 * exiting.
278 if (!rw_tryenter(&t->p_reflock, RW_READER)) {
279 mutex_exit(proc_lock);
280 mutex_exit(t->p_lock);
281 return EBUSY;
284 /* Make sure we can operate on it. */
285 switch (req) {
286 case PT_TRACE_ME:
287 /* Saying that you're being traced is always legal. */
288 break;
290 case PT_ATTACH:
292 * You can't attach to a process if:
293 * (1) it's the process that's doing the attaching,
295 if (t->p_pid == p->p_pid) {
296 error = EINVAL;
297 break;
301 * (2) it's a system process
303 if (t->p_flag & PK_SYSTEM) {
304 error = EPERM;
305 break;
309 * (3) it's already being traced, or
311 if (ISSET(t->p_slflag, PSL_TRACED)) {
312 error = EBUSY;
313 break;
317 * (4) the tracer is chrooted, and its root directory is
318 * not at or above the root directory of the tracee
320 mutex_exit(t->p_lock); /* XXXSMP */
321 tmp = proc_isunder(t, l);
322 mutex_enter(t->p_lock); /* XXXSMP */
323 if (!tmp) {
324 error = EPERM;
325 break;
327 break;
329 case PT_READ_I:
330 case PT_READ_D:
331 case PT_WRITE_I:
332 case PT_WRITE_D:
333 case PT_IO:
334 #ifdef PT_GETREGS
335 case PT_GETREGS:
336 #endif
337 #ifdef PT_SETREGS
338 case PT_SETREGS:
339 #endif
340 #ifdef PT_GETFPREGS
341 case PT_GETFPREGS:
342 #endif
343 #ifdef PT_SETFPREGS
344 case PT_SETFPREGS:
345 #endif
346 #ifdef __HAVE_PTRACE_MACHDEP
347 PTRACE_MACHDEP_REQUEST_CASES
348 #endif
350 * You can't read/write the memory or registers of a process
351 * if the tracer is chrooted, and its root directory is not at
352 * or above the root directory of the tracee.
354 mutex_exit(t->p_lock); /* XXXSMP */
355 tmp = proc_isunder(t, l);
356 mutex_enter(t->p_lock); /* XXXSMP */
357 if (!tmp) {
358 error = EPERM;
359 break;
361 /*FALLTHROUGH*/
363 case PT_CONTINUE:
364 case PT_KILL:
365 case PT_DETACH:
366 case PT_LWPINFO:
367 case PT_SYSCALL:
368 case PT_DUMPCORE:
369 #ifdef PT_STEP
370 case PT_STEP:
371 #endif
373 * You can't do what you want to the process if:
374 * (1) It's not being traced at all,
376 if (!ISSET(t->p_slflag, PSL_TRACED)) {
377 error = EPERM;
378 break;
382 * (2) it's being traced by procfs (which has
383 * different signal delivery semantics),
385 if (ISSET(t->p_slflag, PSL_FSTRACE)) {
386 uprintf("file system traced\n");
387 error = EBUSY;
388 break;
392 * (3) it's not being traced by _you_, or
394 if (t->p_pptr != p) {
395 uprintf("parent %d != %d\n", t->p_pptr->p_pid,
396 p->p_pid);
397 error = EBUSY;
398 break;
402 * (4) it's not currently stopped.
404 if (t->p_stat != SSTOP || !t->p_waited /* XXXSMP */) {
405 uprintf("stat %d flag %d\n", t->p_stat,
406 !t->p_waited);
407 error = EBUSY;
408 break;
410 break;
412 default: /* It was not a legal request. */
413 error = EINVAL;
414 break;
417 if (error == 0) {
418 error = kauth_authorize_process(l->l_cred,
419 KAUTH_PROCESS_PTRACE, t, KAUTH_ARG(req),
420 NULL, NULL);
422 if (error == 0) {
423 lt = lwp_find_first(t);
424 if (lt == NULL)
425 error = ESRCH;
428 if (error != 0) {
429 mutex_exit(proc_lock);
430 mutex_exit(t->p_lock);
431 rw_exit(&t->p_reflock);
432 return error;
435 /* Do single-step fixup if needed. */
436 FIX_SSTEP(t);
437 KASSERT(lt != NULL);
438 lwp_addref(lt);
441 * Which locks do we need held? XXX Ugly.
443 switch (req) {
444 #ifdef PT_STEP
445 case PT_STEP:
446 #endif
447 case PT_CONTINUE:
448 case PT_DETACH:
449 case PT_KILL:
450 case PT_SYSCALL:
451 case PT_ATTACH:
452 case PT_TRACE_ME:
453 pheld = 1;
454 break;
455 default:
456 mutex_exit(proc_lock);
457 mutex_exit(t->p_lock);
458 pheld = 0;
459 break;
462 /* Now do the operation. */
463 write = 0;
464 *retval = 0;
465 tmp = 0;
467 switch (req) {
468 case PT_TRACE_ME:
469 /* Just set the trace flag. */
470 SET(t->p_slflag, PSL_TRACED);
471 t->p_opptr = t->p_pptr;
472 break;
474 case PT_WRITE_I: /* XXX no separate I and D spaces */
475 case PT_WRITE_D:
476 #if defined(__HAVE_RAS)
478 * Can't write to a RAS
480 if (ras_lookup(t, SCARG(uap, addr)) != (void *)-1) {
481 error = EACCES;
482 break;
484 #endif
485 write = 1;
486 tmp = SCARG(uap, data);
487 /* FALLTHROUGH */
489 case PT_READ_I: /* XXX no separate I and D spaces */
490 case PT_READ_D:
491 /* write = 0 done above. */
492 iov.iov_base = (void *)&tmp;
493 iov.iov_len = sizeof(tmp);
494 uio.uio_iov = &iov;
495 uio.uio_iovcnt = 1;
496 uio.uio_offset = (off_t)(unsigned long)SCARG(uap, addr);
497 uio.uio_resid = sizeof(tmp);
498 uio.uio_rw = write ? UIO_WRITE : UIO_READ;
499 UIO_SETUP_SYSSPACE(&uio);
501 error = process_domem(l, lt, &uio);
502 if (!write)
503 *retval = tmp;
504 break;
506 case PT_IO:
507 error = copyin(SCARG(uap, addr), &piod, sizeof(piod));
508 if (error)
509 break;
510 switch (piod.piod_op) {
511 case PIOD_READ_D:
512 case PIOD_READ_I:
513 uio.uio_rw = UIO_READ;
514 break;
515 case PIOD_WRITE_D:
516 case PIOD_WRITE_I:
518 * Can't write to a RAS
520 if (ras_lookup(t, SCARG(uap, addr)) != (void *)-1) {
521 return (EACCES);
523 uio.uio_rw = UIO_WRITE;
524 break;
525 default:
526 error = EINVAL;
527 break;
529 if (error)
530 break;
531 error = proc_vmspace_getref(l->l_proc, &vm);
532 if (error)
533 break;
534 iov.iov_base = piod.piod_addr;
535 iov.iov_len = piod.piod_len;
536 uio.uio_iov = &iov;
537 uio.uio_iovcnt = 1;
538 uio.uio_offset = (off_t)(unsigned long)piod.piod_offs;
539 uio.uio_resid = piod.piod_len;
540 uio.uio_vmspace = vm;
542 error = process_domem(l, lt, &uio);
543 piod.piod_len -= uio.uio_resid;
544 (void) copyout(&piod, SCARG(uap, addr), sizeof(piod));
545 uvmspace_free(vm);
546 break;
548 case PT_DUMPCORE:
549 if ((path = SCARG(uap, addr)) != NULL) {
550 char *dst;
551 len = SCARG(uap, data);
553 if (len < 0 || len >= MAXPATHLEN) {
554 error = EINVAL;
555 break;
557 dst = kmem_alloc(len + 1, KM_SLEEP);
558 if ((error = copyin(path, dst, len)) != 0) {
559 kmem_free(dst, len + 1);
560 break;
562 path = dst;
563 path[len] = '\0';
565 error = (*coredump_vec)(lt, path);
566 if (path)
567 kmem_free(path, len + 1);
568 break;
570 #ifdef PT_STEP
571 case PT_STEP:
573 * From the 4.4BSD PRM:
574 * "Execution continues as in request PT_CONTINUE; however
575 * as soon as possible after execution of at least one
576 * instruction, execution stops again. [ ... ]"
578 #endif
579 case PT_CONTINUE:
580 case PT_SYSCALL:
581 case PT_DETACH:
582 if (req == PT_SYSCALL) {
583 if (!ISSET(t->p_slflag, PSL_SYSCALL)) {
584 SET(t->p_slflag, PSL_SYSCALL);
585 #ifdef __HAVE_SYSCALL_INTERN
586 (*t->p_emul->e_syscall_intern)(t);
587 #endif
589 } else {
590 if (ISSET(t->p_slflag, PSL_SYSCALL)) {
591 CLR(t->p_slflag, PSL_SYSCALL);
592 #ifdef __HAVE_SYSCALL_INTERN
593 (*t->p_emul->e_syscall_intern)(t);
594 #endif
597 p->p_trace_enabled = trace_is_enabled(p);
600 * From the 4.4BSD PRM:
601 * "The data argument is taken as a signal number and the
602 * child's execution continues at location addr as if it
603 * incurred that signal. Normally the signal number will
604 * be either 0 to indicate that the signal that caused the
605 * stop should be ignored, or that value fetched out of
606 * the process's image indicating which signal caused
607 * the stop. If addr is (int *)1 then execution continues
608 * from where it stopped."
611 /* Check that the data is a valid signal number or zero. */
612 if (SCARG(uap, data) < 0 || SCARG(uap, data) >= NSIG) {
613 error = EINVAL;
614 break;
617 /* If the address parameter is not (int *)1, set the pc. */
618 if ((int *)SCARG(uap, addr) != (int *)1) {
619 error = process_set_pc(lt, SCARG(uap, addr));
620 if (error != 0)
621 break;
623 #ifdef PT_STEP
625 * Arrange for a single-step, if that's requested and possible.
627 error = process_sstep(lt, req == PT_STEP);
628 if (error)
629 break;
630 #endif
631 if (req == PT_DETACH) {
632 CLR(t->p_slflag, PSL_TRACED|PSL_FSTRACE|PSL_SYSCALL);
634 /* give process back to original parent or init */
635 if (t->p_opptr != t->p_pptr) {
636 struct proc *pp = t->p_opptr;
637 proc_reparent(t, pp ? pp : initproc);
640 /* not being traced any more */
641 t->p_opptr = NULL;
644 signo = SCARG(uap, data);
645 sendsig:
646 /* Finally, deliver the requested signal (or none). */
647 if (t->p_stat == SSTOP) {
649 * Unstop the process. If it needs to take a
650 * signal, make all efforts to ensure that at
651 * an LWP runs to see it.
653 t->p_xstat = signo;
654 proc_unstop(t);
655 } else if (signo != 0) {
656 KSI_INIT_EMPTY(&ksi);
657 ksi.ksi_signo = signo;
658 kpsignal2(t, &ksi);
660 break;
662 case PT_KILL:
663 /* just send the process a KILL signal. */
664 signo = SIGKILL;
665 goto sendsig; /* in PT_CONTINUE, above. */
667 case PT_ATTACH:
669 * Go ahead and set the trace flag.
670 * Save the old parent (it's reset in
671 * _DETACH, and also in kern_exit.c:wait4()
672 * Reparent the process so that the tracing
673 * proc gets to see all the action.
674 * Stop the target.
676 t->p_opptr = t->p_pptr;
677 if (t->p_pptr != p) {
678 struct proc *parent = t->p_pptr;
680 if (parent->p_lock < t->p_lock) {
681 if (!mutex_tryenter(parent->p_lock)) {
682 mutex_exit(t->p_lock);
683 mutex_enter(parent->p_lock);
685 } else if (parent->p_lock > t->p_lock) {
686 mutex_enter(parent->p_lock);
688 parent->p_slflag |= PSL_CHTRACED;
689 proc_reparent(t, p);
690 if (parent->p_lock != t->p_lock)
691 mutex_exit(parent->p_lock);
693 SET(t->p_slflag, PSL_TRACED);
694 signo = SIGSTOP;
695 goto sendsig;
697 case PT_LWPINFO:
698 if (SCARG(uap, data) != sizeof(pl)) {
699 error = EINVAL;
700 break;
702 error = copyin(SCARG(uap, addr), &pl, sizeof(pl));
703 if (error)
704 break;
705 tmp = pl.pl_lwpid;
706 lwp_delref(lt);
707 mutex_enter(t->p_lock);
708 if (tmp == 0)
709 lt = lwp_find_first(t);
710 else {
711 lt = lwp_find(t, tmp);
712 if (lt == NULL) {
713 mutex_exit(t->p_lock);
714 error = ESRCH;
715 break;
717 lt = LIST_NEXT(lt, l_sibling);
719 while (lt != NULL && !lwp_alive(lt))
720 lt = LIST_NEXT(lt, l_sibling);
721 pl.pl_lwpid = 0;
722 pl.pl_event = 0;
723 if (lt) {
724 lwp_addref(lt);
725 pl.pl_lwpid = lt->l_lid;
726 if (lt->l_lid == t->p_sigctx.ps_lwp)
727 pl.pl_event = PL_EVENT_SIGNAL;
729 mutex_exit(t->p_lock);
731 error = copyout(&pl, SCARG(uap, addr), sizeof(pl));
732 break;
734 #ifdef PT_SETREGS
735 case PT_SETREGS:
736 write = 1;
737 #endif
738 #ifdef PT_GETREGS
739 case PT_GETREGS:
740 /* write = 0 done above. */
741 #endif
742 #if defined(PT_SETREGS) || defined(PT_GETREGS)
743 tmp = SCARG(uap, data);
744 if (tmp != 0 && t->p_nlwps > 1) {
745 lwp_delref(lt);
746 mutex_enter(t->p_lock);
747 lt = lwp_find(t, tmp);
748 if (lt == NULL) {
749 mutex_exit(t->p_lock);
750 error = ESRCH;
751 break;
753 lwp_addref(lt);
754 mutex_exit(t->p_lock);
756 if (!process_validregs(lt))
757 error = EINVAL;
758 else {
759 error = proc_vmspace_getref(l->l_proc, &vm);
760 if (error)
761 break;
762 iov.iov_base = SCARG(uap, addr);
763 iov.iov_len = sizeof(struct reg);
764 uio.uio_iov = &iov;
765 uio.uio_iovcnt = 1;
766 uio.uio_offset = 0;
767 uio.uio_resid = sizeof(struct reg);
768 uio.uio_rw = write ? UIO_WRITE : UIO_READ;
769 uio.uio_vmspace = vm;
771 error = process_doregs(l, lt, &uio);
772 uvmspace_free(vm);
774 break;
775 #endif
777 #ifdef PT_SETFPREGS
778 case PT_SETFPREGS:
779 write = 1;
780 #endif
781 #ifdef PT_GETFPREGS
782 case PT_GETFPREGS:
783 /* write = 0 done above. */
784 #endif
785 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS)
786 tmp = SCARG(uap, data);
787 if (tmp != 0 && t->p_nlwps > 1) {
788 lwp_delref(lt);
789 mutex_enter(t->p_lock);
790 lt = lwp_find(t, tmp);
791 if (lt == NULL) {
792 mutex_exit(t->p_lock);
793 error = ESRCH;
794 break;
796 lwp_addref(lt);
797 mutex_exit(t->p_lock);
799 if (!process_validfpregs(lt))
800 error = EINVAL;
801 else {
802 error = proc_vmspace_getref(l->l_proc, &vm);
803 if (error)
804 break;
805 iov.iov_base = SCARG(uap, addr);
806 iov.iov_len = sizeof(struct fpreg);
807 uio.uio_iov = &iov;
808 uio.uio_iovcnt = 1;
809 uio.uio_offset = 0;
810 uio.uio_resid = sizeof(struct fpreg);
811 uio.uio_rw = write ? UIO_WRITE : UIO_READ;
812 uio.uio_vmspace = vm;
814 error = process_dofpregs(l, lt, &uio);
815 uvmspace_free(vm);
817 break;
818 #endif
820 #ifdef __HAVE_PTRACE_MACHDEP
821 PTRACE_MACHDEP_REQUEST_CASES
822 error = ptrace_machdep_dorequest(l, lt,
823 req, SCARG(uap, addr), SCARG(uap, data));
824 break;
825 #endif
828 if (pheld) {
829 mutex_exit(t->p_lock);
830 mutex_exit(proc_lock);
832 if (lt != NULL)
833 lwp_delref(lt);
834 rw_exit(&t->p_reflock);
836 return error;
840 process_doregs(struct lwp *curl /*tracer*/,
841 struct lwp *l /*traced*/,
842 struct uio *uio)
844 #if defined(PT_GETREGS) || defined(PT_SETREGS)
845 int error;
846 struct reg r;
847 char *kv;
848 int kl;
850 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r))
851 return EINVAL;
853 kl = sizeof(r);
854 kv = (char *)&r;
856 kv += uio->uio_offset;
857 kl -= uio->uio_offset;
858 if ((size_t)kl > uio->uio_resid)
859 kl = uio->uio_resid;
861 error = process_read_regs(l, &r);
862 if (error == 0)
863 error = uiomove(kv, kl, uio);
864 if (error == 0 && uio->uio_rw == UIO_WRITE) {
865 if (l->l_stat != LSSTOP)
866 error = EBUSY;
867 else
868 error = process_write_regs(l, &r);
871 uio->uio_offset = 0;
872 return (error);
873 #else
874 return (EINVAL);
875 #endif
879 process_validregs(struct lwp *l)
882 #if defined(PT_SETREGS) || defined(PT_GETREGS)
883 return ((l->l_flag & LW_SYSTEM) == 0);
884 #else
885 return (0);
886 #endif
890 process_dofpregs(struct lwp *curl /*tracer*/,
891 struct lwp *l /*traced*/,
892 struct uio *uio)
894 #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS)
895 int error;
896 struct fpreg r;
897 char *kv;
898 size_t kl;
900 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r))
901 return EINVAL;
903 kl = sizeof(r);
904 kv = (char *)&r;
906 kv += uio->uio_offset;
907 kl -= uio->uio_offset;
908 if ((size_t)kl > uio->uio_resid)
909 kl = uio->uio_resid;
911 #ifdef __HAVE_PROCESS_XFPREGS
912 error = process_read_xfpregs(l, &r, &kl);
913 #else
914 error = process_read_fpregs(l, &r);
915 #endif
916 if (error == 0)
917 error = uiomove(kv, kl, uio);
918 if (error == 0 && uio->uio_rw == UIO_WRITE) {
919 if (l->l_stat != LSSTOP)
920 error = EBUSY;
921 else
922 #ifdef __HAVE_PROCESS_XFPREGS
923 error = process_write_xfpregs(l, &r, kl);
924 #else
925 error = process_write_fpregs(l, &r);
926 #endif
928 uio->uio_offset = 0;
929 return (error);
930 #else
931 return (EINVAL);
932 #endif
936 process_validfpregs(struct lwp *l)
939 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS)
940 return ((l->l_flag & LW_SYSTEM) == 0);
941 #else
942 return (0);
943 #endif
945 #endif /* PTRACE */
947 #if defined(KTRACE) || defined(PTRACE)
949 process_domem(struct lwp *curl /*tracer*/,
950 struct lwp *l /*traced*/,
951 struct uio *uio)
953 struct proc *p = l->l_proc; /* traced */
954 struct vmspace *vm;
955 int error;
957 size_t len;
958 #ifdef PMAP_NEED_PROCWR
959 vaddr_t addr;
960 #endif
962 error = 0;
963 len = uio->uio_resid;
965 if (len == 0)
966 return (0);
968 #ifdef PMAP_NEED_PROCWR
969 addr = uio->uio_offset;
970 #endif
972 vm = p->p_vmspace;
974 mutex_enter(&vm->vm_map.misc_lock);
975 if ((l->l_flag & LW_WEXIT) || vm->vm_refcnt < 1)
976 error = EFAULT;
977 if (error == 0)
978 p->p_vmspace->vm_refcnt++; /* XXX */
979 mutex_exit(&vm->vm_map.misc_lock);
980 if (error != 0)
981 return (error);
982 error = uvm_io(&vm->vm_map, uio);
983 uvmspace_free(vm);
985 #ifdef PMAP_NEED_PROCWR
986 if (error == 0 && uio->uio_rw == UIO_WRITE)
987 pmap_procwr(p, addr, len);
988 #endif
989 return (error);
991 #endif /* KTRACE || PTRACE */
993 #if defined(KTRACE) || defined(PTRACE)
994 void
995 process_stoptrace(void)
997 struct lwp *l = curlwp;
998 struct proc *p = l->l_proc, *pp;
1000 mutex_enter(proc_lock);
1001 mutex_enter(p->p_lock);
1002 pp = p->p_pptr;
1003 if (pp->p_pid == 1) {
1004 CLR(p->p_slflag, PSL_SYSCALL); /* XXXSMP */
1005 mutex_exit(p->p_lock);
1006 mutex_exit(proc_lock);
1007 return;
1010 p->p_xstat = SIGTRAP;
1011 proc_stop(p, 1, SIGSTOP);
1012 mutex_exit(proc_lock);
1015 * Call issignal() once only, to have it take care of the
1016 * pending stop. Signal processing will take place as usual
1017 * from userret().
1019 KERNEL_UNLOCK_ALL(l, &l->l_biglocks);
1020 (void)issignal(l);
1021 mutex_exit(p->p_lock);
1022 KERNEL_LOCK(l->l_biglocks, l);
1024 #endif /* KTRACE || PTRACE */