1 #ifndef lint 2 static char sccsid[] = "@(#)runpcs.c 4.6 04/25/85"; 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(PT_KILL,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(PT_TRACE_ME,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(PT_STEP,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(PT_WRITE_I,pid,a,bkptr->ins); 236 ELSE 237 ptrace(PT_WRITE_D,pid,a,bkptr->ins); 238 FI 239 FI 240 OD 241 bpstate=BPOUT; 242 FI 243 } 244 245 #ifdef vax 246 #define SETBP(ins) (BPT | ((ins) &~ 0xFF)) 247 #endif 248 249 setbp() 250 { 251 REG ADDR a; 252 REG BKPTR bkptr; 253 254 IF bpstate!=BPIN 255 THEN 256 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt 257 DO IF bkptr->flag 258 THEN a = bkptr->loc; 259 IF a < txtmap.e1 THEN 260 bkptr->ins = ptrace(PT_READ_I, pid, a, 0); 261 ptrace(PT_WRITE_I, pid, a, SETBP(bkptr->ins)); 262 ELSE 263 bkptr->ins = ptrace(PT_READ_D, pid, a, 0); 264 ptrace(PT_WRITE_D, pid, a, SETBP(bkptr->ins)); 265 FI 266 IF errno 267 THEN prints("cannot set breakpoint: "); 268 psymoff(bkptr->loc,ISYM,"\n"); 269 FI 270 FI 271 OD 272 bpstate=BPIN; 273 FI 274 } 275 276 bpwait() 277 { 278 REG ADDR w; 279 ADDR stat; 280 281 signal(SIGINT, 1); 282 WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE 283 signal(SIGINT,sigint); 284 IF w == -1 285 THEN pid=0; 286 errflg=BADWAIT; 287 ELIF (stat & 0177) != 0177 288 THEN sigcode = 0; 289 IF signo = stat&0177 290 THEN sigprint(); 291 FI 292 IF stat&0200 293 THEN prints(" - core dumped"); 294 close(fcor); 295 setcor(); 296 FI 297 pid=0; 298 errflg=ENDPCS; 299 ELSE signo = stat>>8; 300 sigcode = ptrace(PT_READ_U, pid, &((struct user *)0)->u_code, 0); 301 IF signo!=SIGTRAP 302 THEN sigprint(); 303 ELSE signo=0; 304 FI 305 flushbuf(); 306 FI 307 } 308 309 readregs() 310 { 311 /*get REG values from pcs*/ 312 REG i; 313 FOR i=24; --i>=0; 314 DO *(ADDR *)(((ADDR)&u)+reglist[i].roffs) = 315 ptrace(PT_READ_U, pid, reglist[i].roffs, 0); 316 OD 317 userpc= *(ADDR *)(((ADDR)&u)+PC); 318 } 319 320 321