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