|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)command.c 5.4 (Berkeley) 9/26/89"; ! 3: #endif ! 4: ! 5: /* ! 6: * adb - commands ! 7: */ ! 8: ! 9: #include "defs.h" ! 10: #include <ctype.h> ! 11: #include <sys/wait.h> ! 12: #include <paths.h> ! 13: ! 14: extern char BADEQ[]; /* "unexpected `='" */ ! 15: extern char NOMATCH[]; /* "cannot locate value" */ ! 16: extern char BADVAR[]; /* "bad variable" */ ! 17: extern char BADCOM[]; /* "bad command" */ ! 18: extern char NOFORK[]; /* "try again" */ ! 19: ! 20: /* ! 21: * executing is used in main() to see if it is necessary to ! 22: * delete any breakpoints that might have been set; if an ! 23: * error occurs while a subprocess command is running, executing ! 24: * will be set. ! 25: */ ! 26: int executing; ! 27: ! 28: /* lastcom remembers the previous command */ ! 29: static struct { ! 30: int c; /* the command */ ! 31: int star; /* true iff it was in alternate space */ ! 32: } lastcom; ! 33: ! 34: /* ! 35: * Execute the given command buffer. ! 36: * If defcom is nonzero, it is used as the default command. ! 37: */ ! 38: command(buf, defcom) ! 39: char *buf; ! 40: int defcom; ! 41: { ! 42: ! 43: lp = buf; ! 44: do { ! 45: cmds(defcom); ! 46: flushbuf(); ! 47: } while (rdc() == ';'); ! 48: unreadc(); ! 49: } ! 50: ! 51: static ! 52: cmds(defcom) ! 53: int defcom; ! 54: { ! 55: int c; ! 56: struct reglist *reg; ! 57: ! 58: /* ! 59: * Pick up the optional first expression (`dot'), ! 60: * then, if the next character is a comma, pick up ! 61: * the second optional expression (`ecount'). ! 62: */ ! 63: if (gavedot = oexpr()) ! 64: ditto = dot = edot = expv; ! 65: else ! 66: edot = dot; /* probably equal, but possibly truncating */ ! 67: if (rdc() == ',') { ! 68: if (!oexpr()) ! 69: error("count expected"); ! 70: gavecount = 1; ! 71: ecount = expv; ! 72: } else { ! 73: gavecount = 0; ! 74: ecount = 1; ! 75: unreadc(); ! 76: } ! 77: ! 78: /* ! 79: * Pick up the command. If there is no command, do the ! 80: * previous (or default) command, and if no dot was given, ! 81: * use the `next' dot. ! 82: */ ! 83: c = rdc(); ! 84: if (eol(c)) { ! 85: if (defcom != 0) { ! 86: lastcom.c = defcom; ! 87: lastcom.star = 0; ! 88: } ! 89: if (!gavedot) ! 90: dot = inkdot(dotinc); ! 91: unreadc(); ! 92: } else { ! 93: lastcom.c = c; ! 94: lastcom.star = 0; ! 95: } ! 96: ! 97: switch (lastcom.c) { ! 98: ! 99: case '=': ! 100: fmtcom(SP_NONE, 1); ! 101: break; ! 102: ! 103: case '/': ! 104: fmtcom(SP_DATA, 0); ! 105: break; ! 106: ! 107: case '?': ! 108: fmtcom(SP_INSTR, 0); ! 109: break; ! 110: ! 111: case '>': ! 112: lastcom.c = 0; ! 113: if ((reg = reglookup()) != NULL) { ! 114: if (setreg(reg, edot)) ! 115: prints("register write failed"); ! 116: break; ! 117: } ! 118: if ((c = varlookup(rdc())) != -1) ! 119: var[c] = edot; ! 120: else ! 121: error(BADVAR); ! 122: break; ! 123: ! 124: case '!': ! 125: lastcom.c = 0; ! 126: shell(); ! 127: break; ! 128: ! 129: case '$': ! 130: lastcom.c = 0; ! 131: printtrace(nextchar()); ! 132: break; ! 133: ! 134: case ':': ! 135: if (!executing) { ! 136: executing = 1; ! 137: subpcs(nextchar()); ! 138: executing = 0; ! 139: lastcom.c = 0; ! 140: } ! 141: break; ! 142: ! 143: case 0: ! 144: prints("adb\n"); ! 145: break; ! 146: ! 147: default: ! 148: error(BADCOM); ! 149: /* NOTREACHED */ ! 150: } ! 151: } ! 152: ! 153: /* ! 154: * Perform a format-based command (one in ? / or =). ! 155: */ ! 156: static ! 157: fmtcom(space, eqcom) ! 158: int space, eqcom; ! 159: { ! 160: /* special commands m, lL, wW do not operate in SP_NONE (`=') */ ! 161: void mcom(), lcom(), wcom(); ! 162: static struct fcmd { ! 163: int c; ! 164: void (*fn)(); ! 165: } fcmd[] = { ! 166: { 'm', mcom }, ! 167: { 'l', lcom }, { 'L', lcom }, ! 168: { 'w', wcom }, { 'W', wcom }, ! 169: 0 ! 170: }; ! 171: register struct fcmd *f; ! 172: register int c; ! 173: int ptype = space; ! 174: static char stformat[LINELEN] = "X\"= \"^i"; ! 175: static char eqformat[LINELEN] = "z"; ! 176: ! 177: /* ! 178: * Are we operating in the alternate `star' space? ! 179: */ ! 180: if (!eqcom) { ! 181: if (rdc() == '*') ! 182: lastcom.star = 1; ! 183: else ! 184: unreadc(); ! 185: if (lastcom.star) { ! 186: space |= SP_STAR; ! 187: /* print as data for instr, and vice versa */ ! 188: ptype = (SP_DATA + SP_INSTR) - ptype; ! 189: } ! 190: } ! 191: ! 192: /* ! 193: * Check for the special commands first. ! 194: */ ! 195: c = rdc(); ! 196: for (f = fcmd; f->c; f++) { ! 197: if (c == f->c) { ! 198: if (eqcom) ! 199: error(BADEQ); ! 200: (*f->fn)(space, ptype, isupper(c)); ! 201: return; ! 202: } ! 203: } ! 204: unreadc(); ! 205: getformat(eqcom ? eqformat : stformat, LINELEN); ! 206: scanform(!eqcom, eqcom ? eqformat : stformat, space, ptype); ! 207: } ! 208: ! 209: /* ! 210: * Set a map (?m, /m commands). ! 211: */ ! 212: /* ARGSUSED */ ! 213: static void ! 214: mcom(space, ptype, fullword) ! 215: int space, ptype, fullword; ! 216: { ! 217: register struct map *smap; ! 218: register struct m1 *mm; ! 219: char c; ! 220: ! 221: smap = space & SP_DATA ? &datmap : &txtmap; ! 222: mm = space & SP_STAR ? &smap->m2 : &smap->m1; ! 223: if (oexpr()) { ! 224: mm->b = expv; ! 225: if (oexpr()) { ! 226: mm->e = expv; ! 227: if (oexpr()) ! 228: mm->f = expv; ! 229: } ! 230: } ! 231: if ((c = rdc()) == '?') ! 232: smap->ufd = symfile.fd; ! 233: else if (c == '/') ! 234: smap->ufd = corefile.fd; ! 235: else ! 236: unreadc(); ! 237: } ! 238: ! 239: /* ! 240: * Locate a value (l, L commands). ! 241: */ ! 242: static void ! 243: lcom(space, ptype, fullword) ! 244: int space, ptype, fullword; ! 245: { ! 246: register expr_t val, mask; ! 247: addr_t savdot; ! 248: ! 249: /* search for exp */ ! 250: savdot = dot; ! 251: val = rexpr(); ! 252: if (oexpr()) ! 253: mask = expv; ! 254: else ! 255: mask = ~0L; ! 256: if (fullword) { ! 257: expr_t w; ! 258: ! 259: dotinc = sizeof(w); ! 260: for (;;) { ! 261: (void) adbread(space, dot, &w, sizeof(w)); ! 262: if (iserr() || (w & mask) == val) ! 263: break; ! 264: dot = inkdot(sizeof(w)); ! 265: } ! 266: } else { ! 267: hword_t hw; ! 268: ! 269: dotinc = sizeof(hw); ! 270: mask = (hword_t)mask; ! 271: val = (hword_t)val; ! 272: for (;;) { ! 273: (void) adbread(space, dot, &hw, sizeof(hw)); ! 274: if (iserr() || (hw & mask) == val) ! 275: break; ! 276: dot = inkdot(sizeof(hw)); ! 277: } ! 278: } ! 279: if (iserr()) { ! 280: dot = savdot; ! 281: errflag = NOMATCH; ! 282: } ! 283: psymoff("%R", dot, ptype, maxoff, ""); ! 284: } ! 285: ! 286: /* ! 287: * Write new values (w, W). ! 288: */ ! 289: static void ! 290: wcom(space, ptype, fullword) ! 291: int space, ptype, fullword; ! 292: { ! 293: addr_t savdot; ! 294: hword_t hw; ! 295: ! 296: (void) rexpr(); ! 297: do { ! 298: savdot = dot; ! 299: pdot(); ! 300: showdot(fullword, space, ptype); /* also advances */ ! 301: errflag = NULL; ! 302: dot = savdot; ! 303: if (fullword) ! 304: (void) adbwrite(space, dot, &expv, sizeof(expv)); ! 305: else { ! 306: hw = expv; ! 307: (void) adbwrite(space, dot, &hw, sizeof(hw)); ! 308: } ! 309: savdot = dot; ! 310: adbprintf("=%8t"); ! 311: showdot(fullword, space, ptype); ! 312: printc('\n'); ! 313: } while (oexpr() && !iserr()); ! 314: dot = savdot; ! 315: checkerr(); ! 316: } ! 317: ! 318: /* ! 319: * Do a shell escape. ! 320: * ! 321: * THE vfork CODE BELOW IS CURRENTLY BROKEN ! 322: * MUST CHANGE signal TO sigvec BELOW ! 323: */ ! 324: static ! 325: shell() ! 326: { ! 327: int rc, unixpid; ! 328: union wait status; ! 329: char *argp = lp; ! 330: char *getenv(), *eshell = getenv("SHELL"); ! 331: ! 332: if (eshell == 0) ! 333: eshell = _PATH_BSHELL; ! 334: while (readchar() != '\n') ! 335: /* void */; ! 336: #ifndef VFORK ! 337: #define vfork fork ! 338: #endif ! 339: if ((unixpid = vfork()) == 0) { ! 340: *lp = 0; ! 341: (void) signal(SIGINT, sigint); ! 342: (void) signal(SIGQUIT, sigquit); ! 343: execl(eshell, "sh", "-c", argp, (char *)NULL); ! 344: _exit(16); ! 345: /* NOTREACHED */ ! 346: } ! 347: #ifdef VFORK ! 348: *lp = '\n'; ! 349: #endif ! 350: if (unixpid == -1) ! 351: error(NOFORK); ! 352: (void) signal(SIGINT, SIG_IGN); ! 353: while ((rc = wait(&status)) != unixpid && rc != -1) ! 354: /* void */; ! 355: (void) signal(SIGINT, intcatch); ! 356: prints("!"); ! 357: unreadc(); ! 358: } ! 359: ! 360: /* ! 361: * Read a format into the given buffer. If nothing is ! 362: * read, leave the buffer alone. ! 363: */ ! 364: static ! 365: getformat(buf, n) ! 366: char *buf; ! 367: register int n; ! 368: { ! 369: register char *p = buf; ! 370: register int c, quote = 0; ! 371: ! 372: while ((c = readchar()), quote ? c != '\n' : !eol(c)) { ! 373: if (c == '"') ! 374: quote = !quote; ! 375: if (--n > 0) ! 376: *p++ = c; ! 377: } ! 378: unreadc(); ! 379: if (p != buf) /* nonempty */ ! 380: *p++ = 0; ! 381: } ! 382: ! 383: /* ! 384: * Convert a (one-character) variable name to an index, or -1 for ! 385: * error. ! 386: */ ! 387: varlookup(name) ! 388: register int name; ! 389: { ! 390: ! 391: if (isdigit(name)) ! 392: return (name - '0'); ! 393: if (isalpha(name)) ! 394: return (isupper(name) ? name - 'A' + 10 : name - 'a' + 10); ! 395: return (-1); ! 396: } ! 397: ! 398: /* ! 399: * If the text at the current input point matches a register name, ! 400: * consume that text and return a pointer to the register; otherwise ! 401: * leave it unconsumed and return NULL. ! 402: */ ! 403: struct reglist * ! 404: reglookup() ! 405: { ! 406: register struct reglist *p; ! 407: register char *a, *b, c0, c1; ! 408: char *oldlp = lp; ! 409: extern struct reglist reglist[]; ! 410: ! 411: c0 = rdc(); ! 412: c1 = readchar(); ! 413: for (p = reglist; (a = p->r_name) != NULL; p++) { ! 414: if (*a++ != c0 || *a++ != c1) ! 415: continue; ! 416: b = lp; ! 417: do { ! 418: if (*a == 0) { /* name matched: stop short */ ! 419: lp = b; ! 420: return (p); ! 421: } ! 422: } while (*a++ == *b++); ! 423: } ! 424: lp = oldlp; ! 425: return (NULL); ! 426: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.