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