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