1 static char sccsid[] = "@(#)prvar.c 4.3 08/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 } 543