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