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