add memory filesystem initialization
[unix-history] / usr / src / sys / kern / sys_process.c
CommitLineData
da7c5cc6 1/*
c4ec2128 2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
da7c5cc6
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
c4ec2128 6 * @(#)sys_process.c 7.6 (Berkeley) %G%
da7c5cc6 7 */
961945a8 8
ff32eb64 9#define IPCREG
94368568 10#include "param.h"
94368568
JB
11#include "user.h"
12#include "proc.h"
c4ec2128 13#include "vnode.h"
94368568
JB
14#include "text.h"
15#include "seg.h"
94368568 16#include "buf.h"
01b0e233 17#include "ptrace.h"
9ce4de2d 18
d301d150
KM
19#include "machine/reg.h"
20#include "machine/psl.h"
21#include "machine/pte.h"
22
4147b3f6
BJ
23/*
24 * Priority for tracing
25 */
26#define IPCPRI PZERO
27
28/*
29 * Tracing variables.
30 * Used to pass trace command from
31 * parent to child being traced.
32 * This data base cannot be
33 * shared and is locked
34 * per user.
35 */
36struct {
37 int ip_lock;
38 int ip_req;
39 int *ip_addr;
40 int ip_data;
41} ipc;
42
43/*
44 * sys-trace system call.
45 */
46ptrace()
47{
48 register struct proc *p;
49 register struct a {
50 int req;
51 int pid;
52 int *addr;
53 int data;
54 } *uap;
55
56 uap = (struct a *)u.u_ap;
57 if (uap->req <= 0) {
58 u.u_procp->p_flag |= STRC;
59 return;
60 }
61 p = pfind(uap->pid);
f05cf4fe
SL
62 if (p == 0 || p->p_stat != SSTOP || p->p_ppid != u.u_procp->p_pid ||
63 !(p->p_flag & STRC)) {
4147b3f6
BJ
64 u.u_error = ESRCH;
65 return;
66 }
67 while (ipc.ip_lock)
68 sleep((caddr_t)&ipc, IPCPRI);
69 ipc.ip_lock = p->p_pid;
70 ipc.ip_data = uap->data;
71 ipc.ip_addr = uap->addr;
72 ipc.ip_req = uap->req;
73 p->p_flag &= ~SWTED;
74 while (ipc.ip_req > 0) {
75 if (p->p_stat==SSTOP)
76 setrun(p);
77 sleep((caddr_t)&ipc, IPCPRI);
78 }
79 u.u_r.r_val1 = ipc.ip_data;
80 if (ipc.ip_req < 0)
81 u.u_error = EIO;
82 ipc.ip_lock = 0;
83 wakeup((caddr_t)&ipc);
84}
85
fc0890b1 86#define PHYSOFF(p, o) \
883d0f83
BJ
87 ((physadr)(p)+((o)/sizeof(((physadr)0)->r[0])))
88
4147b3f6
BJ
89/*
90 * Code that the child process
91 * executes to implement the command
92 * of the parent process in tracing.
93 */
94procxmt()
95{
96 register int i;
97 register *p;
98 register struct text *xp;
c4ec2128
KM
99 struct vattr vattr;
100 struct vnode *vp;
4147b3f6
BJ
101
102 if (ipc.ip_lock != u.u_procp->p_pid)
103 return (0);
104 u.u_procp->p_slptime = 0;
105 i = ipc.ip_req;
106 ipc.ip_req = 0;
107 switch (i) {
108
01b0e233 109 case PT_READ_I: /* read the child's text space */
4147b3f6
BJ
110 if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
111 goto error;
112 ipc.ip_data = fuiword((caddr_t)ipc.ip_addr);
113 break;
114
01b0e233 115 case PT_READ_D: /* read the child's data space */
4147b3f6
BJ
116 if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
117 goto error;
118 ipc.ip_data = fuword((caddr_t)ipc.ip_addr);
119 break;
120
01b0e233 121 case PT_READ_U: /* read the child's u. */
4147b3f6
BJ
122 i = (int)ipc.ip_addr;
123 if (i<0 || i >= ctob(UPAGES))
124 goto error;
883d0f83 125 ipc.ip_data = *(int *)PHYSOFF(&u, i);
4147b3f6
BJ
126 break;
127
01b0e233 128 case PT_WRITE_I: /* write the child's text space */
4147b3f6
BJ
129 /*
130 * If text, must assure exclusive use
131 */
132 if (xp = u.u_procp->p_textp) {
c4ec2128
KM
133 vp = xp->x_vptr;
134 VOP_GETATTR(vp, &vattr, u.u_cred);
135 if (xp->x_count!=1 || (vattr.va_mode & VSVTX))
4147b3f6 136 goto error;
cdb14d96 137 xp->x_flag |= XTRC;
4147b3f6
BJ
138 }
139 i = -1;
883d0f83
BJ
140 if ((i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data)) < 0) {
141 if (chgprot((caddr_t)ipc.ip_addr, RW) &&
142 chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RW))
143 i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data);
144 (void) chgprot((caddr_t)ipc.ip_addr, RO);
145 (void) chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RO);
146 }
4147b3f6
BJ
147 if (i < 0)
148 goto error;
fb1db32c
MK
149#if defined(tahoe)
150 /* make sure the old value is not in cache */
151 ckeyrelease(u.u_procp->p_ckey);
152 u.u_procp->p_ckey = getcodekey();
153#endif
154 if (xp) {
4147b3f6 155 xp->x_flag |= XWRIT;
fb1db32c
MK
156#if defined(tahoe)
157 xp->x_ckey = u.u_procp->p_ckey;
158#endif
159 }
4147b3f6
BJ
160 break;
161
01b0e233 162 case PT_WRITE_D: /* write the child's data space */
4147b3f6
BJ
163 if (suword((caddr_t)ipc.ip_addr, 0) < 0)
164 goto error;
165 (void) suword((caddr_t)ipc.ip_addr, ipc.ip_data);
166 break;
167
01b0e233 168 case PT_WRITE_U: /* write the child's u. */
4147b3f6 169 i = (int)ipc.ip_addr;
883d0f83
BJ
170 p = (int *)PHYSOFF(&u, i);
171 for (i=0; i<NIPCREG; i++)
4147b3f6
BJ
172 if (p == &u.u_ar0[ipcreg[i]])
173 goto ok;
174 if (p == &u.u_ar0[PS]) {
883d0f83 175 ipc.ip_data |= PSL_USERSET;
4147b3f6 176 ipc.ip_data &= ~PSL_USERCLR;
bf47fbca
MK
177#ifdef PSL_CM_CLR
178 if (ipc.ip_data & PSL_CM)
179 ipc.ip_data &= ~PSL_CM_CLR;
180#endif
4147b3f6
BJ
181 goto ok;
182 }
183 goto error;
184
185 ok:
186 *p = ipc.ip_data;
187 break;
188
01b0e233
MK
189 case PT_STEP: /* single step the child */
190 case PT_CONTINUE: /* continue the child */
4147b3f6
BJ
191 if ((int)ipc.ip_addr != 1)
192 u.u_ar0[PC] = (int)ipc.ip_addr;
193 if ((unsigned)ipc.ip_data > NSIG)
194 goto error;
195 u.u_procp->p_cursig = ipc.ip_data; /* see issig */
01b0e233 196 if (i == PT_STEP)
4147b3f6
BJ
197 u.u_ar0[PS] |= PSL_T;
198 wakeup((caddr_t)&ipc);
199 return (1);
200
01b0e233 201 case PT_KILL: /* kill the child process */
4147b3f6
BJ
202 wakeup((caddr_t)&ipc);
203 exit(u.u_procp->p_cursig);
204
205 default:
206 error:
207 ipc.ip_req = -1;
208 }
209 wakeup((caddr_t)&ipc);
210 return (0);
211}