1 /* sys_process.c 5.3 82/09/04 */ 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/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 u.u_error = ESRCH; 60 return; 61 } 62 while (ipc.ip_lock) 63 sleep((caddr_t)&ipc, IPCPRI); 64 ipc.ip_lock = p->p_pid; 65 ipc.ip_data = uap->data; 66 ipc.ip_addr = uap->addr; 67 ipc.ip_req = uap->req; 68 p->p_flag &= ~SWTED; 69 while (ipc.ip_req > 0) { 70 if (p->p_stat==SSTOP) 71 setrun(p); 72 sleep((caddr_t)&ipc, IPCPRI); 73 } 74 u.u_r.r_val1 = ipc.ip_data; 75 if (ipc.ip_req < 0) 76 u.u_error = EIO; 77 ipc.ip_lock = 0; 78 wakeup((caddr_t)&ipc); 79 } 80 81 int ipcreg[] = {R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,AP,FP,SP,PC}; 82 /* 83 * Code that the child process 84 * executes to implement the command 85 * of the parent process in tracing. 86 */ 87 procxmt() 88 { 89 register int i; 90 register *p; 91 register struct text *xp; 92 93 if (ipc.ip_lock != u.u_procp->p_pid) 94 return (0); 95 u.u_procp->p_slptime = 0; 96 i = ipc.ip_req; 97 ipc.ip_req = 0; 98 switch (i) { 99 100 /* read user I */ 101 case 1: 102 if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ)) 103 goto error; 104 ipc.ip_data = fuiword((caddr_t)ipc.ip_addr); 105 break; 106 107 /* read user D */ 108 case 2: 109 if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ)) 110 goto error; 111 ipc.ip_data = fuword((caddr_t)ipc.ip_addr); 112 break; 113 114 /* read u */ 115 case 3: 116 i = (int)ipc.ip_addr; 117 if (i<0 || i >= ctob(UPAGES)) 118 goto error; 119 ipc.ip_data = ((physadr)&u)->r[i>>2]; 120 break; 121 122 /* write user I */ 123 /* Must set up to allow writing */ 124 case 4: 125 /* 126 * If text, must assure exclusive use 127 */ 128 if (xp = u.u_procp->p_textp) { 129 if (xp->x_count!=1 || xp->x_iptr->i_mode&ISVTX) 130 goto error; 131 xp->x_iptr->i_flag &= ~ITEXT; 132 } 133 i = -1; 134 if (chgprot((caddr_t)ipc.ip_addr, RW) && 135 chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RW)) 136 i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data); 137 (void) chgprot((caddr_t)ipc.ip_addr, RO); 138 (void) chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RO); 139 if (i < 0) 140 goto error; 141 if (xp) 142 xp->x_flag |= XWRIT; 143 break; 144 145 /* write user D */ 146 case 5: 147 if (suword((caddr_t)ipc.ip_addr, 0) < 0) 148 goto error; 149 (void) suword((caddr_t)ipc.ip_addr, ipc.ip_data); 150 break; 151 152 /* write u */ 153 case 6: 154 i = (int)ipc.ip_addr; 155 p = (int *)&((physadr)&u)->r[i>>2]; 156 for (i=0; i<16; i++) 157 if (p == &u.u_ar0[ipcreg[i]]) 158 goto ok; 159 if (p == &u.u_ar0[PS]) { 160 ipc.ip_data |= PSL_CURMOD|PSL_PRVMOD; 161 ipc.ip_data &= ~PSL_USERCLR; 162 goto ok; 163 } 164 goto error; 165 166 ok: 167 *p = ipc.ip_data; 168 break; 169 170 /* set signal and continue */ 171 /* one version causes a trace-trap */ 172 case 9: 173 case 7: 174 if ((int)ipc.ip_addr != 1) 175 u.u_ar0[PC] = (int)ipc.ip_addr; 176 if ((unsigned)ipc.ip_data > NSIG) 177 goto error; 178 u.u_procp->p_cursig = ipc.ip_data; /* see issig */ 179 if (i == 9) 180 u.u_ar0[PS] |= PSL_T; 181 wakeup((caddr_t)&ipc); 182 return (1); 183 184 /* force exit */ 185 case 8: 186 wakeup((caddr_t)&ipc); 187 exit(u.u_procp->p_cursig); 188 189 default: 190 error: 191 ipc.ip_req = -1; 192 } 193 wakeup((caddr_t)&ipc); 194 return (0); 195 } 196