1*1349Sbill static char sccsid[] = "@(#)runpcs.c 4.1 10/09/80"; 2*1349Sbill # 3*1349Sbill /* 4*1349Sbill * 5*1349Sbill * UNIX debugger 6*1349Sbill * 7*1349Sbill */ 8*1349Sbill 9*1349Sbill #include "head.h" 10*1349Sbill #include <a.out.h> 11*1349Sbill #include <stab.h> 12*1349Sbill struct user u; 13*1349Sbill #include <stdio.h> 14*1349Sbill 15*1349Sbill #ifndef SIGTRAP 16*1349Sbill #define SIGTRAP SIGTRC 17*1349Sbill #endif 18*1349Sbill 19*1349Sbill MSG NOFORK; 20*1349Sbill MSG ENDPCS; 21*1349Sbill MSG BADWAIT; 22*1349Sbill 23*1349Sbill ADDR sigint; 24*1349Sbill ADDR sigqit; 25*1349Sbill ADDR userpc; 26*1349Sbill 27*1349Sbill /* breakpoints */ 28*1349Sbill BKPTR bkpthead; 29*1349Sbill 30*1349Sbill CHAR lastc; 31*1349Sbill 32*1349Sbill INT fcor; 33*1349Sbill INT fsym; 34*1349Sbill STRING errflg; 35*1349Sbill int errno; 36*1349Sbill INT signo; 37*1349Sbill 38*1349Sbill L_INT dot; 39*1349Sbill STRING symfil; 40*1349Sbill INT wtflag; 41*1349Sbill INT pid; 42*1349Sbill INT adrflg; 43*1349Sbill L_INT loopcnt; 44*1349Sbill 45*1349Sbill 46*1349Sbill 47*1349Sbill 48*1349Sbill 49*1349Sbill 50*1349Sbill getsig(sig) 51*1349Sbill { return(sig); 52*1349Sbill } 53*1349Sbill 54*1349Sbill runpcs(runmode,execsig) 55*1349Sbill { 56*1349Sbill REG BKPTR bkpt; 57*1349Sbill IF adrflg THEN userpc=dot; FI 58*1349Sbill WHILE --loopcnt>=0 59*1349Sbill DO 60*1349Sbill if (debug) printf("\ncontinue %x %d\n",userpc,execsig); 61*1349Sbill IF runmode==SINGLE 62*1349Sbill THEN delbp(); /* hardware handles single-stepping */ 63*1349Sbill ELSE /* continuing from a breakpoint is hard */ 64*1349Sbill IF bkpt=scanbkpt(userpc) 65*1349Sbill THEN execbkpt(bkpt,execsig); execsig=0; 66*1349Sbill FI 67*1349Sbill setbp(); 68*1349Sbill FI 69*1349Sbill ptrace(runmode,pid,userpc,execsig); 70*1349Sbill bpwait(); chkerr(); execsig=0; delbp(); readregs(); 71*1349Sbill 72*1349Sbill loop1: IF (signo==0) ANDF (bkpt=scanbkpt(userpc)) 73*1349Sbill THEN /* stopped by BPT instruction */ 74*1349Sbill if (debug) printf("\n BPT code; '%s'%o'%o'%d", 75*1349Sbill bkpt->comm,bkpt->comm[0],EOR,bkpt->flag); 76*1349Sbill dot=bkpt->loc; 77*1349Sbill IF bkpt->comm[0] != EOR 78*1349Sbill THEN acommand(bkpt->comm); 79*1349Sbill FI 80*1349Sbill IF bkpt->flag==BKPTEXEC 81*1349Sbill ORF ((bkpt->flag=BKPTEXEC) 82*1349Sbill ANDF bkpt->comm[0]!=EOR) 83*1349Sbill THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++; 84*1349Sbill goto loop1; 85*1349Sbill ELSE bkpt->flag=BKPTSET; bkpt->count=bkpt->initcnt; 86*1349Sbill FI 87*1349Sbill ELSE execsig=signo; 88*1349Sbill if (execsig) break; 89*1349Sbill FI 90*1349Sbill OD 91*1349Sbill if (debug) printf("Returning from runpcs\n"); 92*1349Sbill } 93*1349Sbill 94*1349Sbill #define BPOUT 0 95*1349Sbill #define BPIN 1 96*1349Sbill INT bpstate; 97*1349Sbill 98*1349Sbill endpcs() 99*1349Sbill { 100*1349Sbill REG BKPTR bkptr; 101*1349Sbill if (debug) printf("Entering endpcs with pid=%d\n"); 102*1349Sbill IF pid 103*1349Sbill THEN ptrace(EXIT,pid,0,0); pid=0; userpc=1; 104*1349Sbill FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt 105*1349Sbill DO IF bkptr->flag 106*1349Sbill THEN bkptr->flag=BKPTSET; 107*1349Sbill FI 108*1349Sbill OD 109*1349Sbill FI 110*1349Sbill bpstate=BPOUT; 111*1349Sbill } 112*1349Sbill 113*1349Sbill #ifdef VFORK 114*1349Sbill nullsig() 115*1349Sbill { 116*1349Sbill 117*1349Sbill } 118*1349Sbill #endif 119*1349Sbill 120*1349Sbill setup() 121*1349Sbill { 122*1349Sbill close(fsym); fsym = -1; 123*1349Sbill #ifdef VFORK 124*1349Sbill IF (pid = vfork()) == 0 125*1349Sbill #else 126*1349Sbill IF (pid = fork()) == 0 127*1349Sbill #endif 128*1349Sbill THEN ptrace(SETTRC,0,0,0); 129*1349Sbill signal(SIGINT,sigint); signal(SIGQUIT,sigqit); 130*1349Sbill #ifdef VFORK 131*1349Sbill signal(SIGTRAP,nullsig); 132*1349Sbill #endif 133*1349Sbill if (debug) printf("About to doexec pid=%d\n",pid); 134*1349Sbill doexec(); _exit(0); 135*1349Sbill ELIF pid == -1 136*1349Sbill THEN error(NOFORK); 137*1349Sbill ELSE bpwait(); readregs(); 138*1349Sbill if (debug) printf("About to open symfil = %s\n", symfil); 139*1349Sbill fsym=open(symfil,wtflag); 140*1349Sbill IF errflg 141*1349Sbill THEN printf("%s: cannot execute\n",symfil); 142*1349Sbill if (debug) printf("%d %s\n", errflg, errflg); 143*1349Sbill endpcs(); 144*1349Sbill FI 145*1349Sbill FI 146*1349Sbill bpstate=BPOUT; 147*1349Sbill } 148*1349Sbill 149*1349Sbill execbkpt(bkptr,execsig) 150*1349Sbill BKPTR bkptr; 151*1349Sbill { 152*1349Sbill if (debug) printf("exbkpt: %d\n",bkptr->count); 153*1349Sbill delbp(); 154*1349Sbill ptrace(SINGLE,pid,bkptr->loc,execsig); 155*1349Sbill bkptr->flag=BKPTSET; 156*1349Sbill bpwait(); chkerr(); readregs(); 157*1349Sbill } 158*1349Sbill 159*1349Sbill extern STRING environ; 160*1349Sbill 161*1349Sbill doexec() 162*1349Sbill { 163*1349Sbill char *argl[MAXARG], args[LINSIZ]; 164*1349Sbill register char c, redchar, *argsp, **arglp, *filnam; 165*1349Sbill 166*1349Sbill arglp = argl; 167*1349Sbill argsp = args; 168*1349Sbill *arglp++ = symfil; 169*1349Sbill c = ' '; 170*1349Sbill 171*1349Sbill do { 172*1349Sbill while (eqany(c, " \t")) { 173*1349Sbill c = rdc(); 174*1349Sbill } 175*1349Sbill if (eqany(c, "<>")) { 176*1349Sbill redchar = c; 177*1349Sbill do { 178*1349Sbill c = rdc(); 179*1349Sbill } while (eqany(c, " \t")); 180*1349Sbill filnam = argsp; 181*1349Sbill do { 182*1349Sbill *argsp++ = c; 183*1349Sbill c = rdc(); 184*1349Sbill } while (!eqany(c, " <>\t\n")); 185*1349Sbill *argsp++ = '\0'; 186*1349Sbill if (redchar == '<') { 187*1349Sbill close(0); 188*1349Sbill if (open(filnam,0) < 0) { 189*1349Sbill printf("%s: cannot open\n",filnam); 190*1349Sbill fflush(stdout); 191*1349Sbill _exit(0); 192*1349Sbill } 193*1349Sbill } else { 194*1349Sbill close(1); 195*1349Sbill if (creat(filnam,0666) < 0) { 196*1349Sbill printf("%s: cannot create\n",filnam); 197*1349Sbill fflush(stdout); 198*1349Sbill _exit(0); 199*1349Sbill } 200*1349Sbill } 201*1349Sbill } else if (c != '\n') { 202*1349Sbill *arglp++ = argsp; 203*1349Sbill do { 204*1349Sbill *argsp++ = c; 205*1349Sbill c = rdc(); 206*1349Sbill } while(!eqany(c, " <>\t\n")); 207*1349Sbill *argsp++ = '\0'; 208*1349Sbill } 209*1349Sbill } while (c != '\n'); 210*1349Sbill *arglp = (char *) 0; 211*1349Sbill if (debug) { 212*1349Sbill char **dap; 213*1349Sbill printf("About to exect(%s, %d, %d)\n",symfil,argl,environ); 214*1349Sbill for (dap = argl; *dap; dap++) { 215*1349Sbill printf("%s, ", *dap); 216*1349Sbill } 217*1349Sbill } 218*1349Sbill exect(symfil, argl, environ); 219*1349Sbill perror("Returned from exect"); 220*1349Sbill } 221*1349Sbill 222*1349Sbill BKPTR scanbkpt(adr) 223*1349Sbill ADDR adr; 224*1349Sbill { 225*1349Sbill REG BKPTR bkptr; 226*1349Sbill FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt 227*1349Sbill DO IF bkptr->flag ANDF bkptr->loc==adr 228*1349Sbill THEN break; 229*1349Sbill FI 230*1349Sbill OD 231*1349Sbill return(bkptr); 232*1349Sbill } 233*1349Sbill 234*1349Sbill delbp() 235*1349Sbill { 236*1349Sbill REG ADDR a; 237*1349Sbill REG BKPTR bkptr; 238*1349Sbill IF bpstate!=BPOUT 239*1349Sbill THEN 240*1349Sbill FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt 241*1349Sbill DO IF bkptr->flag 242*1349Sbill THEN a=bkptr->loc; 243*1349Sbill ptrace(WIUSER,pid,a, 244*1349Sbill (bkptr->ins&0xFF)|(ptrace(RIUSER,pid,a,0)&~0xFF)); 245*1349Sbill FI 246*1349Sbill OD 247*1349Sbill bpstate=BPOUT; 248*1349Sbill FI 249*1349Sbill } 250*1349Sbill 251*1349Sbill setbp() 252*1349Sbill { 253*1349Sbill REG ADDR a; 254*1349Sbill REG BKPTR bkptr; 255*1349Sbill 256*1349Sbill IF bpstate!=BPIN 257*1349Sbill THEN 258*1349Sbill FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt 259*1349Sbill DO IF bkptr->flag 260*1349Sbill THEN a = bkptr->loc; 261*1349Sbill bkptr->ins = ptrace(RIUSER, pid, a, 0); 262*1349Sbill ptrace(WIUSER, pid, a, BPT | (bkptr->ins&~0xFF)); 263*1349Sbill IF errno 264*1349Sbill THEN error("cannot set breakpoint: "); 265*1349Sbill printf("%s:%d @ %d\n", adrtoprocp(dot)->pname, 266*1349Sbill adrtolineno(dot), dot); 267*1349Sbill FI 268*1349Sbill FI 269*1349Sbill OD 270*1349Sbill bpstate=BPIN; 271*1349Sbill FI 272*1349Sbill } 273*1349Sbill 274*1349Sbill bpwait() 275*1349Sbill { 276*1349Sbill REG ADDR w; 277*1349Sbill ADDR stat; 278*1349Sbill 279*1349Sbill signal(SIGINT, 1); 280*1349Sbill if (debug) printf("Waiting for pid %d\n",pid); 281*1349Sbill WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE 282*1349Sbill if (debug) printf("Ending wait\n"); 283*1349Sbill if (debug) printf("w = %d; pid = %d; stat = %o;\n", w,pid,stat); 284*1349Sbill signal(SIGINT,sigint); 285*1349Sbill IF w == -1 286*1349Sbill THEN pid=0; 287*1349Sbill errflg=BADWAIT; 288*1349Sbill ELIF (stat & 0177) != 0177 289*1349Sbill THEN IF signo = stat&0177 290*1349Sbill THEN sigprint(); 291*1349Sbill FI 292*1349Sbill IF stat&0200 293*1349Sbill THEN error(" - core dumped"); 294*1349Sbill close(fcor); 295*1349Sbill setcor(); 296*1349Sbill FI 297*1349Sbill pid=0; 298*1349Sbill errflg=ENDPCS; 299*1349Sbill ELSE signo = stat>>8; 300*1349Sbill if (debug) printf("PC = %d, dbsubn = %d\n", 301*1349Sbill ptrace(RUREGS, pid, PC, 0), extaddr("_dbsubn")); 302*1349Sbill IF signo!=SIGTRAP ANDF 303*1349Sbill ptrace(RUREGS, pid, PC, 0) != extaddr("_dbsubn") 304*1349Sbill THEN sigprint(); 305*1349Sbill ELSE signo=0; 306*1349Sbill FI 307*1349Sbill FI 308*1349Sbill } 309*1349Sbill 310*1349Sbill REGLIST reglist[]; 311*1349Sbill readregs() 312*1349Sbill { 313*1349Sbill /*get REG values from pcs*/ 314*1349Sbill REG i; 315*1349Sbill FOR i=24; --i>=0; 316*1349Sbill DO *(ADDR *)(((ADDR)&u)+reglist[i].roffs) = 317*1349Sbill ptrace(RUREGS, pid, reglist[i].roffs, 0); 318*1349Sbill OD 319*1349Sbill userpc= *(ADDR *)(((ADDR)&u)+PC); 320*1349Sbill } 321*1349Sbill 322*1349Sbill char 323*1349Sbill readchar() { 324*1349Sbill lastc = *argsp++; 325*1349Sbill if (lastc == '\0') lastc = '\n'; 326*1349Sbill return(lastc); 327*1349Sbill } 328*1349Sbill 329*1349Sbill char 330*1349Sbill rdc() 331*1349Sbill { 332*1349Sbill register char c; 333*1349Sbill 334*1349Sbill c = *argsp++; 335*1349Sbill return(c == '\0' ? '\n' : c); 336*1349Sbill } 337