1*7776Srrh static char sccsid[] = "@(#)runpcs.c 4.2 08/17/82";
21349Sbill #
31349Sbill /*
41349Sbill *
51349Sbill * UNIX debugger
61349Sbill *
71349Sbill */
81349Sbill
91349Sbill #include "head.h"
101349Sbill #include <a.out.h>
111349Sbill #include <stab.h>
121349Sbill struct user u;
131349Sbill #include <stdio.h>
141349Sbill
151349Sbill #ifndef SIGTRAP
161349Sbill #define SIGTRAP SIGTRC
171349Sbill #endif
181349Sbill
191349Sbill MSG NOFORK;
201349Sbill MSG ENDPCS;
211349Sbill MSG BADWAIT;
221349Sbill
231349Sbill ADDR sigint;
241349Sbill ADDR sigqit;
251349Sbill ADDR userpc;
261349Sbill
271349Sbill /* breakpoints */
281349Sbill BKPTR bkpthead;
291349Sbill
301349Sbill CHAR lastc;
311349Sbill
321349Sbill INT fcor;
331349Sbill INT fsym;
341349Sbill STRING errflg;
351349Sbill int errno;
361349Sbill INT signo;
371349Sbill
381349Sbill L_INT dot;
391349Sbill STRING symfil;
401349Sbill INT wtflag;
411349Sbill INT pid;
421349Sbill INT adrflg;
431349Sbill L_INT loopcnt;
441349Sbill
451349Sbill
461349Sbill
471349Sbill
481349Sbill
491349Sbill
getsig(sig)501349Sbill getsig(sig)
511349Sbill { return(sig);
521349Sbill }
531349Sbill
runpcs(runmode,execsig)541349Sbill runpcs(runmode,execsig)
551349Sbill {
561349Sbill REG BKPTR bkpt;
571349Sbill IF adrflg THEN userpc=dot; FI
581349Sbill WHILE --loopcnt>=0
591349Sbill DO
601349Sbill if (debug) printf("\ncontinue %x %d\n",userpc,execsig);
611349Sbill IF runmode==SINGLE
621349Sbill THEN delbp(); /* hardware handles single-stepping */
631349Sbill ELSE /* continuing from a breakpoint is hard */
641349Sbill IF bkpt=scanbkpt(userpc)
651349Sbill THEN execbkpt(bkpt,execsig); execsig=0;
661349Sbill FI
671349Sbill setbp();
681349Sbill FI
691349Sbill ptrace(runmode,pid,userpc,execsig);
701349Sbill bpwait(); chkerr(); execsig=0; delbp(); readregs();
711349Sbill
721349Sbill loop1: IF (signo==0) ANDF (bkpt=scanbkpt(userpc))
731349Sbill THEN /* stopped by BPT instruction */
741349Sbill if (debug) printf("\n BPT code; '%s'%o'%o'%d",
751349Sbill bkpt->comm,bkpt->comm[0],EOR,bkpt->flag);
761349Sbill dot=bkpt->loc;
771349Sbill IF bkpt->comm[0] != EOR
781349Sbill THEN acommand(bkpt->comm);
791349Sbill FI
801349Sbill IF bkpt->flag==BKPTEXEC
811349Sbill ORF ((bkpt->flag=BKPTEXEC)
821349Sbill ANDF bkpt->comm[0]!=EOR)
831349Sbill THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++;
841349Sbill goto loop1;
851349Sbill ELSE bkpt->flag=BKPTSET; bkpt->count=bkpt->initcnt;
861349Sbill FI
871349Sbill ELSE execsig=signo;
881349Sbill if (execsig) break;
891349Sbill FI
901349Sbill OD
911349Sbill if (debug) printf("Returning from runpcs\n");
921349Sbill }
931349Sbill
941349Sbill #define BPOUT 0
951349Sbill #define BPIN 1
961349Sbill INT bpstate;
971349Sbill
endpcs()981349Sbill endpcs()
991349Sbill {
1001349Sbill REG BKPTR bkptr;
1011349Sbill if (debug) printf("Entering endpcs with pid=%d\n");
1021349Sbill IF pid
1031349Sbill THEN ptrace(EXIT,pid,0,0); pid=0; userpc=1;
1041349Sbill FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
1051349Sbill DO IF bkptr->flag
1061349Sbill THEN bkptr->flag=BKPTSET;
1071349Sbill FI
1081349Sbill OD
1091349Sbill FI
1101349Sbill bpstate=BPOUT;
1111349Sbill }
1121349Sbill
1131349Sbill #ifdef VFORK
nullsig()1141349Sbill nullsig()
1151349Sbill {
1161349Sbill
1171349Sbill }
1181349Sbill #endif
1191349Sbill
setup()1201349Sbill setup()
1211349Sbill {
1221349Sbill close(fsym); fsym = -1;
1231349Sbill #ifdef VFORK
1241349Sbill IF (pid = vfork()) == 0
1251349Sbill #else
1261349Sbill IF (pid = fork()) == 0
1271349Sbill #endif
1281349Sbill THEN ptrace(SETTRC,0,0,0);
1291349Sbill signal(SIGINT,sigint); signal(SIGQUIT,sigqit);
1301349Sbill #ifdef VFORK
1311349Sbill signal(SIGTRAP,nullsig);
1321349Sbill #endif
1331349Sbill if (debug) printf("About to doexec pid=%d\n",pid);
1341349Sbill doexec(); _exit(0);
1351349Sbill ELIF pid == -1
1361349Sbill THEN error(NOFORK);
1371349Sbill ELSE bpwait(); readregs();
1381349Sbill if (debug) printf("About to open symfil = %s\n", symfil);
1391349Sbill fsym=open(symfil,wtflag);
1401349Sbill IF errflg
1411349Sbill THEN printf("%s: cannot execute\n",symfil);
1421349Sbill if (debug) printf("%d %s\n", errflg, errflg);
1431349Sbill endpcs();
1441349Sbill FI
1451349Sbill FI
1461349Sbill bpstate=BPOUT;
1471349Sbill }
1481349Sbill
execbkpt(bkptr,execsig)1491349Sbill execbkpt(bkptr,execsig)
1501349Sbill BKPTR bkptr;
1511349Sbill {
1521349Sbill if (debug) printf("exbkpt: %d\n",bkptr->count);
1531349Sbill delbp();
1541349Sbill ptrace(SINGLE,pid,bkptr->loc,execsig);
1551349Sbill bkptr->flag=BKPTSET;
1561349Sbill bpwait(); chkerr(); readregs();
1571349Sbill }
1581349Sbill
1591349Sbill extern STRING environ;
1601349Sbill
doexec()1611349Sbill doexec()
1621349Sbill {
1631349Sbill char *argl[MAXARG], args[LINSIZ];
1641349Sbill register char c, redchar, *argsp, **arglp, *filnam;
1651349Sbill
1661349Sbill arglp = argl;
1671349Sbill argsp = args;
1681349Sbill *arglp++ = symfil;
1691349Sbill c = ' ';
1701349Sbill
1711349Sbill do {
1721349Sbill while (eqany(c, " \t")) {
1731349Sbill c = rdc();
1741349Sbill }
1751349Sbill if (eqany(c, "<>")) {
1761349Sbill redchar = c;
1771349Sbill do {
1781349Sbill c = rdc();
1791349Sbill } while (eqany(c, " \t"));
1801349Sbill filnam = argsp;
1811349Sbill do {
1821349Sbill *argsp++ = c;
1831349Sbill c = rdc();
1841349Sbill } while (!eqany(c, " <>\t\n"));
1851349Sbill *argsp++ = '\0';
1861349Sbill if (redchar == '<') {
1871349Sbill close(0);
1881349Sbill if (open(filnam,0) < 0) {
1891349Sbill printf("%s: cannot open\n",filnam);
1901349Sbill fflush(stdout);
1911349Sbill _exit(0);
1921349Sbill }
1931349Sbill } else {
1941349Sbill close(1);
1951349Sbill if (creat(filnam,0666) < 0) {
1961349Sbill printf("%s: cannot create\n",filnam);
1971349Sbill fflush(stdout);
1981349Sbill _exit(0);
1991349Sbill }
2001349Sbill }
2011349Sbill } else if (c != '\n') {
2021349Sbill *arglp++ = argsp;
2031349Sbill do {
2041349Sbill *argsp++ = c;
2051349Sbill c = rdc();
2061349Sbill } while(!eqany(c, " <>\t\n"));
2071349Sbill *argsp++ = '\0';
2081349Sbill }
2091349Sbill } while (c != '\n');
2101349Sbill *arglp = (char *) 0;
2111349Sbill if (debug) {
2121349Sbill char **dap;
2131349Sbill printf("About to exect(%s, %d, %d)\n",symfil,argl,environ);
2141349Sbill for (dap = argl; *dap; dap++) {
2151349Sbill printf("%s, ", *dap);
2161349Sbill }
2171349Sbill }
2181349Sbill exect(symfil, argl, environ);
2191349Sbill perror("Returned from exect");
2201349Sbill }
2211349Sbill
scanbkpt(adr)2221349Sbill BKPTR scanbkpt(adr)
2231349Sbill ADDR adr;
2241349Sbill {
2251349Sbill REG BKPTR bkptr;
2261349Sbill FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
2271349Sbill DO IF bkptr->flag ANDF bkptr->loc==adr
2281349Sbill THEN break;
2291349Sbill FI
2301349Sbill OD
2311349Sbill return(bkptr);
2321349Sbill }
2331349Sbill
delbp()2341349Sbill delbp()
2351349Sbill {
2361349Sbill REG ADDR a;
2371349Sbill REG BKPTR bkptr;
2381349Sbill IF bpstate!=BPOUT
2391349Sbill THEN
2401349Sbill FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
2411349Sbill DO IF bkptr->flag
2421349Sbill THEN a=bkptr->loc;
2431349Sbill ptrace(WIUSER,pid,a,
2441349Sbill (bkptr->ins&0xFF)|(ptrace(RIUSER,pid,a,0)&~0xFF));
2451349Sbill FI
2461349Sbill OD
2471349Sbill bpstate=BPOUT;
2481349Sbill FI
2491349Sbill }
2501349Sbill
setbp()2511349Sbill setbp()
2521349Sbill {
2531349Sbill REG ADDR a;
2541349Sbill REG BKPTR bkptr;
2551349Sbill
2561349Sbill IF bpstate!=BPIN
2571349Sbill THEN
2581349Sbill FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
2591349Sbill DO IF bkptr->flag
2601349Sbill THEN a = bkptr->loc;
2611349Sbill bkptr->ins = ptrace(RIUSER, pid, a, 0);
2621349Sbill ptrace(WIUSER, pid, a, BPT | (bkptr->ins&~0xFF));
2631349Sbill IF errno
2641349Sbill THEN error("cannot set breakpoint: ");
2651349Sbill printf("%s:%d @ %d\n", adrtoprocp(dot)->pname,
2661349Sbill adrtolineno(dot), dot);
2671349Sbill FI
2681349Sbill FI
2691349Sbill OD
2701349Sbill bpstate=BPIN;
2711349Sbill FI
2721349Sbill }
2731349Sbill
bpwait()2741349Sbill bpwait()
2751349Sbill {
2761349Sbill REG ADDR w;
2771349Sbill ADDR stat;
2781349Sbill
2791349Sbill signal(SIGINT, 1);
2801349Sbill if (debug) printf("Waiting for pid %d\n",pid);
2811349Sbill WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE
2821349Sbill if (debug) printf("Ending wait\n");
2831349Sbill if (debug) printf("w = %d; pid = %d; stat = %o;\n", w,pid,stat);
2841349Sbill signal(SIGINT,sigint);
2851349Sbill IF w == -1
2861349Sbill THEN pid=0;
2871349Sbill errflg=BADWAIT;
2881349Sbill ELIF (stat & 0177) != 0177
2891349Sbill THEN IF signo = stat&0177
2901349Sbill THEN sigprint();
2911349Sbill FI
2921349Sbill IF stat&0200
2931349Sbill THEN error(" - core dumped");
2941349Sbill close(fcor);
2951349Sbill setcor();
2961349Sbill FI
2971349Sbill pid=0;
2981349Sbill errflg=ENDPCS;
2991349Sbill ELSE signo = stat>>8;
3001349Sbill if (debug) printf("PC = %d, dbsubn = %d\n",
3011349Sbill ptrace(RUREGS, pid, PC, 0), extaddr("_dbsubn"));
3021349Sbill IF signo!=SIGTRAP ANDF
3031349Sbill ptrace(RUREGS, pid, PC, 0) != extaddr("_dbsubn")
3041349Sbill THEN sigprint();
3051349Sbill ELSE signo=0;
3061349Sbill FI
3071349Sbill FI
3081349Sbill }
3091349Sbill
3101349Sbill REGLIST reglist[];
readregs()3111349Sbill readregs()
3121349Sbill {
3131349Sbill /*get REG values from pcs*/
3141349Sbill REG i;
3151349Sbill FOR i=24; --i>=0;
3161349Sbill DO *(ADDR *)(((ADDR)&u)+reglist[i].roffs) =
3171349Sbill ptrace(RUREGS, pid, reglist[i].roffs, 0);
3181349Sbill OD
3191349Sbill userpc= *(ADDR *)(((ADDR)&u)+PC);
3201349Sbill }
3211349Sbill
3221349Sbill char
readchar()3231349Sbill readchar() {
3241349Sbill lastc = *argsp++;
3251349Sbill if (lastc == '\0') lastc = '\n';
3261349Sbill return(lastc);
3271349Sbill }
3281349Sbill
3291349Sbill char
rdc()3301349Sbill rdc()
3311349Sbill {
3321349Sbill register char c;
3331349Sbill
3341349Sbill c = *argsp++;
3351349Sbill return(c == '\0' ? '\n' : c);
3361349Sbill }
337