xref: /csrg-svn/sys/kern/sys_process.c (revision 7501)
1*7501Sroot /*	sys_process.c	5.2	82/07/24	*/
27426Sroot 
37426Sroot #include "../h/param.h"
47426Sroot #include "../h/systm.h"
57426Sroot #include "../h/dir.h"
67426Sroot #include "../h/user.h"
77426Sroot #include "../h/proc.h"
87426Sroot #include "../h/inode.h"
97426Sroot #include "../h/reg.h"
107426Sroot #include "../h/text.h"
117426Sroot #include "../h/seg.h"
127426Sroot #include "../h/mtpr.h"
137426Sroot #include "../h/pte.h"
147426Sroot #include "../h/psl.h"
157426Sroot #include "../h/vm.h"
167426Sroot #include "../h/buf.h"
177426Sroot #include "../h/vlimit.h"
187426Sroot #include "../h/acct.h"
197426Sroot 
20*7501Sroot 
21*7501Sroot /*
22*7501Sroot  * Priority for tracing
23*7501Sroot  */
24*7501Sroot #define	IPCPRI	PZERO
25*7501Sroot 
26*7501Sroot /*
27*7501Sroot  * Tracing variables.
28*7501Sroot  * Used to pass trace command from
29*7501Sroot  * parent to child being traced.
30*7501Sroot  * This data base cannot be
31*7501Sroot  * shared and is locked
32*7501Sroot  * per user.
33*7501Sroot  */
34*7501Sroot struct {
35*7501Sroot 	int	ip_lock;
36*7501Sroot 	int	ip_req;
37*7501Sroot 	int	*ip_addr;
38*7501Sroot 	int	ip_data;
39*7501Sroot } ipc;
40*7501Sroot 
41*7501Sroot /*
42*7501Sroot  * sys-trace system call.
43*7501Sroot  */
44*7501Sroot ptrace()
45*7501Sroot {
46*7501Sroot 	register struct proc *p;
47*7501Sroot 	register struct a {
48*7501Sroot 		int	req;
49*7501Sroot 		int	pid;
50*7501Sroot 		int	*addr;
51*7501Sroot 		int	data;
52*7501Sroot 	} *uap;
53*7501Sroot 
54*7501Sroot 	uap = (struct a *)u.u_ap;
55*7501Sroot 	if (uap->req <= 0) {
56*7501Sroot 		u.u_procp->p_flag |= STRC;
57*7501Sroot 		return;
58*7501Sroot 	}
59*7501Sroot 	p = pfind(uap->pid);
60*7501Sroot 	if (p == 0 || p->p_stat != SSTOP || p->p_ppid != u.u_procp->p_pid) {
61*7501Sroot 		u.u_error = ESRCH;
62*7501Sroot 		return;
63*7501Sroot 	}
64*7501Sroot 	while (ipc.ip_lock)
65*7501Sroot 		sleep((caddr_t)&ipc, IPCPRI);
66*7501Sroot 	ipc.ip_lock = p->p_pid;
67*7501Sroot 	ipc.ip_data = uap->data;
68*7501Sroot 	ipc.ip_addr = uap->addr;
69*7501Sroot 	ipc.ip_req = uap->req;
70*7501Sroot 	p->p_flag &= ~SWTED;
71*7501Sroot 	while (ipc.ip_req > 0) {
72*7501Sroot 		if (p->p_stat==SSTOP)
73*7501Sroot 			setrun(p);
74*7501Sroot 		sleep((caddr_t)&ipc, IPCPRI);
75*7501Sroot 	}
76*7501Sroot 	u.u_r.r_val1 = ipc.ip_data;
77*7501Sroot 	if (ipc.ip_req < 0)
78*7501Sroot 		u.u_error = EIO;
79*7501Sroot 	ipc.ip_lock = 0;
80*7501Sroot 	wakeup((caddr_t)&ipc);
81*7501Sroot }
82*7501Sroot 
83*7501Sroot int ipcreg[] = {R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,AP,FP,SP,PC};
84*7501Sroot /*
85*7501Sroot  * Code that the child process
86*7501Sroot  * executes to implement the command
87*7501Sroot  * of the parent process in tracing.
88*7501Sroot  */
89*7501Sroot procxmt()
90*7501Sroot {
91*7501Sroot 	register int i;
92*7501Sroot 	register *p;
93*7501Sroot 	register struct text *xp;
94*7501Sroot 
95*7501Sroot 	if (ipc.ip_lock != u.u_procp->p_pid)
96*7501Sroot 		return (0);
97*7501Sroot 	u.u_procp->p_slptime = 0;
98*7501Sroot 	i = ipc.ip_req;
99*7501Sroot 	ipc.ip_req = 0;
100*7501Sroot 	switch (i) {
101*7501Sroot 
102*7501Sroot 	/* read user I */
103*7501Sroot 	case 1:
104*7501Sroot 		if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
105*7501Sroot 			goto error;
106*7501Sroot 		ipc.ip_data = fuiword((caddr_t)ipc.ip_addr);
107*7501Sroot 		break;
108*7501Sroot 
109*7501Sroot 	/* read user D */
110*7501Sroot 	case 2:
111*7501Sroot 		if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
112*7501Sroot 			goto error;
113*7501Sroot 		ipc.ip_data = fuword((caddr_t)ipc.ip_addr);
114*7501Sroot 		break;
115*7501Sroot 
116*7501Sroot 	/* read u */
117*7501Sroot 	case 3:
118*7501Sroot 		i = (int)ipc.ip_addr;
119*7501Sroot 		if (i<0 || i >= ctob(UPAGES))
120*7501Sroot 			goto error;
121*7501Sroot 		ipc.ip_data = ((physadr)&u)->r[i>>2];
122*7501Sroot 		break;
123*7501Sroot 
124*7501Sroot 	/* write user I */
125*7501Sroot 	/* Must set up to allow writing */
126*7501Sroot 	case 4:
127*7501Sroot 		/*
128*7501Sroot 		 * If text, must assure exclusive use
129*7501Sroot 		 */
130*7501Sroot 		if (xp = u.u_procp->p_textp) {
131*7501Sroot 			if (xp->x_count!=1 || xp->x_iptr->i_mode&ISVTX)
132*7501Sroot 				goto error;
133*7501Sroot 			xp->x_iptr->i_flag &= ~ITEXT;
134*7501Sroot 		}
135*7501Sroot 		i = -1;
136*7501Sroot 		if (chgprot((caddr_t)ipc.ip_addr, RW) &&
137*7501Sroot 		    chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RW))
138*7501Sroot 			i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data);
139*7501Sroot 		(void) chgprot((caddr_t)ipc.ip_addr, RO);
140*7501Sroot 		(void) chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RO);
141*7501Sroot 		if (i < 0)
142*7501Sroot 			goto error;
143*7501Sroot 		if (xp)
144*7501Sroot 			xp->x_flag |= XWRIT;
145*7501Sroot 		break;
146*7501Sroot 
147*7501Sroot 	/* write user D */
148*7501Sroot 	case 5:
149*7501Sroot 		if (suword((caddr_t)ipc.ip_addr, 0) < 0)
150*7501Sroot 			goto error;
151*7501Sroot 		(void) suword((caddr_t)ipc.ip_addr, ipc.ip_data);
152*7501Sroot 		break;
153*7501Sroot 
154*7501Sroot 	/* write u */
155*7501Sroot 	case 6:
156*7501Sroot 		i = (int)ipc.ip_addr;
157*7501Sroot 		p = (int *)&((physadr)&u)->r[i>>2];
158*7501Sroot 		for (i=0; i<16; i++)
159*7501Sroot 			if (p == &u.u_ar0[ipcreg[i]])
160*7501Sroot 				goto ok;
161*7501Sroot 		if (p == &u.u_ar0[PS]) {
162*7501Sroot 			ipc.ip_data |= PSL_CURMOD|PSL_PRVMOD;
163*7501Sroot 			ipc.ip_data &=  ~PSL_USERCLR;
164*7501Sroot 			goto ok;
165*7501Sroot 		}
166*7501Sroot 		goto error;
167*7501Sroot 
168*7501Sroot 	ok:
169*7501Sroot 		*p = ipc.ip_data;
170*7501Sroot 		break;
171*7501Sroot 
172*7501Sroot 	/* set signal and continue */
173*7501Sroot 	/* one version causes a trace-trap */
174*7501Sroot 	case 9:
175*7501Sroot 	case 7:
176*7501Sroot 		if ((int)ipc.ip_addr != 1)
177*7501Sroot 			u.u_ar0[PC] = (int)ipc.ip_addr;
178*7501Sroot 		if ((unsigned)ipc.ip_data > NSIG)
179*7501Sroot 			goto error;
180*7501Sroot 		u.u_procp->p_cursig = ipc.ip_data;	/* see issig */
181*7501Sroot 		if (i == 9)
182*7501Sroot 			u.u_ar0[PS] |= PSL_T;
183*7501Sroot 		wakeup((caddr_t)&ipc);
184*7501Sroot 		return (1);
185*7501Sroot 
186*7501Sroot 	/* force exit */
187*7501Sroot 	case 8:
188*7501Sroot 		wakeup((caddr_t)&ipc);
189*7501Sroot 		exit(u.u_procp->p_cursig);
190*7501Sroot 
191*7501Sroot 	default:
192*7501Sroot 	error:
193*7501Sroot 		ipc.ip_req = -1;
194*7501Sroot 	}
195*7501Sroot 	wakeup((caddr_t)&ipc);
196*7501Sroot 	return (0);
197*7501Sroot }
198