1*2815Swnj static char sccsid[] = "@(#)display.c 4.2 02/28/81"; 21331Sbill #include "head.h" 31331Sbill #include <a.out.h> 41331Sbill #include <stab.h> 51331Sbill #include "cdefs.h" 61331Sbill struct user u; 71331Sbill BKPTR bkpthead; 81331Sbill 91331Sbill #ifdef FLEXNAMES 101331Sbill #define bread(a,b,c) stread(b,c) 111331Sbill #define blseek(a,b,c) stseek(b,c) 121331Sbill #endif 131331Sbill 141331Sbill /* initialize frame pointers to top of call stack */ 151331Sbill /* MACHINE DEPENDENT */ 161331Sbill struct proct * 171331Sbill initframe() { 181331Sbill argp = *(ADDR *) (((ADDR) &u) + AP); 191331Sbill frame = *(ADDR *) (((ADDR) &u) + FP); 201331Sbill callpc = *(ADDR *) (((ADDR) &u) + PC); 211331Sbill if ((frame == 0) || (frame & 0xf0000000 != 0x70000000)) 221331Sbill return(badproc); 231331Sbill return(adrtoprocp(callpc++)); /* ++ because UNIX backs up instrs */ 241331Sbill } 251331Sbill 261331Sbill 271331Sbill struct proct * 281331Sbill nextframe() { 291331Sbill callpc = get(frame+16, DSP); 301331Sbill argp = get(frame+8, DSP); 311331Sbill frame = get(frame+12, DSP) & EVEN; 32*2815Swnj if (callpc > 0x70000000) { 33*2815Swnj /* error handler kludge */ 34*2815Swnj callpc = get(frame+64, DSP); 351331Sbill argp = get(frame+8, DSP); 361331Sbill frame = get(frame+12, DSP) & EVEN; 371331Sbill } 381331Sbill if ((frame == 0) || (frame & 0xf0000000 != 0x70000000)) 391331Sbill return(badproc); 401331Sbill return(adrtoprocp(callpc-1)); 411331Sbill } 421331Sbill 431331Sbill /* returns core image address for variable */ 441331Sbill /* MACHINE DEPENDENT */ 451331Sbill ADDR 461331Sbill formaddr(class, addr) 471331Sbill register char class; 481331Sbill ADDR addr; { 491331Sbill if (debug) printf("formaddr(%o, %d)\n", class & 0377, addr); 501331Sbill switch(class & STABMASK) { 511331Sbill case N_RSYM: 521331Sbill return(stackreg(addr)); 531331Sbill case N_GSYM: 541331Sbill case N_SSYM: 551331Sbill case N_STSYM: 561331Sbill case N_LCSYM: 571331Sbill return(addr); 581331Sbill 591331Sbill case N_PSYM: 601331Sbill return(argp+addr); 611331Sbill 621331Sbill case N_LSYM: 631331Sbill return(frame+addr); 641331Sbill 651331Sbill default: 661331Sbill printf("Bad class in formaddr: 0%o", 671331Sbill class & 0377); 681331Sbill return(0); 691331Sbill } 701331Sbill } 711331Sbill 721331Sbill char class; 731331Sbill 741331Sbill /* 751331Sbill * stackreg(reg): 761331Sbill * If the register for the current frame is somewhere on the stack 771331Sbill * then return the address of where it is, otherwise its still in 781331Sbill * the register so return the register number. 791331Sbill * We distinguish the two by noting that register numbers are less 801331Sbill * than 16 and that stack addresses are greater. 811331Sbill * 821331Sbill * MACHINE DEPENDENT 831331Sbill */ 841331Sbill ADDR 851331Sbill stackreg(reg) { 861331Sbill register int curframe, regfl, mask, i; 871331Sbill struct proct *procp; 881331Sbill ADDR regaddr; 891331Sbill 901331Sbill curframe = frame; 911331Sbill regaddr = reg; 921331Sbill regfl = 0x10000 << reg; 931331Sbill for (procp=initframe(); frame!=curframe; procp=nextframe()) { 941331Sbill if (procp == badproc) { 951331Sbill error("Stackreg error: frame"); 961331Sbill return(-1); 971331Sbill } 981331Sbill mask = get(frame+4, DSP); 991331Sbill if (mask & regfl) { 1001331Sbill regaddr = frame + 20; 1011331Sbill for (i=0; i<reg; i++) { 1021331Sbill if (mask & 0x10000) 1031331Sbill regaddr += WORDSIZE; 1041331Sbill mask = mask >> 1; 1051331Sbill } 1061331Sbill if (!(mask & 0x10000)) { 1071331Sbill error("Stackreg error: contents"); 1081331Sbill return(-1); 1091331Sbill } 1101331Sbill } 1111331Sbill } 1121331Sbill return(regaddr); 1131331Sbill } 1141331Sbill 1151331Sbill /* returns address of proc:var. Sets externals class and subflag */ 1161331Sbill ADDR 1171331Sbill varaddr(proc, var) 1181331Sbill char *proc, *var; { 1191331Sbill return(findvar(proc, var, "", 0)); 1201331Sbill } 1211331Sbill 1221331Sbill /* 1231331Sbill * displays values of variables matching proc:var, 1241331Sbill * returns its address 1251331Sbill */ 1261331Sbill ADDR 1271331Sbill dispvar(proc, var, fmt) 1281331Sbill char *proc, *var, *fmt; { 1291331Sbill return(findvar(proc, var, fmt, 1)); 1301331Sbill } 1311331Sbill 1321331Sbill /* 1331331Sbill * Find and print values of all variables matching proc:var 1341331Sbill * using specified format. 1351331Sbill * Returns address of last matching variable. 1361331Sbill * 1371331Sbill * prvar==0 => no output, 1381331Sbill * prvar==1 => output value, 1391331Sbill * prvar==2 => output addr 1401331Sbill */ 1411331Sbill ADDR 1421331Sbill findvar(proc, var, fmt, prvar) 1431331Sbill char *proc, *var, *fmt; { 1441331Sbill ADDR addr = -1, a = -1; 1451331Sbill int metaflag = 0, match=0, nullflag=0, depthcnt = -1; 1461331Sbill char *comblk; 1471331Sbill register struct proct *procp; 1481331Sbill 1491331Sbill if (percentflag) { /* kludge for register names */ 1501331Sbill return(regout(var, prvar, fmt)); 1511331Sbill } 1521331Sbill 1531331Sbill if (var[0] == '\0') { 1541331Sbill error("Unexpected null variable name"); 1551331Sbill return(-1); 1561331Sbill } 1571331Sbill 1581331Sbill metaflag = eqany('*', proc) || eqany('?', proc) || 1591331Sbill eqany('*', var) || eqany('?', var); 1601331Sbill 1611331Sbill if (proc[0] == '\0') { 1621331Sbill nullflag++; 1631331Sbill proc = curproc()->pname; 1641331Sbill } 1651331Sbill 1661331Sbill comblk = colonflag ? "" : "*"; 1671331Sbill 1681331Sbill if (integ && !eqany(var[0], "->.[")) { 1691331Sbill depthcnt = integ; 1701331Sbill } 1711331Sbill if (integ) { 1721331Sbill if (eqany(var[0], "->.[")) 1731331Sbill match++; 1741331Sbill else 1751331Sbill depthcnt = integ; 1761331Sbill } 1771331Sbill 1781331Sbill procp = initframe(); 1791331Sbill if (!eqany(var[0], "->.[") && !(nullflag && colonflag)) { 1801331Sbill do { 1811331Sbill if (eqpat(proc, procp->pname)) { 1821331Sbill match++; 1831331Sbill if (--depthcnt==0 || integ==0) { 1841331Sbill a = outvar(procp->pname, var, fmt, 1851331Sbill metaflag, integ, N_GSYM, 1861331Sbill 0, prname, comblk, prvar); 1871331Sbill if (a != -1) 1881331Sbill addr = a; 1891331Sbill if (depthcnt == 0) 1901331Sbill break; 1911331Sbill } 1921331Sbill } 1931331Sbill } while ((procp=nextframe()) != badproc); 1941331Sbill } 1951331Sbill 1961331Sbill if ((colonflag || metaflag || a == -1) && 1971331Sbill (nullflag || eqpat(proc, ""))) { 1981331Sbill a = outvar("", var, fmt, metaflag, integ, 1991331Sbill N_GSYM, 0, prname, comblk, prvar); 2001331Sbill if (a != -1) { 2011331Sbill addr = a; 2021331Sbill match++; 2031331Sbill } 2041331Sbill } 2051331Sbill 2061331Sbill if (match==0 && colonflag) { 2071331Sbill procp = initframe(); 2081331Sbill do { 2091331Sbill if (eqstr(curproc()->pname, procp->pname)) 2101331Sbill break; 2111331Sbill } while ((procp=nextframe()) != badproc); 2121331Sbill a = outvar(curproc()->pname, var, fmt, metaflag, 2131331Sbill integ, N_GSYM, 0, prname, 2141331Sbill nullflag ? "_BLNK_" : proc, prvar); 2151331Sbill if (a != -1) { 2161331Sbill addr = a; 2171331Sbill match++; 2181331Sbill } 2191331Sbill } 2201331Sbill 2211331Sbill if (addr == -1 && match == 0) { 2221331Sbill addr = extoutvar(var, fmt, metaflag, prvar); 2231331Sbill if (addr != -1) 2241331Sbill return(addr); 2251331Sbill } 2261331Sbill if (match == 0) { 2271331Sbill printf("%s not an active procedure\n", proc); 2281331Sbill return(-1); 2291331Sbill } 2301331Sbill if (addr == -1) { 2311331Sbill if (var[0] == '.') 2321331Sbill var++; 2331331Sbill if (proc[0]) 2341331Sbill #ifndef FLEXNAMES 2351331Sbill printf("%.16s:%s not found\n", proc, var); 2361331Sbill #else 2371331Sbill printf("%s:%s not found\n", proc, var); 2381331Sbill #endif 2391331Sbill else 2401331Sbill printf("%s not found\n", var); 2411331Sbill return(-1); 2421331Sbill } 2431331Sbill return(addr); 2441331Sbill } 2451331Sbill 2461331Sbill char * 2471331Sbill typetodesc(type, subflag) 2481331Sbill short type; { 2491331Sbill register int ptr, ftn, ary; 2501331Sbill register char *desc; 2511331Sbill 2521331Sbill static char *typedesc[] = { 2531331Sbill "d", /* undef */ 2541331Sbill "d", /* farg */ 2551331Sbill "c", /* char */ 2561331Sbill "hd", /* short */ 2571331Sbill "d", /* int */ 2581331Sbill "ld", /* long */ 2591331Sbill "f", /* float */ 2601331Sbill "g", /* double */ 2611331Sbill "d", /* strty */ 2621331Sbill "d", /* unionty */ 2631331Sbill "d", /* enumty */ 2641331Sbill "d", /* moety */ 2651331Sbill "bu", /* uchar */ 2661331Sbill "hu", /* ushort */ 2671331Sbill "u", /* unsigned */ 2681331Sbill "lu", /* ulong */ 2691331Sbill "d" /* ? */ 2701331Sbill }; 2711331Sbill 2721331Sbill ptr = ftn = ary = 0; 2731331Sbill 2741331Sbill desc = typedesc[type&BTMASK]; 2751331Sbill for (; type & TMASK; type = DECREF(type)) { 2761331Sbill if (ISPTR(type)) ptr++; 2771331Sbill else if (ISFTN(type)) ftn++; 2781331Sbill else if (ISARY(type)) ary++; 2791331Sbill } 2801331Sbill 2811331Sbill if ((ptr-subflag == 1 || ary-subflag == 1) && desc[0] == 'c') 2821331Sbill return("s"); 2831331Sbill if (debug) 2841331Sbill printf ("PTR %d; FTN %d; ARY %d; DESC %s\n",ptr,ftn,ary,desc); 2851331Sbill if (ptr + ary == subflag) 2861331Sbill return(desc); 2871331Sbill if (ptr) return("x"); 2881331Sbill if (ptr==1 && ftn==1) return("p"); 2891331Sbill return(desc); 2901331Sbill } 2911331Sbill 2921331Sbill typetosize(type, stsize) 2931331Sbill short type; { 2941331Sbill register int ptr, ftn, ary; 2951331Sbill register int size; 2961331Sbill 2971331Sbill static char typesize[] = { 2981331Sbill 4, /* undef */ 2991331Sbill 4, /* farg */ 3001331Sbill 1, /* char */ 3011331Sbill 2, /* short */ 3021331Sbill WORDSIZE, /* int */ 3031331Sbill 4, /* long */ 3041331Sbill 4, /* float */ 3051331Sbill 8, /* double */ 3061331Sbill 0, /* strty */ 3071331Sbill 0, /* unionty */ 3081331Sbill 4, /* enumty */ 3091331Sbill 4, /* moety */ 3101331Sbill 1, /* uchar */ 3111331Sbill 2, /* ushort */ 3121331Sbill 4, /* unsigned */ 3131331Sbill 4, /* ulong */ 3141331Sbill 4 /* ? */ 3151331Sbill }; 3161331Sbill 3171331Sbill ptr = ftn = ary = 0; 3181331Sbill 3191331Sbill size = typesize[type&BTMASK]; 3201331Sbill for (; type & TMASK; type = DECREF(type)) { 3211331Sbill if (ISPTR(type)) ptr++; 3221331Sbill else if (ISFTN(type)) ftn++; 3231331Sbill else if (ISARY(type)) ary++; 3241331Sbill } 3251331Sbill 3261331Sbill if (debug) 3271331Sbill printf ("PTR %d; FTN %d; ARY %d; SIZE %d; STSIZE %d\n", 3281331Sbill ptr,ftn,ary,size,stsize); 3291331Sbill if (ptr>1) return(4); 3301331Sbill if (size == 0) return(stsize); 3311331Sbill else return(size); 3321331Sbill } 3331331Sbill 3341331Sbill 3351331Sbill /* print breakpoints */ 3361331Sbill prbkpt() { 3371331Sbill register BKPTR bkptr; 3381331Sbill register int cnt; 3391331Sbill char *cmdp; 3401331Sbill 3411331Sbill cnt = 0; 3421331Sbill 3431331Sbill for (bkptr = bkpthead; bkptr; bkptr=bkptr->nxtbkpt) 3441331Sbill if (bkptr->flag) { 3451331Sbill cnt++; 3461331Sbill printbkpt("", adrtoprocp(bkptr->loc), bkptr->loc); 3471331Sbill cmdp = bkptr->comm; 3481331Sbill if (*cmdp != '\n') { 3491331Sbill printf(" <"); 3501331Sbill while (*cmdp != '\n') 3511331Sbill printf("%c", *cmdp++); 3521331Sbill printf(">\n"); 3531331Sbill } 3541331Sbill else 3551331Sbill printf("\n"); 3561331Sbill } 3571331Sbill if (cnt == 0) 3581331Sbill printf("No breakpoints set\n"); 3591331Sbill } 3601331Sbill 3611331Sbill /* interactively delete breakpoints */ 3621331Sbill 3631331Sbill idbkpt() { 3641331Sbill register BKPTR bkptr; 3651331Sbill register int yesflg, cnt; 3661331Sbill register char c; 3671331Sbill 3681331Sbill cnt = 0; 3691331Sbill 3701331Sbill for (bkptr = bkpthead; bkptr; bkptr=bkptr->nxtbkpt) 3711331Sbill if (bkptr->flag) { 3721331Sbill printbkpt(" ? ", adrtoprocp(bkptr->loc), bkptr->loc); 3731331Sbill yesflg = 0; 3741331Sbill cnt++; 3751331Sbill do { 3761331Sbill c = getchar(); 3771331Sbill if (c == 'y' || c == 'd') yesflg++; 3781331Sbill } while (c != '\n'); 3791331Sbill if (yesflg) 3801331Sbill bkptr->flag = 0; 3811331Sbill } 3821331Sbill if (cnt == 0) 3831331Sbill printf("No breakpoints set\n"); 3841331Sbill } 3851331Sbill 3861331Sbill /* delete all breakpoints */ 3871331Sbill 3881331Sbill dabkpt() { 3891331Sbill register BKPTR bkptr; 3901331Sbill 3911331Sbill for (bkptr = bkpthead; bkptr; bkptr=bkptr->nxtbkpt) 3921331Sbill bkptr->flag = 0; 3931331Sbill } 3941331Sbill 3951331Sbill /* 3961331Sbill * Print name of breakpoint for a, b, d commands: 3971331Sbill */ 3981331Sbill printbkpt(s, procp, dot) 3991331Sbill char *s; struct proct *procp; ADDR dot; { 4001331Sbill adrtolineno(dot); 4011331Sbill if (dot != lnfaddr) 4021331Sbill printf("0x%x (", dot); 4031331Sbill prlnoff(procp, dot); 4041331Sbill if (dot != lnfaddr) 4051331Sbill printf(")"); 4061331Sbill printf("%s", s); 4071331Sbill } 4081331Sbill 4091331Sbill /* print call frame */ 4101331Sbill prframe() { 4111331Sbill prfrx(0); 4121331Sbill } 4131331Sbill 4141331Sbill /* set top to print just the top procedure */ 4151331Sbill prfrx(top) { 4161331Sbill int narg; 4171331Sbill long offset; 4181331Sbill register char class; 4191331Sbill register int endflg; 4201331Sbill char *p; 4211331Sbill struct proct *procp; 4221331Sbill struct nlist stentry; 4231331Sbill 4241331Sbill if ((procp = initframe()) == badproc) return; 4251331Sbill do { 4261331Sbill if (get(frame+12, DSP) == 0) return; 4271331Sbill p = procp->pname; 4281331Sbill if (eqstr("__dbsubc", p)) return; 4291331Sbill if (p[0] == '_') { 4301331Sbill endflg = 1; 4311331Sbill #ifndef FLEXNAMES 4321331Sbill printf("%.15s(", p+1); 4331331Sbill #else 4341331Sbill printf("%s(", p+1); 4351331Sbill #endif 4361331Sbill } 4371331Sbill else { 4381331Sbill #ifndef FLEXNAMES 4391331Sbill printf("%.16s(", p); 4401331Sbill #else 4411331Sbill printf("%s(", p); 4421331Sbill #endif 4431331Sbill endflg = 0; 4441331Sbill } 4451331Sbill if (endflg == 0) { 4461331Sbill offset = procp->st_offset; 4471331Sbill blseek(&sbuf, offset, 0); 4481331Sbill do { 4491331Sbill if (bread(&sbuf, &stentry, sizeof stentry) < 4501331Sbill sizeof stentry) { 4511331Sbill endflg++; 4521331Sbill break; 4531331Sbill } 4541331Sbill class = stentry.n_type & STABMASK; 4551331Sbill } while (class == N_FUN); 4561331Sbill while (class != N_PSYM) { 4571331Sbill if (bread(&sbuf, &stentry, sizeof stentry) < 4581331Sbill sizeof stentry) { 4591331Sbill endflg++; 4601331Sbill break; 4611331Sbill } 4621331Sbill class = stentry.n_type & STABMASK; 4631331Sbill if (class == N_FUN) { 4641331Sbill endflg++; 4651331Sbill break; 4661331Sbill } 4671331Sbill } 4681331Sbill } 4691331Sbill 4701331Sbill narg = get(argp, DSP); 4711331Sbill if (narg & ~0xff) narg = 0; 4721331Sbill argp += WORDSIZE; 4731331Sbill while (narg) { 4741331Sbill if (endflg) { 4751331Sbill printf("%d", get(argp, DSP)); 4761331Sbill argp += 4; 4771331Sbill } else { 4781331Sbill int length; 4791331Sbill #ifndef FLEXNAMES 4801331Sbill printf("%.16s=", stentry.n_name); 4811331Sbill #else 4821331Sbill printf("%s=", stentry.n_un.n_name); 4831331Sbill #endif 4841331Sbill dispx(argp, "", N_GSYM, stentry.n_desc, 4851331Sbill 0, 0, DSP); 4861331Sbill length = typetosize(stentry.n_desc, 0); 4871331Sbill if (length > WORDSIZE) 4881331Sbill argp += length; 4891331Sbill else 4901331Sbill argp += WORDSIZE; 4911331Sbill } 4921331Sbill do { 4931331Sbill if (endflg) break; 4941331Sbill if (bread(&sbuf, &stentry, sizeof stentry) < 4951331Sbill sizeof stentry) { 4961331Sbill endflg++; 4971331Sbill break; 4981331Sbill } 4991331Sbill class = stentry.n_type & STABMASK; 5001331Sbill if (class == N_FUN) { 5011331Sbill endflg++; 5021331Sbill break; 5031331Sbill } 5041331Sbill } while (class != N_PSYM); 5051331Sbill l1: if (--narg != 0) printf(","); 5061331Sbill } 5071331Sbill printf(")"); 5081331Sbill if (debug) printf(" @ 0x%x ", callpc); 5091331Sbill if (procp->sfptr != badfile) 5101331Sbill printf(" [%s:%d]", adrtofilep(callpc-1)->sfilename, 5111331Sbill adrtolineno(callpc-1)); 5121331Sbill printf("\n"); 5131331Sbill } while (((procp = nextframe()) != badproc) && !top); 5141331Sbill } 5151331Sbill 5161331Sbill INT signo; 5171331Sbill STRING signals[]; 5181331Sbill extern nsig; 5191331Sbill sigprint() 5201331Sbill { 5211331Sbill 5221331Sbill if (signo < nsig) 5231331Sbill printf("%s", signals[signo]); 5241331Sbill else 5251331Sbill printf("signal %d???", signals[signo]); 5261331Sbill } 527