BSD 4 development
[unix-history] / .ref-5cb41021d721f4e0ac572d592613f963e495d1ff / usr / src / old / sdb / prvar.c
CommitLineData
e7d8a5d2
BJ
1static char sccsid[] = "@(#)prvar.c 4.1 %G%";
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)
29ADDR addr; char *proc, *var, *fmt, class, *prnamep, *comblk; {
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)
228char *desc; short type; ADDR addr; {
229 dispx(addr, desc, class, type, size, subflag, DSP);
230 printf("\n");
231}
232
233/* display addr in instruction space using format desc or class s */
234/* returns -1 if bad address */
235dispi(addr, desc, class, type, size, subflag, space)
236char *desc; short type; ADDR addr; {
237 register i;
238 i = dispx(addr, desc, class, type, size, subflag, ISP);
239 printf("\n");
240 return(i);
241}
242
243char pd[3];
244dispx(addr, desc, class, type, size, subflag, space)
245char *desc; short type; ADDR addr; {
246 int i, sflag;
247 char *p;
248 char dlen, dfmt;
249 long value;
250 union {
251 char c[WORDSIZE];
252 int w;
253 float f;
254 } word;
255 union {
256 struct{
257 int w1, w2;
258 } ww;
259 double d;
260 } dbl;
261
262 class &= STABMASK;
263 if (desc[0] == '\0') desc = typetodesc(type, subflag);
264 cpstr(odesc, desc);
265 otype = type;
266 oclass = class;
267 oaddr = addr;
268 oincr = 0;
269 if (debug) printf("dispx(addr=%d,desc=%s,class=%d,type=%d,size=%d,subflg=%d,space=%d)\n",
270 addr, desc, class, type, size, subflag, space);
271 pd[0] = '%';
272 pd[1] = dfmt = 'd';
273 dlen = '\0';
274 for (p = desc; *p; p++) {
275 if (*p>= '0' && *p<'9') {
276 size = readint(&p);
277 p--;
278 } else switch (*p) {
279 case 'l':
280 case 'h':
281 case 'b':
282 dlen = *p;
283 break;
284
285 case 'a':
286 case 'c':
287 case 'd':
288 case 'f':
289 case 'g':
290 case 'i':
291 case 'I':
292 case 'o':
293 case 'p':
294 case 's':
295 case 'u':
296 case 'x':
297 pd[1] = dfmt = *p;
298 break;
299
300 default:
301 printf("Illegal descriptor: %c\n", *p);
302 return(1);
303 }
304 }
305
306 if (type == -1)
307 value = addr;
308 else if (class == N_RSYM && addr < 16) {
309 /* MACHINE DEPENDENT */
310 if ((addr > 0 && addr < 6) || addr > 11) {
311 printf("Bad register var %d\n", addr);
312 return(-1);
313 }
314 value = *(ADDR *)(((ADDR) &u) + R0 + (WORDSIZE)*addr);
315 }
316 else {
317 value = getval(addr, dfmt == 'g' ? 'd' : dfmt, space);
318 }
319
320 if (errflg) {
321 printf("%s", errflg);
322 errflg = 0;
323 return(-1);
324 }
325
326 switch (dfmt) {
327 default:
328 switch (dfmt) {
329 case 'u':
330 case 'x':
331 case 'o':
332 switch (dlen) {
333 case 'h':
334 value = (unsigned short) value;
335 oincr = 2;
336 break;
337 case 'b':
338 value = (unsigned char) value;
339 oincr = 1;
340 break;
341 case 'l':
342 value = (unsigned long) value;
343 oincr = 4;
344 break;
345 default:
346 oincr = WORDSIZE;
347 break;
348 }
349 break;
350
351 default:
352 switch (dlen) {
353 case 'h':
354 value = (short) value;
355 oincr = 2;
356 break;
357 case 'b':
358 value = (char) value;
359 oincr = 1;
360 break;
361 case 'l':
362 value = (long) value;
363 oincr = 4;
364 break;
365 default:
366 oincr = WORDSIZE;
367 break;
368 }
369 }
370 if (dfmt == 'x' && (value > 9 || value < 0))
371 printf("0x");
372 else if (dfmt == 'o' && (value > 7 || value < 0))
373 printf("0");
374 printf(pd, value);
375 return(1);
376
377 case 'f':
378 pd[1] = 'g';
379 word.w = value;
380 printf(pd, word.f);
381 return(1);
382
383 case 'g':
384 dbl.ww.w1 = value;
385 dbl.ww.w2 = (class == (char) N_RSYM) ?
386 *(ADDR *)(((ADDR) &u)+R0+(WORDSIZE)*(addr+1)) :
387 getval(addr+WORDSIZE, 'd', space);
388 printf("%.13g", dbl.d);
389 return(1);
390
391 case 'p':
392 printf("%s:%d", adrtoprocp(value)->pname,
393 adrtolineno(value));
394 return(1);
395
396 case 's':
397 addr = getindir(class, addr, type);
398 goto aa;
399
400 case 'c':
401 if (size <= 1) {
402 oincr = 1;
403 printchar(value);
404 return(1);
405 } else
406 goto aa;
407
408 case 'a':
409 aa: sflag = size == 0;
410 if (sflag)
411 size = 128; /* maximum length for s and a */
412 else
413 oincr = size;
414 for (;;) {
415 word.w = getval(addr, 'd', space);
416 for (i=0; i<WORDSIZE; i++) {
417 if (sflag && word.c[i] == 0)
418 return(1);
419 if (size-- == 0)
420 return(1);
421 printchar(word.c[i]);
422 }
423 addr += WORDSIZE;
424 }
425 break;
426
427 case 'i':
428 case 'I':
429 value = chkget(dot, space);
430 if (errflg) {
431 printf("%s", errflg);
432 errflg = 0;
433 return(-1);
434 }
435 printins(dfmt, space, value);
436 break;
437
438 }
439 return(1);
440}
441
442/* print variable as in prvar */
443printit(metaflag, prvar, addr, desc, class, type, size, subflag, space)
444char *desc; short type; ADDR addr; {
445 if (prvar == 0)
446 return;
447 if (metaflag) {
448 if (prvar == 1)
449 printf("/ ");
450 else
451 printf("= ");
452 }
453 if (prvar == 1)
454 dispf(addr, desc, class, type, size,
455 subflag, space);
456 else
457 dispf(addr, desc, 0, -1, 0, 0, DSP);
458}
459
460printchar(c) {
461 if ((c & 0177) < ' ')
462 printf("^%c", c + ('A' - 1));
463 else if ((c & 0177) == 0177)
464 printf("^?");
465 else
466 printf("%c", c);
467}
468
469INT fcor;
470printmap(s,amap)
471STRING s; MAP *amap;
472{
473 int file;
474 file=amap->ufd;
475 printf("%s\t`%s'\n",s,(file<0 ? "-" : (file==fcor ? corfil : symfil)));
476 printf("b1 = 0x%-16x",amap->b1);
477 printf("e1 = 0x%-16x",amap->e1);
478 printf("f1 = 0x%-x",amap->f1);
479 printf("\nb2 = 0x%-16x",amap->b2);
480 printf("e2 = 0x%-16x",amap->e2);
481 printf("f2 = 0x%-x",amap->f2);
482 printf("\n");
483}
484
485#define NUMREGS 24 /* number of hardware registers */
486REGLIST reglist[];
487
488printregs()
489{
490 REG REGPTR p;
491
492 for (p=reglist; p < &reglist[NUMREGS/2]; p++) {
493 printf("%4.4s/ ", p->rname);
494 prhex12(*(ADDR *)(((ADDR)&u)+p->roffs));
495 printf(" %4.4s/ ",(p+NUMREGS/2)->rname);
496 prhex(*(ADDR *)(((ADDR)&u)+(p+NUMREGS/2)->roffs));
497 printf("\n");
498 }
499 printpc();
500}
501
502printpc()
503{
504 dot= *(ADDR *)(((ADDR)&u)+PC);
505 prisploc();
506 printins('i',ISP,chkget(dot,ISP));
507 printf("\n");
508}
509
510/* print register */
511REGLIST reglist[];
512regout(name, prvar, fmt)
513char *name, *fmt; {
514 REG REGPTR p;
515 for (p=reglist; p< &reglist[24]; p++) {
516 if (eqstr(name, p->rname)) {
517 printit(0, prvar, *(ADDR *)(((ADDR)&u)+p->roffs),
518 fmt[0] ? fmt : "d", N_GSYM, -1, 0, 0, DSP);
519 return(p->roffs);
520 }
521 }
522 error("Unknown register variable");
523 return(-1);
524}
525/* Print symbolic location of dot */
526prisploc() {
527 struct proct *procp;
528 int lineno;
529
530 printf("0x%x", dot);
531 procp = adrtoprocp(dot);
532 if (procp != badproc) {
533 printf(" (");
534 prlnoff(procp, dot);
535 printf("): \t");
536 } else
537 printf(": \t");
538}