1: #ifndef lint 2: static char sccsid[] = "@(#)runpcs.c 4.6 4/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: }