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