cont now takes an argument which is the signal that is passed
[unix-history] / usr / src / old / dbx / printsym.c
CommitLineData
6eb0951d
ML
1/* Copyright (c) 1982 Regents of the University of California */
2
b38a9c14 3static char sccsid[] = "@(#)printsym.c 1.3 %G%";
6eb0951d
ML
4
5/*
6 * Printing of symbolic information.
7 */
8
9#include "defs.h"
10#include "symbols.h"
11#include "languages.h"
12#include "printsym.h"
13#include "tree.h"
14#include "eval.h"
15#include "mappings.h"
16#include "process.h"
17#include "runtime.h"
18#include "machine.h"
19#include "names.h"
20#include "main.h"
21
22#ifndef public
23#endif
24
b38a9c14
ML
25/*
26 * Maximum number of arguments to a function.
27 * This is used as a check for the possibility that the stack has been
28 * overwritten and therefore a saved argument pointer might indicate
29 * to an absurdly large number of arguments.
30 */
31
32#define MAXARGSPASSED 20
33
6eb0951d
ML
34/*
35 * Return a pointer to the string for the name of the class that
36 * the given symbol belongs to.
37 */
38
39private String clname[] = {
40 "bad use", "constant", "type", "variable", "array", "fileptr",
41 "record", "field", "procedure", "function", "funcvar",
42 "ref", "pointer", "file", "set", "range", "label", "withptr",
43 "scalar", "string", "program", "improper", "variant",
44 "procparam", "funcparam", "module", "typeref", "tag"
45};
46
47public String classname(s)
48Symbol s;
49{
50 return clname[ord(s->class)];
51}
52
53/*
54 * Note the entry of the given block, unless it's the main program.
55 */
56
57public printentry(s)
58Symbol s;
59{
60 if (s != program) {
61 printf("\nentering %s %s\n", classname(s), symname(s));
62 }
63}
64
65/*
66 * Note the exit of the given block
67 */
68
69public printexit(s)
70Symbol s;
71{
72 if (s != program) {
73 printf("leaving %s %s\n\n", classname(s), symname(s));
74 }
75}
76
77/*
78 * Note the call of s from t.
79 */
80
81public printcall(s, t)
82Symbol s, t;
83{
84 printf("calling %s", symname(s));
85 printparams(s, nil);
86 printf(" from %s %s\n", classname(t), symname(t));
87}
88
89/*
90 * Note the return from s. If s is a function, print the value
91 * it is returning. This is somewhat painful, since the function
92 * has actually just returned.
93 */
94
95public printrtn(s)
96Symbol s;
97{
98 register Symbol t;
99 register int len;
100 Boolean isindirect;
101
102 printf("returning ");
103 if (s->class == FUNC) {
104 len = size(s->type);
105 if (canpush(len)) {
106 t = rtype(s->type);
107 isindirect = (Boolean) (t->class == RECORD or t->class == VARNT);
108 pushretval(len, isindirect);
109 printval(s->type);
110 putchar(' ');
111 } else {
112 printf("(value too large) ");
113 }
114 }
115 printf("from %s\n", symname(s));
116}
117
118/*
119 * Print the values of the parameters of the given procedure or function.
120 * The frame distinguishes recursive instances of a procedure.
121 */
122
123public printparams(f, frame)
124Symbol f;
125Frame frame;
126{
127 Symbol param;
128 int n, m, s;
129
130 n = nargspassed(frame);
131 param = f->chain;
132 if (param != nil or n > 0) {
133 printf("(");
134 m = n;
135 if (param != nil) {
136 for (;;) {
137 s = size(param) div sizeof(Word);
138 if (s == 0) {
139 s = 1;
140 }
141 m -= s;
142 printv(param, frame);
143 param = param->chain;
144 if (param == nil) break;
145 printf(", ");
146 }
147 }
148 if (m > 0) {
b38a9c14
ML
149 if (m > MAXARGSPASSED) {
150 m = MAXARGSPASSED;
151 }
6eb0951d
ML
152 if (f->chain != nil) {
153 printf(", ");
154 }
155 for (;;) {
156 --m;
157 printf("0x%x", argn(n - m, frame));
158 if (m <= 0) break;
159 printf(", ");
160 }
161 }
162 printf(")");
163 }
164}
165
166/*
167 * Test if a symbol should be printed. We don't print files,
168 * for example, simply because there's no good way to do it.
169 * The symbol must be within the given function.
170 */
171
172public Boolean should_print(s)
173Symbol s;
174{
175 Boolean b;
176 register Symbol t;
177
178 switch (s->class) {
179 case VAR:
180 case FVAR:
181 t = rtype(s->type);
182 b = (Boolean) (
183 not isparam(s) and
184 t != nil and t->class != FILET and t->class != SET
185 );
186 break;
187
188 default:
189 b = false;
190 break;
191 }
192 return b;
193}
194
195/*
196 * Print the name and value of a variable.
197 */
198
199public printv(s, frame)
200Symbol s;
201Frame frame;
202{
203 Address addr;
204 int len;
205
206 if (isambiguous(s) and ismodule(container(s))) {
207 printname(stdout, s);
208 printf(" = ");
209 } else {
210 printf("%s = ", symname(s));
211 }
212 if (isvarparam(s)) {
213 rpush(address(s, frame), sizeof(Address));
214 addr = pop(Address);
215 len = size(s->type);
216 } else {
217 addr = address(s, frame);
218 len = size(s);
219 }
220 if (canpush(len)) {
221 rpush(addr, len);
222 printval(s->type);
223 } else {
224 printf("*** expression too large ***");
225 }
226}
227
228/*
229 * Print out the name of a symbol.
230 */
231
232public printname(f, s)
233File f;
234Symbol s;
235{
236 if (s == nil) {
237 fprintf(f, "(noname)");
238 } else if (isredirected() or isambiguous(s)) {
239 printwhich(f, s);
240 } else {
241 fprintf(f, "%s", symname(s));
242 }
243}
244
245/*
246 * Print the fully specified variable that is described by the given identifer.
247 */
248
249public printwhich(f, s)
250File f;
251Symbol s;
252{
253 printouter(f, container(s));
254 fprintf(f, "%s", symname(s));
255}
256
257/*
258 * Print the fully qualified name of each symbol that has the same name
259 * as the given symbol.
260 */
261
262public printwhereis(f, s)
263File f;
264Symbol s;
265{
266 register Name n;
267 register Symbol t;
268
269 checkref(s);
270 n = s->name;
271 t = lookup(n);
272 printwhich(f, t);
273 t = t->next_sym;
274 while (t != nil) {
275 if (t->name == n) {
276 putc(' ', f);
277 printwhich(f, t);
278 }
279 t = t->next_sym;
280 }
281 putc('\n', f);
282}
283
284private printouter(f, s)
285File f;
286Symbol s;
287{
288 Symbol outer;
289
290 if (s != nil) {
291 outer = container(s);
292 if (outer != nil and outer != program) {
293 printouter(f, outer);
294 }
295 fprintf(f, "%s.", symname(s));
296 }
297}
298
299public printdecl(s)
300Symbol s;
301{
302 checkref(s);
303 (*language_op(s->language, L_PRINTDECL))(s);
304}
305
306/*
307 * Straight dump of symbol information.
308 */
309
310public psym(s)
311Symbol s;
312{
313 printf("name\t%s\n", symname(s));
314 printf("lang\t%s\n", language_name(s->language));
315 printf("level\t%d\n", s->level);
316 printf("class\t%s\n", classname(s));
317 printf("type\t0x%x", s->type);
318 if (s->type != nil and s->type->name != nil) {
319 printf(" (%s)", symname(s->type));
320 }
321 printf("\nchain\t0x%x", s->chain);
322 if (s->chain != nil and s->chain->name != nil) {
323 printf(" (%s)", symname(s->chain));
324 }
325 printf("\nblock\t0x%x", s->block);
326 if (s->block->name != nil) {
327 printf(" (");
328 printname(stdout, s->block);
329 putchar(')');
330 }
331 putchar('\n');
332 switch (s->class) {
333 case VAR:
334 case REF:
335 if (s->level >= 3) {
336 printf("address\t0x%x\n", s->symvalue.offset);
337 } else {
338 printf("offset\t%d\n", s->symvalue.offset);
339 }
340 break;
341
342 case RECORD:
343 case VARNT:
344 printf("size\t%d\n", s->symvalue.offset);
345 break;
346
347 case FIELD:
348 printf("offset\t%d\n", s->symvalue.field.offset);
349 printf("size\t%d\n", s->symvalue.field.length);
350 break;
351
352 case PROC:
353 case FUNC:
354 printf("address\t0x%x\n", s->symvalue.funcv.beginaddr);
b38a9c14
ML
355 if (nosource(s)) {
356 printf("does not have source information\n");
357 } else {
358 printf("has source information\n");
359 }
6eb0951d
ML
360 break;
361
362 case RANGE:
363 printf("lower\t%d\n", s->symvalue.rangev.lower);
364 printf("upper\t%d\n", s->symvalue.rangev.upper);
365 break;
366
367 default:
368 /* do nothing */
369 break;
370 }
371}
372
373/*
374 * Print out the value on top of the stack according to the given type.
375 */
376
377public printval(t)
378Symbol t;
379{
380 Symbol s;
381
382 checkref(t);
383 switch (t->class) {
384 case PROC:
385 case FUNC:
386 s = pop(Symbol);
387 printf("%s", symname(s));
388 break;
389
390 default:
391 if (t->language == nil) {
392 error("unknown language");
393 } else {
394 (*language_op(t->language, L_PRINTVAL))(t);
395 }
396 break;
397 }
398}
399
400/*
401 * Print out the value of a record, field by field.
402 */
403
404public printrecord(s)
405Symbol s;
406{
407 if (s->chain == nil) {
408 error("record has no fields");
409 }
410 printf("(");
411 sp -= size(s);
412 printfield(s->chain);
413 printf(")");
414}
415
416/*
417 * Print out a field, first printing out other fields.
418 * This is done because the fields are chained together backwards.
419 */
420
421private printfield(s)
422Symbol s;
423{
424 Stack *savesp;
425
426 if (s->chain != nil) {
427 printfield(s->chain);
428 printf(", ");
429 }
430 printf("%s = ", symname(s));
431 savesp = sp;
432 sp += ((s->symvalue.field.offset div BITSPERBYTE) + size(s->type));
433 printval(s);
434 sp = savesp;
435}
436
437/*
438 * Print out the contents of an array.
439 * Haven't quite figured out what the best format is.
440 *
441 * This is rather inefficient.
442 *
443 * The "2*elsize" is there since "printval" drops the stack by elsize.
444 */
445
446public printarray(a)
447Symbol a;
448{
449 Stack *savesp, *newsp;
450 Symbol eltype;
451 long elsize;
452 String sep;
453
454 savesp = sp;
455 sp -= size(a);
456 newsp = sp;
457 eltype = rtype(a->type);
458 elsize = size(eltype);
459 printf("(");
460 if (eltype->class == RECORD or eltype->class == ARRAY or
461 eltype->class == VARNT) {
462 sep = "\n";
463 putchar('\n');
464 } else {
465 sep = ", ";
466 }
467 for (sp += elsize; sp <= savesp; sp += 2*elsize) {
468 if (sp - elsize != newsp) {
469 fputs(sep, stdout);
470 }
471 printval(eltype);
472 }
473 sp = newsp;
474 if (streq(sep, "\n")) {
475 putchar('\n');
476 }
477 printf(")");
478}
479
480/*
481 * Print out the value of a real number in Pascal notation.
482 * This is, unfortunately, different than what one gets
483 * from "%g" in printf.
484 */
485
486public prtreal(r)
487double r;
488{
489 extern char *index();
490 char buf[256];
491
492 sprintf(buf, "%g", r);
493 if (buf[0] == '.') {
494 printf("0%s", buf);
495 } else if (buf[0] == '-' and buf[1] == '.') {
496 printf("-0%s", &buf[1]);
497 } else {
498 printf("%s", buf);
499 }
500 if (index(buf, '.') == nil) {
501 printf(".0");
502 }
503}
504
505/*
506 * Print out a character using ^? notation for unprintables.
507 */
508
509public printchar(c)
510char c;
511{
512 if (c == 0) {
513 putchar('\\');
514 putchar('0');
515 } else if (c == '\n') {
516 putchar('\\');
517 putchar('n');
518 } else if (c > 0 and c < ' ') {
519 putchar('^');
520 putchar(c - 1 + 'A');
521 } else {
522 putchar(c);
523 }
524}