BSD 3 development
[unix-history] / usr / src / cmd / sdb / prvar.c
CommitLineData
780dc7a7
HK
1#include "head.h"
2#include <a.out.h>
3#include "cdefs.h"
4struct user u;
5BKPTR bkpthead;
6STRING errflg;
7
8/*
9 * outvar():
10 * Prints named variable, recursing once for each structure member or
11 * subscript.
12 * proc:var: variable name
13 * fmt: print format
14 * metaflag: set iff var contains metacharacters * or ?
15 * addr: partial address of variable, initally 0
16 * class: type class of variable
17 * subflag: number of levels of subscript indirection
18 * prnamep: pointer to end of partially formed print name of variable
19 * comblk: name of common block containing variable, if any
20 * prflag: as in findvar
21 *
22 * Here and elsewhere we assume that -1 is an invalid address, and
23 * its is used to indicate error.
24 */
25outvar(proc, var, fmt, metaflag, addr, class, subflag, prnamep, comblk, prflag)
26ADDR addr; char *proc, *var, *fmt, class, *prnamep, *comblk; {
27 char *p, *q, *r, *oldpr;
28 register int match;
29 long soffset, goffset;
30 register ADDR newaddr = -1, arrowaddr;
31 register enum {INIT, ARROW, DOT} typeflag;
32
33 switch (var[0]) {
34 case '\0':
35 if (prflag == 0) return(addr);
36 if (metaflag) {
37 if (comblk[0] && !(eqstr(comblk, "*")))
38 printf("%.8s:%.8s", comblk, prname);
39 else if (proc[0])
40 printf("%.8s:%.8s", proc, prname);
41 else
42 printf("%s", prname);
43 if (prflag == 1)
44 printf("/ ");
45 else
46 printf("= ");
47 }
48 if (prflag == 1)
49 dispf(addr, fmt, class, sl_type, sl_size, subflag);
50 else
51 dispf(addr, fmt, 0, -1, 0, 0);
52 return(addr);
53
54 case '[':
55 *prnamep++ = *var++;
56 p = var;
57 for (;;) {
58 *prnamep++ = *var;
59 if (*var == '\0' || *var == ']') break;
60 var++;
61 }
62 newaddr = getindir(class, addr, sl_type);
63 newaddr += typetosize(sl_type, sl_size) * readint(&p);
64 return(outvar(proc, var+1, fmt, metaflag, newaddr, N_GSYM,
65 subflag+1, prnamep, comblk, prflag));
66
67 case '-':
68 case '>':
69 typeflag = ARROW;
70 while (eqany(*var, "->"))
71 *prnamep++ = *var++;
72 subflag++;
73 arrowaddr = getindir(class, addr, sl_type);
74 if (errflg) {
75 printf("%s\n", errflg);
76 errflg = 0;
77 return(0);
78 }
79 class = N_GSYM;
80 if (var[0] == '\0') {
81 p = var;
82 goto recurse;
83 }
84 break;
85
86 case '.':
87 typeflag = DOT;
88 if (class == N_RSYM) {
89 error("Not with a register variable");
90 return(0);
91 }
92 *prnamep++ = *var++;
93 subflag = 0;
94 break;
95
96 default:
97 typeflag = INIT;
98 break;
99 }
100
101 if (typeflag == INIT) {
102 soffset = proc[0] ? adrtostoffset(callpc-1) : -1;
103 goffset = proc[0] ? -1 : findfile(curfile)->stf_offset;
104 } else {
105 soffset = proc[0] ? adrtostoffset(callpc-1) : -1;
106 goffset = findfile(curfile)->stf_offset;
107 }
108
109 p = var;
110 oldpr = prnamep;
111 while (!eqany(*p, "->.[") && *p != '\0')
112 *prnamep++ = *p++;
113 *prnamep = '\0';
114
115 match = 0;
116 slookinit();
117
118 for (;;) {
119 if (soffset != -1)
120 if ((soffset = slooknext(var, soffset, typeflag!=INIT,
121 comblk)) != -1)
122 goto found;
123 if (goffset != -1)
124 if ((goffset = globallookup(var, goffset,
125 typeflag!=INIT)) != -1)
126 goto found;
127 return(newaddr);
128
129 found:
130 r = sl_name;
131 q = oldpr;
132 while (*r) *q++ = *r++;
133 *q ='\0';
134
135 switch(typeflag) {
136 case INIT:
137 class = sl_class & STABMASK;
138 if (!varclass(class) || class == N_SSYM)
139 goto l;
140 newaddr = (class == N_LSYM) ? -sl_addr : sl_addr;
141 newaddr = formaddr(class, newaddr);
142 break;
143
144 case ARROW:
145 class = sl_class & STABMASK;
146 if (!varclass(class) || class != N_SSYM)
147 goto l;
148 newaddr = arrowaddr + sl_addr;
149 break;
150
151 case DOT:
152 class = sl_class & STABMASK;
153 if (!varclass(class) || class != N_SSYM)
154 goto l;
155 newaddr = addr + sl_addr;
156 break;
157 }
158
159 recurse:
160 newaddr = outvar(proc, p, fmt, metaflag, newaddr,
161 class, subflag, prnamep, comblk, prflag);
162
163 if (!metaflag)
164 return(newaddr);
165l:; }
166}
167
168prdebug() {
169 register struct proct *procp;
170 register struct filet *filep;
171
172 printf("dot=%d\n", dot);
173 printf("extstart = %d\n", extstart);
174 for(filep=files;filep->sfilename[0];filep++)
175 printf("%s offs %d @ %d flag %d addr 0x%x\n", filep->sfilename, filep->stf_offset, filep, filep->lineflag, filep->faddr);
176 for(procp=procs;procp->pname[0];procp++) {
177 printf("%8.8s addr 0x%x; offs %d; sfptr %d; line %d",
178 procp->pname, procp->paddr, procp->st_offset,
179 procp->sfptr, procp->lineno);
180 if (procp->entrypt) printf(" entrypoint");
181 printf("\n");
182 }
183}
184
185/* display addr using format desc or class s */
186dispf(addr, desc, class, type, size, subflag)
187char *desc; short type; ADDR addr; {
188 dispx(addr, desc, class, type, size, subflag);
189 printf("\n");
190}
191
192char pd[] = "%x";
193dispx(addr, desc, class, type, size, subflag)
194char *desc; short type; ADDR addr; {
195 int i, sflag;
196 char *p;
197 char dlen, dfmt;
198 long value;
199 union {
200 struct {
201 char c[WORDSIZE];
202 };
203 struct {
204 int w;
205 };
206 struct {
207 float f;
208 }
209 } word;
210 union {
211 struct{
212 int w1, w2;
213 };
214 struct {
215 double d;
216 };
217 } dbl;
218
219 class &= STABMASK;
220 if (desc[0] == '\0') desc = typetodesc(type, subflag);
221 cpstr(odesc, desc);
222 otype = type;
223 oclass = class;
224 oaddr = addr;
225 oincr = 0;
226 if (debug) printf("dispf(%d,%s,0%o,0%o)\n", addr,desc,class,type);
227 pd[1] = dfmt = 'd';
228 dlen = '\0';
229 for (p = desc; *p; p++) {
230 if (*p>= '0' && *p<'9') {
231 size = readint(&p);
232 p--;
233 } else switch (*p) {
234 case 'l':
235 case 'h':
236 case 'b':
237 dlen = *p;
238 break;
239
240 case 'a':
241 case 'c':
242 case 'd':
243 case 'f':
244 case 'g':
245 case 'o':
246 case 'p':
247 case 's':
248 case 'u':
249 case 'x':
250 pd[1] = dfmt = *p;
251 break;
252
253 default:
254 printf("Illegal descriptor: %c\n", *p);
255 return;
256 }
257 }
258
259 if (type == -1)
260 value = addr;
261 else if (class == N_RSYM && addr < 16) {
262 /* MACHINE DEPENDENT */
263 if ((addr > 0 && addr < 6) || addr > 11) {
264 printf("Bad register var %d\n", addr);
265 return;
266 }
267 value = *(ADDR *)(((ADDR) &u) + R0 + (WORDSIZE)*addr);
268 }
269 else {
270 value = getval(addr, dfmt == 'g' ? 'd' : dfmt);
271 }
272
273 if (errflg) {
274 printf("%s", errflg);
275 errflg = 0;
276 return;
277 }
278
279 switch (dfmt) {
280 default:
281 switch (dfmt) {
282 case 'u':
283 case 'x':
284 case 'o':
285 switch (dlen) {
286 case 'h':
287 value = (unsigned short) value;
288 oincr = 2;
289 break;
290 case 'b':
291 value = (unsigned char) value;
292 oincr = 1;
293 break;
294 case 'l':
295 value = (unsigned long) value;
296 oincr = 4;
297 break;
298 }
299 break;
300
301 default:
302 switch (dlen) {
303 case 'h':
304 value = (short) value;
305 oincr = 2;
306 break;
307 case 'b':
308 value = (char) value;
309 oincr = 1;
310 break;
311 case 'l':
312 value = (long) value;
313 oincr = 4;
314 break;
315 }
316 }
317 if (value > 0) {
318 if (value > 9 && dfmt == 'x')
319 printf("0x");
320 else if (value > 7 && dfmt == 'o')
321 printf("0");
322 }
323 printf(pd, value);
324 return;
325
326 case 'f':
327 pd[1] = 'g';
328 word.w = value;
329 printf(pd, word.f);
330 return;
331
332 case 'g':
333 dbl.w1 = value;
334 dbl.w2 = (class == (char) N_RSYM) ?
335 *(ADDR *)(((ADDR) &u)+R0+(WORDSIZE)*(addr+1)) :
336 getval(addr+WORDSIZE, 'd');
337 printf("%.13g", dbl.d);
338 return;
339
340 case 'p':
341 printf("%s:%d", adrtoprocp(value)->pname,
342 adrtolineno(value));
343 return;
344
345 case 's':
346 addr = getindir(class, addr, type);
347 goto aa;
348
349 case 'c':
350 if (size <= 1) {
351 oincr = 1;
352 printchar(value);
353 return;
354 } else
355 goto aa;
356
357 case 'a':
358 aa: sflag = size == 0;
359 if (sflag)
360 size = 128; /* maximum length for s and a */
361 else
362 oincr = size;
363 for (;;) {
364 word.w = getval(addr, 'd');
365 for (i=0; i<WORDSIZE; i++) {
366 if (sflag && word.c[i] == 0)
367 return;
368 if (size-- == 0)
369 return;
370 printchar(word.c[i]);
371 }
372 addr += WORDSIZE;
373 }
374
375 }
376}
377
378printchar(c) {
379 if ((c & 0177) < ' ')
380 printf("^%c", c + ('A' - 1));
381 else if ((c & 0177) == 0177)
382 printf("^?");
383 else
384 printf("%c", c);
385}
386