add manual page, cleanup
[unix-history] / usr / src / old / sdb / prvar.c
CommitLineData
28c97a66 1static char sccsid[] = "@(#)prvar.c 4.3 %G%";
e7d8a5d2
BJ
2#include "head.h"
3#include <a.out.h>
4#include <stab.h>
5#include "cdefs.h"
6struct user u;
7BKPTR bkpthead;
8STRING 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 */
27outvar(proc, var, fmt, metaflag, addr, class, subflag, prnamep,
28 comblk, prvar)
28c97a66 29ADDR addr; char *proc, *var, *fmt, *prnamep, *comblk; u_char class; {
e7d8a5d2
BJ
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);
171l:; }
172}
173
174/* Output external variables. Arguments as in outvar() */
175extoutvar(var, fmt, metaflag, prvar)
176char *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
201prdebug() {
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 */
227dispf(addr, desc, class, type, size, subflag, space)
28c97a66 228u_char class;
e7d8a5d2
BJ
229char *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 */
236dispi(addr, desc, class, type, size, subflag, space)
28c97a66 237u_char class;
e7d8a5d2
BJ
238char *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
245char pd[3];
246dispx(addr, desc, class, type, size, subflag, space)
28c97a66 247u_char class;
e7d8a5d2
BJ
248char *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;
28c97a66 388 dbl.ww.w2 = (class == N_RSYM) ?
e7d8a5d2
BJ
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 */
446printit(metaflag, prvar, addr, desc, class, type, size, subflag, space)
28c97a66 447u_char class;
e7d8a5d2
BJ
448char *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
464printchar(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
473INT fcor;
474printmap(s,amap)
475STRING 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 */
490REGLIST reglist[];
491
492printregs()
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
506printpc()
507{
508 dot= *(ADDR *)(((ADDR)&u)+PC);
509 prisploc();
510 printins('i',ISP,chkget(dot,ISP));
511 printf("\n");
512}
513
514/* print register */
515REGLIST reglist[];
516regout(name, prvar, fmt)
517char *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 */
530prisploc() {
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}