1: static char sccsid[] = "@(#)runpcs.c 4.2 8/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: }