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