|
|
1.1 ! root 1: /* ! 2: * ! 3: * UNIX debugger ! 4: * ! 5: */ ! 6: ! 7: #include "defs.h" ! 8: ! 9: extern MAP txtmap; ! 10: ! 11: MSG NOFORK; ! 12: MSG ENDPCS; ! 13: MSG BADWAIT; ! 14: ! 15: CHAR *lp; ! 16: SIG sigint; ! 17: SIG sigqit; ! 18: ! 19: /* breakpoints */ ! 20: BKPTR bkpthead; ! 21: ! 22: REGLIST reglist[]; ! 23: ! 24: CHAR lastc; ! 25: ! 26: INT fcor; ! 27: INT fsym; ! 28: STRING errflg; ! 29: INT errno; ! 30: INT signo; ! 31: INT sigcode; ! 32: ! 33: L_INT dot; ! 34: STRING symfil; ! 35: INT wtflag; ! 36: L_INT pid; ! 37: L_INT expv; ! 38: INT adrflg; ! 39: L_INT loopcnt; ! 40: ! 41: ! 42: ! 43: ! 44: ! 45: /* service routines for sub process control */ ! 46: ! 47: getsig(sig) ! 48: { return(expr(0) ? expv : sig); ! 49: } ! 50: ! 51: ADDR userpc = 1; ! 52: ! 53: runpcs(runmode,execsig) ! 54: { ! 55: REG rc; ! 56: REG BKPTR bkpt; ! 57: IF adrflg THEN userpc=dot; FI ! 58: printf("%s: running\n", symfil); ! 59: ! 60: WHILE --loopcnt>=0 ! 61: DO ! 62: #ifdef DEBUG ! 63: printf("\ncontinue %X %D loopcnt=%D\n",userpc,execsig, loopcnt); ! 64: #endif ! 65: IF runmode==SINGLE ! 66: THEN delbp(); /* hardware handles single-stepping */ ! 67: ELSE /* continuing from a breakpoint is hard */ ! 68: IF bkpt=scanbkpt(userpc) ! 69: THEN execbkpt(bkpt,execsig); execsig=0; ! 70: FI ! 71: setbp(); ! 72: FI ! 73: ptrace(runmode,pid,userpc,execsig); ! 74: bpwait(); chkerr(); execsig=0; delbp(); readregs(); ! 75: ! 76: IF (signo==0) ANDF (bkpt=scanbkpt(userpc)) ! 77: THEN /* stopped by BPT instruction */ ! 78: #ifdef DEBUG ! 79: printf("\n BPT code; '%s'%o'%d", ! 80: bkpt->comm,bkpt->comm[0],EOR,bkpt->flag); ! 81: #endif ! 82: dot=bkpt->loc; ! 83: IF bkpt->flag==BKPTEXEC ! 84: ORF ((bkpt->flag=BKPTEXEC) ! 85: ANDF bkpt->comm[0]!=EOR ! 86: ANDF command(bkpt->comm,':') ! 87: ANDF --bkpt->count) ! 88: THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++; ! 89: ELSE bkpt->count=bkpt->initcnt; rc=1; ! 90: FI ! 91: ELSE execsig=signo; rc=0; ! 92: FI ! 93: OD ! 94: return(rc); ! 95: } ! 96: ! 97: #define BPOUT 0 ! 98: #define BPIN 1 ! 99: INT bpstate = BPOUT; ! 100: ! 101: endpcs() ! 102: { ! 103: REG BKPTR bkptr; ! 104: IF pid ! 105: THEN ptrace(EXIT,pid,0,0); pid=0; userpc=1; ! 106: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt ! 107: DO IF bkptr->flag ! 108: THEN bkptr->flag=BKPTSET; ! 109: FI ! 110: OD ! 111: FI ! 112: bpstate=BPOUT; ! 113: } ! 114: ! 115: #ifdef VFORK ! 116: nullsig() ! 117: { ! 118: ! 119: } ! 120: #endif ! 121: ! 122: setup() ! 123: { ! 124: close(fsym); fsym = -1; ! 125: #ifndef VFORK ! 126: IF (pid = fork()) == 0 ! 127: #else ! 128: IF (pid = vfork()) == 0 ! 129: #endif ! 130: THEN ptrace(SETTRC,0,0,0); ! 131: #ifdef VFORK ! 132: signal(SIGTRAP,nullsig); ! 133: #endif ! 134: signal(SIGINT,sigint); signal(SIGQUIT,sigqit); ! 135: doexec(); exit(0); ! 136: ELIF pid == -1 ! 137: THEN error(NOFORK); ! 138: ELSE bpwait(); readregs(); lp[0]=EOR; lp[1]=0; ! 139: fsym=open(symfil,wtflag); ! 140: IF errflg ! 141: THEN printf("%s: cannot execute\n",symfil); ! 142: endpcs(); error(0); ! 143: FI ! 144: FI ! 145: bpstate=BPOUT; ! 146: } ! 147: ! 148: execbkpt(bkptr,execsig) ! 149: BKPTR bkptr; ! 150: { ! 151: #ifdef DEBUG ! 152: printf("exbkpt: %d\n",bkptr->count); ! 153: #endif ! 154: delbp(); ! 155: ptrace(SINGLE,pid,bkptr->loc,execsig); ! 156: bkptr->flag=BKPTSET; ! 157: bpwait(); chkerr(); readregs(); ! 158: } ! 159: ! 160: ! 161: doexec() ! 162: { ! 163: STRING argl[MAXARG]; ! 164: CHAR args[LINSIZ]; ! 165: REG STRING p, *ap, filnam; ! 166: extern STRING environ; ! 167: ! 168: ap=argl; p=args; ! 169: *ap++=symfil; ! 170: REP IF rdc()==EOR THEN break; FI ! 171: *ap = p; ! 172: WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB DO *p++=lastc; readchar(); OD ! 173: *p++=0; filnam = *ap+1; ! 174: IF **ap=='<' ! 175: THEN close(0); ! 176: IF open(filnam,0)<0 ! 177: THEN printf("%s: cannot open\n",filnam); _exit(0); ! 178: FI ! 179: ELIF **ap=='>' ! 180: THEN close(1); ! 181: IF creat(filnam,0666)<0 ! 182: THEN printf("%s: cannot create\n",filnam); _exit(0); ! 183: FI ! 184: ELSE ap++; ! 185: FI ! 186: PER lastc!=EOR DONE ! 187: *ap++=0; ! 188: execve(symfil, argl, environ); ! 189: perror(symfil); ! 190: } ! 191: ! 192: BKPTR scanbkpt(adr) ! 193: ADDR adr; ! 194: { ! 195: REG BKPTR bkptr; ! 196: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt ! 197: DO IF bkptr->flag ANDF bkptr->loc==adr ! 198: THEN break; ! 199: FI ! 200: OD ! 201: return(bkptr); ! 202: } ! 203: ! 204: delbp() ! 205: { ! 206: REG ADDR a; ! 207: REG BKPTR bkptr; ! 208: IF bpstate!=BPOUT ! 209: THEN ! 210: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt ! 211: DO IF bkptr->flag ! 212: THEN a=bkptr->loc; ! 213: IF a < txtmap.e1 THEN ! 214: ptrace(WIUSER,pid,a, ! 215: (bkptr->ins&0xFF000000)|(ptrace(RIUSER,pid,a,0)&0xFFFFFF)); ! 216: ELSE ! 217: ptrace(WDUSER,pid,a, ! 218: (bkptr->ins&0xFF000000)|(ptrace(RDUSER,pid,a,0)&0xFFFFFF)); ! 219: FI ! 220: FI ! 221: OD ! 222: bpstate=BPOUT; ! 223: FI ! 224: } ! 225: ! 226: setbp() ! 227: { ! 228: REG ADDR a; ! 229: REG BKPTR bkptr; ! 230: ! 231: IF bpstate!=BPIN ! 232: THEN ! 233: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt ! 234: DO IF bkptr->flag ! 235: THEN a = bkptr->loc; ! 236: IF a < txtmap.e1 THEN ! 237: bkptr->ins = ptrace(RIUSER, pid, a, 0); ! 238: ptrace(WIUSER, pid, a, BPT<<24 | (bkptr->ins&0xFFFFFF)); ! 239: ELSE ! 240: bkptr->ins = ptrace(RDUSER, pid, a, 0); ! 241: ptrace(WDUSER, pid, a, BPT<<24 | (bkptr->ins&0xFFFFFF)); ! 242: FI ! 243: IF errno ! 244: THEN printf("cannot set breakpoint: "); ! 245: psymoff(bkptr->loc,ISYM,"\n"); ! 246: FI ! 247: FI ! 248: OD ! 249: bpstate=BPIN; ! 250: FI ! 251: } ! 252: ! 253: bpwait() ! 254: { ! 255: REG w; ! 256: ADDR stat; ! 257: ! 258: signal(SIGINT, 1); ! 259: WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE ! 260: signal(SIGINT,sigint); ! 261: IF w == -1 ! 262: THEN pid=0; ! 263: errflg=BADWAIT; ! 264: ELIF (stat & 0177) != 0177 ! 265: THEN sigcode = 0; ! 266: IF signo = stat&0177 ! 267: THEN sigprint(); ! 268: FI ! 269: IF stat&0200 ! 270: THEN printf(" - core dumped"); ! 271: close(fcor); ! 272: setcor(); ! 273: FI ! 274: pid=0; ! 275: errflg=ENDPCS; ! 276: ELSE signo = stat>>8; ! 277: sigcode = ptrace(RUREGS, pid, &((struct user *)0)->u_code, 0); ! 278: IF signo!=SIGTRAP ! 279: THEN sigprint(); ! 280: ELSE signo=0; ! 281: FI ! 282: flushbuf(); ! 283: FI ! 284: } ! 285: ! 286: readregs() ! 287: { ! 288: /*get REG values from pcs*/ ! 289: REG REGPTR p; ! 290: ! 291: FOR p=reglist; p->rname; p++ ! 292: DO uw[p->roffs] = ! 293: ptrace(RUREGS, pid, p->roffs*NBPW, 0); ! 294: OD ! 295: userpc= uw[PC]; ! 296: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.