1 static char sccsid[] = "@(#)display.c 4.1 10/09/80"; 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 9 #ifdef FLEXNAMES 10 #define bread(a,b,c) stread(b,c) 11 #define blseek(a,b,c) stseek(b,c) 12 #endif 13 14 /* initialize frame pointers to top of call stack */ 15 /* MACHINE DEPENDENT */ 16 struct proct * 17 initframe() { 18 argp = *(ADDR *) (((ADDR) &u) + AP); 19 frame = *(ADDR *) (((ADDR) &u) + FP); 20 callpc = *(ADDR *) (((ADDR) &u) + PC); 21 if ((frame == 0) || (frame & 0xf0000000 != 0x70000000)) 22 return(badproc); 23 return(adrtoprocp(callpc++)); /* ++ because UNIX backs up instrs */ 24 } 25 26 27 struct proct * 28 nextframe() { 29 callpc = get(frame+16, DSP); 30 argp = get(frame+8, DSP); 31 frame = get(frame+12, DSP) & EVEN; 32 if (callpc > 0x70000000) { /* error handler kludge */ 33 callpc = get(argp+12, DSP); 34 argp = get(frame+8, DSP); 35 frame = get(frame+12, DSP) & EVEN; 36 } 37 if ((frame == 0) || (frame & 0xf0000000 != 0x70000000)) 38 return(badproc); 39 return(adrtoprocp(callpc-1)); 40 } 41 42 /* returns core image address for variable */ 43 /* MACHINE DEPENDENT */ 44 ADDR 45 formaddr(class, addr) 46 register char class; 47 ADDR addr; { 48 if (debug) printf("formaddr(%o, %d)\n", class & 0377, addr); 49 switch(class & STABMASK) { 50 case N_RSYM: 51 return(stackreg(addr)); 52 case N_GSYM: 53 case N_SSYM: 54 case N_STSYM: 55 case N_LCSYM: 56 return(addr); 57 58 case N_PSYM: 59 return(argp+addr); 60 61 case N_LSYM: 62 return(frame+addr); 63 64 default: 65 printf("Bad class in formaddr: 0%o", 66 class & 0377); 67 return(0); 68 } 69 } 70 71 char class; 72 73 /* 74 * stackreg(reg): 75 * If the register for the current frame is somewhere on the stack 76 * then return the address of where it is, otherwise its still in 77 * the register so return the register number. 78 * We distinguish the two by noting that register numbers are less 79 * than 16 and that stack addresses are greater. 80 * 81 * MACHINE DEPENDENT 82 */ 83 ADDR 84 stackreg(reg) { 85 register int curframe, regfl, mask, i; 86 struct proct *procp; 87 ADDR regaddr; 88 89 curframe = frame; 90 regaddr = reg; 91 regfl = 0x10000 << reg; 92 for (procp=initframe(); frame!=curframe; procp=nextframe()) { 93 if (procp == badproc) { 94 error("Stackreg error: frame"); 95 return(-1); 96 } 97 mask = get(frame+4, DSP); 98 if (mask & regfl) { 99 regaddr = frame + 20; 100 for (i=0; i<reg; i++) { 101 if (mask & 0x10000) 102 regaddr += WORDSIZE; 103 mask = mask >> 1; 104 } 105 if (!(mask & 0x10000)) { 106 error("Stackreg error: contents"); 107 return(-1); 108 } 109 } 110 } 111 return(regaddr); 112 } 113 114 /* returns address of proc:var. Sets externals class and subflag */ 115 ADDR 116 varaddr(proc, var) 117 char *proc, *var; { 118 return(findvar(proc, var, "", 0)); 119 } 120 121 /* 122 * displays values of variables matching proc:var, 123 * returns its address 124 */ 125 ADDR 126 dispvar(proc, var, fmt) 127 char *proc, *var, *fmt; { 128 return(findvar(proc, var, fmt, 1)); 129 } 130 131 /* 132 * Find and print values of all variables matching proc:var 133 * using specified format. 134 * Returns address of last matching variable. 135 * 136 * prvar==0 => no output, 137 * prvar==1 => output value, 138 * prvar==2 => output addr 139 */ 140 ADDR 141 findvar(proc, var, fmt, prvar) 142 char *proc, *var, *fmt; { 143 ADDR addr = -1, a = -1; 144 int metaflag = 0, match=0, nullflag=0, depthcnt = -1; 145 char *comblk; 146 register struct proct *procp; 147 148 if (percentflag) { /* kludge for register names */ 149 return(regout(var, prvar, fmt)); 150 } 151 152 if (var[0] == '\0') { 153 error("Unexpected null variable name"); 154 return(-1); 155 } 156 157 metaflag = eqany('*', proc) || eqany('?', proc) || 158 eqany('*', var) || eqany('?', var); 159 160 if (proc[0] == '\0') { 161 nullflag++; 162 proc = curproc()->pname; 163 } 164 165 comblk = colonflag ? "" : "*"; 166 167 if (integ && !eqany(var[0], "->.[")) { 168 depthcnt = integ; 169 } 170 if (integ) { 171 if (eqany(var[0], "->.[")) 172 match++; 173 else 174 depthcnt = integ; 175 } 176 177 procp = initframe(); 178 if (!eqany(var[0], "->.[") && !(nullflag && colonflag)) { 179 do { 180 if (eqpat(proc, procp->pname)) { 181 match++; 182 if (--depthcnt==0 || integ==0) { 183 a = outvar(procp->pname, var, fmt, 184 metaflag, integ, N_GSYM, 185 0, prname, comblk, prvar); 186 if (a != -1) 187 addr = a; 188 if (depthcnt == 0) 189 break; 190 } 191 } 192 } while ((procp=nextframe()) != badproc); 193 } 194 195 if ((colonflag || metaflag || a == -1) && 196 (nullflag || eqpat(proc, ""))) { 197 a = outvar("", var, fmt, metaflag, integ, 198 N_GSYM, 0, prname, comblk, prvar); 199 if (a != -1) { 200 addr = a; 201 match++; 202 } 203 } 204 205 if (match==0 && colonflag) { 206 procp = initframe(); 207 do { 208 if (eqstr(curproc()->pname, procp->pname)) 209 break; 210 } while ((procp=nextframe()) != badproc); 211 a = outvar(curproc()->pname, var, fmt, metaflag, 212 integ, N_GSYM, 0, prname, 213 nullflag ? "_BLNK_" : proc, prvar); 214 if (a != -1) { 215 addr = a; 216 match++; 217 } 218 } 219 220 if (addr == -1 && match == 0) { 221 addr = extoutvar(var, fmt, metaflag, prvar); 222 if (addr != -1) 223 return(addr); 224 } 225 if (match == 0) { 226 printf("%s not an active procedure\n", proc); 227 return(-1); 228 } 229 if (addr == -1) { 230 if (var[0] == '.') 231 var++; 232 if (proc[0]) 233 #ifndef FLEXNAMES 234 printf("%.16s:%s not found\n", proc, var); 235 #else 236 printf("%s:%s not found\n", proc, var); 237 #endif 238 else 239 printf("%s not found\n", var); 240 return(-1); 241 } 242 return(addr); 243 } 244 245 char * 246 typetodesc(type, subflag) 247 short type; { 248 register int ptr, ftn, ary; 249 register char *desc; 250 251 static char *typedesc[] = { 252 "d", /* undef */ 253 "d", /* farg */ 254 "c", /* char */ 255 "hd", /* short */ 256 "d", /* int */ 257 "ld", /* long */ 258 "f", /* float */ 259 "g", /* double */ 260 "d", /* strty */ 261 "d", /* unionty */ 262 "d", /* enumty */ 263 "d", /* moety */ 264 "bu", /* uchar */ 265 "hu", /* ushort */ 266 "u", /* unsigned */ 267 "lu", /* ulong */ 268 "d" /* ? */ 269 }; 270 271 ptr = ftn = ary = 0; 272 273 desc = typedesc[type&BTMASK]; 274 for (; type & TMASK; type = DECREF(type)) { 275 if (ISPTR(type)) ptr++; 276 else if (ISFTN(type)) ftn++; 277 else if (ISARY(type)) ary++; 278 } 279 280 if ((ptr-subflag == 1 || ary-subflag == 1) && desc[0] == 'c') 281 return("s"); 282 if (debug) 283 printf ("PTR %d; FTN %d; ARY %d; DESC %s\n",ptr,ftn,ary,desc); 284 if (ptr + ary == subflag) 285 return(desc); 286 if (ptr) return("x"); 287 if (ptr==1 && ftn==1) return("p"); 288 return(desc); 289 } 290 291 typetosize(type, stsize) 292 short type; { 293 register int ptr, ftn, ary; 294 register int size; 295 296 static char typesize[] = { 297 4, /* undef */ 298 4, /* farg */ 299 1, /* char */ 300 2, /* short */ 301 WORDSIZE, /* int */ 302 4, /* long */ 303 4, /* float */ 304 8, /* double */ 305 0, /* strty */ 306 0, /* unionty */ 307 4, /* enumty */ 308 4, /* moety */ 309 1, /* uchar */ 310 2, /* ushort */ 311 4, /* unsigned */ 312 4, /* ulong */ 313 4 /* ? */ 314 }; 315 316 ptr = ftn = ary = 0; 317 318 size = typesize[type&BTMASK]; 319 for (; type & TMASK; type = DECREF(type)) { 320 if (ISPTR(type)) ptr++; 321 else if (ISFTN(type)) ftn++; 322 else if (ISARY(type)) ary++; 323 } 324 325 if (debug) 326 printf ("PTR %d; FTN %d; ARY %d; SIZE %d; STSIZE %d\n", 327 ptr,ftn,ary,size,stsize); 328 if (ptr>1) return(4); 329 if (size == 0) return(stsize); 330 else return(size); 331 } 332 333 334 /* print breakpoints */ 335 prbkpt() { 336 register BKPTR bkptr; 337 register int cnt; 338 char *cmdp; 339 340 cnt = 0; 341 342 for (bkptr = bkpthead; bkptr; bkptr=bkptr->nxtbkpt) 343 if (bkptr->flag) { 344 cnt++; 345 printbkpt("", adrtoprocp(bkptr->loc), bkptr->loc); 346 cmdp = bkptr->comm; 347 if (*cmdp != '\n') { 348 printf(" <"); 349 while (*cmdp != '\n') 350 printf("%c", *cmdp++); 351 printf(">\n"); 352 } 353 else 354 printf("\n"); 355 } 356 if (cnt == 0) 357 printf("No breakpoints set\n"); 358 } 359 360 /* interactively delete breakpoints */ 361 362 idbkpt() { 363 register BKPTR bkptr; 364 register int yesflg, cnt; 365 register char c; 366 367 cnt = 0; 368 369 for (bkptr = bkpthead; bkptr; bkptr=bkptr->nxtbkpt) 370 if (bkptr->flag) { 371 printbkpt(" ? ", adrtoprocp(bkptr->loc), bkptr->loc); 372 yesflg = 0; 373 cnt++; 374 do { 375 c = getchar(); 376 if (c == 'y' || c == 'd') yesflg++; 377 } while (c != '\n'); 378 if (yesflg) 379 bkptr->flag = 0; 380 } 381 if (cnt == 0) 382 printf("No breakpoints set\n"); 383 } 384 385 /* delete all breakpoints */ 386 387 dabkpt() { 388 register BKPTR bkptr; 389 390 for (bkptr = bkpthead; bkptr; bkptr=bkptr->nxtbkpt) 391 bkptr->flag = 0; 392 } 393 394 /* 395 * Print name of breakpoint for a, b, d commands: 396 */ 397 printbkpt(s, procp, dot) 398 char *s; struct proct *procp; ADDR dot; { 399 adrtolineno(dot); 400 if (dot != lnfaddr) 401 printf("0x%x (", dot); 402 prlnoff(procp, dot); 403 if (dot != lnfaddr) 404 printf(")"); 405 printf("%s", s); 406 } 407 408 /* print call frame */ 409 prframe() { 410 prfrx(0); 411 } 412 413 /* set top to print just the top procedure */ 414 prfrx(top) { 415 int narg; 416 long offset; 417 register char class; 418 register int endflg; 419 char *p; 420 struct proct *procp; 421 struct nlist stentry; 422 423 if ((procp = initframe()) == badproc) return; 424 do { 425 if (get(frame+12, DSP) == 0) return; 426 p = procp->pname; 427 if (eqstr("__dbsubc", p)) return; 428 if (p[0] == '_') { 429 endflg = 1; 430 #ifndef FLEXNAMES 431 printf("%.15s(", p+1); 432 #else 433 printf("%s(", p+1); 434 #endif 435 } 436 else { 437 #ifndef FLEXNAMES 438 printf("%.16s(", p); 439 #else 440 printf("%s(", p); 441 #endif 442 endflg = 0; 443 } 444 if (endflg == 0) { 445 offset = procp->st_offset; 446 blseek(&sbuf, offset, 0); 447 do { 448 if (bread(&sbuf, &stentry, sizeof stentry) < 449 sizeof stentry) { 450 endflg++; 451 break; 452 } 453 class = stentry.n_type & STABMASK; 454 } while (class == N_FUN); 455 while (class != N_PSYM) { 456 if (bread(&sbuf, &stentry, sizeof stentry) < 457 sizeof stentry) { 458 endflg++; 459 break; 460 } 461 class = stentry.n_type & STABMASK; 462 if (class == N_FUN) { 463 endflg++; 464 break; 465 } 466 } 467 } 468 469 narg = get(argp, DSP); 470 if (narg & ~0xff) narg = 0; 471 argp += WORDSIZE; 472 while (narg) { 473 if (endflg) { 474 printf("%d", get(argp, DSP)); 475 argp += 4; 476 } else { 477 int length; 478 #ifndef FLEXNAMES 479 printf("%.16s=", stentry.n_name); 480 #else 481 printf("%s=", stentry.n_un.n_name); 482 #endif 483 dispx(argp, "", N_GSYM, stentry.n_desc, 484 0, 0, DSP); 485 length = typetosize(stentry.n_desc, 0); 486 if (length > WORDSIZE) 487 argp += length; 488 else 489 argp += WORDSIZE; 490 } 491 do { 492 if (endflg) break; 493 if (bread(&sbuf, &stentry, sizeof stentry) < 494 sizeof stentry) { 495 endflg++; 496 break; 497 } 498 class = stentry.n_type & STABMASK; 499 if (class == N_FUN) { 500 endflg++; 501 break; 502 } 503 } while (class != N_PSYM); 504 l1: if (--narg != 0) printf(","); 505 } 506 printf(")"); 507 if (debug) printf(" @ 0x%x ", callpc); 508 if (procp->sfptr != badfile) 509 printf(" [%s:%d]", adrtofilep(callpc-1)->sfilename, 510 adrtolineno(callpc-1)); 511 printf("\n"); 512 } while (((procp = nextframe()) != badproc) && !top); 513 } 514 515 INT signo; 516 STRING signals[]; 517 extern nsig; 518 sigprint() 519 { 520 521 if (signo < nsig) 522 printf("%s", signals[signo]); 523 else 524 printf("signal %d???", signals[signo]); 525 } 526