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