1: #include "defs.h" 2: #include <sys/file.h> 3: 4: MSG NOFORK; 5: MSG ENDPCS; 6: MSG BADWAIT; 7: char *lp; 8: int sigint; 9: int sigqit; 10: BKPTR bkpthead; 11: REGLIST reglist[]; 12: char lastc; 13: u_int corhdr[]; 14: u_int *uar0; 15: int overlay; 16: char curov; 17: int fcor; 18: int fsym; 19: char *errflg; 20: int signo; 21: long dot; 22: char *symfil; 23: int wtflag; 24: int pid; 25: long expv; 26: int adrflg; 27: long loopcnt; 28: long var[]; 29: int userpc=1; 30: 31: /* service routines for sub process control */ 32: 33: getsig(sig) 34: { 35: return(expr(0) ? shorten(expv) : sig); 36: } 37: 38: runpcs(runmode, execsig) 39: { 40: int rc; 41: register BKPTR bkpt; 42: 43: IF adrflg 44: THEN userpc=shorten(dot); 45: FI 46: if (overlay) 47: choverlay(((U*)corhdr)->u_ovdata.uo_curov); 48: printf("%s: running\n", symfil); 49: 50: WHILE (loopcnt--)>0 51: DO 52: #ifdef DEBUG 53: printf("\ncontinue %d %d\n",userpc,execsig); 54: #endif 55: stty(0,&usrtty); 56: ptrace(runmode,pid,userpc,execsig); 57: bpwait(); chkerr(); readregs(); 58: 59: /*look for bkpt*/ 60: IF signo==0 ANDF (bkpt=scanbkpt(uar0[PC]-2)) 61: THEN /*stopped at bkpt*/ 62: userpc=uar0[PC]=bkpt->loc; 63: IF bkpt->flag==BKPTEXEC 64: ORF ((bkpt->flag=BKPTEXEC, command(bkpt->comm,':')) ANDF --bkpt->count) 65: THEN execbkpt(bkpt); execsig=0; loopcnt++; 66: userpc=1; 67: ELSE bkpt->count=bkpt->initcnt; 68: rc=1; 69: FI 70: ELSE rc=0; execsig=signo; userpc=1; 71: FI 72: OD 73: return(rc); 74: } 75: 76: endpcs() 77: { 78: register BKPTR bkptr; 79: 80: IF pid 81: THEN ptrace(PT_KILL,pid,0,0); pid=0; userpc=1; 82: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt 83: DO IF bkptr->flag 84: THEN bkptr->flag=BKPTSET; 85: FI 86: OD 87: FI 88: } 89: 90: setup() 91: { 92: 93: close(fsym); fsym = -1; 94: IF (pid = fork()) == 0 95: THEN ptrace(PT_TRACE_ME,0,0,0); 96: signal(SIGINT,sigint); signal(SIGQUIT,sigqit); 97: doexec(); exit(0); 98: ELIF pid == -1 99: THEN error(NOFORK); 100: ELSE bpwait(); readregs(); lp[0]=EOR; lp[1]=0; 101: fsym=open(symfil,wtflag); 102: IF errflg 103: THEN printf("%s: cannot execute\n",symfil); 104: endpcs(); error((char *)0); 105: FI 106: FI 107: } 108: 109: execbkpt(bkptr) 110: BKPTR bkptr; 111: { 112: int bkptloc; 113: #ifdef DEBUG 114: printf("exbkpt: %d\n",bkptr->count); 115: #endif 116: bkptloc = bkptr->loc; 117: ptrace(PT_WRITE_I,pid,bkptloc,bkptr->ins); 118: stty(0,&usrtty); 119: ptrace(PT_STEP,pid,bkptloc,0); 120: bpwait(); chkerr(); 121: ptrace(PT_WRITE_I,pid,bkptloc,BPT); 122: bkptr->flag=BKPTSET; 123: } 124: 125: doexec() 126: { 127: char *argl[MAXARG]; 128: char args[LINSIZ]; 129: char *p, **ap, *filnam; 130: 131: ap=argl; p=args; 132: *ap++=symfil; 133: REP IF rdc()==EOR THEN break; FI 134: /* 135: * If we find an argument beginning with a `<' or a `>', open 136: * the following file name for input and output, respectively 137: * and back the argument collocation pointer, p, back up. 138: */ 139: *ap = p; 140: WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB DO *p++=lastc; readchar(); OD 141: *p++=0; filnam = *ap+1; 142: IF **ap=='<' 143: THEN close(0); 144: IF open(filnam,0)<0 145: THEN printf("%s: cannot open\n",filnam); exit(0); 146: FI 147: p = *ap; 148: ELIF **ap=='>' 149: THEN close(1); 150: IF open(filnam, O_CREAT|O_WRONLY, 0666)<0 151: THEN printf("%s: cannot create\n",filnam); exit(0); 152: FI 153: p = *ap; 154: ELSE ap++; 155: FI 156: PER lastc!=EOR DONE 157: *ap++=0; 158: execv(symfil, argl); 159: } 160: 161: BKPTR scanbkpt(adr) 162: { 163: register BKPTR bkptr; 164: 165: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt 166: DO IF bkptr->flag ANDF bkptr->loc==adr ANDF 167: (bkptr->ovly == 0 || bkptr->ovly==curov) 168: THEN break; 169: FI 170: OD 171: return(bkptr); 172: } 173: 174: delbp() 175: { 176: register BKPTR bkptr; 177: 178: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt 179: DO IF bkptr->flag 180: THEN del1bp(bkptr); 181: FI 182: OD 183: } 184: 185: del1bp(bkptr) 186: BKPTR bkptr; 187: { 188: if (bkptr->ovly) 189: choverlay(bkptr->ovly); 190: ptrace(PT_WRITE_I,pid,bkptr->loc,bkptr->ins); 191: } 192: 193: /* change overlay in subprocess */ 194: choverlay(ovno) 195: char ovno; 196: { 197: errno = 0; 198: if (overlay && pid && ovno>0 && ovno<=NOVL) 199: ptrace(PT_WRITE_U,pid,&(((U*)0)->u_ovdata.uo_curov),ovno); 200: IF errno 201: THEN printf("cannot change to overlay %d\n", ovno); 202: FI 203: } 204: 205: setbp() 206: { 207: register BKPTR bkptr; 208: 209: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt 210: DO IF bkptr->flag 211: THEN set1bp(bkptr); 212: FI 213: OD 214: } 215: set1bp(bkptr) 216: BKPTR bkptr; 217: { 218: register int a; 219: 220: a = bkptr->loc; 221: if (bkptr->ovly) 222: choverlay(bkptr->ovly); 223: bkptr->ins = ptrace(PT_READ_I, pid, a, 0); 224: ptrace(PT_WRITE_I, pid, a, BPT); 225: IF errno 226: THEN printf("cannot set breakpoint: "); 227: psymoff(leng(bkptr->loc),ISYM,"\n"); 228: FI 229: } 230: 231: bpwait() 232: { 233: register int w; 234: int stat; 235: 236: signal(SIGINT, SIG_IGN); 237: WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE 238: signal(SIGINT,sigint); 239: gtty(0,&usrtty); 240: stty(0,&adbtty); 241: IF w == -1 242: THEN pid=0; 243: errflg=BADWAIT; 244: ELIF (stat & 0177) != 0177 245: THEN IF signo = stat&0177 246: THEN sigprint(); 247: FI 248: IF stat&0200 249: THEN printf(" - core dumped"); 250: close(fcor); 251: setcor(); 252: FI 253: pid=0; 254: errflg=ENDPCS; 255: ELSE signo = stat>>8; 256: IF signo!=SIGTRAP 257: THEN sigprint(); 258: ELSE signo=0; 259: FI 260: flushbuf(); 261: FI 262: } 263: 264: readregs() 265: { 266: /*get REG values from pcs*/ 267: register u_int i, *afp; 268: char ovno; 269: 270: FOR i=0; i<NREG; i++ 271: DO uar0[reglist[i].roffs] = 272: ptrace(PT_READ_U, pid, 273: (int *)((int)&uar0[reglist[i].roffs] - (int)&corhdr), 274: 0); 275: OD 276: /* if overlaid, get ov */ 277: IF overlay 278: THEN 279: ovno = ptrace(PT_READ_U, pid, 280: &(((struct user *)0)->u_ovdata.uo_curov),0); 281: var[VARC] = ovno; 282: ((U *)corhdr)->u_ovdata.uo_curov = ovno; 283: setovmap(ovno); 284: FI 285: /* 286: * The following section was totally and completely broken. It had been that 287: * way since V7. If you've ever wondered why the FP regs couldn't be displayed 288: * for a traced program that was the reason. The reading of the FP regs was 289: * redone 1998/4/21 for 2.11BSD. 290: */ 291: i = offsetof(struct user, u_fps); 292: afp = (u_int *)&((U *)corhdr)->u_fps; 293: while (i < offsetof(struct user, u_fps) + sizeof (struct fps)) 294: { 295: *afp++ = ptrace(PT_READ_U, pid, i, 0); 296: i += sizeof (u_int); 297: } 298: }