1*7773Srrh static char sccsid[] = "@(#)display.c 4.3 08/17/82";
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 *
initframe()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 *
nextframe()281331Sbill nextframe() {
291331Sbill callpc = get(frame+16, DSP);
301331Sbill argp = get(frame+8, DSP);
311331Sbill frame = get(frame+12, DSP) & EVEN;
322815Swnj if (callpc > 0x70000000) {
332815Swnj /* error handler kludge */
342815Swnj 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
formaddr(class,addr)461331Sbill formaddr(class, addr)
47*7773Srrh u_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
stackreg(reg)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
varaddr(proc,var)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
dispvar(proc,var,fmt)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
findvar(proc,var,fmt,prvar)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 *
typetodesc(type,subflag)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
typetosize(type,stsize)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 */
prbkpt()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
idbkpt()3631331Sbill idbkpt() {
3641331Sbill register BKPTR bkptr;
3651331Sbill register int yesflg, cnt;
366*7773Srrh 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
dabkpt()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 */
printbkpt(s,procp,dot)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 */
prframe()4101331Sbill prframe() {
4111331Sbill prfrx(0);
4121331Sbill }
4131331Sbill
4141331Sbill /* set top to print just the top procedure */
prfrx(top)4151331Sbill prfrx(top) {
4161331Sbill int narg;
4171331Sbill long offset;
418*7773Srrh u_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 narg = get(argp, DSP);
4701331Sbill if (narg & ~0xff) narg = 0;
4711331Sbill argp += WORDSIZE;
4721331Sbill while (narg) {
4731331Sbill if (endflg) {
4741331Sbill printf("%d", get(argp, DSP));
4751331Sbill argp += 4;
4761331Sbill } else {
4771331Sbill int length;
4781331Sbill #ifndef FLEXNAMES
4791331Sbill printf("%.16s=", stentry.n_name);
4801331Sbill #else
4811331Sbill printf("%s=", stentry.n_un.n_name);
4821331Sbill #endif
4831331Sbill dispx(argp, "", N_GSYM, stentry.n_desc,
4841331Sbill 0, 0, DSP);
4851331Sbill length = typetosize(stentry.n_desc, 0);
4861331Sbill if (length > WORDSIZE)
4871331Sbill argp += length;
4881331Sbill else
4891331Sbill argp += WORDSIZE;
4901331Sbill }
4911331Sbill do {
4921331Sbill if (endflg) break;
4931331Sbill if (bread(&sbuf, &stentry, sizeof stentry) <
4941331Sbill sizeof stentry) {
4951331Sbill endflg++;
4961331Sbill break;
4971331Sbill }
4981331Sbill class = stentry.n_type & STABMASK;
4991331Sbill if (class == N_FUN) {
5001331Sbill endflg++;
5011331Sbill break;
5021331Sbill }
5031331Sbill } while (class != N_PSYM);
5041331Sbill l1: if (--narg != 0) printf(",");
5051331Sbill }
5061331Sbill printf(")");
5071331Sbill if (debug) printf(" @ 0x%x ", callpc);
5081331Sbill if (procp->sfptr != badfile)
5091331Sbill printf(" [%s:%d]", adrtofilep(callpc-1)->sfilename,
5101331Sbill adrtolineno(callpc-1));
5111331Sbill printf("\n");
5121331Sbill } while (((procp = nextframe()) != badproc) && !top);
5131331Sbill }
5141331Sbill
5151331Sbill INT signo;
5161331Sbill STRING signals[];
5171331Sbill extern nsig;
sigprint()5181331Sbill sigprint()
5191331Sbill {
5201331Sbill
5211331Sbill if (signo < nsig)
5221331Sbill printf("%s", signals[signo]);
5231331Sbill else
5241331Sbill printf("signal %d???", signals[signo]);
5251331Sbill }
526