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