xref: /original-bsd/old/sdb/prvar.c (revision c55b7a8d)
1 static	char sccsid[] = "@(#)prvar.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 STRING	errflg;
9 
10 /*
11  *  outvar():
12  * Prints named variable, recursing once for each structure member or
13  *  subscript.
14  * proc:var: variable name
15  * fmt: print format
16  * metaflag: set iff var contains metacharacters * or ?
17  * addr: partial address of variable, initally 0
18  * class: type class of variable
19  * subflag: number of levels of subscript indirection
20  * prnamep: pointer to end of partially formed print name of variable
21  * comblk: name of common block containing variable, if any
22  * prvar: as in findvar
23  *
24  * Here and elsewhere we assume that -1 is an invalid address, and
25  *	its is used to indicate error.
26  */
outvar(proc,var,fmt,metaflag,addr,class,subflag,prnamep,comblk,prvar)27 outvar(proc, var, fmt, metaflag, addr, class, subflag, prnamep,
28 		comblk, prvar)
29 ADDR addr; char *proc, *var, *fmt, *prnamep, *comblk; u_char class; {
30 	char *p, *q, *r, *oldpr;
31 	register int match;
32 	long soffset, goffset;
33 	register ADDR newaddr = -1, arrowaddr;
34 	register enum {INIT, ARROW, DOT} typeflag;
35 
36 	switch (var[0]) {
37 	case '\0':
38 		if (prvar == 0) return(addr);
39 		if (metaflag) {
40 			if (comblk[0] && !(eqstr(comblk, "*")))
41 #ifndef FLEXNAMES
42 				printf("%.8s:%.8s", comblk, prname);
43 #else
44 				printf("%s:%s", comblk, prname);
45 #endif
46 			else if (proc[0])
47 #ifndef FLEXNAMES
48 				printf("%.8s:%.8s", proc, prname);
49 #else
50 				printf("%s:%s", proc, prname);
51 #endif
52 			else
53 				printf("%s", prname);
54 		}
55 		printit(metaflag, prvar, addr, fmt, class, sl_type,
56 			sl_size, subflag, DSP);
57 		return(addr);
58 
59 	case '[':
60 		*prnamep++ = *var++;
61 		p = var;
62 		for (;;) {
63 			*prnamep++ = *var;
64 			if (*var == '\0' || *var == ']') break;
65 			var++;
66 		}
67 		newaddr = getindir(class, addr, sl_type);
68 		newaddr += typetosize(sl_type, sl_size) * readint(&p);
69 		return(outvar(proc, var+1, fmt, metaflag, newaddr, N_GSYM,
70 			subflag+1, prnamep, comblk, prvar));
71 
72 	case '-':
73 	case '>':
74 		typeflag = ARROW;
75 		while (eqany(*var, "->"))
76 			*prnamep++ = *var++;
77 		subflag++;
78 		arrowaddr = getindir(class, addr, sl_type);
79 		if (errflg) {
80 			printf("%s\n", errflg);
81 			errflg = 0;
82 			return(0);
83 		}
84 		class = N_GSYM;
85 		if (var[0] == '\0') {
86 			p = var;
87 			newaddr = arrowaddr;
88 			goto recurse;
89 		}
90 		break;
91 
92 	case '.':
93 		typeflag = DOT;
94 		if (class == N_RSYM) {
95 			error("Not with a register variable");
96 			return(0);
97 		}
98 		*prnamep++ = *var++;
99 		subflag = 0;
100 		break;
101 
102 	default:
103 		typeflag = INIT;
104 		break;
105 	}
106 
107 	if (typeflag == INIT) {
108 		soffset = proc[0] ? adrtostoffset(callpc-1) : -1;
109 		goffset = proc[0] ? -1 : findfile(curfile)->stf_offset;
110 	} else {
111 		soffset = proc[0] ? adrtostoffset(callpc-1) : -1;
112 		goffset = findfile(curfile)->stf_offset;
113 	}
114 
115 	p = var;
116 	oldpr = prnamep;
117 	while (!eqany(*p, "->.[") && *p != '\0')
118 		*prnamep++ = *p++;
119 	*prnamep = '\0';
120 
121 	match = 0;
122 	slookinit();
123 
124 	for (;;) {
125 		if (soffset != -1)
126 			if ((soffset = slooknext(var, soffset, typeflag!=INIT,
127 				comblk)) != -1)
128 				goto found;
129 		if (goffset != -1)
130 			if ((goffset = globallookup(var, goffset,
131 				typeflag!=INIT)) != -1)
132 				goto found;
133 		return(newaddr);
134 
135 	found:
136 		r = sl_name;
137 		q = oldpr;
138 		while (*r) *q++ = *r++;
139 		*q ='\0';
140 
141 		switch(typeflag) {
142 		case INIT:
143 			class = sl_class & STABMASK;
144 			if (!varclass(class) || class == N_SSYM)
145 				goto l;
146 			newaddr = (class == N_LSYM) ? -sl_addr : sl_addr;
147 			newaddr = formaddr(class, newaddr);
148 			break;
149 
150 		case ARROW:
151 			class = sl_class & STABMASK;
152 			if (!varclass(class) || class != N_SSYM)
153 				goto l;
154 			newaddr = arrowaddr + sl_addr;
155 			break;
156 
157 		case DOT:
158 			class = sl_class & STABMASK;
159 			if (!varclass(class) || class != N_SSYM)
160 				goto l;
161 			newaddr = addr + sl_addr;
162 			break;
163 		}
164 
165 	recurse:
166 		newaddr = outvar(proc, p, fmt, metaflag, newaddr,
167 			class, subflag, prnamep, comblk, prvar);
168 
169 		if (!metaflag)
170 			return(newaddr);
171 l:;	}
172 }
173 
174 /* Output external variables.  Arguments as in outvar() */
extoutvar(var,fmt,metaflag,prvar)175 extoutvar(var, fmt, metaflag, prvar)
176 char *var, *fmt; {
177 	long offset;
178 	ADDR addr = -1;
179 
180 	offset = extstart;
181 	sl_addr = -1;
182 
183 	for (;;) {
184 		offset = extlookup(var, offset);
185 		addr = sl_addr;
186 		if (offset == -1)
187 			return(addr);
188 		if (metaflag)
189 #ifndef FLEXNAMES
190 			printf("%.7s", sl_name);
191 #else
192 			printf("%s", sl_name);
193 #endif
194 		printit(metaflag, prvar, addr, fmt[0] ? fmt : "d",
195 			N_GSYM, 0, 0, 0, DSP);
196 		if (!metaflag)
197 			return(addr);
198 	}
199 }
200 
prdebug()201 prdebug() {
202 	register struct proct *procp;
203 	register struct filet *filep;
204 
205 	printf("dot=%d\n", dot);
206 	printf("extstart = %d\n", extstart);
207 	printf("firstdata = %d\n", firstdata);
208 	for(filep=files;filep->sfilename[0];filep++)
209 		printf("%s offs %d @ %d flag %d addr 0x%x\n", filep->sfilename, filep->stf_offset, filep, filep->lineflag, filep->faddr);
210 	for(procp=procs;procp->pname[0];procp++) {
211 #ifndef FLEXNAMES
212 		printf("%s addr 0x%x; offs %d; sfptr %d; line %d",
213 #else
214 		printf("%8.8s addr 0x%x; offs %d; sfptr %d; line %d",
215 #endif
216 			procp->pname, procp->paddr, procp->st_offset,
217 			procp->sfptr, procp->lineno);
218 		if (procp->entrypt) printf(" entrypoint");
219 		printf("\n");
220 	}
221 }
222 
223 /*
224  * display addr in data space using format desc or class s
225  *  type == 1 => use addr for value to print
226  */
dispf(addr,desc,class,type,size,subflag,space)227 dispf(addr, desc, class, type, size, subflag, space)
228 u_char class;
229 char *desc; short type; ADDR addr; {
230 	dispx(addr, desc, class, type, size, subflag, DSP);
231 	printf("\n");
232 }
233 
234 /* display addr in instruction space using format desc or class s */
235 /*  returns -1 if bad address */
dispi(addr,desc,class,type,size,subflag,space)236 dispi(addr, desc, class, type, size, subflag, space)
237 u_char class;
238 char *desc; short type; ADDR addr; {
239 	register i;
240 	i = dispx(addr, desc, class, type, size, subflag, ISP);
241 	printf("\n");
242 	return(i);
243 }
244 
245 char	pd[3];
dispx(addr,desc,class,type,size,subflag,space)246 dispx(addr, desc, class, type, size, subflag, space)
247 u_char class;
248 char *desc; short type; ADDR addr; {
249 	int i, sflag;
250 	char *p;
251 	char dlen, dfmt;
252 	long value;
253 	union {
254 		char c[WORDSIZE];
255 		int w;
256 		float f;
257 	} word;
258 	union {
259 		struct{
260 			int w1, w2;
261 		} ww;
262 		double d;
263 	} dbl;
264 
265 	class &= STABMASK;
266 	if (desc[0]  == '\0') desc = typetodesc(type, subflag);
267 	cpstr(odesc, desc);
268 	otype = type;
269 	oclass = class;
270 	oaddr = addr;
271 	oincr = 0;
272 	if (debug) printf("dispx(addr=%d,desc=%s,class=%d,type=%d,size=%d,subflg=%d,space=%d)\n",
273 		addr, desc, class, type, size, subflag, space);
274 	pd[0] = '%';
275 	pd[1] = dfmt = 'd';
276 	dlen = '\0';
277 	for (p = desc; *p; p++) {
278 		if (*p>= '0' && *p<'9') {
279 			size = readint(&p);
280 			p--;
281 		} else switch (*p) {
282 			case 'l':
283 			case 'h':
284 			case 'b':
285 				dlen = *p;
286 				break;
287 
288 			case 'a':
289 			case 'c':
290 			case 'd':
291 			case 'f':
292 			case 'g':
293 			case 'i':
294 			case 'I':
295 			case 'o':
296 			case 'p':
297 			case 's':
298 			case 'u':
299 			case 'x':
300 				pd[1] = dfmt = *p;
301 				break;
302 
303 			default:
304 				printf("Illegal descriptor: %c\n", *p);
305 				return(1);
306 		}
307 	}
308 
309 	if (type == -1)
310 		value = addr;
311 	else if (class == N_RSYM && addr < 16) {
312 		/* MACHINE DEPENDENT */
313 		if ((addr > 0 && addr < 6) || addr > 11) {
314 			printf("Bad register var %d\n", addr);
315 			return(-1);
316 		}
317 		value = *(ADDR *)(((ADDR) &u) + R0 + (WORDSIZE)*addr);
318 	}
319 	else {
320 		value = getval(addr, dfmt == 'g' ? 'd' : dfmt, space);
321 	}
322 
323 	if (errflg) {
324 		printf("%s", errflg);
325 		errflg = 0;
326 		return(-1);
327 	}
328 
329 	switch (dfmt) {
330 	default:
331 		switch (dfmt) {
332 		case 'u':
333 		case 'x':
334 		case 'o':
335 			switch (dlen) {
336 			case 'h':
337 				value = (unsigned short) value;
338 				oincr = 2;
339 				break;
340 			case 'b':
341 				value = (unsigned char) value;
342 				oincr = 1;
343 				break;
344 			case 'l':
345 				value = (unsigned long) value;
346 				oincr = 4;
347 				break;
348 			default:
349 				oincr = WORDSIZE;
350 				break;
351 			}
352 			break;
353 
354 		default:
355 			switch (dlen) {
356 			case 'h':
357 				value = (short) value;
358 				oincr = 2;
359 				break;
360 			case 'b':
361 				value = (char) value;
362 				oincr = 1;
363 				break;
364 			case 'l':
365 				value = (long) value;
366 				oincr = 4;
367 				break;
368 			default:
369 				oincr = WORDSIZE;
370 				break;
371 			}
372 		}
373 		if (dfmt == 'x' && (value > 9 || value < 0))
374 			printf("0x");
375 		else if (dfmt == 'o' && (value > 7 || value < 0))
376 			printf("0");
377 		printf(pd, value);
378 		return(1);
379 
380 	case 'f':
381 		pd[1] = 'g';
382 		word.w = value;
383 		printf(pd, word.f);
384 		return(1);
385 
386 	case 'g':
387 		dbl.ww.w1 = value;
388 		dbl.ww.w2 = (class == N_RSYM) ?
389 			*(ADDR *)(((ADDR) &u)+R0+(WORDSIZE)*(addr+1)) :
390 			getval(addr+WORDSIZE, 'd', space);
391 		printf("%.13g", dbl.d);
392 		return(1);
393 
394 	case 'p':
395 		printf("%s:%d", adrtoprocp(value)->pname,
396 			adrtolineno(value));
397 		return(1);
398 
399 	case 's':
400 		addr = getindir(class, addr, type);
401 		goto aa;
402 
403 	case 'c':
404 		if (size <= 1) {
405 			oincr = 1;
406 			printchar(value);
407 			return(1);
408 		} else
409 			goto aa;
410 
411 	case 'a':
412 	aa:	sflag = size == 0;
413 		if (sflag)
414 			size = 128;  /* maximum length for s and a */
415 		else
416 			oincr = size;
417 		for (;;) {
418 			word.w = getval(addr, 'd', space);
419 			for (i=0; i<WORDSIZE; i++) {
420 				if (sflag && word.c[i] == 0)
421 					return(1);
422 				if (size-- == 0)
423 					return(1);
424 				printchar(word.c[i]);
425 			}
426 			addr += WORDSIZE;
427 		}
428 		break;
429 
430 	case 'i':
431 	case 'I':
432 		value = chkget(dot, space);
433 		if (errflg) {
434 			printf("%s", errflg);
435 			errflg = 0;
436 			return(-1);
437 		}
438 		printins(dfmt, space, value);
439 		break;
440 
441 	}
442 	return(1);
443 }
444 
445 /* print variable as in prvar */
printit(metaflag,prvar,addr,desc,class,type,size,subflag,space)446 printit(metaflag, prvar, addr, desc, class, type, size, subflag, space)
447 u_char class;
448 char *desc; short type; ADDR addr; {
449 	if (prvar == 0)
450 		return;
451 	if (metaflag) {
452 		if (prvar == 1)
453 			printf("/ ");
454 		else
455 			printf("= ");
456 	}
457 	if (prvar == 1)
458 		dispf(addr, desc, class, type, size,
459 			subflag, space);
460 	else
461 		dispf(addr, desc, 0, -1, 0, 0, DSP);
462 }
463 
printchar(c)464 printchar(c) {
465 	if ((c & 0177) < ' ')
466 		printf("^%c", c + ('A' - 1));
467 	else if ((c & 0177) == 0177)
468 		printf("^?");
469 	else
470 		printf("%c", c);
471 }
472 
473 INT fcor;
printmap(s,amap)474 printmap(s,amap)
475 STRING	s; MAP *amap;
476 {
477 	int file;
478 	file=amap->ufd;
479 	printf("%s\t`%s'\n",s,(file<0 ? "-" : (file==fcor ? corfil : symfil)));
480 	printf("b1 = 0x%-16x",amap->b1);
481 	printf("e1 = 0x%-16x",amap->e1);
482 	printf("f1 = 0x%-x",amap->f1);
483 	printf("\nb2 = 0x%-16x",amap->b2);
484 	printf("e2 = 0x%-16x",amap->e2);
485 	printf("f2 = 0x%-x",amap->f2);
486 	printf("\n");
487 }
488 
489 #define NUMREGS 24	/* number of hardware registers */
490 REGLIST reglist[];
491 
printregs()492 printregs()
493 {
494 	REG REGPTR	p;
495 
496 	for (p=reglist; p < &reglist[NUMREGS/2]; p++) {
497 		printf("%4.4s/  ", p->rname);
498 		prhex12(*(ADDR *)(((ADDR)&u)+p->roffs));
499 		printf("      %4.4s/  ",(p+NUMREGS/2)->rname);
500 		prhex(*(ADDR *)(((ADDR)&u)+(p+NUMREGS/2)->roffs));
501 		printf("\n");
502 	}
503 	printpc();
504 }
505 
printpc()506 printpc()
507 {
508 	dot= *(ADDR *)(((ADDR)&u)+PC);
509 	prisploc();
510 	printins('i',ISP,chkget(dot,ISP));
511 	printf("\n");
512 }
513 
514 /* print register */
515 REGLIST reglist[];
regout(name,prvar,fmt)516 regout(name, prvar, fmt)
517 char *name, *fmt; {
518 	REG REGPTR p;
519 	for (p=reglist; p< &reglist[24]; p++) {
520 		if (eqstr(name, p->rname)) {
521 			printit(0, prvar, *(ADDR *)(((ADDR)&u)+p->roffs),
522 				fmt[0] ? fmt : "d", N_GSYM, -1, 0, 0, DSP);
523 			return(p->roffs);
524 		}
525 	}
526 	error("Unknown register variable");
527 	return(-1);
528 }
529 /* Print symbolic location of dot */
prisploc()530 prisploc() {
531 	struct proct *procp;
532 	int lineno;
533 
534 	printf("0x%x", dot);
535 	procp = adrtoprocp(dot);
536 	if (procp != badproc) {
537 		printf(" (");
538 		prlnoff(procp, dot);
539 		printf("):  \t");
540 	} else
541 		printf(":  \t");
542 }
543