1*17401Skarels /* sys_process.c 6.3 84/11/20 */ 27426Sroot 39759Ssam #include "../machine/reg.h" 49759Ssam #include "../machine/psl.h" 59759Ssam #include "../machine/pte.h" 69759Ssam 717095Sbloom #include "param.h" 817095Sbloom #include "systm.h" 917095Sbloom #include "dir.h" 1017095Sbloom #include "user.h" 1117095Sbloom #include "proc.h" 1217095Sbloom #include "inode.h" 1317095Sbloom #include "text.h" 1417095Sbloom #include "seg.h" 1517095Sbloom #include "vm.h" 1617095Sbloom #include "buf.h" 1717095Sbloom #include "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); 5812496Ssam if (p == 0 || p->p_stat != SSTOP || p->p_ppid != u.u_procp->p_pid || 5912496Ssam !(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 int ipcreg[NIPCREG] = 858952Sroot {R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,AP,FP,SP,PC}; 868952Sroot #endif 878952Sroot 888953Sroot #define PHYSOFF(p, o) \ 898952Sroot ((physadr)(p)+((o)/sizeof(((physadr)0)->r[0]))) 908952Sroot 917501Sroot /* 927501Sroot * Code that the child process 937501Sroot * executes to implement the command 947501Sroot * of the parent process in tracing. 957501Sroot */ 967501Sroot procxmt() 977501Sroot { 987501Sroot register int i; 997501Sroot register *p; 1007501Sroot register struct text *xp; 1017501Sroot 1027501Sroot if (ipc.ip_lock != u.u_procp->p_pid) 1037501Sroot return (0); 1047501Sroot u.u_procp->p_slptime = 0; 1057501Sroot i = ipc.ip_req; 1067501Sroot ipc.ip_req = 0; 1077501Sroot switch (i) { 1087501Sroot 1097501Sroot /* read user I */ 1107501Sroot case 1: 1117501Sroot if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ)) 1127501Sroot goto error; 1137501Sroot ipc.ip_data = fuiword((caddr_t)ipc.ip_addr); 1147501Sroot break; 1157501Sroot 1167501Sroot /* read user D */ 1177501Sroot case 2: 1187501Sroot if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ)) 1197501Sroot goto error; 1207501Sroot ipc.ip_data = fuword((caddr_t)ipc.ip_addr); 1217501Sroot break; 1227501Sroot 1237501Sroot /* read u */ 1247501Sroot case 3: 1257501Sroot i = (int)ipc.ip_addr; 1267501Sroot if (i<0 || i >= ctob(UPAGES)) 1277501Sroot goto error; 1288952Sroot ipc.ip_data = *(int *)PHYSOFF(&u, i); 1297501Sroot break; 1307501Sroot 1317501Sroot /* write user I */ 1327501Sroot /* Must set up to allow writing */ 1337501Sroot case 4: 1347501Sroot /* 1357501Sroot * If text, must assure exclusive use 1367501Sroot */ 1377501Sroot if (xp = u.u_procp->p_textp) { 1387501Sroot if (xp->x_count!=1 || xp->x_iptr->i_mode&ISVTX) 1397501Sroot goto error; 140*17401Skarels xp->x_iptr->i_flag |= IXMOD; /* XXX */ 1417501Sroot } 1427501Sroot i = -1; 1438952Sroot if ((i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data)) < 0) { 1448952Sroot if (chgprot((caddr_t)ipc.ip_addr, RW) && 1458952Sroot chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RW)) 1468952Sroot i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data); 1478952Sroot (void) chgprot((caddr_t)ipc.ip_addr, RO); 1488952Sroot (void) chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RO); 1498952Sroot } 1507501Sroot if (i < 0) 1517501Sroot goto error; 1527501Sroot if (xp) 1537501Sroot xp->x_flag |= XWRIT; 1547501Sroot break; 1557501Sroot 1567501Sroot /* write user D */ 1577501Sroot case 5: 1587501Sroot if (suword((caddr_t)ipc.ip_addr, 0) < 0) 1597501Sroot goto error; 1607501Sroot (void) suword((caddr_t)ipc.ip_addr, ipc.ip_data); 1617501Sroot break; 1627501Sroot 1637501Sroot /* write u */ 1647501Sroot case 6: 1657501Sroot i = (int)ipc.ip_addr; 1668952Sroot p = (int *)PHYSOFF(&u, i); 1678952Sroot for (i=0; i<NIPCREG; i++) 1687501Sroot if (p == &u.u_ar0[ipcreg[i]]) 1697501Sroot goto ok; 1707501Sroot if (p == &u.u_ar0[PS]) { 1718952Sroot ipc.ip_data |= PSL_USERSET; 1727501Sroot ipc.ip_data &= ~PSL_USERCLR; 1737501Sroot goto ok; 1747501Sroot } 1757501Sroot goto error; 1767501Sroot 1777501Sroot ok: 1787501Sroot *p = ipc.ip_data; 1797501Sroot break; 1807501Sroot 1817501Sroot /* set signal and continue */ 1827501Sroot /* one version causes a trace-trap */ 1837501Sroot case 9: 1847501Sroot case 7: 1857501Sroot if ((int)ipc.ip_addr != 1) 1867501Sroot u.u_ar0[PC] = (int)ipc.ip_addr; 1877501Sroot if ((unsigned)ipc.ip_data > NSIG) 1887501Sroot goto error; 1897501Sroot u.u_procp->p_cursig = ipc.ip_data; /* see issig */ 1909759Ssam if (i == 9) 1917501Sroot u.u_ar0[PS] |= PSL_T; 1927501Sroot wakeup((caddr_t)&ipc); 1937501Sroot return (1); 1947501Sroot 1957501Sroot /* force exit */ 1967501Sroot case 8: 1977501Sroot wakeup((caddr_t)&ipc); 1987501Sroot exit(u.u_procp->p_cursig); 1997501Sroot 2007501Sroot default: 2017501Sroot error: 2027501Sroot ipc.ip_req = -1; 2037501Sroot } 2047501Sroot wakeup((caddr_t)&ipc); 2057501Sroot return (0); 2067501Sroot } 207