1 static char sccsid[] = "@(#)prvar.c 4.2 06/22/81"; 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; int 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 char *desc; short type; ADDR addr; { 229 dispx(addr, desc, class, type, size, subflag, DSP); 230 printf("\n"); 231 } 232 233 /* display addr in instruction space using format desc or class s */ 234 /* returns -1 if bad address */ 235 dispi(addr, desc, class, type, size, subflag, space) 236 char *desc; short type; ADDR addr; { 237 register i; 238 i = dispx(addr, desc, class, type, size, subflag, ISP); 239 printf("\n"); 240 return(i); 241 } 242 243 char pd[3]; 244 dispx(addr, desc, class, type, size, subflag, space) 245 char *desc; short type; ADDR addr; { 246 int i, sflag; 247 char *p; 248 char dlen, dfmt; 249 long value; 250 union { 251 char c[WORDSIZE]; 252 int w; 253 float f; 254 } word; 255 union { 256 struct{ 257 int w1, w2; 258 } ww; 259 double d; 260 } dbl; 261 262 class &= STABMASK; 263 if (desc[0] == '\0') desc = typetodesc(type, subflag); 264 cpstr(odesc, desc); 265 otype = type; 266 oclass = class; 267 oaddr = addr; 268 oincr = 0; 269 if (debug) printf("dispx(addr=%d,desc=%s,class=%d,type=%d,size=%d,subflg=%d,space=%d)\n", 270 addr, desc, class, type, size, subflag, space); 271 pd[0] = '%'; 272 pd[1] = dfmt = 'd'; 273 dlen = '\0'; 274 for (p = desc; *p; p++) { 275 if (*p>= '0' && *p<'9') { 276 size = readint(&p); 277 p--; 278 } else switch (*p) { 279 case 'l': 280 case 'h': 281 case 'b': 282 dlen = *p; 283 break; 284 285 case 'a': 286 case 'c': 287 case 'd': 288 case 'f': 289 case 'g': 290 case 'i': 291 case 'I': 292 case 'o': 293 case 'p': 294 case 's': 295 case 'u': 296 case 'x': 297 pd[1] = dfmt = *p; 298 break; 299 300 default: 301 printf("Illegal descriptor: %c\n", *p); 302 return(1); 303 } 304 } 305 306 if (type == -1) 307 value = addr; 308 else if (class == N_RSYM && addr < 16) { 309 /* MACHINE DEPENDENT */ 310 if ((addr > 0 && addr < 6) || addr > 11) { 311 printf("Bad register var %d\n", addr); 312 return(-1); 313 } 314 value = *(ADDR *)(((ADDR) &u) + R0 + (WORDSIZE)*addr); 315 } 316 else { 317 value = getval(addr, dfmt == 'g' ? 'd' : dfmt, space); 318 } 319 320 if (errflg) { 321 printf("%s", errflg); 322 errflg = 0; 323 return(-1); 324 } 325 326 switch (dfmt) { 327 default: 328 switch (dfmt) { 329 case 'u': 330 case 'x': 331 case 'o': 332 switch (dlen) { 333 case 'h': 334 value = (unsigned short) value; 335 oincr = 2; 336 break; 337 case 'b': 338 value = (unsigned char) value; 339 oincr = 1; 340 break; 341 case 'l': 342 value = (unsigned long) value; 343 oincr = 4; 344 break; 345 default: 346 oincr = WORDSIZE; 347 break; 348 } 349 break; 350 351 default: 352 switch (dlen) { 353 case 'h': 354 value = (short) value; 355 oincr = 2; 356 break; 357 case 'b': 358 value = (char) value; 359 oincr = 1; 360 break; 361 case 'l': 362 value = (long) value; 363 oincr = 4; 364 break; 365 default: 366 oincr = WORDSIZE; 367 break; 368 } 369 } 370 if (dfmt == 'x' && (value > 9 || value < 0)) 371 printf("0x"); 372 else if (dfmt == 'o' && (value > 7 || value < 0)) 373 printf("0"); 374 printf(pd, value); 375 return(1); 376 377 case 'f': 378 pd[1] = 'g'; 379 word.w = value; 380 printf(pd, word.f); 381 return(1); 382 383 case 'g': 384 dbl.ww.w1 = value; 385 dbl.ww.w2 = (class == (char) N_RSYM) ? 386 *(ADDR *)(((ADDR) &u)+R0+(WORDSIZE)*(addr+1)) : 387 getval(addr+WORDSIZE, 'd', space); 388 printf("%.13g", dbl.d); 389 return(1); 390 391 case 'p': 392 printf("%s:%d", adrtoprocp(value)->pname, 393 adrtolineno(value)); 394 return(1); 395 396 case 's': 397 addr = getindir(class, addr, type); 398 goto aa; 399 400 case 'c': 401 if (size <= 1) { 402 oincr = 1; 403 printchar(value); 404 return(1); 405 } else 406 goto aa; 407 408 case 'a': 409 aa: sflag = size == 0; 410 if (sflag) 411 size = 128; /* maximum length for s and a */ 412 else 413 oincr = size; 414 for (;;) { 415 word.w = getval(addr, 'd', space); 416 for (i=0; i<WORDSIZE; i++) { 417 if (sflag && word.c[i] == 0) 418 return(1); 419 if (size-- == 0) 420 return(1); 421 printchar(word.c[i]); 422 } 423 addr += WORDSIZE; 424 } 425 break; 426 427 case 'i': 428 case 'I': 429 value = chkget(dot, space); 430 if (errflg) { 431 printf("%s", errflg); 432 errflg = 0; 433 return(-1); 434 } 435 printins(dfmt, space, value); 436 break; 437 438 } 439 return(1); 440 } 441 442 /* print variable as in prvar */ 443 printit(metaflag, prvar, addr, desc, class, type, size, subflag, space) 444 char *desc; short type; ADDR addr; { 445 if (prvar == 0) 446 return; 447 if (metaflag) { 448 if (prvar == 1) 449 printf("/ "); 450 else 451 printf("= "); 452 } 453 if (prvar == 1) 454 dispf(addr, desc, class, type, size, 455 subflag, space); 456 else 457 dispf(addr, desc, 0, -1, 0, 0, DSP); 458 } 459 460 printchar(c) { 461 if ((c & 0177) < ' ') 462 printf("^%c", c + ('A' - 1)); 463 else if ((c & 0177) == 0177) 464 printf("^?"); 465 else 466 printf("%c", c); 467 } 468 469 INT fcor; 470 printmap(s,amap) 471 STRING s; MAP *amap; 472 { 473 int file; 474 file=amap->ufd; 475 printf("%s\t`%s'\n",s,(file<0 ? "-" : (file==fcor ? corfil : symfil))); 476 printf("b1 = 0x%-16x",amap->b1); 477 printf("e1 = 0x%-16x",amap->e1); 478 printf("f1 = 0x%-x",amap->f1); 479 printf("\nb2 = 0x%-16x",amap->b2); 480 printf("e2 = 0x%-16x",amap->e2); 481 printf("f2 = 0x%-x",amap->f2); 482 printf("\n"); 483 } 484 485 #define NUMREGS 24 /* number of hardware registers */ 486 REGLIST reglist[]; 487 488 printregs() 489 { 490 REG REGPTR p; 491 492 for (p=reglist; p < ®list[NUMREGS/2]; p++) { 493 printf("%4.4s/ ", p->rname); 494 prhex12(*(ADDR *)(((ADDR)&u)+p->roffs)); 495 printf(" %4.4s/ ",(p+NUMREGS/2)->rname); 496 prhex(*(ADDR *)(((ADDR)&u)+(p+NUMREGS/2)->roffs)); 497 printf("\n"); 498 } 499 printpc(); 500 } 501 502 printpc() 503 { 504 dot= *(ADDR *)(((ADDR)&u)+PC); 505 prisploc(); 506 printins('i',ISP,chkget(dot,ISP)); 507 printf("\n"); 508 } 509 510 /* print register */ 511 REGLIST reglist[]; 512 regout(name, prvar, fmt) 513 char *name, *fmt; { 514 REG REGPTR p; 515 for (p=reglist; p< ®list[24]; p++) { 516 if (eqstr(name, p->rname)) { 517 printit(0, prvar, *(ADDR *)(((ADDR)&u)+p->roffs), 518 fmt[0] ? fmt : "d", N_GSYM, -1, 0, 0, DSP); 519 return(p->roffs); 520 } 521 } 522 error("Unknown register variable"); 523 return(-1); 524 } 525 /* Print symbolic location of dot */ 526 prisploc() { 527 struct proct *procp; 528 int lineno; 529 530 printf("0x%x", dot); 531 procp = adrtoprocp(dot); 532 if (procp != badproc) { 533 printf(" ("); 534 prlnoff(procp, dot); 535 printf("): \t"); 536 } else 537 printf(": \t"); 538 } 539