xref: /csrg-svn/sys/kern/sys_process.c (revision 12496)
1*12496Ssam /*	sys_process.c	5.9	83/05/18	*/
27426Sroot 
39759Ssam #include "../machine/reg.h"
49759Ssam #include "../machine/psl.h"
59759Ssam #include "../machine/pte.h"
69759Ssam 
77426Sroot #include "../h/param.h"
87426Sroot #include "../h/systm.h"
97426Sroot #include "../h/dir.h"
107426Sroot #include "../h/user.h"
117426Sroot #include "../h/proc.h"
127426Sroot #include "../h/inode.h"
137426Sroot #include "../h/text.h"
147426Sroot #include "../h/seg.h"
157426Sroot #include "../h/vm.h"
167426Sroot #include "../h/buf.h"
177426Sroot #include "../h/acct.h"
187426Sroot 
197501Sroot /*
207501Sroot  * Priority for tracing
217501Sroot  */
227501Sroot #define	IPCPRI	PZERO
237501Sroot 
247501Sroot /*
257501Sroot  * Tracing variables.
267501Sroot  * Used to pass trace command from
277501Sroot  * parent to child being traced.
287501Sroot  * This data base cannot be
297501Sroot  * shared and is locked
307501Sroot  * per user.
317501Sroot  */
327501Sroot struct {
337501Sroot 	int	ip_lock;
347501Sroot 	int	ip_req;
357501Sroot 	int	*ip_addr;
367501Sroot 	int	ip_data;
377501Sroot } ipc;
387501Sroot 
397501Sroot /*
407501Sroot  * sys-trace system call.
417501Sroot  */
427501Sroot ptrace()
437501Sroot {
447501Sroot 	register struct proc *p;
457501Sroot 	register struct a {
467501Sroot 		int	req;
477501Sroot 		int	pid;
487501Sroot 		int	*addr;
497501Sroot 		int	data;
507501Sroot 	} *uap;
517501Sroot 
527501Sroot 	uap = (struct a *)u.u_ap;
537501Sroot 	if (uap->req <= 0) {
547501Sroot 		u.u_procp->p_flag |= STRC;
557501Sroot 		return;
567501Sroot 	}
577501Sroot 	p = pfind(uap->pid);
58*12496Ssam 	if (p == 0 || p->p_stat != SSTOP || p->p_ppid != u.u_procp->p_pid ||
59*12496Ssam 	    !(p->p_flag & STRC)) {
607501Sroot 		u.u_error = ESRCH;
617501Sroot 		return;
627501Sroot 	}
637501Sroot 	while (ipc.ip_lock)
647501Sroot 		sleep((caddr_t)&ipc, IPCPRI);
657501Sroot 	ipc.ip_lock = p->p_pid;
667501Sroot 	ipc.ip_data = uap->data;
677501Sroot 	ipc.ip_addr = uap->addr;
687501Sroot 	ipc.ip_req = uap->req;
697501Sroot 	p->p_flag &= ~SWTED;
707501Sroot 	while (ipc.ip_req > 0) {
717501Sroot 		if (p->p_stat==SSTOP)
727501Sroot 			setrun(p);
737501Sroot 		sleep((caddr_t)&ipc, IPCPRI);
747501Sroot 	}
757501Sroot 	u.u_r.r_val1 = ipc.ip_data;
767501Sroot 	if (ipc.ip_req < 0)
777501Sroot 		u.u_error = EIO;
787501Sroot 	ipc.ip_lock = 0;
797501Sroot 	wakeup((caddr_t)&ipc);
807501Sroot }
817501Sroot 
828966Sroot #ifdef vax
838952Sroot #define	NIPCREG 16
848952Sroot #endif
858966Sroot #ifdef sun
868952Sroot #define	NIPCREG 17
878952Sroot #endif
888952Sroot int ipcreg[NIPCREG] =
898966Sroot #ifdef vax
908952Sroot 	{R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,AP,FP,SP,PC};
918952Sroot #endif
928966Sroot #ifdef sun
938952Sroot 	{R0,R1,R2,R3,R4,R5,R6,R7,AR0,AR1,AR2,AR3,AR4,AR5,AR6,AR7,PC};
948952Sroot #endif
958952Sroot 
968953Sroot #define	PHYSOFF(p, o) \
978952Sroot 	((physadr)(p)+((o)/sizeof(((physadr)0)->r[0])))
988952Sroot 
997501Sroot /*
1007501Sroot  * Code that the child process
1017501Sroot  * executes to implement the command
1027501Sroot  * of the parent process in tracing.
1037501Sroot  */
1047501Sroot procxmt()
1057501Sroot {
1067501Sroot 	register int i;
1077501Sroot 	register *p;
1087501Sroot 	register struct text *xp;
1097501Sroot 
1107501Sroot 	if (ipc.ip_lock != u.u_procp->p_pid)
1117501Sroot 		return (0);
1127501Sroot 	u.u_procp->p_slptime = 0;
1137501Sroot 	i = ipc.ip_req;
1147501Sroot 	ipc.ip_req = 0;
1157501Sroot 	switch (i) {
1167501Sroot 
1177501Sroot 	/* read user I */
1187501Sroot 	case 1:
1197501Sroot 		if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
1207501Sroot 			goto error;
1217501Sroot 		ipc.ip_data = fuiword((caddr_t)ipc.ip_addr);
1227501Sroot 		break;
1237501Sroot 
1247501Sroot 	/* read user D */
1257501Sroot 	case 2:
1267501Sroot 		if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
1277501Sroot 			goto error;
1287501Sroot 		ipc.ip_data = fuword((caddr_t)ipc.ip_addr);
1297501Sroot 		break;
1307501Sroot 
1317501Sroot 	/* read u */
1327501Sroot 	case 3:
1337501Sroot 		i = (int)ipc.ip_addr;
1347501Sroot 		if (i<0 || i >= ctob(UPAGES))
1357501Sroot 			goto error;
1368952Sroot 		ipc.ip_data = *(int *)PHYSOFF(&u, i);
1377501Sroot 		break;
1387501Sroot 
1397501Sroot 	/* write user I */
1407501Sroot 	/* Must set up to allow writing */
1417501Sroot 	case 4:
1427501Sroot 		/*
1437501Sroot 		 * If text, must assure exclusive use
1447501Sroot 		 */
1457501Sroot 		if (xp = u.u_procp->p_textp) {
1467501Sroot 			if (xp->x_count!=1 || xp->x_iptr->i_mode&ISVTX)
1477501Sroot 				goto error;
1487501Sroot 			xp->x_iptr->i_flag &= ~ITEXT;
1497501Sroot 		}
1507501Sroot 		i = -1;
1518952Sroot 		if ((i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data)) < 0) {
1528952Sroot 			if (chgprot((caddr_t)ipc.ip_addr, RW) &&
1538952Sroot 			    chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RW))
1548952Sroot 				i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data);
1558952Sroot 			(void) chgprot((caddr_t)ipc.ip_addr, RO);
1568952Sroot 			(void) chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RO);
1578952Sroot 		}
1587501Sroot 		if (i < 0)
1597501Sroot 			goto error;
1607501Sroot 		if (xp)
1617501Sroot 			xp->x_flag |= XWRIT;
1627501Sroot 		break;
1637501Sroot 
1647501Sroot 	/* write user D */
1657501Sroot 	case 5:
1667501Sroot 		if (suword((caddr_t)ipc.ip_addr, 0) < 0)
1677501Sroot 			goto error;
1687501Sroot 		(void) suword((caddr_t)ipc.ip_addr, ipc.ip_data);
1697501Sroot 		break;
1707501Sroot 
1717501Sroot 	/* write u */
1727501Sroot 	case 6:
1737501Sroot 		i = (int)ipc.ip_addr;
1748952Sroot 		p = (int *)PHYSOFF(&u, i);
1758952Sroot 		for (i=0; i<NIPCREG; i++)
1767501Sroot 			if (p == &u.u_ar0[ipcreg[i]])
1777501Sroot 				goto ok;
1787501Sroot 		if (p == &u.u_ar0[PS]) {
1798952Sroot 			ipc.ip_data |= PSL_USERSET;
1807501Sroot 			ipc.ip_data &=  ~PSL_USERCLR;
1819759Ssam #ifdef sun
1829759Ssam 			if (ipc.ip_data & PSL_T)
1839759Ssam 				traceon();
1849759Ssam 			else
1859759Ssam 				traceoff();
1869759Ssam #endif
1877501Sroot 			goto ok;
1887501Sroot 		}
1897501Sroot 		goto error;
1907501Sroot 
1917501Sroot 	ok:
1927501Sroot 		*p = ipc.ip_data;
1937501Sroot 		break;
1947501Sroot 
1957501Sroot 	/* set signal and continue */
1967501Sroot 	/* one version causes a trace-trap */
1977501Sroot 	case 9:
1987501Sroot 	case 7:
1997501Sroot 		if ((int)ipc.ip_addr != 1)
2007501Sroot 			u.u_ar0[PC] = (int)ipc.ip_addr;
2017501Sroot 		if ((unsigned)ipc.ip_data > NSIG)
2027501Sroot 			goto error;
2037501Sroot 		u.u_procp->p_cursig = ipc.ip_data;	/* see issig */
2049759Ssam 		if (i == 9)
2059759Ssam #ifdef sun
2069759Ssam 			traceon();
2079759Ssam #else
2087501Sroot 			u.u_ar0[PS] |= PSL_T;
2099759Ssam #endif
2107501Sroot 		wakeup((caddr_t)&ipc);
2117501Sroot 		return (1);
2127501Sroot 
2137501Sroot 	/* force exit */
2147501Sroot 	case 8:
2157501Sroot 		wakeup((caddr_t)&ipc);
2167501Sroot 		exit(u.u_procp->p_cursig);
2177501Sroot 
2187501Sroot 	default:
2197501Sroot 	error:
2207501Sroot 		ipc.ip_req = -1;
2217501Sroot 	}
2227501Sroot 	wakeup((caddr_t)&ipc);
2237501Sroot 	return (0);
2247501Sroot }
225