1 /* sys_process.c 5.2 82/07/24 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/dir.h" 6 #include "../h/user.h" 7 #include "../h/proc.h" 8 #include "../h/inode.h" 9 #include "../h/reg.h" 10 #include "../h/text.h" 11 #include "../h/seg.h" 12 #include "../h/mtpr.h" 13 #include "../h/pte.h" 14 #include "../h/psl.h" 15 #include "../h/vm.h" 16 #include "../h/buf.h" 17 #include "../h/vlimit.h" 18 #include "../h/acct.h" 19 20 21 /* 22 * Priority for tracing 23 */ 24 #define IPCPRI PZERO 25 26 /* 27 * Tracing variables. 28 * Used to pass trace command from 29 * parent to child being traced. 30 * This data base cannot be 31 * shared and is locked 32 * per user. 33 */ 34 struct { 35 int ip_lock; 36 int ip_req; 37 int *ip_addr; 38 int ip_data; 39 } ipc; 40 41 /* 42 * sys-trace system call. 43 */ 44 ptrace() 45 { 46 register struct proc *p; 47 register struct a { 48 int req; 49 int pid; 50 int *addr; 51 int data; 52 } *uap; 53 54 uap = (struct a *)u.u_ap; 55 if (uap->req <= 0) { 56 u.u_procp->p_flag |= STRC; 57 return; 58 } 59 p = pfind(uap->pid); 60 if (p == 0 || p->p_stat != SSTOP || p->p_ppid != u.u_procp->p_pid) { 61 u.u_error = ESRCH; 62 return; 63 } 64 while (ipc.ip_lock) 65 sleep((caddr_t)&ipc, IPCPRI); 66 ipc.ip_lock = p->p_pid; 67 ipc.ip_data = uap->data; 68 ipc.ip_addr = uap->addr; 69 ipc.ip_req = uap->req; 70 p->p_flag &= ~SWTED; 71 while (ipc.ip_req > 0) { 72 if (p->p_stat==SSTOP) 73 setrun(p); 74 sleep((caddr_t)&ipc, IPCPRI); 75 } 76 u.u_r.r_val1 = ipc.ip_data; 77 if (ipc.ip_req < 0) 78 u.u_error = EIO; 79 ipc.ip_lock = 0; 80 wakeup((caddr_t)&ipc); 81 } 82 83 int ipcreg[] = {R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,AP,FP,SP,PC}; 84 /* 85 * Code that the child process 86 * executes to implement the command 87 * of the parent process in tracing. 88 */ 89 procxmt() 90 { 91 register int i; 92 register *p; 93 register struct text *xp; 94 95 if (ipc.ip_lock != u.u_procp->p_pid) 96 return (0); 97 u.u_procp->p_slptime = 0; 98 i = ipc.ip_req; 99 ipc.ip_req = 0; 100 switch (i) { 101 102 /* read user I */ 103 case 1: 104 if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ)) 105 goto error; 106 ipc.ip_data = fuiword((caddr_t)ipc.ip_addr); 107 break; 108 109 /* read user D */ 110 case 2: 111 if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ)) 112 goto error; 113 ipc.ip_data = fuword((caddr_t)ipc.ip_addr); 114 break; 115 116 /* read u */ 117 case 3: 118 i = (int)ipc.ip_addr; 119 if (i<0 || i >= ctob(UPAGES)) 120 goto error; 121 ipc.ip_data = ((physadr)&u)->r[i>>2]; 122 break; 123 124 /* write user I */ 125 /* Must set up to allow writing */ 126 case 4: 127 /* 128 * If text, must assure exclusive use 129 */ 130 if (xp = u.u_procp->p_textp) { 131 if (xp->x_count!=1 || xp->x_iptr->i_mode&ISVTX) 132 goto error; 133 xp->x_iptr->i_flag &= ~ITEXT; 134 } 135 i = -1; 136 if (chgprot((caddr_t)ipc.ip_addr, RW) && 137 chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RW)) 138 i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data); 139 (void) chgprot((caddr_t)ipc.ip_addr, RO); 140 (void) chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RO); 141 if (i < 0) 142 goto error; 143 if (xp) 144 xp->x_flag |= XWRIT; 145 break; 146 147 /* write user D */ 148 case 5: 149 if (suword((caddr_t)ipc.ip_addr, 0) < 0) 150 goto error; 151 (void) suword((caddr_t)ipc.ip_addr, ipc.ip_data); 152 break; 153 154 /* write u */ 155 case 6: 156 i = (int)ipc.ip_addr; 157 p = (int *)&((physadr)&u)->r[i>>2]; 158 for (i=0; i<16; i++) 159 if (p == &u.u_ar0[ipcreg[i]]) 160 goto ok; 161 if (p == &u.u_ar0[PS]) { 162 ipc.ip_data |= PSL_CURMOD|PSL_PRVMOD; 163 ipc.ip_data &= ~PSL_USERCLR; 164 goto ok; 165 } 166 goto error; 167 168 ok: 169 *p = ipc.ip_data; 170 break; 171 172 /* set signal and continue */ 173 /* one version causes a trace-trap */ 174 case 9: 175 case 7: 176 if ((int)ipc.ip_addr != 1) 177 u.u_ar0[PC] = (int)ipc.ip_addr; 178 if ((unsigned)ipc.ip_data > NSIG) 179 goto error; 180 u.u_procp->p_cursig = ipc.ip_data; /* see issig */ 181 if (i == 9) 182 u.u_ar0[PS] |= PSL_T; 183 wakeup((caddr_t)&ipc); 184 return (1); 185 186 /* force exit */ 187 case 8: 188 wakeup((caddr_t)&ipc); 189 exit(u.u_procp->p_cursig); 190 191 default: 192 error: 193 ipc.ip_req = -1; 194 } 195 wakeup((caddr_t)&ipc); 196 return (0); 197 } 198