xref: /csrg-svn/old/dbx/printsym.c (revision 16616)
19676Slinton /* Copyright (c) 1982 Regents of the University of California */
29676Slinton 
3*16616Ssam static char sccsid[] = "@(#)printsym.c 1.12 8/10/83";
49676Slinton 
5*16616Ssam static char rcsid[] = "$Header: printsym.c,v 1.3 84/03/27 10:23:14 linton Exp $";
6*16616Ssam 
79676Slinton /*
89676Slinton  * Printing of symbolic information.
99676Slinton  */
109676Slinton 
119676Slinton #include "defs.h"
129676Slinton #include "symbols.h"
139676Slinton #include "languages.h"
149676Slinton #include "printsym.h"
159676Slinton #include "tree.h"
169676Slinton #include "eval.h"
179676Slinton #include "mappings.h"
189676Slinton #include "process.h"
199676Slinton #include "runtime.h"
209676Slinton #include "machine.h"
219676Slinton #include "names.h"
229676Slinton #include "main.h"
239676Slinton 
249676Slinton #ifndef public
259676Slinton #endif
269676Slinton 
279676Slinton /*
2811863Slinton  * Maximum number of arguments to a function.
2911863Slinton  * This is used as a check for the possibility that the stack has been
3011863Slinton  * overwritten and therefore a saved argument pointer might indicate
3111863Slinton  * to an absurdly large number of arguments.
3211863Slinton  */
3311863Slinton 
3411863Slinton #define MAXARGSPASSED 20
3511863Slinton 
3611863Slinton /*
379676Slinton  * Return a pointer to the string for the name of the class that
389676Slinton  * the given symbol belongs to.
399676Slinton  */
409676Slinton 
419676Slinton private String clname[] = {
429676Slinton     "bad use", "constant", "type", "variable", "array", "fileptr",
439676Slinton     "record", "field", "procedure", "function", "funcvar",
449676Slinton     "ref", "pointer", "file", "set", "range", "label", "withptr",
459676Slinton     "scalar", "string", "program", "improper", "variant",
46*16616Ssam     "procparam", "funcparam", "module", "tag", "common", "extref", "typeref"
479676Slinton };
489676Slinton 
499676Slinton public String classname(s)
509676Slinton Symbol s;
519676Slinton {
529676Slinton     return clname[ord(s->class)];
539676Slinton }
549676Slinton 
559676Slinton /*
569676Slinton  * Note the entry of the given block, unless it's the main program.
579676Slinton  */
589676Slinton 
599676Slinton public printentry(s)
609676Slinton Symbol s;
619676Slinton {
629676Slinton     if (s != program) {
639676Slinton 	printf("\nentering %s %s\n", classname(s), symname(s));
649676Slinton     }
659676Slinton }
669676Slinton 
679676Slinton /*
689676Slinton  * Note the exit of the given block
699676Slinton  */
709676Slinton 
719676Slinton public printexit(s)
729676Slinton Symbol s;
739676Slinton {
749676Slinton     if (s != program) {
759676Slinton 	printf("leaving %s %s\n\n", classname(s), symname(s));
769676Slinton     }
779676Slinton }
789676Slinton 
799676Slinton /*
809676Slinton  * Note the call of s from t.
819676Slinton  */
829676Slinton 
839676Slinton public printcall(s, t)
849676Slinton Symbol s, t;
859676Slinton {
869676Slinton     printf("calling %s", symname(s));
879676Slinton     printparams(s, nil);
889676Slinton     printf(" from %s %s\n", classname(t), symname(t));
899676Slinton }
909676Slinton 
919676Slinton /*
929676Slinton  * Note the return from s.  If s is a function, print the value
939676Slinton  * it is returning.  This is somewhat painful, since the function
949676Slinton  * has actually just returned.
959676Slinton  */
969676Slinton 
979676Slinton public printrtn(s)
989676Slinton Symbol s;
999676Slinton {
1009676Slinton     register Symbol t;
1019676Slinton     register int len;
1029676Slinton     Boolean isindirect;
1039676Slinton 
1049676Slinton     printf("returning ");
10512628Scsvaf     if (s->class == FUNC && (!istypename(s->type,"void"))) {
1069676Slinton 	len = size(s->type);
1079676Slinton 	if (canpush(len)) {
1089676Slinton 	    t = rtype(s->type);
1099676Slinton 	    isindirect = (Boolean) (t->class == RECORD or t->class == VARNT);
1109676Slinton 	    pushretval(len, isindirect);
1119676Slinton 	    printval(s->type);
1129676Slinton 	    putchar(' ');
1139676Slinton 	} else {
1149676Slinton 	    printf("(value too large) ");
1159676Slinton 	}
1169676Slinton     }
1179676Slinton     printf("from %s\n", symname(s));
1189676Slinton }
1199676Slinton 
1209676Slinton /*
1219676Slinton  * Print the values of the parameters of the given procedure or function.
1229676Slinton  * The frame distinguishes recursive instances of a procedure.
123*16616Ssam  *
124*16616Ssam  * If the procedure or function is internal, the argument count is
125*16616Ssam  * not valid so we ignore it.
1269676Slinton  */
1279676Slinton 
1289676Slinton public printparams(f, frame)
1299676Slinton Symbol f;
1309676Slinton Frame frame;
1319676Slinton {
1329676Slinton     Symbol param;
1339676Slinton     int n, m, s;
1349676Slinton 
1359676Slinton     n = nargspassed(frame);
136*16616Ssam     if (isinternal(f)) {
137*16616Ssam 	n = 0;
138*16616Ssam     }
1399676Slinton     param = f->chain;
1409676Slinton     if (param != nil or n > 0) {
1419676Slinton 	printf("(");
1429676Slinton 	m = n;
1439676Slinton 	if (param != nil) {
1449676Slinton 	    for (;;) {
1459676Slinton 		s = size(param) div sizeof(Word);
1469676Slinton 		if (s == 0) {
1479676Slinton 		    s = 1;
1489676Slinton 		}
1499676Slinton 		m -= s;
1509676Slinton 		printv(param, frame);
1519676Slinton 		param = param->chain;
1529676Slinton 	    if (param == nil) break;
1539676Slinton 		printf(", ");
1549676Slinton 	    }
1559676Slinton 	}
1569676Slinton 	if (m > 0) {
15711863Slinton 	    if (m > MAXARGSPASSED) {
15811863Slinton 		m = MAXARGSPASSED;
15911863Slinton 	    }
1609676Slinton 	    if (f->chain != nil) {
1619676Slinton 		printf(", ");
1629676Slinton 	    }
1639676Slinton 	    for (;;) {
1649676Slinton 		--m;
1659676Slinton 		printf("0x%x", argn(n - m, frame));
1669676Slinton 	    if (m <= 0) break;
1679676Slinton 		printf(", ");
1689676Slinton 	    }
1699676Slinton 	}
1709676Slinton 	printf(")");
1719676Slinton     }
1729676Slinton }
1739676Slinton 
1749676Slinton /*
1759676Slinton  * Test if a symbol should be printed.  We don't print files,
1769676Slinton  * for example, simply because there's no good way to do it.
1779676Slinton  * The symbol must be within the given function.
1789676Slinton  */
1799676Slinton 
1809676Slinton public Boolean should_print(s)
1819676Slinton Symbol s;
1829676Slinton {
1839676Slinton     Boolean b;
1849676Slinton     register Symbol t;
1859676Slinton 
1869676Slinton     switch (s->class) {
1879676Slinton 	case VAR:
1889676Slinton 	case FVAR:
18914339Slinton 	    if (isparam(s)) {
19014339Slinton 		b = false;
19114339Slinton 	    } else {
19214339Slinton 		t = rtype(s->type);
19314339Slinton 		if (t == nil) {
19414339Slinton 		    b = false;
19514339Slinton 		} else {
19614339Slinton 		    switch (t->class) {
19714339Slinton 			case FILET:
19814339Slinton 			case SET:
19914339Slinton 			case BADUSE:
20014339Slinton 			    b = false;
20114339Slinton 			    break;
20214339Slinton 
20314339Slinton 			default:
20414339Slinton 			    b = true;
20514339Slinton 			    break;
20614339Slinton 		    }
20714339Slinton 		}
20814339Slinton 	    }
2099676Slinton 	    break;
2109676Slinton 
2119676Slinton 	default:
2129676Slinton 	    b = false;
2139676Slinton 	    break;
2149676Slinton     }
2159676Slinton     return b;
2169676Slinton }
2179676Slinton 
2189676Slinton /*
2199676Slinton  * Print the name and value of a variable.
2209676Slinton  */
2219676Slinton 
2229676Slinton public printv(s, frame)
2239676Slinton Symbol s;
2249676Slinton Frame frame;
2259676Slinton {
2269676Slinton     Address addr;
2279676Slinton     int len;
228*16616Ssam     Symbol t;
2299676Slinton 
2309676Slinton     if (isambiguous(s) and ismodule(container(s))) {
2319676Slinton 	printname(stdout, s);
2329676Slinton 	printf(" = ");
2339676Slinton     } else {
2349676Slinton 	printf("%s = ", symname(s));
2359676Slinton     }
236*16616Ssam /*
237*16616Ssam  * Not today.
238*16616Ssam     t = rtype(s->type);
239*16616Ssam     if (t->class == ARRAY and not istypename(t->type, "char")) {
240*16616Ssam 	printf("ARRAY");
2419676Slinton     } else {
242*16616Ssam  */
24312628Scsvaf        if (isvarparam(s)) {
24412628Scsvaf 	   rpush(address(s, frame), sizeof(Address));
24512628Scsvaf 	   addr = pop(Address);
24612628Scsvaf 	   len = size(s->type);
24712628Scsvaf        } else {
24812628Scsvaf 	   addr = address(s, frame);
24912628Scsvaf 	   len = size(s);
25012628Scsvaf        }
25112628Scsvaf        if (canpush(len)) {
25212628Scsvaf 	   rpush(addr, len);
25312628Scsvaf 	   printval(s->type);
25412628Scsvaf        } else {
25512628Scsvaf 	   printf("*** expression too large ***");
25612628Scsvaf        }
257*16616Ssam /*
258*16616Ssam  * Matches brace commented out above.
25912628Scsvaf    }
260*16616Ssam  */
2619676Slinton }
2629676Slinton 
2639676Slinton /*
2649676Slinton  * Print out the name of a symbol.
2659676Slinton  */
2669676Slinton 
2679676Slinton public printname(f, s)
2689676Slinton File f;
2699676Slinton Symbol s;
2709676Slinton {
2719676Slinton     if (s == nil) {
2729676Slinton 	fprintf(f, "(noname)");
273*16616Ssam     } else if (s == program) {
274*16616Ssam 	fprintf(f, ".");
2759676Slinton     } else if (isredirected() or isambiguous(s)) {
2769676Slinton 	printwhich(f, s);
2779676Slinton     } else {
2789676Slinton 	fprintf(f, "%s", symname(s));
2799676Slinton     }
2809676Slinton }
2819676Slinton 
2829676Slinton /*
2839676Slinton  * Print the fully specified variable that is described by the given identifer.
2849676Slinton  */
2859676Slinton 
2869676Slinton public printwhich(f, s)
2879676Slinton File f;
2889676Slinton Symbol s;
2899676Slinton {
2909676Slinton     printouter(f, container(s));
2919676Slinton     fprintf(f, "%s", symname(s));
2929676Slinton }
2939676Slinton 
2949676Slinton /*
2959676Slinton  * Print the fully qualified name of each symbol that has the same name
2969676Slinton  * as the given symbol.
2979676Slinton  */
2989676Slinton 
2999676Slinton public printwhereis(f, s)
3009676Slinton File f;
3019676Slinton Symbol s;
3029676Slinton {
3039676Slinton     register Name n;
3049676Slinton     register Symbol t;
3059676Slinton 
3069676Slinton     checkref(s);
3079676Slinton     n = s->name;
3089676Slinton     t = lookup(n);
3099676Slinton     printwhich(f, t);
3109676Slinton     t = t->next_sym;
3119676Slinton     while (t != nil) {
3129676Slinton 	if (t->name == n) {
3139676Slinton 	    putc(' ', f);
3149676Slinton 	    printwhich(f, t);
3159676Slinton 	}
3169676Slinton 	t = t->next_sym;
3179676Slinton     }
3189676Slinton     putc('\n', f);
3199676Slinton }
3209676Slinton 
3219676Slinton private printouter(f, s)
3229676Slinton File f;
3239676Slinton Symbol s;
3249676Slinton {
3259676Slinton     Symbol outer;
3269676Slinton 
3279676Slinton     if (s != nil) {
3289676Slinton 	outer = container(s);
3299676Slinton 	if (outer != nil and outer != program) {
3309676Slinton 	    printouter(f, outer);
3319676Slinton 	}
3329676Slinton 	fprintf(f, "%s.", symname(s));
3339676Slinton     }
3349676Slinton }
3359676Slinton 
3369676Slinton public printdecl(s)
3379676Slinton Symbol s;
3389676Slinton {
3399676Slinton     checkref(s);
3409676Slinton     (*language_op(s->language, L_PRINTDECL))(s);
3419676Slinton }
3429676Slinton 
3439676Slinton /*
3449676Slinton  * Straight dump of symbol information.
3459676Slinton  */
3469676Slinton 
3479676Slinton public psym(s)
3489676Slinton Symbol s;
3499676Slinton {
3509676Slinton     printf("name\t%s\n", symname(s));
3519676Slinton     printf("lang\t%s\n", language_name(s->language));
3529676Slinton     printf("level\t%d\n", s->level);
3539676Slinton     printf("class\t%s\n", classname(s));
3549676Slinton     printf("type\t0x%x", s->type);
3559676Slinton     if (s->type != nil and s->type->name != nil) {
3569676Slinton 	printf(" (%s)", symname(s->type));
3579676Slinton     }
3589676Slinton     printf("\nchain\t0x%x", s->chain);
3599676Slinton     if (s->chain != nil and s->chain->name != nil) {
3609676Slinton 	printf(" (%s)", symname(s->chain));
3619676Slinton     }
3629676Slinton     printf("\nblock\t0x%x", s->block);
3639676Slinton     if (s->block->name != nil) {
3649676Slinton 	printf(" (");
3659676Slinton 	printname(stdout, s->block);
3669676Slinton 	putchar(')');
3679676Slinton     }
3689676Slinton     putchar('\n');
3699676Slinton     switch (s->class) {
3709676Slinton 	case VAR:
3719676Slinton 	case REF:
3729676Slinton 	    if (s->level >= 3) {
3739676Slinton 		printf("address\t0x%x\n", s->symvalue.offset);
3749676Slinton 	    } else {
3759676Slinton 		printf("offset\t%d\n", s->symvalue.offset);
3769676Slinton 	    }
37712545Scsvaf 	    printf("size\t%d\n", size(s));
3789676Slinton 	    break;
3799676Slinton 
3809676Slinton 	case RECORD:
3819676Slinton 	case VARNT:
3829676Slinton 	    printf("size\t%d\n", s->symvalue.offset);
3839676Slinton 	    break;
3849676Slinton 
3859676Slinton 	case FIELD:
3869676Slinton 	    printf("offset\t%d\n", s->symvalue.field.offset);
3879676Slinton 	    printf("size\t%d\n", s->symvalue.field.length);
3889676Slinton 	    break;
3899676Slinton 
39014381Slinton 	case PROG:
3919676Slinton 	case PROC:
3929676Slinton 	case FUNC:
3939676Slinton 	    printf("address\t0x%x\n", s->symvalue.funcv.beginaddr);
39414438Slinton 	    if (isinline(s)) {
39514440Slinton 		printf("inline procedure\n");
39614438Slinton 	    }
39711863Slinton 	    if (nosource(s)) {
39811863Slinton 		printf("does not have source information\n");
39911863Slinton 	    } else {
40011863Slinton 		printf("has source information\n");
40111863Slinton 	    }
4029676Slinton 	    break;
4039676Slinton 
4049676Slinton 	case RANGE:
40514381Slinton 	    prangetype(s->symvalue.rangev.lowertype);
4069676Slinton 	    printf("lower\t%d\n", s->symvalue.rangev.lower);
40714381Slinton 	    prangetype(s->symvalue.rangev.uppertype);
4089676Slinton 	    printf("upper\t%d\n", s->symvalue.rangev.upper);
4099676Slinton 	    break;
4109676Slinton 
4119676Slinton 	default:
4129676Slinton 	    /* do nothing */
4139676Slinton 	    break;
4149676Slinton     }
4159676Slinton }
4169676Slinton 
41714381Slinton private prangetype(r)
41814381Slinton Rangetype r;
41914381Slinton {
42014381Slinton     switch (r) {
42114381Slinton 	case R_CONST:
42214381Slinton 	    printf("CONST");
42314381Slinton 	    break;
42414381Slinton 
42514381Slinton 	case R_ARG:
42614381Slinton 	    printf("ARG");
42714381Slinton 	    break;
42814381Slinton 
42914381Slinton 	case R_TEMP:
43014381Slinton 	    printf("TEMP");
43114381Slinton 	    break;
43214381Slinton 
43314381Slinton 	case R_ADJUST:
43414381Slinton 	    printf("ADJUST");
43514381Slinton 	    break;
43614381Slinton     }
43714381Slinton }
43814381Slinton 
4399676Slinton /*
4409676Slinton  * Print out the value on top of the stack according to the given type.
4419676Slinton  */
4429676Slinton 
4439676Slinton public printval(t)
4449676Slinton Symbol t;
4459676Slinton {
4469676Slinton     Symbol s;
4479676Slinton 
4489676Slinton     checkref(t);
449*16616Ssam     if (t->class == TYPEREF) {
450*16616Ssam 	resolveRef(t);
451*16616Ssam     }
4529676Slinton     switch (t->class) {
4539676Slinton 	case PROC:
4549676Slinton 	case FUNC:
4559676Slinton 	    s = pop(Symbol);
4569676Slinton 	    printf("%s", symname(s));
4579676Slinton 	    break;
4589676Slinton 
4599676Slinton 	default:
4609676Slinton 	    if (t->language == nil) {
4619676Slinton 		error("unknown language");
462*16616Ssam 	    } else if (t->language == primlang) {
463*16616Ssam 		(*language_op(findlanguage(".c"), L_PRINTVAL))(t);
4649676Slinton 	    } else {
4659676Slinton 		(*language_op(t->language, L_PRINTVAL))(t);
4669676Slinton 	    }
4679676Slinton 	    break;
4689676Slinton     }
4699676Slinton }
4709676Slinton 
4719676Slinton /*
4729676Slinton  * Print out the value of a record, field by field.
4739676Slinton  */
4749676Slinton 
4759676Slinton public printrecord(s)
4769676Slinton Symbol s;
4779676Slinton {
478*16616Ssam     Symbol f;
479*16616Ssam 
4809676Slinton     if (s->chain == nil) {
4819676Slinton 	error("record has no fields");
4829676Slinton     }
4839676Slinton     printf("(");
4849676Slinton     sp -= size(s);
485*16616Ssam     f = s->chain;
486*16616Ssam     if (f != nil) {
487*16616Ssam 	for (;;) {
488*16616Ssam 	    printfield(f);
489*16616Ssam 	    f = f->chain;
490*16616Ssam 	if (f == nil) break;
491*16616Ssam 	    printf(", ");
492*16616Ssam 	}
493*16616Ssam     }
4949676Slinton     printf(")");
4959676Slinton }
4969676Slinton 
4979676Slinton /*
498*16616Ssam  * Print out a field.
4999676Slinton  */
5009676Slinton 
501*16616Ssam private printfield(f)
502*16616Ssam Symbol f;
5039676Slinton {
5049676Slinton     Stack *savesp;
505*16616Ssam     register int off, len;
5069676Slinton 
507*16616Ssam     printf("%s = ", symname(f));
5089676Slinton     savesp = sp;
509*16616Ssam     off = f->symvalue.field.offset;
510*16616Ssam     len = f->symvalue.field.length;
511*16616Ssam     sp += ((off + len + BITSPERBYTE - 1) div BITSPERBYTE);
512*16616Ssam     printval(f);
5139676Slinton     sp = savesp;
5149676Slinton }
5159676Slinton 
5169676Slinton /*
5179676Slinton  * Print out the contents of an array.
5189676Slinton  * Haven't quite figured out what the best format is.
5199676Slinton  *
5209676Slinton  * This is rather inefficient.
5219676Slinton  *
5229676Slinton  * The "2*elsize" is there since "printval" drops the stack by elsize.
5239676Slinton  */
5249676Slinton 
5259676Slinton public printarray(a)
5269676Slinton Symbol a;
5279676Slinton {
5289676Slinton     Stack *savesp, *newsp;
5299676Slinton     Symbol eltype;
5309676Slinton     long elsize;
5319676Slinton     String sep;
5329676Slinton 
5339676Slinton     savesp = sp;
53412544Scsvaf     sp -= (size(a));
5359676Slinton     newsp = sp;
5369676Slinton     eltype = rtype(a->type);
5379676Slinton     elsize = size(eltype);
5389676Slinton     printf("(");
5399676Slinton     if (eltype->class == RECORD or eltype->class == ARRAY or
5409676Slinton       eltype->class == VARNT) {
5419676Slinton 	sep = "\n";
5429676Slinton 	putchar('\n');
5439676Slinton     } else {
5449676Slinton 	sep = ", ";
5459676Slinton     }
5469676Slinton     for (sp += elsize; sp <= savesp; sp += 2*elsize) {
5479676Slinton 	if (sp - elsize != newsp) {
5489676Slinton 	    fputs(sep, stdout);
5499676Slinton 	}
5509676Slinton 	printval(eltype);
5519676Slinton     }
5529676Slinton     sp = newsp;
5539676Slinton     if (streq(sep, "\n")) {
5549676Slinton 	putchar('\n');
5559676Slinton     }
5569676Slinton     printf(")");
5579676Slinton }
5589676Slinton 
5599676Slinton /*
5609676Slinton  * Print out the value of a real number in Pascal notation.
5619676Slinton  * This is, unfortunately, different than what one gets
5629676Slinton  * from "%g" in printf.
5639676Slinton  */
5649676Slinton 
5659676Slinton public prtreal(r)
5669676Slinton double r;
5679676Slinton {
5689676Slinton     extern char *index();
5699676Slinton     char buf[256];
5709676Slinton 
5719676Slinton     sprintf(buf, "%g", r);
5729676Slinton     if (buf[0] == '.') {
5739676Slinton 	printf("0%s", buf);
5749676Slinton     } else if (buf[0] == '-' and buf[1] == '.') {
5759676Slinton 	printf("-0%s", &buf[1]);
5769676Slinton     } else {
5779676Slinton 	printf("%s", buf);
5789676Slinton     }
5799676Slinton     if (index(buf, '.') == nil) {
5809676Slinton 	printf(".0");
5819676Slinton     }
5829676Slinton }
5839676Slinton 
5849676Slinton /*
5859676Slinton  * Print out a character using ^? notation for unprintables.
5869676Slinton  */
5879676Slinton 
5889676Slinton public printchar(c)
5899676Slinton char c;
5909676Slinton {
5919676Slinton     if (c == 0) {
5929676Slinton 	putchar('\\');
5939676Slinton 	putchar('0');
5949676Slinton     } else if (c == '\n') {
5959676Slinton 	putchar('\\');
5969676Slinton 	putchar('n');
5979676Slinton     } else if (c > 0 and c < ' ') {
5989676Slinton 	putchar('^');
5999676Slinton 	putchar(c - 1 + 'A');
600*16616Ssam     } else if (c >= ' ' && c <= '~') {
601*16616Ssam 	putchar(c);
6029676Slinton     } else {
603*16616Ssam 	printf("\\0%o",c);
6049676Slinton     }
6059676Slinton }
606