1 # 2 /* 3 * 4 * UNIX debugger 5 * 6 */ 7 8 #include "defs.h" 9 static char sccsid[] = "@(#)runpcs.c 4.1 05/14/81"; 10 11 extern MAP txtmap; 12 13 MSG NOFORK; 14 MSG ENDPCS; 15 MSG BADWAIT; 16 17 CHAR *lp; 18 ADDR sigint; 19 ADDR sigqit; 20 21 /* breakpoints */ 22 BKPTR bkpthead; 23 24 REGLIST reglist[]; 25 26 CHAR lastc; 27 28 INT fcor; 29 INT fsym; 30 STRING errflg; 31 INT errno; 32 INT signo; 33 INT sigcode; 34 35 L_INT dot; 36 STRING symfil; 37 INT wtflag; 38 L_INT pid; 39 L_INT expv; 40 INT adrflg; 41 L_INT loopcnt; 42 43 44 45 46 47 /* service routines for sub process control */ 48 49 getsig(sig) 50 { return(expr(0) ? expv : sig); 51 } 52 53 ADDR userpc = 1; 54 55 runpcs(runmode,execsig) 56 { 57 INT rc; 58 REG BKPTR bkpt; 59 IF adrflg THEN userpc=dot; FI 60 printf("%s: running\n", symfil); 61 62 WHILE --loopcnt>=0 63 DO 64 #ifdef DEBUG 65 printf("\ncontinue %x %d\n",userpc,execsig); 66 #endif 67 IF runmode==SINGLE 68 THEN delbp(); /* hardware handles single-stepping */ 69 ELSE /* continuing from a breakpoint is hard */ 70 IF bkpt=scanbkpt(userpc) 71 THEN execbkpt(bkpt,execsig); execsig=0; 72 FI 73 setbp(); 74 FI 75 ptrace(runmode,pid,userpc,execsig); 76 bpwait(); chkerr(); execsig=0; delbp(); readregs(); 77 78 IF (signo==0) ANDF (bkpt=scanbkpt(userpc)) 79 THEN /* stopped by BPT instruction */ 80 #ifdef DEBUG 81 printf("\n BPT code; '%s'%o'%o'%d", 82 bkpt->comm,bkpt->comm[0],EOR,bkpt->flag); 83 #endif 84 dot=bkpt->loc; 85 IF bkpt->flag==BKPTEXEC 86 ORF ((bkpt->flag=BKPTEXEC) 87 ANDF bkpt->comm[0]!=EOR 88 ANDF command(bkpt->comm,':') 89 ANDF --bkpt->count) 90 THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++; 91 ELSE bkpt->count=bkpt->initcnt; rc=1; 92 FI 93 ELSE execsig=signo; rc=0; 94 FI 95 OD 96 return(rc); 97 } 98 99 #define BPOUT 0 100 #define BPIN 1 101 INT bpstate = BPOUT; 102 103 endpcs() 104 { 105 REG BKPTR bkptr; 106 IF pid 107 THEN ptrace(EXIT,pid,0,0); pid=0; userpc=1; 108 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt 109 DO IF bkptr->flag 110 THEN bkptr->flag=BKPTSET; 111 FI 112 OD 113 FI 114 bpstate=BPOUT; 115 } 116 117 #ifdef VFORK 118 nullsig() 119 { 120 121 } 122 #endif 123 124 setup() 125 { 126 close(fsym); fsym = -1; 127 #ifndef VFORK 128 IF (pid = fork()) == 0 129 #else 130 IF (pid = vfork()) == 0 131 #endif 132 THEN ptrace(SETTRC,0,0,0); 133 #ifdef VFORK 134 signal(SIGTRAP,nullsig); 135 #endif 136 signal(SIGINT,sigint); signal(SIGQUIT,sigqit); 137 doexec(); exit(0); 138 ELIF pid == -1 139 THEN error(NOFORK); 140 ELSE bpwait(); readregs(); lp[0]=EOR; lp[1]=0; 141 fsym=open(symfil,wtflag); 142 IF errflg 143 THEN printf("%s: cannot execute\n",symfil); 144 endpcs(); error(0); 145 FI 146 FI 147 bpstate=BPOUT; 148 } 149 150 execbkpt(bkptr,execsig) 151 BKPTR bkptr; 152 { 153 #ifdef DEBUG 154 printf("exbkpt: %d\n",bkptr->count); 155 #endif 156 delbp(); 157 ptrace(SINGLE,pid,bkptr->loc,execsig); 158 bkptr->flag=BKPTSET; 159 bpwait(); chkerr(); readregs(); 160 } 161 162 163 doexec() 164 { 165 STRING argl[MAXARG]; 166 CHAR args[LINSIZ]; 167 STRING p, *ap, filnam; 168 extern STRING environ; 169 ap=argl; p=args; 170 *ap++=symfil; 171 REP IF rdc()==EOR THEN break; FI 172 *ap = p; 173 WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB DO *p++=lastc; readchar(); OD 174 *p++=0; filnam = *ap+1; 175 IF **ap=='<' 176 THEN close(0); 177 IF open(filnam,0)<0 178 THEN printf("%s: cannot open\n",filnam); _exit(0); 179 FI 180 ELIF **ap=='>' 181 THEN close(1); 182 IF creat(filnam,0666)<0 183 THEN printf("%s: cannot create\n",filnam); _exit(0); 184 FI 185 ELSE ap++; 186 FI 187 PER lastc!=EOR DONE 188 *ap++=0; 189 exect(symfil, argl, environ); 190 perror(symfil); 191 } 192 193 BKPTR scanbkpt(adr) 194 ADDR adr; 195 { 196 REG BKPTR bkptr; 197 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt 198 DO IF bkptr->flag ANDF bkptr->loc==adr 199 THEN break; 200 FI 201 OD 202 return(bkptr); 203 } 204 205 delbp() 206 { 207 REG ADDR a; 208 REG BKPTR bkptr; 209 IF bpstate!=BPOUT 210 THEN 211 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt 212 DO IF bkptr->flag 213 THEN a=bkptr->loc; 214 IF a < txtmap.e1 THEN 215 ptrace(WIUSER,pid,a, 216 (bkptr->ins&0xFF)|(ptrace(RIUSER,pid,a,0)&~0xFF)); 217 ELSE 218 ptrace(WDUSER,pid,a, 219 (bkptr->ins&0xFF)|(ptrace(RDUSER,pid,a,0)&~0xFF)); 220 FI 221 FI 222 OD 223 bpstate=BPOUT; 224 FI 225 } 226 227 setbp() 228 { 229 REG ADDR a; 230 REG BKPTR bkptr; 231 232 IF bpstate!=BPIN 233 THEN 234 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt 235 DO IF bkptr->flag 236 THEN a = bkptr->loc; 237 IF a < txtmap.e1 THEN 238 bkptr->ins = ptrace(RIUSER, pid, a, 0); 239 ptrace(WIUSER, pid, a, BPT | (bkptr->ins&~0xFF)); 240 ELSE 241 bkptr->ins = ptrace(RDUSER, pid, a, 0); 242 ptrace(WDUSER, pid, a, BPT | (bkptr->ins&~0xFF)); 243 FI 244 IF errno 245 THEN prints("cannot set breakpoint: "); 246 psymoff(bkptr->loc,ISYM,"\n"); 247 FI 248 FI 249 OD 250 bpstate=BPIN; 251 FI 252 } 253 254 bpwait() 255 { 256 REG ADDR w; 257 ADDR stat; 258 259 signal(SIGINT, 1); 260 WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE 261 signal(SIGINT,sigint); 262 IF w == -1 263 THEN pid=0; 264 errflg=BADWAIT; 265 ELIF (stat & 0177) != 0177 266 THEN sigcode = 0; 267 IF signo = stat&0177 268 THEN sigprint(); 269 FI 270 IF stat&0200 271 THEN prints(" - core dumped"); 272 close(fcor); 273 setcor(); 274 FI 275 pid=0; 276 errflg=ENDPCS; 277 ELSE signo = stat>>8; 278 sigcode = ptrace(RUREGS, pid, &((struct user *)0)->u_code, 0); 279 IF signo!=SIGTRAP 280 THEN sigprint(); 281 ELSE signo=0; 282 FI 283 flushbuf(); 284 FI 285 } 286 287 readregs() 288 { 289 /*get REG values from pcs*/ 290 REG i; 291 FOR i=24; --i>=0; 292 DO *(ADDR *)(((ADDR)&u)+reglist[i].roffs) = 293 ptrace(RUREGS, pid, reglist[i].roffs, 0); 294 OD 295 userpc= *(ADDR *)(((ADDR)&u)+PC); 296 } 297 298 299