This commit was manufactured by cvs2svn to create tag 'FreeBSD-release/1.0'.
[unix-history] / sys / kern / sys_process.c
CommitLineData
15637ed4
RG
1/*
2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * from: @(#)sys_process.c 7.22 (Berkeley) 5/11/91
78ed81a3 34 * $Id$
15637ed4
RG
35 */
36
78ed81a3 37#include <stddef.h>
38
15637ed4
RG
39#define IPCREG
40#include "param.h"
41#include "proc.h"
42#include "vnode.h"
43#include "buf.h"
44#include "ptrace.h"
45
78ed81a3 46#include "machine/eflags.h"
15637ed4
RG
47#include "machine/reg.h"
48#include "machine/psl.h"
49#include "vm/vm.h"
50#include "vm/vm_page.h"
51
52#include "user.h"
53
54/*
55 * NOTES.
56 *
57 * The following ptrace calls have been defined in addition to
58 * the standard ones found in original <sys/ptrace.h>:
59 *
60 * PT_ATTACH - attach to running process
61 * PT_DETACH - detach from running process
62 * PT_SYSCALL - trace system calls
63 * PT_GETREG - get register file
64 * PT_SETREG - set register file
65 * PT_BREAD_[IDU] - block read from process (not yet implemented)
66 * PT_BWRITE_[IDU] - block write " "
67 * PT_INHERIT - make forked processes inherit trace flags
68 *
69 */
70
71/* Define to prevent extraneous clutter in source */
72#ifndef SSTRC
73#define SSTRC 0
74#endif
75#ifndef SFTRC
76#define SFTRC 0
77#endif
78
79/*
80 * `ipcreg' defined in <machine/reg.h>
81 * Should we define a structure with all regs?
82 */
83int sipcreg[NIPCREG] =
84 { 0,0,sEDI,sESI,sEBP,sEBX,sEDX,sECX,sEAX,sEIP,sCS,sEFLAGS,sESP,sSS };
85
86struct {
87 int flag;
88#define IPC_BUSY 1
89#define IPC_WANT 2
90#define IPC_DONE 4
91 int req; /* copy of ptrace request */
92 int *addr; /* copy of ptrace address */
93 int data; /* copy of ptrace data */
94 int error; /* errno from `procxmt' */
95 int regs[NIPCREG]; /* PT_[GS]ETREG */
96 caddr_t buf; /* PT_BREAD/WRITE */
97 int buflen; /* " */
98} ipc;
99
100/*
101 * Process debugging system call.
102 */
78ed81a3 103
104struct ptrace_args {
105 int req;
106 int pid;
107 int *addr;
108 int data;
109};
110
15637ed4
RG
111ptrace(curp, uap, retval)
112 struct proc *curp;
78ed81a3 113 register struct ptrace_args *uap;
15637ed4
RG
114 int *retval;
115{
116 struct proc *p;
117 int s, error = 0;
118
119 *retval = 0;
120 if (uap->req == PT_TRACE_ME) {
121 curp->p_flag |= STRC;
122 /*p->p_tptr = p->p_pptr; * What shall we do here ? */
123 return 0;
124 }
125 if ((p = pfind(uap->pid)) == NULL) {
126 return ESRCH;
127 }
128
129#ifdef notyet
130 if (uap->req != PT_ATTACH && (
131 (p->p_flag & STRC) == 0 ||
132 (p->p_tptr && curp != p->p_tptr) ||
133 (!p->p_tptr && curp != p->p_pptr)))
134
135 return ESRCH;
136#endif
137
138
139#ifdef PT_ATTACH
140 switch (uap->req) {
141 case PT_ATTACH:
142 if (curp->p_ucred->cr_uid != 0 && (
143 curp->p_ucred->cr_uid != p->p_ucred->cr_uid ||
144 curp->p_ucred->cr_uid != p->p_cred->p_svuid))
145 return EACCES;
146
147 p->p_tptr = curp;
148 p->p_flag |= STRC;
149 psignal(p, SIGTRAP);
150 return 0;
151
152 case PT_DETACH:
153 if ((unsigned)uap->data >= NSIG)
154 return EINVAL;
155 p->p_flag &= ~(STRC|SSTRC|SFTRC);
156 p->p_tptr = NULL;
157 psignal(p->p_pptr, SIGCHLD);
158 wakeup((caddr_t)p->p_pptr);
159 s = splhigh();
160 if (p->p_stat == SSTOP) {
161 p->p_xstat = uap->data;
162 setrun(p);
163 } else if (uap->data) {
164 psignal(p, uap->data);
165 }
166 splx(s);
167 return 0;
168
169#ifdef PT_INHERIT
170 case PT_INHERIT:
171 if ((p->p_flag & STRC) == 0)
172 return ESRCH;
173 p->p_flag |= SFTRC;
174 return 0;
175#endif
176
177 default:
178 break;
179 }
180#endif
181
182 /* Other ptrace calls require target process to be in stopped state */
183 if ((p->p_flag & STRC) == 0 || p->p_stat != SSTOP) {
184 return ESRCH;
185 }
186
187 /* Acquire the ipc structure */
188 while (ipc.flag & IPC_BUSY) {
189 ipc.flag |= IPC_WANT;
190 error = tsleep((caddr_t)&ipc, PWAIT|PCATCH, "ipc", 0);
191 if (error)
192 goto out;
193 }
194
195 /* Got it, fill it */
196 ipc.flag = IPC_BUSY;
197 ipc.error = 0;
198 ipc.req = uap->req;
199 ipc.addr = uap->addr;
200 ipc.data = uap->data;
201
202#ifdef PT_GETREGS
203 switch (uap->req) {
204 case PT_SETREGS:
205 error = copyin((char *)ipc.addr, (char *)ipc.regs, sizeof(ipc.regs));
206 if (error)
207 goto out;
208 break;
209
210#ifdef notyet /* requires change in number of args to ptrace syscall */
211 case PT_BWRITE_I:
212 case PT_BWRITE_D:
213 ipc.buflen = uap->data;
214 ipc.buf = kmem_alloc_wait(kernelmap, uap->data);
215 error = copyin((char *)ipc.addr, (char *)ipc.buf, ipc.buflen);
216 if (error) {
217 kmem_free_wakeup(kernelmap, ipc.buf, ipc.buflen);
218 goto out;
219 }
220#endif
221 default:
222 break;
223 }
224#endif
225
226 setrun(p);
227 while ((ipc.flag & IPC_DONE) == 0) {
228 error = tsleep((caddr_t)&ipc, PWAIT|PCATCH, "ipc", 0);
229 if (error)
230 goto out;
231 }
232
233 *retval = ipc.data;
234 if (error = ipc.error)
235 goto out;
236
237#ifdef PT_GETREGS
238 switch (uap->req) {
239 case PT_GETREGS:
240 error = copyout((char *)ipc.regs, (char *)ipc.addr, sizeof(ipc.regs));
241 break;
242
243 case PT_BREAD_I:
244 case PT_BREAD_D:
245 /* Not yet */
246 default:
247 break;
248 }
249#endif
250
251out:
252 /* Release ipc structure */
253 ipc.flag &= ~IPC_BUSY;
254 if (ipc.flag & IPC_WANT) {
255 ipc.flag &= ~IPC_WANT;
256 wakeup((caddr_t)&ipc);
257 }
258 return error;
259}
260
261procxmt(p)
262 register struct proc *p;
263{
264 int i, *xreg, rv = 0;
78ed81a3 265#ifdef i386
266 int new_eflags, old_cs, old_ds, old_es, old_ss, old_eflags;
267 int *regs;
268#endif
15637ed4
RG
269
270 /* Are we still being traced? */
271 if ((p->p_flag & STRC) == 0)
272 return 1;
273
274 p->p_addr->u_kproc.kp_proc = *p;
275 fill_eproc(p, &p->p_addr->u_kproc.kp_eproc);
276
277 switch (ipc.req) {
278 case PT_READ_I:
279 case PT_READ_D:
280 if (!useracc(ipc.addr, sizeof(ipc.data), B_READ)) {
281 ipc.error = EFAULT;
282 break;
283 }
284 ipc.error = copyin((char *)ipc.addr, (char *)&ipc.data, sizeof(ipc.data));
285 break;
286
287 case PT_READ_U:
288 if ((u_int)ipc.addr > UPAGES * NBPG - sizeof(int)) {
289 ipc.error = EFAULT;
290 break;
291 }
292 ipc.data = *(int *)((u_int)p->p_addr + (u_int)ipc.addr);
293 break;
294
295 case PT_WRITE_I:
296 case PT_WRITE_D: { /* 04 Sep 92*/
297 vm_prot_t prot; /* current protection of region */
298 int cow; /* ensure copy-on-write happens */
299
300 if (cow = (useracc(ipc.addr, sizeof(ipc.data), B_WRITE) == 0)) {
301 vm_offset_t addr = (vm_offset_t)ipc.addr;
302 vm_size_t size;
303 vm_prot_t max_prot;
304 vm_inherit_t inh;
305 boolean_t shared;
306 vm_object_t object;
307 vm_offset_t objoff;
308
309 /*
310 * XXX - the useracc check is stronger than the vm
311 * checks because the user page tables are in the map.
78ed81a3 312 * Anyway, most of this can be removed now that COW
313 * works.
15637ed4
RG
314 */
315 if (!useracc(ipc.addr, sizeof(ipc.data), B_READ) ||
316 vm_region(&p->p_vmspace->vm_map, &addr, &size,
317 &prot, &max_prot, &inh, &shared,
318 &object, &objoff) != KERN_SUCCESS ||
319 vm_protect(&p->p_vmspace->vm_map, ipc.addr,
320 sizeof(ipc.data), FALSE,
321 prot|VM_PROT_WRITE) != KERN_SUCCESS ||
322 vm_fault(&p->p_vmspace->vm_map,trunc_page(ipc.addr),
323 VM_PROT_WRITE, FALSE) != KERN_SUCCESS) {
324
325 ipc.error = EFAULT;
326 break;
327 }
328 }
329 ipc.error = copyout((char *)&ipc.data,
330 (char *)ipc.addr, sizeof(ipc.data));
331 if (cow)
332 if (vm_protect(&p->p_vmspace->vm_map, ipc.addr,
333 sizeof(ipc.data), FALSE,
334 prot) != KERN_SUCCESS)
335 printf("ptrace: oops\n");
336 break;
337 }
338
339 case PT_WRITE_U:
78ed81a3 340#ifdef i386
341 regs = p->p_regs;
342 /*
343 * XXX - privileged kernel state is scattered all over the
344 * user area. Only allow write access to areas known to
345 * be safe.
346 */
347#define GO_IF_SAFE(min, size) \
348 if ((u_int)ipc.addr >= (min) \
349 && (u_int)ipc.addr <= (min) + (size) - sizeof(int)) \
350 goto pt_write_u
351 /*
352 * Allow writing entire FPU state.
353 */
354 GO_IF_SAFE(offsetof(struct user, u_pcb)
355 + offsetof(struct pcb, pcb_savefpu),
356 sizeof(struct save87));
357 /*
358 * Allow writing ordinary registers. Changes to segment
359 * registers and to some bits in %eflags will be silently
360 * ignored. Such changes ought to be an error.
361 */
362/*
363 * XXX - there is no define for the base of the user area except USRSTACK.
364 * XXX - USRSTACK is not the base of the user stack. It is the base of the
365 * user area.
366 */
367#define USER_OFF(va) ((u_int)(va) - USRSTACK)
368 GO_IF_SAFE(USER_OFF(regs),
369 (curpcb->pcb_flags & FM_TRAP ? tSS + 1 : sSS + 1)
370 * sizeof *regs);
371 ipc.error = EFAULT;
372 break;
373#else
15637ed4
RG
374 if ((u_int)ipc.addr > UPAGES * NBPG - sizeof(int)) {
375 ipc.error = EFAULT;
376 break;
377 }
78ed81a3 378#endif
379 pt_write_u:
380#ifdef i386
381 if (curpcb->pcb_flags & FM_TRAP) {
382 old_cs = regs[tCS];
383 old_ds = regs[tES];
384 old_es = regs[tES];
385 old_ss = regs[tSS];
386 old_eflags = regs[tEFLAGS];
387 } else {
388 old_cs = regs[sCS];
389 old_ss = regs[sSS];
390 old_eflags = regs[sEFLAGS];
391 }
392#endif
15637ed4 393 *(int *)((u_int)p->p_addr + (u_int)ipc.addr) = ipc.data;
78ed81a3 394#ifdef i386
395 /*
396 * Don't allow segment registers to change (although they can
397 * be changed directly to certain values).
398 * Don't allow privileged bits in %eflags to change. Users
399 * have privilege to change TF and NT although although they
400 * usually shouldn't.
401 * XXX - fix PT_SETREGS.
402 * XXX - simplify. Maybe copy through a temporary struct.
403 * Watch out for problems when ipc.addr is not a multiple
404 * of the register size.
405 */
406#define EFL_UNPRIVILEGED (EFL_CF | EFL_PF | EFL_AF | EFL_ZF | EFL_SF \
407 | EFL_TF | EFL_DF | EFL_OF | EFL_NT)
408 if (curpcb->pcb_flags & FM_TRAP) {
409 regs[tCS] = old_cs;
410 regs[tDS] = old_ds;
411 regs[tES] = old_es;
412 regs[tSS] = old_es;
413 new_eflags = regs[tEFLAGS];
414 regs[tEFLAGS]
415 = (new_eflags & EFL_UNPRIVILEGED)
416 | (old_eflags & ~EFL_UNPRIVILEGED);
417 } else {
418 regs[sCS] = old_cs;
419 regs[sSS] = old_ss;
420 new_eflags = regs[sEFLAGS];
421 regs[sEFLAGS]
422 = (new_eflags & EFL_UNPRIVILEGED)
423 | (old_eflags & ~EFL_UNPRIVILEGED);
424 }
425#endif
15637ed4
RG
426 break;
427
428 case PT_CONTINUE:
429 if (ipc.addr != (int *)1) {
430#ifdef i386
431 p->p_regs[(curpcb->pcb_flags&FM_TRAP)?tEIP:sEIP] = (int)ipc.addr;
432#endif
433 }
434 p->p_flag &= ~SSTRC; /* Only set by PT_SYSCALL */
435 if ((unsigned)ipc.data >= NSIG) {
436 ipc.error = EINVAL;
437 } else {
438 p->p_xstat = ipc.data;
439 rv = 1;
440 }
441 break;
442
443 case PT_KILL:
444 p->p_flag &= ~SSTRC; /* Only set by PT_SYSCALL */
445 rv = 2;
446 break;
447
448 case PT_STEP:
449#ifdef i386
450 if (ipc.addr != (int *)1) {
451 p->p_regs[(curpcb->pcb_flags&FM_TRAP)?tEIP:sEIP] = (int)ipc.addr;
452 }
453 p->p_regs[(curpcb->pcb_flags&FM_TRAP)?tEFLAGS:sEFLAGS] |= PSL_T;
454#endif
455 p->p_flag &= ~SSTRC; /* Only set by PT_SYSCALL */
456 p->p_xstat = 0;
457 rv = 1;
458 break;
459
460#ifdef PT_SYSCALL
461 case PT_SYSCALL:
462 if (ipc.addr != (int *)1) {
463#ifdef i386
464 p->p_regs[(curpcb->pcb_flags&FM_TRAP)?tEIP:sEIP] = (int)ipc.addr;
465#endif
466 }
467 p->p_flag |= SSTRC;
468 p->p_xstat = 0;
469 rv = 1;
470 break;
471#endif
472#ifdef PT_GETREGS
473 case PT_GETREGS:
474#ifdef i386
475 xreg = (curpcb->pcb_flags&FM_TRAP)?ipcreg:sipcreg;
476#endif
477
478 for (i = 0; i < NIPCREG; i++)
479 ipc.regs[i] = p->p_regs[xreg[i]];
480 break;
481
482 case PT_SETREGS:
483#ifdef i386
484 xreg = (curpcb->pcb_flags&FM_TRAP)?ipcreg:sipcreg;
485#endif
486
487 for (i = 0; i < NIPCREG; i++)
488 p->p_regs[xreg[i]] = ipc.regs[i];
489 break;
490#endif
491
492#ifdef PT_DUMP
493 case PT_DUMP:
494 /* Should be able to specify core file name */
495 ipc.error = coredump(p);
496 break;
497#endif
498
499 default:
500 ipc.error = EINVAL;
501 }
502 ipc.flag |= IPC_DONE;
503 wakeup((caddr_t)&ipc);
504
505 if (rv == 2)
78ed81a3 506 kexit(p, 0); /*???*/
15637ed4
RG
507
508 return rv;
509}
510
511/*
512 * Enable process profiling system call.
513 */
78ed81a3 514
515struct profil_args {
516 short *bufbase; /* base of data buffer */
517 unsigned bufsize; /* size of data buffer */
518 unsigned pcoffset; /* pc offset (for subtraction) */
519 unsigned pcscale; /* scaling factor for offset pc */
520};
521
15637ed4
RG
522/* ARGSUSED */
523profil(p, uap, retval)
524 struct proc *p;
78ed81a3 525 register struct profil_args *uap;
15637ed4
RG
526 int *retval;
527{
528 /* from looking at man pages, and include files, looks like
529 * this just sets up the fields of p->p_stats->p_prof...
530 * and those fields come straight from the args.
531 * only thing *we* have to do is check the args for validity...
532 *
533 * cgd
534 */
535
536 /* check to make sure that the buffer is OK. addupc (in locore)
537 * checks for faults, but would one be generated, say, writing to
538 * kernel space? probably not -- it just uses "movl"...
539 *
540 * so we've gotta check to make sure that the info set up for
541 * addupc is set right... it's gotta be writable by the user...
542 */
543
544 if (useracc(uap->bufbase,uap->bufsize*sizeof(short),B_WRITE) == 0)
545 return EFAULT;
546
547 p->p_stats->p_prof.pr_base = uap->bufbase;
548 p->p_stats->p_prof.pr_size = uap->bufsize;
549 p->p_stats->p_prof.pr_off = uap->pcoffset;
550 p->p_stats->p_prof.pr_scale = uap->pcscale;
551
552 return 0;
553}