1: static char sccsid[] = "@(#)prvar.c 4.3 8/17/82"; 2: #include "head.h" 3: #include <a.out.h> 4: #include <stab.h> 5: #include "cdefs.h" 6: struct user u; 7: BKPTR bkpthead; 8: STRING errflg; 9: 10: /* 11: * outvar(): 12: * Prints named variable, recursing once for each structure member or 13: * subscript. 14: * proc:var: variable name 15: * fmt: print format 16: * metaflag: set iff var contains metacharacters * or ? 17: * addr: partial address of variable, initally 0 18: * class: type class of variable 19: * subflag: number of levels of subscript indirection 20: * prnamep: pointer to end of partially formed print name of variable 21: * comblk: name of common block containing variable, if any 22: * prvar: as in findvar 23: * 24: * Here and elsewhere we assume that -1 is an invalid address, and 25: * its is used to indicate error. 26: */ 27: outvar(proc, var, fmt, metaflag, addr, class, subflag, prnamep, 28: comblk, prvar) 29: ADDR addr; char *proc, *var, *fmt, *prnamep, *comblk; u_char class; { 30: char *p, *q, *r, *oldpr; 31: register int match; 32: long soffset, goffset; 33: register ADDR newaddr = -1, arrowaddr; 34: register enum {INIT, ARROW, DOT} typeflag; 35: 36: switch (var[0]) { 37: case '\0': 38: if (prvar == 0) return(addr); 39: if (metaflag) { 40: if (comblk[0] && !(eqstr(comblk, "*"))) 41: #ifndef FLEXNAMES 42: printf("%.8s:%.8s", comblk, prname); 43: #else 44: printf("%s:%s", comblk, prname); 45: #endif 46: else if (proc[0]) 47: #ifndef FLEXNAMES 48: printf("%.8s:%.8s", proc, prname); 49: #else 50: printf("%s:%s", proc, prname); 51: #endif 52: else 53: printf("%s", prname); 54: } 55: printit(metaflag, prvar, addr, fmt, class, sl_type, 56: sl_size, subflag, DSP); 57: return(addr); 58: 59: case '[': 60: *prnamep++ = *var++; 61: p = var; 62: for (;;) { 63: *prnamep++ = *var; 64: if (*var == '\0' || *var == ']') break; 65: var++; 66: } 67: newaddr = getindir(class, addr, sl_type); 68: newaddr += typetosize(sl_type, sl_size) * readint(&p); 69: return(outvar(proc, var+1, fmt, metaflag, newaddr, N_GSYM, 70: subflag+1, prnamep, comblk, prvar)); 71: 72: case '-': 73: case '>': 74: typeflag = ARROW; 75: while (eqany(*var, "->")) 76: *prnamep++ = *var++; 77: subflag++; 78: arrowaddr = getindir(class, addr, sl_type); 79: if (errflg) { 80: printf("%s\n", errflg); 81: errflg = 0; 82: return(0); 83: } 84: class = N_GSYM; 85: if (var[0] == '\0') { 86: p = var; 87: newaddr = arrowaddr; 88: goto recurse; 89: } 90: break; 91: 92: case '.': 93: typeflag = DOT; 94: if (class == N_RSYM) { 95: error("Not with a register variable"); 96: return(0); 97: } 98: *prnamep++ = *var++; 99: subflag = 0; 100: break; 101: 102: default: 103: typeflag = INIT; 104: break; 105: } 106: 107: if (typeflag == INIT) { 108: soffset = proc[0] ? adrtostoffset(callpc-1) : -1; 109: goffset = proc[0] ? -1 : findfile(curfile)->stf_offset; 110: } else { 111: soffset = proc[0] ? adrtostoffset(callpc-1) : -1; 112: goffset = findfile(curfile)->stf_offset; 113: } 114: 115: p = var; 116: oldpr = prnamep; 117: while (!eqany(*p, "->.[") && *p != '\0') 118: *prnamep++ = *p++; 119: *prnamep = '\0'; 120: 121: match = 0; 122: slookinit(); 123: 124: for (;;) { 125: if (soffset != -1) 126: if ((soffset = slooknext(var, soffset, typeflag!=INIT, 127: comblk)) != -1) 128: goto found; 129: if (goffset != -1) 130: if ((goffset = globallookup(var, goffset, 131: typeflag!=INIT)) != -1) 132: goto found; 133: return(newaddr); 134: 135: found: 136: r = sl_name; 137: q = oldpr; 138: while (*r) *q++ = *r++; 139: *q ='\0'; 140: 141: switch(typeflag) { 142: case INIT: 143: class = sl_class & STABMASK; 144: if (!varclass(class) || class == N_SSYM) 145: goto l; 146: newaddr = (class == N_LSYM) ? -sl_addr : sl_addr; 147: newaddr = formaddr(class, newaddr); 148: break; 149: 150: case ARROW: 151: class = sl_class & STABMASK; 152: if (!varclass(class) || class != N_SSYM) 153: goto l; 154: newaddr = arrowaddr + sl_addr; 155: break; 156: 157: case DOT: 158: class = sl_class & STABMASK; 159: if (!varclass(class) || class != N_SSYM) 160: goto l; 161: newaddr = addr + sl_addr; 162: break; 163: } 164: 165: recurse: 166: newaddr = outvar(proc, p, fmt, metaflag, newaddr, 167: class, subflag, prnamep, comblk, prvar); 168: 169: if (!metaflag) 170: return(newaddr); 171: l:; } 172: } 173: 174: /* Output external variables. Arguments as in outvar() */ 175: extoutvar(var, fmt, metaflag, prvar) 176: char *var, *fmt; { 177: long offset; 178: ADDR addr = -1; 179: 180: offset = extstart; 181: sl_addr = -1; 182: 183: for (;;) { 184: offset = extlookup(var, offset); 185: addr = sl_addr; 186: if (offset == -1) 187: return(addr); 188: if (metaflag) 189: #ifndef FLEXNAMES 190: printf("%.7s", sl_name); 191: #else 192: printf("%s", sl_name); 193: #endif 194: printit(metaflag, prvar, addr, fmt[0] ? fmt : "d", 195: N_GSYM, 0, 0, 0, DSP); 196: if (!metaflag) 197: return(addr); 198: } 199: } 200: 201: prdebug() { 202: register struct proct *procp; 203: register struct filet *filep; 204: 205: printf("dot=%d\n", dot); 206: printf("extstart = %d\n", extstart); 207: printf("firstdata = %d\n", firstdata); 208: for(filep=files;filep->sfilename[0];filep++) 209: printf("%s offs %d @ %d flag %d addr 0x%x\n", filep->sfilename, filep->stf_offset, filep, filep->lineflag, filep->faddr); 210: for(procp=procs;procp->pname[0];procp++) { 211: #ifndef FLEXNAMES 212: printf("%s addr 0x%x; offs %d; sfptr %d; line %d", 213: #else 214: printf("%8.8s addr 0x%x; offs %d; sfptr %d; line %d", 215: #endif 216: procp->pname, procp->paddr, procp->st_offset, 217: procp->sfptr, procp->lineno); 218: if (procp->entrypt) printf(" entrypoint"); 219: printf("\n"); 220: } 221: } 222: 223: /* 224: * display addr in data space using format desc or class s 225: * type == 1 => use addr for value to print 226: */ 227: dispf(addr, desc, class, type, size, subflag, space) 228: u_char class; 229: char *desc; short type; ADDR addr; { 230: dispx(addr, desc, class, type, size, subflag, DSP); 231: printf("\n"); 232: } 233: 234: /* display addr in instruction space using format desc or class s */ 235: /* returns -1 if bad address */ 236: dispi(addr, desc, class, type, size, subflag, space) 237: u_char class; 238: char *desc; short type; ADDR addr; { 239: register i; 240: i = dispx(addr, desc, class, type, size, subflag, ISP); 241: printf("\n"); 242: return(i); 243: } 244: 245: char pd[3]; 246: dispx(addr, desc, class, type, size, subflag, space) 247: u_char class; 248: char *desc; short type; ADDR addr; { 249: int i, sflag; 250: char *p; 251: char dlen, dfmt; 252: long value; 253: union { 254: char c[WORDSIZE]; 255: int w; 256: float f; 257: } word; 258: union { 259: struct{ 260: int w1, w2; 261: } ww; 262: double d; 263: } dbl; 264: 265: class &= STABMASK; 266: if (desc[0] == '\0') desc = typetodesc(type, subflag); 267: cpstr(odesc, desc); 268: otype = type; 269: oclass = class; 270: oaddr = addr; 271: oincr = 0; 272: if (debug) printf("dispx(addr=%d,desc=%s,class=%d,type=%d,size=%d,subflg=%d,space=%d)\n", 273: addr, desc, class, type, size, subflag, space); 274: pd[0] = '%'; 275: pd[1] = dfmt = 'd'; 276: dlen = '\0'; 277: for (p = desc; *p; p++) { 278: if (*p>= '0' && *p<'9') { 279: size = readint(&p); 280: p--; 281: } else switch (*p) { 282: case 'l': 283: case 'h': 284: case 'b': 285: dlen = *p; 286: break; 287: 288: case 'a': 289: case 'c': 290: case 'd': 291: case 'f': 292: case 'g': 293: case 'i': 294: case 'I': 295: case 'o': 296: case 'p': 297: case 's': 298: case 'u': 299: case 'x': 300: pd[1] = dfmt = *p; 301: break; 302: 303: default: 304: printf("Illegal descriptor: %c\n", *p); 305: return(1); 306: } 307: } 308: 309: if (type == -1) 310: value = addr; 311: else if (class == N_RSYM && addr < 16) { 312: /* MACHINE DEPENDENT */ 313: if ((addr > 0 && addr < 6) || addr > 11) { 314: printf("Bad register var %d\n", addr); 315: return(-1); 316: } 317: value = *(ADDR *)(((ADDR) &u) + R0 + (WORDSIZE)*addr); 318: } 319: else { 320: value = getval(addr, dfmt == 'g' ? 'd' : dfmt, space); 321: } 322: 323: if (errflg) { 324: printf("%s", errflg); 325: errflg = 0; 326: return(-1); 327: } 328: 329: switch (dfmt) { 330: default: 331: switch (dfmt) { 332: case 'u': 333: case 'x': 334: case 'o': 335: switch (dlen) { 336: case 'h': 337: value = (unsigned short) value; 338: oincr = 2; 339: break; 340: case 'b': 341: value = (unsigned char) value; 342: oincr = 1; 343: break; 344: case 'l': 345: value = (unsigned long) value; 346: oincr = 4; 347: break; 348: default: 349: oincr = WORDSIZE; 350: break; 351: } 352: break; 353: 354: default: 355: switch (dlen) { 356: case 'h': 357: value = (short) value; 358: oincr = 2; 359: break; 360: case 'b': 361: value = (char) value; 362: oincr = 1; 363: break; 364: case 'l': 365: value = (long) value; 366: oincr = 4; 367: break; 368: default: 369: oincr = WORDSIZE; 370: break; 371: } 372: } 373: if (dfmt == 'x' && (value > 9 || value < 0)) 374: printf("0x"); 375: else if (dfmt == 'o' && (value > 7 || value < 0)) 376: printf("0"); 377: printf(pd, value); 378: return(1); 379: 380: case 'f': 381: pd[1] = 'g'; 382: word.w = value; 383: printf(pd, word.f); 384: return(1); 385: 386: case 'g': 387: dbl.ww.w1 = value; 388: dbl.ww.w2 = (class == N_RSYM) ? 389: *(ADDR *)(((ADDR) &u)+R0+(WORDSIZE)*(addr+1)) : 390: getval(addr+WORDSIZE, 'd', space); 391: printf("%.13g", dbl.d); 392: return(1); 393: 394: case 'p': 395: printf("%s:%d", adrtoprocp(value)->pname, 396: adrtolineno(value)); 397: return(1); 398: 399: case 's': 400: addr = getindir(class, addr, type); 401: goto aa; 402: 403: case 'c': 404: if (size <= 1) { 405: oincr = 1; 406: printchar(value); 407: return(1); 408: } else 409: goto aa; 410: 411: case 'a': 412: aa: sflag = size == 0; 413: if (sflag) 414: size = 128; /* maximum length for s and a */ 415: else 416: oincr = size; 417: for (;;) { 418: word.w = getval(addr, 'd', space); 419: for (i=0; i<WORDSIZE; i++) { 420: if (sflag && word.c[i] == 0) 421: return(1); 422: if (size-- == 0) 423: return(1); 424: printchar(word.c[i]); 425: } 426: addr += WORDSIZE; 427: } 428: break; 429: 430: case 'i': 431: case 'I': 432: value = chkget(dot, space); 433: if (errflg) { 434: printf("%s", errflg); 435: errflg = 0; 436: return(-1); 437: } 438: printins(dfmt, space, value); 439: break; 440: 441: } 442: return(1); 443: } 444: 445: /* print variable as in prvar */ 446: printit(metaflag, prvar, addr, desc, class, type, size, subflag, space) 447: u_char class; 448: char *desc; short type; ADDR addr; { 449: if (prvar == 0) 450: return; 451: if (metaflag) { 452: if (prvar == 1) 453: printf("/ "); 454: else 455: printf("= "); 456: } 457: if (prvar == 1) 458: dispf(addr, desc, class, type, size, 459: subflag, space); 460: else 461: dispf(addr, desc, 0, -1, 0, 0, DSP); 462: } 463: 464: printchar(c) { 465: if ((c & 0177) < ' ') 466: printf("^%c", c + ('A' - 1)); 467: else if ((c & 0177) == 0177) 468: printf("^?"); 469: else 470: printf("%c", c); 471: } 472: 473: INT fcor; 474: printmap(s,amap) 475: STRING s; MAP *amap; 476: { 477: int file; 478: file=amap->ufd; 479: printf("%s\t`%s'\n",s,(file<0 ? "-" : (file==fcor ? corfil : symfil))); 480: printf("b1 = 0x%-16x",amap->b1); 481: printf("e1 = 0x%-16x",amap->e1); 482: printf("f1 = 0x%-x",amap->f1); 483: printf("\nb2 = 0x%-16x",amap->b2); 484: printf("e2 = 0x%-16x",amap->e2); 485: printf("f2 = 0x%-x",amap->f2); 486: printf("\n"); 487: } 488: 489: #define NUMREGS 24 /* number of hardware registers */ 490: REGLIST reglist[]; 491: 492: printregs() 493: { 494: REG REGPTR p; 495: 496: for (p=reglist; p < ®list[NUMREGS/2]; p++) { 497: printf("%4.4s/ ", p->rname); 498: prhex12(*(ADDR *)(((ADDR)&u)+p->roffs)); 499: printf(" %4.4s/ ",(p+NUMREGS/2)->rname); 500: prhex(*(ADDR *)(((ADDR)&u)+(p+NUMREGS/2)->roffs)); 501: printf("\n"); 502: } 503: printpc(); 504: } 505: 506: printpc() 507: { 508: dot= *(ADDR *)(((ADDR)&u)+PC); 509: prisploc(); 510: printins('i',ISP,chkget(dot,ISP)); 511: printf("\n"); 512: } 513: 514: /* print register */ 515: REGLIST reglist[]; 516: regout(name, prvar, fmt) 517: char *name, *fmt; { 518: REG REGPTR p; 519: for (p=reglist; p< ®list[24]; p++) { 520: if (eqstr(name, p->rname)) { 521: printit(0, prvar, *(ADDR *)(((ADDR)&u)+p->roffs), 522: fmt[0] ? fmt : "d", N_GSYM, -1, 0, 0, DSP); 523: return(p->roffs); 524: } 525: } 526: error("Unknown register variable"); 527: return(-1); 528: } 529: /* Print symbolic location of dot */ 530: prisploc() { 531: struct proct *procp; 532: int lineno; 533: 534: printf("0x%x", dot); 535: procp = adrtoprocp(dot); 536: if (procp != badproc) { 537: printf(" ("); 538: prlnoff(procp, dot); 539: printf("): \t"); 540: } else 541: printf(": \t"); 542: }