xref: /original-bsd/old/sdb/display.c (revision ba72ef4c)
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