1*b09715edSrrh static char sccsid[] = "@(#)runpcs.c 4.2 08/17/82";
21e5ca63fSbill #
31e5ca63fSbill /*
41e5ca63fSbill *
51e5ca63fSbill * UNIX debugger
61e5ca63fSbill *
71e5ca63fSbill */
81e5ca63fSbill
91e5ca63fSbill #include "head.h"
101e5ca63fSbill #include <a.out.h>
111e5ca63fSbill #include <stab.h>
121e5ca63fSbill struct user u;
131e5ca63fSbill #include <stdio.h>
141e5ca63fSbill
151e5ca63fSbill #ifndef SIGTRAP
161e5ca63fSbill #define SIGTRAP SIGTRC
171e5ca63fSbill #endif
181e5ca63fSbill
191e5ca63fSbill MSG NOFORK;
201e5ca63fSbill MSG ENDPCS;
211e5ca63fSbill MSG BADWAIT;
221e5ca63fSbill
231e5ca63fSbill ADDR sigint;
241e5ca63fSbill ADDR sigqit;
251e5ca63fSbill ADDR userpc;
261e5ca63fSbill
271e5ca63fSbill /* breakpoints */
281e5ca63fSbill BKPTR bkpthead;
291e5ca63fSbill
301e5ca63fSbill CHAR lastc;
311e5ca63fSbill
321e5ca63fSbill INT fcor;
331e5ca63fSbill INT fsym;
341e5ca63fSbill STRING errflg;
351e5ca63fSbill int errno;
361e5ca63fSbill INT signo;
371e5ca63fSbill
381e5ca63fSbill L_INT dot;
391e5ca63fSbill STRING symfil;
401e5ca63fSbill INT wtflag;
411e5ca63fSbill INT pid;
421e5ca63fSbill INT adrflg;
431e5ca63fSbill L_INT loopcnt;
441e5ca63fSbill
451e5ca63fSbill
461e5ca63fSbill
471e5ca63fSbill
481e5ca63fSbill
491e5ca63fSbill
getsig(sig)501e5ca63fSbill getsig(sig)
511e5ca63fSbill { return(sig);
521e5ca63fSbill }
531e5ca63fSbill
runpcs(runmode,execsig)541e5ca63fSbill runpcs(runmode,execsig)
551e5ca63fSbill {
561e5ca63fSbill REG BKPTR bkpt;
571e5ca63fSbill IF adrflg THEN userpc=dot; FI
581e5ca63fSbill WHILE --loopcnt>=0
591e5ca63fSbill DO
601e5ca63fSbill if (debug) printf("\ncontinue %x %d\n",userpc,execsig);
611e5ca63fSbill IF runmode==SINGLE
621e5ca63fSbill THEN delbp(); /* hardware handles single-stepping */
631e5ca63fSbill ELSE /* continuing from a breakpoint is hard */
641e5ca63fSbill IF bkpt=scanbkpt(userpc)
651e5ca63fSbill THEN execbkpt(bkpt,execsig); execsig=0;
661e5ca63fSbill FI
671e5ca63fSbill setbp();
681e5ca63fSbill FI
691e5ca63fSbill ptrace(runmode,pid,userpc,execsig);
701e5ca63fSbill bpwait(); chkerr(); execsig=0; delbp(); readregs();
711e5ca63fSbill
721e5ca63fSbill loop1: IF (signo==0) ANDF (bkpt=scanbkpt(userpc))
731e5ca63fSbill THEN /* stopped by BPT instruction */
741e5ca63fSbill if (debug) printf("\n BPT code; '%s'%o'%o'%d",
751e5ca63fSbill bkpt->comm,bkpt->comm[0],EOR,bkpt->flag);
761e5ca63fSbill dot=bkpt->loc;
771e5ca63fSbill IF bkpt->comm[0] != EOR
781e5ca63fSbill THEN acommand(bkpt->comm);
791e5ca63fSbill FI
801e5ca63fSbill IF bkpt->flag==BKPTEXEC
811e5ca63fSbill ORF ((bkpt->flag=BKPTEXEC)
821e5ca63fSbill ANDF bkpt->comm[0]!=EOR)
831e5ca63fSbill THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++;
841e5ca63fSbill goto loop1;
851e5ca63fSbill ELSE bkpt->flag=BKPTSET; bkpt->count=bkpt->initcnt;
861e5ca63fSbill FI
871e5ca63fSbill ELSE execsig=signo;
881e5ca63fSbill if (execsig) break;
891e5ca63fSbill FI
901e5ca63fSbill OD
911e5ca63fSbill if (debug) printf("Returning from runpcs\n");
921e5ca63fSbill }
931e5ca63fSbill
941e5ca63fSbill #define BPOUT 0
951e5ca63fSbill #define BPIN 1
961e5ca63fSbill INT bpstate;
971e5ca63fSbill
endpcs()981e5ca63fSbill endpcs()
991e5ca63fSbill {
1001e5ca63fSbill REG BKPTR bkptr;
1011e5ca63fSbill if (debug) printf("Entering endpcs with pid=%d\n");
1021e5ca63fSbill IF pid
1031e5ca63fSbill THEN ptrace(EXIT,pid,0,0); pid=0; userpc=1;
1041e5ca63fSbill FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
1051e5ca63fSbill DO IF bkptr->flag
1061e5ca63fSbill THEN bkptr->flag=BKPTSET;
1071e5ca63fSbill FI
1081e5ca63fSbill OD
1091e5ca63fSbill FI
1101e5ca63fSbill bpstate=BPOUT;
1111e5ca63fSbill }
1121e5ca63fSbill
1131e5ca63fSbill #ifdef VFORK
nullsig()1141e5ca63fSbill nullsig()
1151e5ca63fSbill {
1161e5ca63fSbill
1171e5ca63fSbill }
1181e5ca63fSbill #endif
1191e5ca63fSbill
setup()1201e5ca63fSbill setup()
1211e5ca63fSbill {
1221e5ca63fSbill close(fsym); fsym = -1;
1231e5ca63fSbill #ifdef VFORK
1241e5ca63fSbill IF (pid = vfork()) == 0
1251e5ca63fSbill #else
1261e5ca63fSbill IF (pid = fork()) == 0
1271e5ca63fSbill #endif
1281e5ca63fSbill THEN ptrace(SETTRC,0,0,0);
1291e5ca63fSbill signal(SIGINT,sigint); signal(SIGQUIT,sigqit);
1301e5ca63fSbill #ifdef VFORK
1311e5ca63fSbill signal(SIGTRAP,nullsig);
1321e5ca63fSbill #endif
1331e5ca63fSbill if (debug) printf("About to doexec pid=%d\n",pid);
1341e5ca63fSbill doexec(); _exit(0);
1351e5ca63fSbill ELIF pid == -1
1361e5ca63fSbill THEN error(NOFORK);
1371e5ca63fSbill ELSE bpwait(); readregs();
1381e5ca63fSbill if (debug) printf("About to open symfil = %s\n", symfil);
1391e5ca63fSbill fsym=open(symfil,wtflag);
1401e5ca63fSbill IF errflg
1411e5ca63fSbill THEN printf("%s: cannot execute\n",symfil);
1421e5ca63fSbill if (debug) printf("%d %s\n", errflg, errflg);
1431e5ca63fSbill endpcs();
1441e5ca63fSbill FI
1451e5ca63fSbill FI
1461e5ca63fSbill bpstate=BPOUT;
1471e5ca63fSbill }
1481e5ca63fSbill
execbkpt(bkptr,execsig)1491e5ca63fSbill execbkpt(bkptr,execsig)
1501e5ca63fSbill BKPTR bkptr;
1511e5ca63fSbill {
1521e5ca63fSbill if (debug) printf("exbkpt: %d\n",bkptr->count);
1531e5ca63fSbill delbp();
1541e5ca63fSbill ptrace(SINGLE,pid,bkptr->loc,execsig);
1551e5ca63fSbill bkptr->flag=BKPTSET;
1561e5ca63fSbill bpwait(); chkerr(); readregs();
1571e5ca63fSbill }
1581e5ca63fSbill
1591e5ca63fSbill extern STRING environ;
1601e5ca63fSbill
doexec()1611e5ca63fSbill doexec()
1621e5ca63fSbill {
1631e5ca63fSbill char *argl[MAXARG], args[LINSIZ];
1641e5ca63fSbill register char c, redchar, *argsp, **arglp, *filnam;
1651e5ca63fSbill
1661e5ca63fSbill arglp = argl;
1671e5ca63fSbill argsp = args;
1681e5ca63fSbill *arglp++ = symfil;
1691e5ca63fSbill c = ' ';
1701e5ca63fSbill
1711e5ca63fSbill do {
1721e5ca63fSbill while (eqany(c, " \t")) {
1731e5ca63fSbill c = rdc();
1741e5ca63fSbill }
1751e5ca63fSbill if (eqany(c, "<>")) {
1761e5ca63fSbill redchar = c;
1771e5ca63fSbill do {
1781e5ca63fSbill c = rdc();
1791e5ca63fSbill } while (eqany(c, " \t"));
1801e5ca63fSbill filnam = argsp;
1811e5ca63fSbill do {
1821e5ca63fSbill *argsp++ = c;
1831e5ca63fSbill c = rdc();
1841e5ca63fSbill } while (!eqany(c, " <>\t\n"));
1851e5ca63fSbill *argsp++ = '\0';
1861e5ca63fSbill if (redchar == '<') {
1871e5ca63fSbill close(0);
1881e5ca63fSbill if (open(filnam,0) < 0) {
1891e5ca63fSbill printf("%s: cannot open\n",filnam);
1901e5ca63fSbill fflush(stdout);
1911e5ca63fSbill _exit(0);
1921e5ca63fSbill }
1931e5ca63fSbill } else {
1941e5ca63fSbill close(1);
1951e5ca63fSbill if (creat(filnam,0666) < 0) {
1961e5ca63fSbill printf("%s: cannot create\n",filnam);
1971e5ca63fSbill fflush(stdout);
1981e5ca63fSbill _exit(0);
1991e5ca63fSbill }
2001e5ca63fSbill }
2011e5ca63fSbill } else if (c != '\n') {
2021e5ca63fSbill *arglp++ = argsp;
2031e5ca63fSbill do {
2041e5ca63fSbill *argsp++ = c;
2051e5ca63fSbill c = rdc();
2061e5ca63fSbill } while(!eqany(c, " <>\t\n"));
2071e5ca63fSbill *argsp++ = '\0';
2081e5ca63fSbill }
2091e5ca63fSbill } while (c != '\n');
2101e5ca63fSbill *arglp = (char *) 0;
2111e5ca63fSbill if (debug) {
2121e5ca63fSbill char **dap;
2131e5ca63fSbill printf("About to exect(%s, %d, %d)\n",symfil,argl,environ);
2141e5ca63fSbill for (dap = argl; *dap; dap++) {
2151e5ca63fSbill printf("%s, ", *dap);
2161e5ca63fSbill }
2171e5ca63fSbill }
2181e5ca63fSbill exect(symfil, argl, environ);
2191e5ca63fSbill perror("Returned from exect");
2201e5ca63fSbill }
2211e5ca63fSbill
scanbkpt(adr)2221e5ca63fSbill BKPTR scanbkpt(adr)
2231e5ca63fSbill ADDR adr;
2241e5ca63fSbill {
2251e5ca63fSbill REG BKPTR bkptr;
2261e5ca63fSbill FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
2271e5ca63fSbill DO IF bkptr->flag ANDF bkptr->loc==adr
2281e5ca63fSbill THEN break;
2291e5ca63fSbill FI
2301e5ca63fSbill OD
2311e5ca63fSbill return(bkptr);
2321e5ca63fSbill }
2331e5ca63fSbill
delbp()2341e5ca63fSbill delbp()
2351e5ca63fSbill {
2361e5ca63fSbill REG ADDR a;
2371e5ca63fSbill REG BKPTR bkptr;
2381e5ca63fSbill IF bpstate!=BPOUT
2391e5ca63fSbill THEN
2401e5ca63fSbill FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
2411e5ca63fSbill DO IF bkptr->flag
2421e5ca63fSbill THEN a=bkptr->loc;
2431e5ca63fSbill ptrace(WIUSER,pid,a,
2441e5ca63fSbill (bkptr->ins&0xFF)|(ptrace(RIUSER,pid,a,0)&~0xFF));
2451e5ca63fSbill FI
2461e5ca63fSbill OD
2471e5ca63fSbill bpstate=BPOUT;
2481e5ca63fSbill FI
2491e5ca63fSbill }
2501e5ca63fSbill
setbp()2511e5ca63fSbill setbp()
2521e5ca63fSbill {
2531e5ca63fSbill REG ADDR a;
2541e5ca63fSbill REG BKPTR bkptr;
2551e5ca63fSbill
2561e5ca63fSbill IF bpstate!=BPIN
2571e5ca63fSbill THEN
2581e5ca63fSbill FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
2591e5ca63fSbill DO IF bkptr->flag
2601e5ca63fSbill THEN a = bkptr->loc;
2611e5ca63fSbill bkptr->ins = ptrace(RIUSER, pid, a, 0);
2621e5ca63fSbill ptrace(WIUSER, pid, a, BPT | (bkptr->ins&~0xFF));
2631e5ca63fSbill IF errno
2641e5ca63fSbill THEN error("cannot set breakpoint: ");
2651e5ca63fSbill printf("%s:%d @ %d\n", adrtoprocp(dot)->pname,
2661e5ca63fSbill adrtolineno(dot), dot);
2671e5ca63fSbill FI
2681e5ca63fSbill FI
2691e5ca63fSbill OD
2701e5ca63fSbill bpstate=BPIN;
2711e5ca63fSbill FI
2721e5ca63fSbill }
2731e5ca63fSbill
bpwait()2741e5ca63fSbill bpwait()
2751e5ca63fSbill {
2761e5ca63fSbill REG ADDR w;
2771e5ca63fSbill ADDR stat;
2781e5ca63fSbill
2791e5ca63fSbill signal(SIGINT, 1);
2801e5ca63fSbill if (debug) printf("Waiting for pid %d\n",pid);
2811e5ca63fSbill WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE
2821e5ca63fSbill if (debug) printf("Ending wait\n");
2831e5ca63fSbill if (debug) printf("w = %d; pid = %d; stat = %o;\n", w,pid,stat);
2841e5ca63fSbill signal(SIGINT,sigint);
2851e5ca63fSbill IF w == -1
2861e5ca63fSbill THEN pid=0;
2871e5ca63fSbill errflg=BADWAIT;
2881e5ca63fSbill ELIF (stat & 0177) != 0177
2891e5ca63fSbill THEN IF signo = stat&0177
2901e5ca63fSbill THEN sigprint();
2911e5ca63fSbill FI
2921e5ca63fSbill IF stat&0200
2931e5ca63fSbill THEN error(" - core dumped");
2941e5ca63fSbill close(fcor);
2951e5ca63fSbill setcor();
2961e5ca63fSbill FI
2971e5ca63fSbill pid=0;
2981e5ca63fSbill errflg=ENDPCS;
2991e5ca63fSbill ELSE signo = stat>>8;
3001e5ca63fSbill if (debug) printf("PC = %d, dbsubn = %d\n",
3011e5ca63fSbill ptrace(RUREGS, pid, PC, 0), extaddr("_dbsubn"));
3021e5ca63fSbill IF signo!=SIGTRAP ANDF
3031e5ca63fSbill ptrace(RUREGS, pid, PC, 0) != extaddr("_dbsubn")
3041e5ca63fSbill THEN sigprint();
3051e5ca63fSbill ELSE signo=0;
3061e5ca63fSbill FI
3071e5ca63fSbill FI
3081e5ca63fSbill }
3091e5ca63fSbill
3101e5ca63fSbill REGLIST reglist[];
readregs()3111e5ca63fSbill readregs()
3121e5ca63fSbill {
3131e5ca63fSbill /*get REG values from pcs*/
3141e5ca63fSbill REG i;
3151e5ca63fSbill FOR i=24; --i>=0;
3161e5ca63fSbill DO *(ADDR *)(((ADDR)&u)+reglist[i].roffs) =
3171e5ca63fSbill ptrace(RUREGS, pid, reglist[i].roffs, 0);
3181e5ca63fSbill OD
3191e5ca63fSbill userpc= *(ADDR *)(((ADDR)&u)+PC);
3201e5ca63fSbill }
3211e5ca63fSbill
3221e5ca63fSbill char
readchar()3231e5ca63fSbill readchar() {
3241e5ca63fSbill lastc = *argsp++;
3251e5ca63fSbill if (lastc == '\0') lastc = '\n';
3261e5ca63fSbill return(lastc);
3271e5ca63fSbill }
3281e5ca63fSbill
3291e5ca63fSbill char
rdc()3301e5ca63fSbill rdc()
3311e5ca63fSbill {
3321e5ca63fSbill register char c;
3331e5ca63fSbill
3341e5ca63fSbill c = *argsp++;
3351e5ca63fSbill return(c == '\0' ? '\n' : c);
3361e5ca63fSbill }
337