114471Ssam #ifndef lint
2*18764Ssam static char sccsid[] = "@(#)runpcs.c 4.6 04/25/85";
314471Ssam #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
getsig(sig)503765Sroot getsig(sig)
513765Sroot { return(expr(0) ? expv : sig);
523765Sroot }
533765Sroot
543765Sroot ADDR userpc = 1;
553765Sroot
runpcs(runmode,execsig)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
endpcs()1043765Sroot endpcs()
1053765Sroot {
1063765Sroot REG BKPTR bkptr;
1073765Sroot IF pid
10817254Ssam THEN ptrace(PT_KILL,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
nullsig()1193765Sroot nullsig()
1203765Sroot {
1213765Sroot
1223765Sroot }
1233765Sroot #endif
1243765Sroot
setup()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
13317254Ssam THEN ptrace(PT_TRACE_ME,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
execbkpt(bkptr,execsig)1513765Sroot execbkpt(bkptr,execsig)
1523765Sroot BKPTR bkptr;
1533765Sroot {
1543765Sroot #ifdef DEBUG
1553765Sroot printf("exbkpt: %d\n",bkptr->count);
1563765Sroot #endif
1573765Sroot delbp();
15817254Ssam ptrace(PT_STEP,pid,bkptr->loc,execsig);
1593765Sroot bkptr->flag=BKPTSET;
1603765Sroot bpwait(); chkerr(); readregs();
1613765Sroot }
1623765Sroot
1633765Sroot
doexec()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
2073765Sroot PER lastc!=EOR DONE
2083765Sroot *ap++=0;
2093765Sroot exect(symfil, argl, environ);
2103765Sroot perror(symfil);
2113765Sroot }
2123765Sroot
scanbkpt(adr)2133765Sroot BKPTR scanbkpt(adr)
2143765Sroot ADDR adr;
2153765Sroot {
2163765Sroot REG BKPTR bkptr;
2173765Sroot FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
2183765Sroot DO IF bkptr->flag ANDF bkptr->loc==adr
2193765Sroot THEN break;
2203765Sroot FI
2213765Sroot OD
2223765Sroot return(bkptr);
2233765Sroot }
2243765Sroot
delbp()2253765Sroot delbp()
2263765Sroot {
2273765Sroot REG ADDR a;
2283765Sroot REG BKPTR bkptr;
2293765Sroot IF bpstate!=BPOUT
2303765Sroot THEN
2313765Sroot FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
2323765Sroot DO IF bkptr->flag
2333765Sroot THEN a=bkptr->loc;
2343765Sroot IF a < txtmap.e1 THEN
235*18764Ssam ptrace(PT_WRITE_I,pid,a,bkptr->ins);
2363765Sroot ELSE
237*18764Ssam ptrace(PT_WRITE_D,pid,a,bkptr->ins);
2383765Sroot FI
2393765Sroot FI
2403765Sroot OD
2413765Sroot bpstate=BPOUT;
2423765Sroot FI
2433765Sroot }
2443765Sroot
245*18764Ssam #ifdef vax
246*18764Ssam #define SETBP(ins) (BPT | ((ins) &~ 0xFF))
247*18764Ssam #endif
248*18764Ssam
setbp()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
26017254Ssam bkptr->ins = ptrace(PT_READ_I, pid, a, 0);
261*18764Ssam ptrace(PT_WRITE_I, pid, a, SETBP(bkptr->ins));
2623765Sroot ELSE
26317254Ssam bkptr->ins = ptrace(PT_READ_D, pid, a, 0);
264*18764Ssam ptrace(PT_WRITE_D, pid, a, SETBP(bkptr->ins));
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
bpwait()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;
30017254Ssam sigcode = ptrace(PT_READ_U, 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
readregs()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) =
31517254Ssam ptrace(PT_READ_U, pid, reglist[i].roffs, 0);
3163765Sroot OD
3173765Sroot userpc= *(ADDR *)(((ADDR)&u)+PC);
3183765Sroot }
3193765Sroot
3203765Sroot
321