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