|
|
1.1 ! root 1: static char sccsid[] = "@(#)runpcs.c 4.1 10/9/80"; ! 2: # ! 3: /* ! 4: * ! 5: * UNIX debugger ! 6: * process control routines for sdb ! 7: * this is a hack on top of a hack on top of a hack ! 8: * ! 9: */ ! 10: ! 11: #include "head.h" ! 12: #include <a.out.h> ! 13: #include <stab.h> ! 14: struct user u; ! 15: #include <stdio.h> ! 16: #include <sys/pioctl.h> ! 17: #include <sys/proc.h> ! 18: #include "base.h" ! 19: ! 20: #ifndef SIGTRAP ! 21: #define SIGTRAP SIGTRC ! 22: #endif ! 23: ! 24: MSG NOFORK; ! 25: MSG ENDPCS; ! 26: MSG BADWAIT; ! 27: ! 28: ADDR sigint; ! 29: ADDR sigqit; ! 30: ADDR userpc; ! 31: ! 32: /* breakpoints */ ! 33: BKPTR bkpthead; ! 34: ! 35: CHAR lastc; ! 36: ! 37: INT fcor; ! 38: INT fsym; ! 39: STRING errflg; ! 40: int errno; ! 41: INT signo; ! 42: ! 43: L_INT dot; ! 44: STRING symfil; ! 45: INT wtflag; ! 46: INT pid; ! 47: INT adrflg; ! 48: L_INT loopcnt; ! 49: ! 50: ! 51: ! 52: ! 53: ! 54: ! 55: getsig(sig) ! 56: { return(sig); ! 57: } ! 58: ! 59: runpcs(runmode,execsig) ! 60: { ! 61: REG BKPTR bkpt; ! 62: IF adrflg THEN userpc=dot; FI ! 63: WHILE --loopcnt>=0 ! 64: DO ! 65: if (debug) printf("\ncontinue %x %d\n",userpc,execsig); ! 66: IF runmode==SINGLE ! 67: THEN delbp(); /* hardware handles single-stepping */ ! 68: ELSE /* continuing from a breakpoint is hard */ ! 69: IF bkpt=scanbkpt(userpc) ! 70: THEN execbkpt(bkpt,execsig); execsig=0; ! 71: FI ! 72: setbp(); ! 73: FI ! 74: setrun(runmode,userpc,execsig); ! 75: bpwait(); chkerr(); execsig=0; delbp(); readregs(); ! 76: ! 77: loop1: IF (signo==0) ANDF (bkpt=scanbkpt(userpc)) ! 78: THEN /* stopped by BPT instruction */ ! 79: if (debug) printf("\n BPT code; '%s'%o'%o'%d", ! 80: bkpt->comm,bkpt->comm[0],EOR,bkpt->flag); ! 81: dot=bkpt->loc; ! 82: IF bkpt->comm[0] != EOR ! 83: THEN acommand(bkpt->comm); ! 84: FI ! 85: IF bkpt->flag==BKPTEXEC ! 86: ORF ((bkpt->flag=BKPTEXEC) ! 87: ANDF bkpt->comm[0]!=EOR) ! 88: THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++; ! 89: goto loop1; ! 90: ELSE bkpt->flag=BKPTSET; bkpt->count=bkpt->initcnt; ! 91: FI ! 92: ELSE execsig=signo; ! 93: if (execsig) break; ! 94: FI ! 95: OD ! 96: if (debug) printf("Returning from runpcs\n"); ! 97: } ! 98: ! 99: #define BPOUT 0 ! 100: #define BPIN 1 ! 101: INT bpstate; ! 102: ! 103: endpcs() ! 104: { ! 105: REG BKPTR bkptr; ! 106: if (debug) printf("Entering endpcs with pid=%d\n"); ! 107: IF pid ! 108: THEN killpcs(); pid=0; userpc=1; ! 109: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt ! 110: DO IF bkptr->flag ! 111: THEN bkptr->flag=BKPTSET; ! 112: FI ! 113: OD ! 114: FI ! 115: bpstate=BPOUT; ! 116: } ! 117: ! 118: setup() ! 119: { ! 120: int fd; ! 121: long tsigs = ~0; ! 122: ! 123: fd = openproc(getpid()); ! 124: if (ioctl(fd, PIOCSEXEC, 0) < 0) { ! 125: close(fd); ! 126: error("no process ioctl"); ! 127: } ! 128: close(fsym); ! 129: fsym = -1; ! 130: IF (pid = fork()) == 0 ! 131: THEN close(fd); ! 132: signal(SIGINT,sigint); signal(SIGQUIT,sigqit); ! 133: if (debug) printf("About to doexec pid=%d\n",pid); ! 134: doexec(); _exit(0); ! 135: ELIF pid == -1 ! 136: THEN error(NOFORK); ! 137: ELSE ioctl(fd, PIOCREXEC, 0); ! 138: close(fd); ! 139: datmap.ufd = fcor = openproc(pid); ! 140: ioctl(fcor, PIOCSMASK, &tsigs); ! 141: bpwait(); ! 142: readregs(); ! 143: if (debug) printf("About to open symfil = %s\n", symfil); ! 144: fsym=open(symfil,wtflag); ! 145: IF errflg ! 146: THEN printf("%s: cannot execute\n",symfil); ! 147: if (debug) printf("%d %s\n", errflg, errflg); ! 148: endpcs(); ! 149: FI ! 150: FI ! 151: bpstate=BPOUT; ! 152: } ! 153: ! 154: execbkpt(bkptr,execsig) ! 155: BKPTR bkptr; ! 156: { ! 157: if (debug) printf("exbkpt: %d\n",bkptr->count); ! 158: delbp(); ! 159: setrun(SINGLE,bkptr->loc,execsig); ! 160: bkptr->flag=BKPTSET; ! 161: bpwait(); chkerr(); readregs(); ! 162: } ! 163: ! 164: doexec() ! 165: { ! 166: char *argl[MAXARG], args[LINSIZ]; ! 167: register char c, redchar, *argsp, **arglp, *filnam; ! 168: ! 169: arglp = argl; ! 170: argsp = args; ! 171: *arglp++ = symfil; ! 172: c = ' '; ! 173: ! 174: do { ! 175: while (eqany(c, " \t")) { ! 176: c = rdc(); ! 177: } ! 178: if (eqany(c, "<>")) { ! 179: redchar = c; ! 180: do { ! 181: c = rdc(); ! 182: } while (eqany(c, " \t")); ! 183: filnam = argsp; ! 184: do { ! 185: *argsp++ = c; ! 186: c = rdc(); ! 187: } while (!eqany(c, " <>\t\n")); ! 188: *argsp++ = '\0'; ! 189: if (redchar == '<') { ! 190: close(0); ! 191: if (open(filnam,0) < 0) { ! 192: printf("%s: cannot open\n",filnam); ! 193: fflush(stdout); ! 194: _exit(0); ! 195: } ! 196: } else { ! 197: close(1); ! 198: if (creat(filnam,0666) < 0) { ! 199: printf("%s: cannot create\n",filnam); ! 200: fflush(stdout); ! 201: _exit(0); ! 202: } ! 203: } ! 204: } else if (c != '\n') { ! 205: *arglp++ = argsp; ! 206: do { ! 207: *argsp++ = c; ! 208: c = rdc(); ! 209: } while(!eqany(c, " <>\t\n")); ! 210: *argsp++ = '\0'; ! 211: } ! 212: } while (c != '\n'); ! 213: *arglp = (char *) 0; ! 214: if (debug) { ! 215: char **dap; ! 216: printf("About to execv(%s, %d)\n",symfil,argl); ! 217: for (dap = argl; *dap; dap++) { ! 218: printf("%s, ", *dap); ! 219: } ! 220: } ! 221: execv(symfil, argl); ! 222: perror("Returned from exect"); ! 223: } ! 224: ! 225: BKPTR scanbkpt(adr) ! 226: ADDR adr; ! 227: { ! 228: REG BKPTR bkptr; ! 229: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt ! 230: DO IF bkptr->flag ANDF bkptr->loc==adr ! 231: THEN break; ! 232: FI ! 233: OD ! 234: return(bkptr); ! 235: } ! 236: ! 237: delbp() ! 238: { ! 239: REG ADDR a; ! 240: REG BKPTR bkptr; ! 241: IF bpstate!=BPOUT ! 242: THEN ! 243: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt ! 244: DO IF bkptr->flag ! 245: THEN a=bkptr->loc; ! 246: prwrite(a, &bkptr->ins, 1); ! 247: FI ! 248: OD ! 249: bpstate=BPOUT; ! 250: FI ! 251: } ! 252: ! 253: setbp() ! 254: { ! 255: REG ADDR a; ! 256: REG BKPTR bkptr; ! 257: char bpt = BPT; ! 258: ! 259: IF bpstate!=BPIN ! 260: THEN ! 261: FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt ! 262: DO IF bkptr->flag ! 263: THEN a = bkptr->loc; ! 264: prread(a, &bkptr->ins, 1); ! 265: prwrite(a, &bpt, 1); ! 266: IF errflg ! 267: THEN error("cannot set breakpoint: "); ! 268: printf("%s:%d @ %d\n", adrtoprocp(dot)->pname, ! 269: adrtolineno(dot), dot); ! 270: errflg = 0; ! 271: FI ! 272: FI ! 273: OD ! 274: bpstate=BPIN; ! 275: FI ! 276: } ! 277: ! 278: #define WSLEEP 10 ! 279: ! 280: bpwait() ! 281: { ! 282: register int w; ! 283: struct proc p; ! 284: int pc; ! 285: int stat; ! 286: int (*isig)(); ! 287: int nulsig(); ! 288: extern int errno; ! 289: ! 290: isig = signal(SIGINT, SIG_IGN); ! 291: /* ! 292: * alarm stuff is just in case ! 293: */ ! 294: for (;;) { ! 295: signal(SIGALRM, nulsig); ! 296: alarm(WSLEEP); ! 297: if (ioctl(fcor, PIOCWSTOP, 0) >= 0) ! 298: errno = 0; ! 299: alarm(0); ! 300: if (errno == 0) { ! 301: signal(SIGINT, isig); ! 302: ioctl(fcor, PIOCGETPR, &p); ! 303: signo = p.p_cursig; ! 304: prread(UBASE + PC, &pc, sizeof(pc)); ! 305: if (signo == SIGTRAP || signo == SIGSTOP) ! 306: signo = 0; ! 307: else if (pc == extaddr("_dbsubn")) ! 308: signo = 0; ! 309: else ! 310: sigprint(); ! 311: return; ! 312: } ! 313: if (errno == ENOENT) ! 314: break; ! 315: /* still there, still running. try again. */ ! 316: } ! 317: /* ! 318: * process has died; wait and report status ! 319: * should check if it's really our child ! 320: */ ! 321: signal(SIGALRM, nulsig); ! 322: alarm(WSLEEP); ! 323: while ((w = wait(&stat)) != -1 && w != pid) ! 324: ; ! 325: alarm(0); ! 326: pid = 0; ! 327: signal(SIGINT, isig); ! 328: close(fcor); ! 329: pid = 0; ! 330: corfil = NULL; ! 331: errflg = ENDPCS; ! 332: if (w == -1) ! 333: errflg = BADWAIT; ! 334: else { ! 335: if ((stat & 0177) == 0177) ! 336: printf("trace status? 0%o\n", stat); ! 337: else { ! 338: if ((signo = stat & 0177) != 0) ! 339: sigprint(); ! 340: if (stat & 0200) { ! 341: printf(" - core dumped"); ! 342: corfil = "core"; ! 343: setcor(); ! 344: } ! 345: printf("\n"); ! 346: } ! 347: } ! 348: } ! 349: ! 350: nulsig() {} ! 351: ! 352: REGLIST reglist[]; ! 353: readregs() ! 354: { ! 355: /*get REG values from pcs*/ ! 356: REG i; ! 357: FOR i=24; --i>=0; ! 358: DO prread(UBASE + reglist[i].roffs, (char *)&u + reglist[i].roffs, sizeof(int)); ! 359: OD ! 360: userpc = *(ADDR *)((char *)&u + PC); ! 361: } ! 362: ! 363: char ! 364: readchar() { ! 365: lastc = *argsp++; ! 366: if (lastc == '\0') lastc = '\n'; ! 367: return(lastc); ! 368: } ! 369: ! 370: char ! 371: rdc() ! 372: { ! 373: register char c; ! 374: ! 375: c = *argsp++; ! 376: return(c == '\0' ? '\n' : c); ! 377: } ! 378: ! 379: /* ! 380: * miscellaneous /proc hooks ! 381: */ ! 382: ! 383: setrun(mode, pc, sig) ! 384: { ! 385: int ps; ! 386: ! 387: if (pc != 1) ! 388: prwrite(UBASE + PC, &pc, sizeof(pc)); ! 389: if (mode == SINGLE) { ! 390: prread(UBASE + PSL, &ps, sizeof(ps)); ! 391: ps |= TBIT; ! 392: prwrite(UBASE + PSL, &ps, sizeof(ps)); ! 393: } ! 394: if (sig == 0) ! 395: ioctl(fcor, PIOCCSIG, 0); ! 396: ioctl(fcor, PIOCRUN, 0); ! 397: } ! 398: ! 399: killpcs() ! 400: { ! 401: long ksig = SIGKILL; ! 402: ! 403: ioctl(fcor, PIOCCSIG, 0); ! 404: ioctl(fcor, PIOCKILL, &ksig); ! 405: ioctl(fcor, PIOCRUN, 0); ! 406: /* ! 407: * assert that it's our child ! 408: */ ! 409: while (wait((int *)0) >= 0) ! 410: ; ! 411: } ! 412: ! 413: int ! 414: openproc(id) ! 415: int id; ! 416: { ! 417: char buf[20]; ! 418: int fd; ! 419: ! 420: sprintf(buf, "/proc/%d", id); ! 421: if ((fd = open(buf, 2)) < 0) { ! 422: perror("can't open process"); ! 423: longjmp(env, 0); ! 424: } ! 425: return (fd); ! 426: } ! 427: ! 428: prread(addr, buf, size) ! 429: char *buf; ! 430: { ! 431: ! 432: lseek(fcor, (long)addr, 0); ! 433: if (read(fcor, buf, size) != size) ! 434: errflg = "can't read process"; ! 435: } ! 436: ! 437: prwrite(addr, buf, size) ! 438: char *buf; ! 439: { ! 440: ! 441: lseek(fcor, (long)addr, 0); ! 442: if (write(fcor, buf, size) != size) ! 443: errflg = "can't read process"; ! 444: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.