1*9759Ssam /* sys_process.c 5.8 82/12/17 */ 27426Sroot 3*9759Ssam #include "../machine/reg.h" 4*9759Ssam #include "../machine/psl.h" 5*9759Ssam #include "../machine/pte.h" 6*9759Ssam 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); 587501Sroot if (p == 0 || p->p_stat != SSTOP || p->p_ppid != u.u_procp->p_pid) { 597501Sroot u.u_error = ESRCH; 607501Sroot return; 617501Sroot } 627501Sroot while (ipc.ip_lock) 637501Sroot sleep((caddr_t)&ipc, IPCPRI); 647501Sroot ipc.ip_lock = p->p_pid; 657501Sroot ipc.ip_data = uap->data; 667501Sroot ipc.ip_addr = uap->addr; 677501Sroot ipc.ip_req = uap->req; 687501Sroot p->p_flag &= ~SWTED; 697501Sroot while (ipc.ip_req > 0) { 707501Sroot if (p->p_stat==SSTOP) 717501Sroot setrun(p); 727501Sroot sleep((caddr_t)&ipc, IPCPRI); 737501Sroot } 747501Sroot u.u_r.r_val1 = ipc.ip_data; 757501Sroot if (ipc.ip_req < 0) 767501Sroot u.u_error = EIO; 777501Sroot ipc.ip_lock = 0; 787501Sroot wakeup((caddr_t)&ipc); 797501Sroot } 807501Sroot 818966Sroot #ifdef vax 828952Sroot #define NIPCREG 16 838952Sroot #endif 848966Sroot #ifdef sun 858952Sroot #define NIPCREG 17 868952Sroot #endif 878952Sroot int ipcreg[NIPCREG] = 888966Sroot #ifdef vax 898952Sroot {R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,AP,FP,SP,PC}; 908952Sroot #endif 918966Sroot #ifdef sun 928952Sroot {R0,R1,R2,R3,R4,R5,R6,R7,AR0,AR1,AR2,AR3,AR4,AR5,AR6,AR7,PC}; 938952Sroot #endif 948952Sroot 958953Sroot #define PHYSOFF(p, o) \ 968952Sroot ((physadr)(p)+((o)/sizeof(((physadr)0)->r[0]))) 978952Sroot 987501Sroot /* 997501Sroot * Code that the child process 1007501Sroot * executes to implement the command 1017501Sroot * of the parent process in tracing. 1027501Sroot */ 1037501Sroot procxmt() 1047501Sroot { 1057501Sroot register int i; 1067501Sroot register *p; 1077501Sroot register struct text *xp; 1087501Sroot 1097501Sroot if (ipc.ip_lock != u.u_procp->p_pid) 1107501Sroot return (0); 1117501Sroot u.u_procp->p_slptime = 0; 1127501Sroot i = ipc.ip_req; 1137501Sroot ipc.ip_req = 0; 1147501Sroot switch (i) { 1157501Sroot 1167501Sroot /* read user I */ 1177501Sroot case 1: 1187501Sroot if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ)) 1197501Sroot goto error; 1207501Sroot ipc.ip_data = fuiword((caddr_t)ipc.ip_addr); 1217501Sroot break; 1227501Sroot 1237501Sroot /* read user D */ 1247501Sroot case 2: 1257501Sroot if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ)) 1267501Sroot goto error; 1277501Sroot ipc.ip_data = fuword((caddr_t)ipc.ip_addr); 1287501Sroot break; 1297501Sroot 1307501Sroot /* read u */ 1317501Sroot case 3: 1327501Sroot i = (int)ipc.ip_addr; 1337501Sroot if (i<0 || i >= ctob(UPAGES)) 1347501Sroot goto error; 1358952Sroot ipc.ip_data = *(int *)PHYSOFF(&u, i); 1367501Sroot break; 1377501Sroot 1387501Sroot /* write user I */ 1397501Sroot /* Must set up to allow writing */ 1407501Sroot case 4: 1417501Sroot /* 1427501Sroot * If text, must assure exclusive use 1437501Sroot */ 1447501Sroot if (xp = u.u_procp->p_textp) { 1457501Sroot if (xp->x_count!=1 || xp->x_iptr->i_mode&ISVTX) 1467501Sroot goto error; 1477501Sroot xp->x_iptr->i_flag &= ~ITEXT; 1487501Sroot } 1497501Sroot i = -1; 1508952Sroot if ((i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data)) < 0) { 1518952Sroot if (chgprot((caddr_t)ipc.ip_addr, RW) && 1528952Sroot chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RW)) 1538952Sroot i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data); 1548952Sroot (void) chgprot((caddr_t)ipc.ip_addr, RO); 1558952Sroot (void) chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RO); 1568952Sroot } 1577501Sroot if (i < 0) 1587501Sroot goto error; 1597501Sroot if (xp) 1607501Sroot xp->x_flag |= XWRIT; 1617501Sroot break; 1627501Sroot 1637501Sroot /* write user D */ 1647501Sroot case 5: 1657501Sroot if (suword((caddr_t)ipc.ip_addr, 0) < 0) 1667501Sroot goto error; 1677501Sroot (void) suword((caddr_t)ipc.ip_addr, ipc.ip_data); 1687501Sroot break; 1697501Sroot 1707501Sroot /* write u */ 1717501Sroot case 6: 1727501Sroot i = (int)ipc.ip_addr; 1738952Sroot p = (int *)PHYSOFF(&u, i); 1748952Sroot for (i=0; i<NIPCREG; i++) 1757501Sroot if (p == &u.u_ar0[ipcreg[i]]) 1767501Sroot goto ok; 1777501Sroot if (p == &u.u_ar0[PS]) { 1788952Sroot ipc.ip_data |= PSL_USERSET; 1797501Sroot ipc.ip_data &= ~PSL_USERCLR; 180*9759Ssam #ifdef sun 181*9759Ssam if (ipc.ip_data & PSL_T) 182*9759Ssam traceon(); 183*9759Ssam else 184*9759Ssam traceoff(); 185*9759Ssam #endif 1867501Sroot goto ok; 1877501Sroot } 1887501Sroot goto error; 1897501Sroot 1907501Sroot ok: 1917501Sroot *p = ipc.ip_data; 1927501Sroot break; 1937501Sroot 1947501Sroot /* set signal and continue */ 1957501Sroot /* one version causes a trace-trap */ 1967501Sroot case 9: 1977501Sroot case 7: 1987501Sroot if ((int)ipc.ip_addr != 1) 1997501Sroot u.u_ar0[PC] = (int)ipc.ip_addr; 2007501Sroot if ((unsigned)ipc.ip_data > NSIG) 2017501Sroot goto error; 2027501Sroot u.u_procp->p_cursig = ipc.ip_data; /* see issig */ 203*9759Ssam if (i == 9) 204*9759Ssam #ifdef sun 205*9759Ssam traceon(); 206*9759Ssam #else 2077501Sroot u.u_ar0[PS] |= PSL_T; 208*9759Ssam #endif 2097501Sroot wakeup((caddr_t)&ipc); 2107501Sroot return (1); 2117501Sroot 2127501Sroot /* force exit */ 2137501Sroot case 8: 2147501Sroot wakeup((caddr_t)&ipc); 2157501Sroot exit(u.u_procp->p_cursig); 2167501Sroot 2177501Sroot default: 2187501Sroot error: 2197501Sroot ipc.ip_req = -1; 2207501Sroot } 2217501Sroot wakeup((caddr_t)&ipc); 2227501Sroot return (0); 2237501Sroot } 224