13765Sroot # 23765Sroot /* 33765Sroot * 43765Sroot * UNIX debugger 53765Sroot * 63765Sroot */ 73765Sroot 83765Sroot #include "defs.h" 9*8926Srrh static char sccsid[] = "@(#)runpcs.c 4.2 10/28/82"; 103765Sroot 113765Sroot extern MAP txtmap; 123765Sroot 133765Sroot MSG NOFORK; 143765Sroot MSG ENDPCS; 153765Sroot MSG BADWAIT; 163765Sroot 173765Sroot CHAR *lp; 183765Sroot ADDR sigint; 193765Sroot ADDR sigqit; 203765Sroot 213765Sroot /* breakpoints */ 223765Sroot BKPTR bkpthead; 233765Sroot 243765Sroot REGLIST reglist[]; 253765Sroot 263765Sroot CHAR lastc; 273765Sroot 283765Sroot INT fcor; 293765Sroot INT fsym; 303765Sroot STRING errflg; 313765Sroot INT errno; 323765Sroot INT signo; 333765Sroot INT sigcode; 343765Sroot 353765Sroot L_INT dot; 363765Sroot STRING symfil; 373765Sroot INT wtflag; 383765Sroot L_INT pid; 393765Sroot L_INT expv; 403765Sroot INT adrflg; 413765Sroot L_INT loopcnt; 423765Sroot 433765Sroot 443765Sroot 453765Sroot 463765Sroot 473765Sroot /* service routines for sub process control */ 483765Sroot 493765Sroot getsig(sig) 503765Sroot { return(expr(0) ? expv : sig); 513765Sroot } 523765Sroot 533765Sroot ADDR userpc = 1; 543765Sroot 553765Sroot runpcs(runmode,execsig) 563765Sroot { 573765Sroot INT rc; 583765Sroot REG BKPTR bkpt; 593765Sroot IF adrflg THEN userpc=dot; FI 603765Sroot printf("%s: running\n", symfil); 613765Sroot 623765Sroot WHILE --loopcnt>=0 633765Sroot DO 643765Sroot #ifdef DEBUG 653765Sroot printf("\ncontinue %x %d\n",userpc,execsig); 663765Sroot #endif 673765Sroot IF runmode==SINGLE 683765Sroot THEN delbp(); /* hardware handles single-stepping */ 693765Sroot ELSE /* continuing from a breakpoint is hard */ 703765Sroot IF bkpt=scanbkpt(userpc) 713765Sroot THEN execbkpt(bkpt,execsig); execsig=0; 723765Sroot FI 733765Sroot setbp(); 743765Sroot FI 753765Sroot ptrace(runmode,pid,userpc,execsig); 763765Sroot bpwait(); chkerr(); execsig=0; delbp(); readregs(); 773765Sroot 783765Sroot IF (signo==0) ANDF (bkpt=scanbkpt(userpc)) 793765Sroot THEN /* stopped by BPT instruction */ 803765Sroot #ifdef DEBUG 813765Sroot printf("\n BPT code; '%s'%o'%o'%d", 823765Sroot bkpt->comm,bkpt->comm[0],EOR,bkpt->flag); 833765Sroot #endif 843765Sroot dot=bkpt->loc; 853765Sroot IF bkpt->flag==BKPTEXEC 863765Sroot ORF ((bkpt->flag=BKPTEXEC) 873765Sroot ANDF bkpt->comm[0]!=EOR 883765Sroot ANDF command(bkpt->comm,':') 893765Sroot ANDF --bkpt->count) 903765Sroot THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++; 913765Sroot ELSE bkpt->count=bkpt->initcnt; rc=1; 923765Sroot FI 933765Sroot ELSE execsig=signo; rc=0; 943765Sroot FI 953765Sroot OD 963765Sroot return(rc); 973765Sroot } 983765Sroot 993765Sroot #define BPOUT 0 1003765Sroot #define BPIN 1 1013765Sroot INT bpstate = BPOUT; 1023765Sroot 1033765Sroot endpcs() 1043765Sroot { 1053765Sroot REG BKPTR bkptr; 1063765Sroot IF pid 1073765Sroot THEN ptrace(EXIT,pid,0,0); pid=0; userpc=1; 1083765Sroot FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt 1093765Sroot DO IF bkptr->flag 1103765Sroot THEN bkptr->flag=BKPTSET; 1113765Sroot FI 1123765Sroot OD 1133765Sroot FI 1143765Sroot bpstate=BPOUT; 1153765Sroot } 1163765Sroot 1173765Sroot #ifdef VFORK 1183765Sroot nullsig() 1193765Sroot { 1203765Sroot 1213765Sroot } 1223765Sroot #endif 1233765Sroot 1243765Sroot setup() 1253765Sroot { 1263765Sroot close(fsym); fsym = -1; 1273765Sroot #ifndef VFORK 1283765Sroot IF (pid = fork()) == 0 1293765Sroot #else 1303765Sroot IF (pid = vfork()) == 0 1313765Sroot #endif 1323765Sroot THEN ptrace(SETTRC,0,0,0); 1333765Sroot #ifdef VFORK 1343765Sroot signal(SIGTRAP,nullsig); 1353765Sroot #endif 1363765Sroot signal(SIGINT,sigint); signal(SIGQUIT,sigqit); 1373765Sroot doexec(); exit(0); 1383765Sroot ELIF pid == -1 1393765Sroot THEN error(NOFORK); 1403765Sroot ELSE bpwait(); readregs(); lp[0]=EOR; lp[1]=0; 1413765Sroot fsym=open(symfil,wtflag); 1423765Sroot IF errflg 1433765Sroot THEN printf("%s: cannot execute\n",symfil); 1443765Sroot endpcs(); error(0); 1453765Sroot FI 1463765Sroot FI 1473765Sroot bpstate=BPOUT; 1483765Sroot } 1493765Sroot 1503765Sroot execbkpt(bkptr,execsig) 1513765Sroot BKPTR bkptr; 1523765Sroot { 1533765Sroot #ifdef DEBUG 1543765Sroot printf("exbkpt: %d\n",bkptr->count); 1553765Sroot #endif 1563765Sroot delbp(); 1573765Sroot ptrace(SINGLE,pid,bkptr->loc,execsig); 1583765Sroot bkptr->flag=BKPTSET; 1593765Sroot bpwait(); chkerr(); readregs(); 1603765Sroot } 1613765Sroot 1623765Sroot 1633765Sroot doexec() 1643765Sroot { 1653765Sroot STRING argl[MAXARG]; 1663765Sroot CHAR args[LINSIZ]; 1673765Sroot STRING p, *ap, filnam; 1683765Sroot extern STRING environ; 1693765Sroot ap=argl; p=args; 1703765Sroot *ap++=symfil; 1713765Sroot REP IF rdc()==EOR THEN break; FI 1723765Sroot *ap = p; 173*8926Srrh /* 174*8926Srrh * First thing is to look for direction characters 175*8926Srrh * and get filename. Do not use up the args for filenames. 176*8926Srrh * Then get rid of spaces before next args. 177*8926Srrh */ 178*8926Srrh IF lastc=='<' 179*8926Srrh THEN REP readchar(); PER lastc==SP ORF lastc==TB DONE 180*8926Srrh filnam = p; 181*8926Srrh WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB ANDF lastc!='>' 182*8926Srrh DO *p++=lastc; readchar(); OD 183*8926Srrh *p = 0; 184*8926Srrh close(0); 1853765Sroot IF open(filnam,0)<0 1863765Sroot THEN printf("%s: cannot open\n",filnam); _exit(0); 1873765Sroot FI 188*8926Srrh p = *ap; 189*8926Srrh ELIF lastc=='>' 190*8926Srrh THEN REP readchar(); PER lastc==SP ORF lastc==TB DONE 191*8926Srrh filnam = p; 192*8926Srrh WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB ANDF lastc!='<' 193*8926Srrh DO *p++=lastc; readchar(); OD 194*8926Srrh *p = '\0'; 195*8926Srrh close(1); 1963765Sroot IF creat(filnam,0666)<0 1973765Sroot THEN printf("%s: cannot create\n",filnam); _exit(0); 1983765Sroot FI 199*8926Srrh p = *ap; 200*8926Srrh ELSE 201*8926Srrh WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB ANDF lastc!='>' ANDF lastc!='<' 202*8926Srrh DO *p++=lastc; readchar(); OD 203*8926Srrh *p++ = '\0'; 204*8926Srrh ap++; 2053765Sroot FI 206*8926Srrh WHILE lastc==SP ORF lastc==TB DO readchar(); OD 207*8926Srrh 2083765Sroot PER lastc!=EOR DONE 2093765Sroot *ap++=0; 2103765Sroot exect(symfil, argl, environ); 2113765Sroot perror(symfil); 2123765Sroot } 2133765Sroot 2143765Sroot BKPTR scanbkpt(adr) 2153765Sroot ADDR adr; 2163765Sroot { 2173765Sroot REG BKPTR bkptr; 2183765Sroot FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt 2193765Sroot DO IF bkptr->flag ANDF bkptr->loc==adr 2203765Sroot THEN break; 2213765Sroot FI 2223765Sroot OD 2233765Sroot return(bkptr); 2243765Sroot } 2253765Sroot 2263765Sroot delbp() 2273765Sroot { 2283765Sroot REG ADDR a; 2293765Sroot REG BKPTR bkptr; 2303765Sroot IF bpstate!=BPOUT 2313765Sroot THEN 2323765Sroot FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt 2333765Sroot DO IF bkptr->flag 2343765Sroot THEN a=bkptr->loc; 2353765Sroot IF a < txtmap.e1 THEN 2363765Sroot ptrace(WIUSER,pid,a, 2373765Sroot (bkptr->ins&0xFF)|(ptrace(RIUSER,pid,a,0)&~0xFF)); 2383765Sroot ELSE 2393765Sroot ptrace(WDUSER,pid,a, 2403765Sroot (bkptr->ins&0xFF)|(ptrace(RDUSER,pid,a,0)&~0xFF)); 2413765Sroot FI 2423765Sroot FI 2433765Sroot OD 2443765Sroot bpstate=BPOUT; 2453765Sroot FI 2463765Sroot } 2473765Sroot 2483765Sroot setbp() 2493765Sroot { 2503765Sroot REG ADDR a; 2513765Sroot REG BKPTR bkptr; 2523765Sroot 2533765Sroot IF bpstate!=BPIN 2543765Sroot THEN 2553765Sroot FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt 2563765Sroot DO IF bkptr->flag 2573765Sroot THEN a = bkptr->loc; 2583765Sroot IF a < txtmap.e1 THEN 2593765Sroot bkptr->ins = ptrace(RIUSER, pid, a, 0); 2603765Sroot ptrace(WIUSER, pid, a, BPT | (bkptr->ins&~0xFF)); 2613765Sroot ELSE 2623765Sroot bkptr->ins = ptrace(RDUSER, pid, a, 0); 2633765Sroot ptrace(WDUSER, pid, a, BPT | (bkptr->ins&~0xFF)); 2643765Sroot FI 2653765Sroot IF errno 2663765Sroot THEN prints("cannot set breakpoint: "); 2673765Sroot psymoff(bkptr->loc,ISYM,"\n"); 2683765Sroot FI 2693765Sroot FI 2703765Sroot OD 2713765Sroot bpstate=BPIN; 2723765Sroot FI 2733765Sroot } 2743765Sroot 2753765Sroot bpwait() 2763765Sroot { 2773765Sroot REG ADDR w; 2783765Sroot ADDR stat; 2793765Sroot 2803765Sroot signal(SIGINT, 1); 2813765Sroot WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE 2823765Sroot signal(SIGINT,sigint); 2833765Sroot IF w == -1 2843765Sroot THEN pid=0; 2853765Sroot errflg=BADWAIT; 2863765Sroot ELIF (stat & 0177) != 0177 2873765Sroot THEN sigcode = 0; 2883765Sroot IF signo = stat&0177 2893765Sroot THEN sigprint(); 2903765Sroot FI 2913765Sroot IF stat&0200 2923765Sroot THEN prints(" - core dumped"); 2933765Sroot close(fcor); 2943765Sroot setcor(); 2953765Sroot FI 2963765Sroot pid=0; 2973765Sroot errflg=ENDPCS; 2983765Sroot ELSE signo = stat>>8; 2993765Sroot sigcode = ptrace(RUREGS, pid, &((struct user *)0)->u_code, 0); 3003765Sroot IF signo!=SIGTRAP 3013765Sroot THEN sigprint(); 3023765Sroot ELSE signo=0; 3033765Sroot FI 3043765Sroot flushbuf(); 3053765Sroot FI 3063765Sroot } 3073765Sroot 3083765Sroot readregs() 3093765Sroot { 3103765Sroot /*get REG values from pcs*/ 3113765Sroot REG i; 3123765Sroot FOR i=24; --i>=0; 3133765Sroot DO *(ADDR *)(((ADDR)&u)+reglist[i].roffs) = 3143765Sroot ptrace(RUREGS, pid, reglist[i].roffs, 0); 3153765Sroot OD 3163765Sroot userpc= *(ADDR *)(((ADDR)&u)+PC); 3173765Sroot } 3183765Sroot 3193765Sroot 320