Deleted Added
full compact
procfs_ctl.c (85297) procfs_ctl.c (87321)
1/*
2 * Copyright (c) 1993 Jan-Simon Pendry
3 * Copyright (c) 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Jan-Simon Pendry.
8 *

--- 21 unchanged lines hidden (view full) ---

30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 * @(#)procfs_ctl.c 8.4 (Berkeley) 6/15/94
1/*
2 * Copyright (c) 1993 Jan-Simon Pendry
3 * Copyright (c) 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Jan-Simon Pendry.
8 *

--- 21 unchanged lines hidden (view full) ---

30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 * @(#)procfs_ctl.c 8.4 (Berkeley) 6/15/94
38 * $FreeBSD: head/sys/fs/procfs/procfs_ctl.c 85297 2001-10-21 23:57:24Z des $
38 * $FreeBSD: head/sys/fs/procfs/procfs_ctl.c 87321 2001-12-04 01:35:06Z des $
39 */
40
41#include <sys/param.h>
42#include <sys/systm.h>
43#include <sys/lock.h>
44#include <sys/mutex.h>
45#include <sys/proc.h>
46#include <sys/ptrace.h>
39 */
40
41#include <sys/param.h>
42#include <sys/systm.h>
43#include <sys/lock.h>
44#include <sys/mutex.h>
45#include <sys/proc.h>
46#include <sys/ptrace.h>
47#include <sys/sbuf.h>
47#include <sys/signalvar.h>
48#include <sys/sx.h>
48#include <sys/signalvar.h>
49#include <sys/sx.h>
49#include <sys/vnode.h>
50#include <sys/uio.h>
50
51
52#include <fs/pseudofs/pseudofs.h>
51#include <fs/procfs/procfs.h>
52
53#include <vm/vm.h>
54
55/*
56 * True iff process (p) is in trace wait state
57 * relative to process (curp)
58 */
59#define TRACE_WAIT_P(curp, p) \
60 ((p)->p_stat == SSTOP && \
61 (p)->p_pptr == (curp) && \
62 ((p)->p_flag & P_TRACED))
63
64#define PROCFS_CTL_ATTACH 1
65#define PROCFS_CTL_DETACH 2
66#define PROCFS_CTL_STEP 3
67#define PROCFS_CTL_RUN 4
68#define PROCFS_CTL_WAIT 5
69
53#include <fs/procfs/procfs.h>
54
55#include <vm/vm.h>
56
57/*
58 * True iff process (p) is in trace wait state
59 * relative to process (curp)
60 */
61#define TRACE_WAIT_P(curp, p) \
62 ((p)->p_stat == SSTOP && \
63 (p)->p_pptr == (curp) && \
64 ((p)->p_flag & P_TRACED))
65
66#define PROCFS_CTL_ATTACH 1
67#define PROCFS_CTL_DETACH 2
68#define PROCFS_CTL_STEP 3
69#define PROCFS_CTL_RUN 4
70#define PROCFS_CTL_WAIT 5
71
70static vfs_namemap_t ctlnames[] = {
72struct namemap {
73 const char *nm_name;
74 int nm_val;
75};
76
77static struct namemap ctlnames[] = {
71 /* special /proc commands */
72 { "attach", PROCFS_CTL_ATTACH },
73 { "detach", PROCFS_CTL_DETACH },
74 { "step", PROCFS_CTL_STEP },
75 { "run", PROCFS_CTL_RUN },
76 { "wait", PROCFS_CTL_WAIT },
77 { 0 },
78};
79
78 /* special /proc commands */
79 { "attach", PROCFS_CTL_ATTACH },
80 { "detach", PROCFS_CTL_DETACH },
81 { "step", PROCFS_CTL_STEP },
82 { "run", PROCFS_CTL_RUN },
83 { "wait", PROCFS_CTL_WAIT },
84 { 0 },
85};
86
80static vfs_namemap_t signames[] = {
87static struct namemap signames[] = {
81 /* regular signal names */
82 { "hup", SIGHUP }, { "int", SIGINT },
83 { "quit", SIGQUIT }, { "ill", SIGILL },
84 { "trap", SIGTRAP }, { "abrt", SIGABRT },
85 { "iot", SIGIOT }, { "emt", SIGEMT },
86 { "fpe", SIGFPE }, { "kill", SIGKILL },
87 { "bus", SIGBUS }, { "segv", SIGSEGV },
88 { "sys", SIGSYS }, { "pipe", SIGPIPE },

--- 7 unchanged lines hidden (view full) ---

96 { "winch", SIGWINCH }, { "info", SIGINFO },
97 { "usr1", SIGUSR1 }, { "usr2", SIGUSR2 },
98 { 0 },
99};
100
101static int procfs_control __P((struct proc *curp, struct proc *p, int op));
102
103static int
88 /* regular signal names */
89 { "hup", SIGHUP }, { "int", SIGINT },
90 { "quit", SIGQUIT }, { "ill", SIGILL },
91 { "trap", SIGTRAP }, { "abrt", SIGABRT },
92 { "iot", SIGIOT }, { "emt", SIGEMT },
93 { "fpe", SIGFPE }, { "kill", SIGKILL },
94 { "bus", SIGBUS }, { "segv", SIGSEGV },
95 { "sys", SIGSYS }, { "pipe", SIGPIPE },

--- 7 unchanged lines hidden (view full) ---

103 { "winch", SIGWINCH }, { "info", SIGINFO },
104 { "usr1", SIGUSR1 }, { "usr2", SIGUSR2 },
105 { 0 },
106};
107
108static int procfs_control __P((struct proc *curp, struct proc *p, int op));
109
110static int
104procfs_control(curp, p, op)
105 struct proc *curp;
106 struct proc *p;
107 int op;
111procfs_control(struct proc *curp, struct proc *p, int op)
108{
109 int error = 0;
110
111 /*
112 * Authorization check: rely on normal debugging protection, except
113 * allow processes to disengage debugging on a process onto which
114 * they have previously attached, but no longer have permission to
115 * debug.

--- 119 unchanged lines hidden (view full) ---

235 wakeup((caddr_t) curp); /* XXX for CTL_WAIT below ? */
236
237 break;
238
239 /*
240 * Step. Let the target process execute a single instruction.
241 */
242 case PROCFS_CTL_STEP:
112{
113 int error = 0;
114
115 /*
116 * Authorization check: rely on normal debugging protection, except
117 * allow processes to disengage debugging on a process onto which
118 * they have previously attached, but no longer have permission to
119 * debug.

--- 119 unchanged lines hidden (view full) ---

239 wakeup((caddr_t) curp); /* XXX for CTL_WAIT below ? */
240
241 break;
242
243 /*
244 * Step. Let the target process execute a single instruction.
245 */
246 case PROCFS_CTL_STEP:
243 _PHOLD(p);
244 PROC_UNLOCK(p);
245 error = proc_sstep(&p->p_thread); /* XXXKSE */
246 PRELE(p);
247 if (error)
248 return (error);
249 break;
250
251 /*

--- 44 unchanged lines hidden (view full) ---

296
297 mtx_lock_spin(&sched_lock);
298 if (p->p_stat == SSTOP)
299 setrunnable(&p->p_thread); /* XXXKSE */
300 mtx_unlock_spin(&sched_lock);
301 return (0);
302}
303
247 PROC_UNLOCK(p);
248 error = proc_sstep(&p->p_thread); /* XXXKSE */
249 PRELE(p);
250 if (error)
251 return (error);
252 break;
253
254 /*

--- 44 unchanged lines hidden (view full) ---

299
300 mtx_lock_spin(&sched_lock);
301 if (p->p_stat == SSTOP)
302 setrunnable(&p->p_thread); /* XXXKSE */
303 mtx_unlock_spin(&sched_lock);
304 return (0);
305}
306
307static struct namemap *
308findname(struct namemap *nm, char *buf, int buflen)
309{
310
311 for (; nm->nm_name; nm++)
312 if (bcmp(buf, nm->nm_name, buflen+1) == 0)
313 return (nm);
314
315 return (0);
316}
317
304int
318int
305procfs_doctl(curp, p, pfs, uio)
306 struct proc *curp;
307 struct pfsnode *pfs;
308 struct uio *uio;
309 struct proc *p;
319procfs_doprocctl(PFS_FILL_ARGS)
310{
320{
311 int xlen;
312 int error;
321 int error;
313 char msg[PROCFS_CTLLEN+1];
314 vfs_namemap_t *nm;
322 struct namemap *nm;
315
323
316 if (uio->uio_rw != UIO_WRITE)
324 if (uio == NULL || uio->uio_rw != UIO_WRITE)
317 return (EOPNOTSUPP);
318
325 return (EOPNOTSUPP);
326
319 xlen = PROCFS_CTLLEN;
320 error = vfs_getuserstr(uio, msg, &xlen);
321 if (error)
322 return (error);
323
324 /*
325 * Map signal names into signal generation
326 * or debug control. Unknown commands and/or signals
327 * return EOPNOTSUPP.
328 *
329 * Sending a signal while the process is being debugged
330 * also has the side effect of letting the target continue
331 * to run. There is no way to single-step a signal delivery.
332 */
333 error = EOPNOTSUPP;
334
327 /*
328 * Map signal names into signal generation
329 * or debug control. Unknown commands and/or signals
330 * return EOPNOTSUPP.
331 *
332 * Sending a signal while the process is being debugged
333 * also has the side effect of letting the target continue
334 * to run. There is no way to single-step a signal delivery.
335 */
336 error = EOPNOTSUPP;
337
335 nm = vfs_findname(ctlnames, msg, xlen);
338 sbuf_trim(sb);
339 sbuf_finish(sb);
340 nm = findname(ctlnames, sbuf_data(sb), sbuf_len(sb));
336 if (nm) {
341 if (nm) {
337 error = procfs_control(curp, p, nm->nm_val);
342 printf("procfs: got a %s command\n", sbuf_data(sb));
343 error = procfs_control(td->td_proc, p, nm->nm_val);
338 } else {
344 } else {
339 nm = vfs_findname(signames, msg, xlen);
345 nm = findname(signames, sbuf_data(sb), sbuf_len(sb));
340 if (nm) {
346 if (nm) {
347 printf("procfs: got a sig%s\n", sbuf_data(sb));
341 PROC_LOCK(p);
342 mtx_lock_spin(&sched_lock);
348 PROC_LOCK(p);
349 mtx_lock_spin(&sched_lock);
343 if (TRACE_WAIT_P(curp, p)) {
350 if (TRACE_WAIT_P(td->td_proc, p)) {
344 p->p_xstat = nm->nm_val;
345#ifdef FIX_SSTEP
346 FIX_SSTEP(&p->p_thread); /* XXXKSE */
347#endif
348 setrunnable(&p->p_thread); /* XXXKSE */
349 mtx_unlock_spin(&sched_lock);
350 } else {
351 mtx_unlock_spin(&sched_lock);
352 psignal(p, nm->nm_val);
353 }
354 PROC_UNLOCK(p);
355 error = 0;
356 }
357 }
358
359 return (error);
360}
351 p->p_xstat = nm->nm_val;
352#ifdef FIX_SSTEP
353 FIX_SSTEP(&p->p_thread); /* XXXKSE */
354#endif
355 setrunnable(&p->p_thread); /* XXXKSE */
356 mtx_unlock_spin(&sched_lock);
357 } else {
358 mtx_unlock_spin(&sched_lock);
359 psignal(p, nm->nm_val);
360 }
361 PROC_UNLOCK(p);
362 error = 0;
363 }
364 }
365
366 return (error);
367}