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