xref: /csrg-svn/old/dbx/printsym.c (revision 14339)
19676Slinton /* Copyright (c) 1982 Regents of the University of California */
29676Slinton 
3*14339Slinton static char sccsid[] = "@(#)printsym.c 1.8 08/05/83";
49676Slinton 
59676Slinton /*
69676Slinton  * Printing of symbolic information.
79676Slinton  */
89676Slinton 
99676Slinton #include "defs.h"
109676Slinton #include "symbols.h"
119676Slinton #include "languages.h"
129676Slinton #include "printsym.h"
139676Slinton #include "tree.h"
149676Slinton #include "eval.h"
159676Slinton #include "mappings.h"
169676Slinton #include "process.h"
179676Slinton #include "runtime.h"
189676Slinton #include "machine.h"
199676Slinton #include "names.h"
209676Slinton #include "main.h"
219676Slinton 
229676Slinton #ifndef public
239676Slinton #endif
249676Slinton 
259676Slinton /*
2611863Slinton  * Maximum number of arguments to a function.
2711863Slinton  * This is used as a check for the possibility that the stack has been
2811863Slinton  * overwritten and therefore a saved argument pointer might indicate
2911863Slinton  * to an absurdly large number of arguments.
3011863Slinton  */
3111863Slinton 
3211863Slinton #define MAXARGSPASSED 20
3311863Slinton 
3411863Slinton /*
359676Slinton  * Return a pointer to the string for the name of the class that
369676Slinton  * the given symbol belongs to.
379676Slinton  */
389676Slinton 
399676Slinton private String clname[] = {
409676Slinton     "bad use", "constant", "type", "variable", "array", "fileptr",
419676Slinton     "record", "field", "procedure", "function", "funcvar",
429676Slinton     "ref", "pointer", "file", "set", "range", "label", "withptr",
439676Slinton     "scalar", "string", "program", "improper", "variant",
4412544Scsvaf     "procparam", "funcparam", "module", "tag", "common", "typeref"
459676Slinton };
469676Slinton 
479676Slinton public String classname(s)
489676Slinton Symbol s;
499676Slinton {
509676Slinton     return clname[ord(s->class)];
519676Slinton }
529676Slinton 
539676Slinton /*
549676Slinton  * Note the entry of the given block, unless it's the main program.
559676Slinton  */
569676Slinton 
579676Slinton public printentry(s)
589676Slinton Symbol s;
599676Slinton {
609676Slinton     if (s != program) {
619676Slinton 	printf("\nentering %s %s\n", classname(s), symname(s));
629676Slinton     }
639676Slinton }
649676Slinton 
659676Slinton /*
669676Slinton  * Note the exit of the given block
679676Slinton  */
689676Slinton 
699676Slinton public printexit(s)
709676Slinton Symbol s;
719676Slinton {
729676Slinton     if (s != program) {
739676Slinton 	printf("leaving %s %s\n\n", classname(s), symname(s));
749676Slinton     }
759676Slinton }
769676Slinton 
779676Slinton /*
789676Slinton  * Note the call of s from t.
799676Slinton  */
809676Slinton 
819676Slinton public printcall(s, t)
829676Slinton Symbol s, t;
839676Slinton {
849676Slinton     printf("calling %s", symname(s));
859676Slinton     printparams(s, nil);
869676Slinton     printf(" from %s %s\n", classname(t), symname(t));
879676Slinton }
889676Slinton 
899676Slinton /*
909676Slinton  * Note the return from s.  If s is a function, print the value
919676Slinton  * it is returning.  This is somewhat painful, since the function
929676Slinton  * has actually just returned.
939676Slinton  */
949676Slinton 
959676Slinton public printrtn(s)
969676Slinton Symbol s;
979676Slinton {
989676Slinton     register Symbol t;
999676Slinton     register int len;
1009676Slinton     Boolean isindirect;
1019676Slinton 
1029676Slinton     printf("returning ");
10312628Scsvaf     if (s->class == FUNC && (!istypename(s->type,"void"))) {
1049676Slinton 	len = size(s->type);
1059676Slinton 	if (canpush(len)) {
1069676Slinton 	    t = rtype(s->type);
1079676Slinton 	    isindirect = (Boolean) (t->class == RECORD or t->class == VARNT);
1089676Slinton 	    pushretval(len, isindirect);
1099676Slinton 	    printval(s->type);
1109676Slinton 	    putchar(' ');
1119676Slinton 	} else {
1129676Slinton 	    printf("(value too large) ");
1139676Slinton 	}
1149676Slinton     }
1159676Slinton     printf("from %s\n", symname(s));
1169676Slinton }
1179676Slinton 
1189676Slinton /*
1199676Slinton  * Print the values of the parameters of the given procedure or function.
1209676Slinton  * The frame distinguishes recursive instances of a procedure.
1219676Slinton  */
1229676Slinton 
1239676Slinton public printparams(f, frame)
1249676Slinton Symbol f;
1259676Slinton Frame frame;
1269676Slinton {
1279676Slinton     Symbol param;
1289676Slinton     int n, m, s;
1299676Slinton 
1309676Slinton     n = nargspassed(frame);
1319676Slinton     param = f->chain;
1329676Slinton     if (param != nil or n > 0) {
1339676Slinton 	printf("(");
1349676Slinton 	m = n;
1359676Slinton 	if (param != nil) {
1369676Slinton 	    for (;;) {
1379676Slinton 		s = size(param) div sizeof(Word);
1389676Slinton 		if (s == 0) {
1399676Slinton 		    s = 1;
1409676Slinton 		}
1419676Slinton 		m -= s;
1429676Slinton 		printv(param, frame);
1439676Slinton 		param = param->chain;
1449676Slinton 	    if (param == nil) break;
1459676Slinton 		printf(", ");
1469676Slinton 	    }
1479676Slinton 	}
1489676Slinton 	if (m > 0) {
14911863Slinton 	    if (m > MAXARGSPASSED) {
15011863Slinton 		m = MAXARGSPASSED;
15111863Slinton 	    }
1529676Slinton 	    if (f->chain != nil) {
1539676Slinton 		printf(", ");
1549676Slinton 	    }
1559676Slinton 	    for (;;) {
1569676Slinton 		--m;
1579676Slinton 		printf("0x%x", argn(n - m, frame));
1589676Slinton 	    if (m <= 0) break;
1599676Slinton 		printf(", ");
1609676Slinton 	    }
1619676Slinton 	}
1629676Slinton 	printf(")");
1639676Slinton     }
1649676Slinton }
1659676Slinton 
1669676Slinton /*
1679676Slinton  * Test if a symbol should be printed.  We don't print files,
1689676Slinton  * for example, simply because there's no good way to do it.
1699676Slinton  * The symbol must be within the given function.
1709676Slinton  */
1719676Slinton 
1729676Slinton public Boolean should_print(s)
1739676Slinton Symbol s;
1749676Slinton {
1759676Slinton     Boolean b;
1769676Slinton     register Symbol t;
1779676Slinton 
1789676Slinton     switch (s->class) {
1799676Slinton 	case VAR:
1809676Slinton 	case FVAR:
181*14339Slinton 	    if (isparam(s)) {
182*14339Slinton 		b = false;
183*14339Slinton 	    } else {
184*14339Slinton 		t = rtype(s->type);
185*14339Slinton 		if (t == nil) {
186*14339Slinton 		    b = false;
187*14339Slinton 		} else {
188*14339Slinton 		    switch (t->class) {
189*14339Slinton 			case FILET:
190*14339Slinton 			case SET:
191*14339Slinton 			case VARNT:
192*14339Slinton 			case BADUSE:
193*14339Slinton 			    b = false;
194*14339Slinton 			    break;
195*14339Slinton 
196*14339Slinton 			default:
197*14339Slinton 			    b = true;
198*14339Slinton 			    break;
199*14339Slinton 		    }
200*14339Slinton 		}
201*14339Slinton 	    }
2029676Slinton 	    break;
2039676Slinton 
2049676Slinton 	default:
2059676Slinton 	    b = false;
2069676Slinton 	    break;
2079676Slinton     }
2089676Slinton     return b;
2099676Slinton }
2109676Slinton 
2119676Slinton /*
2129676Slinton  * Print the name and value of a variable.
2139676Slinton  */
2149676Slinton 
2159676Slinton public printv(s, frame)
2169676Slinton Symbol s;
2179676Slinton Frame frame;
2189676Slinton {
2199676Slinton     Address addr;
2209676Slinton     int len;
2219676Slinton 
2229676Slinton     if (isambiguous(s) and ismodule(container(s))) {
2239676Slinton 	printname(stdout, s);
2249676Slinton 	printf(" = ");
2259676Slinton     } else {
2269676Slinton 	printf("%s = ", symname(s));
2279676Slinton     }
22812628Scsvaf     if(s->type->class == ARRAY && (! istypename(s->type->type,"char")) ) {
22912628Scsvaf 	printf(" ARRAY ");
2309676Slinton     } else {
23112628Scsvaf        if (isvarparam(s)) {
23212628Scsvaf 	   rpush(address(s, frame), sizeof(Address));
23312628Scsvaf 	   addr = pop(Address);
23412628Scsvaf 	   len = size(s->type);
23512628Scsvaf        } else {
23612628Scsvaf 	   addr = address(s, frame);
23712628Scsvaf 	   len = size(s);
23812628Scsvaf        }
23912628Scsvaf        if (canpush(len)) {
24012628Scsvaf 	   rpush(addr, len);
24112628Scsvaf 	   printval(s->type);
24212628Scsvaf        } else {
24312628Scsvaf 	   printf("*** expression too large ***");
24412628Scsvaf        }
24512628Scsvaf    }
2469676Slinton }
2479676Slinton 
2489676Slinton /*
2499676Slinton  * Print out the name of a symbol.
2509676Slinton  */
2519676Slinton 
2529676Slinton public printname(f, s)
2539676Slinton File f;
2549676Slinton Symbol s;
2559676Slinton {
2569676Slinton     if (s == nil) {
2579676Slinton 	fprintf(f, "(noname)");
2589676Slinton     } else if (isredirected() or isambiguous(s)) {
2599676Slinton 	printwhich(f, s);
2609676Slinton     } else {
2619676Slinton 	fprintf(f, "%s", symname(s));
2629676Slinton     }
2639676Slinton }
2649676Slinton 
2659676Slinton /*
2669676Slinton  * Print the fully specified variable that is described by the given identifer.
2679676Slinton  */
2689676Slinton 
2699676Slinton public printwhich(f, s)
2709676Slinton File f;
2719676Slinton Symbol s;
2729676Slinton {
2739676Slinton     printouter(f, container(s));
2749676Slinton     fprintf(f, "%s", symname(s));
2759676Slinton }
2769676Slinton 
2779676Slinton /*
2789676Slinton  * Print the fully qualified name of each symbol that has the same name
2799676Slinton  * as the given symbol.
2809676Slinton  */
2819676Slinton 
2829676Slinton public printwhereis(f, s)
2839676Slinton File f;
2849676Slinton Symbol s;
2859676Slinton {
2869676Slinton     register Name n;
2879676Slinton     register Symbol t;
2889676Slinton 
2899676Slinton     checkref(s);
2909676Slinton     n = s->name;
2919676Slinton     t = lookup(n);
2929676Slinton     printwhich(f, t);
2939676Slinton     t = t->next_sym;
2949676Slinton     while (t != nil) {
2959676Slinton 	if (t->name == n) {
2969676Slinton 	    putc(' ', f);
2979676Slinton 	    printwhich(f, t);
2989676Slinton 	}
2999676Slinton 	t = t->next_sym;
3009676Slinton     }
3019676Slinton     putc('\n', f);
3029676Slinton }
3039676Slinton 
3049676Slinton private printouter(f, s)
3059676Slinton File f;
3069676Slinton Symbol s;
3079676Slinton {
3089676Slinton     Symbol outer;
3099676Slinton 
3109676Slinton     if (s != nil) {
3119676Slinton 	outer = container(s);
3129676Slinton 	if (outer != nil and outer != program) {
3139676Slinton 	    printouter(f, outer);
3149676Slinton 	}
3159676Slinton 	fprintf(f, "%s.", symname(s));
3169676Slinton     }
3179676Slinton }
3189676Slinton 
3199676Slinton public printdecl(s)
3209676Slinton Symbol s;
3219676Slinton {
3229676Slinton     checkref(s);
3239676Slinton     (*language_op(s->language, L_PRINTDECL))(s);
3249676Slinton }
3259676Slinton 
3269676Slinton /*
3279676Slinton  * Straight dump of symbol information.
3289676Slinton  */
3299676Slinton 
3309676Slinton public psym(s)
3319676Slinton Symbol s;
3329676Slinton {
3339676Slinton     printf("name\t%s\n", symname(s));
3349676Slinton     printf("lang\t%s\n", language_name(s->language));
3359676Slinton     printf("level\t%d\n", s->level);
3369676Slinton     printf("class\t%s\n", classname(s));
3379676Slinton     printf("type\t0x%x", s->type);
3389676Slinton     if (s->type != nil and s->type->name != nil) {
3399676Slinton 	printf(" (%s)", symname(s->type));
3409676Slinton     }
3419676Slinton     printf("\nchain\t0x%x", s->chain);
3429676Slinton     if (s->chain != nil and s->chain->name != nil) {
3439676Slinton 	printf(" (%s)", symname(s->chain));
3449676Slinton     }
3459676Slinton     printf("\nblock\t0x%x", s->block);
3469676Slinton     if (s->block->name != nil) {
3479676Slinton 	printf(" (");
3489676Slinton 	printname(stdout, s->block);
3499676Slinton 	putchar(')');
3509676Slinton     }
3519676Slinton     putchar('\n');
3529676Slinton     switch (s->class) {
3539676Slinton 	case VAR:
3549676Slinton 	case REF:
3559676Slinton 	    if (s->level >= 3) {
3569676Slinton 		printf("address\t0x%x\n", s->symvalue.offset);
3579676Slinton 	    } else {
3589676Slinton 		printf("offset\t%d\n", s->symvalue.offset);
3599676Slinton 	    }
36012545Scsvaf 	    printf("size\t%d\n", size(s));
3619676Slinton 	    break;
3629676Slinton 
3639676Slinton 	case RECORD:
3649676Slinton 	case VARNT:
3659676Slinton 	    printf("size\t%d\n", s->symvalue.offset);
3669676Slinton 	    break;
3679676Slinton 
3689676Slinton 	case FIELD:
3699676Slinton 	    printf("offset\t%d\n", s->symvalue.field.offset);
3709676Slinton 	    printf("size\t%d\n", s->symvalue.field.length);
3719676Slinton 	    break;
3729676Slinton 
3739676Slinton 	case PROC:
3749676Slinton 	case FUNC:
3759676Slinton 	    printf("address\t0x%x\n", s->symvalue.funcv.beginaddr);
37611863Slinton 	    if (nosource(s)) {
37711863Slinton 		printf("does not have source information\n");
37811863Slinton 	    } else {
37911863Slinton 		printf("has source information\n");
38011863Slinton 	    }
3819676Slinton 	    break;
3829676Slinton 
3839676Slinton 	case RANGE:
38412544Scsvaf             switch(s->symvalue.rangev.lowertype) {
38512544Scsvaf 
38612544Scsvaf 	      case R_CONST :  printf("CONST");
38712544Scsvaf 		              break;
38812544Scsvaf 	      case R_ARG :    printf("ARG");
38912544Scsvaf 			      break;
39012544Scsvaf 	      case R_TEMP :   printf("TEMP");
39112544Scsvaf 			      break;
39212544Scsvaf 	      case R_ADJUST : printf("ADJUST");
39312544Scsvaf 			      break;
39412544Scsvaf             }
3959676Slinton 	    printf("lower\t%d\n", s->symvalue.rangev.lower);
39612544Scsvaf 
39712544Scsvaf             switch(s->symvalue.rangev.uppertype) {
39812544Scsvaf 
39912544Scsvaf 	      case R_CONST :  printf("CONST");
40012544Scsvaf 		              break;
40112544Scsvaf 	      case R_ARG :    printf("ARG");
40212544Scsvaf 			      break;
40312544Scsvaf 	      case R_TEMP :   printf("TEMP");
40412544Scsvaf 			      break;
40512544Scsvaf 	      case R_ADJUST : printf("ADJUST");
40612544Scsvaf 			      break;
40712544Scsvaf             }
40812544Scsvaf 
4099676Slinton 	    printf("upper\t%d\n", s->symvalue.rangev.upper);
4109676Slinton 	    break;
4119676Slinton 
4129676Slinton 	default:
4139676Slinton 	    /* do nothing */
4149676Slinton 	    break;
4159676Slinton     }
4169676Slinton }
4179676Slinton 
4189676Slinton /*
4199676Slinton  * Print out the value on top of the stack according to the given type.
4209676Slinton  */
4219676Slinton 
4229676Slinton public printval(t)
4239676Slinton Symbol t;
4249676Slinton {
4259676Slinton     Symbol s;
4269676Slinton 
4279676Slinton     checkref(t);
4289676Slinton     switch (t->class) {
4299676Slinton 	case PROC:
4309676Slinton 	case FUNC:
4319676Slinton 	    s = pop(Symbol);
4329676Slinton 	    printf("%s", symname(s));
4339676Slinton 	    break;
4349676Slinton 
4359676Slinton 	default:
4369676Slinton 	    if (t->language == nil) {
4379676Slinton 		error("unknown language");
4389676Slinton 	    } else {
4399676Slinton 		(*language_op(t->language, L_PRINTVAL))(t);
4409676Slinton 	    }
4419676Slinton 	    break;
4429676Slinton     }
4439676Slinton }
4449676Slinton 
4459676Slinton /*
4469676Slinton  * Print out the value of a record, field by field.
4479676Slinton  */
4489676Slinton 
4499676Slinton public printrecord(s)
4509676Slinton Symbol s;
4519676Slinton {
4529676Slinton     if (s->chain == nil) {
4539676Slinton 	error("record has no fields");
4549676Slinton     }
4559676Slinton     printf("(");
4569676Slinton     sp -= size(s);
4579676Slinton     printfield(s->chain);
4589676Slinton     printf(")");
4599676Slinton }
4609676Slinton 
4619676Slinton /*
4629676Slinton  * Print out a field, first printing out other fields.
4639676Slinton  * This is done because the fields are chained together backwards.
4649676Slinton  */
4659676Slinton 
4669676Slinton private printfield(s)
4679676Slinton Symbol s;
4689676Slinton {
4699676Slinton     Stack *savesp;
4709676Slinton 
4719676Slinton     if (s->chain != nil) {
4729676Slinton 	printfield(s->chain);
4739676Slinton 	printf(", ");
4749676Slinton     }
4759676Slinton     printf("%s = ", symname(s));
4769676Slinton     savesp = sp;
4779676Slinton     sp += ((s->symvalue.field.offset div BITSPERBYTE) + size(s->type));
4789676Slinton     printval(s);
4799676Slinton     sp = savesp;
4809676Slinton }
4819676Slinton 
4829676Slinton /*
4839676Slinton  * Print out the contents of an array.
4849676Slinton  * Haven't quite figured out what the best format is.
4859676Slinton  *
4869676Slinton  * This is rather inefficient.
4879676Slinton  *
4889676Slinton  * The "2*elsize" is there since "printval" drops the stack by elsize.
4899676Slinton  */
4909676Slinton 
4919676Slinton public printarray(a)
4929676Slinton Symbol a;
4939676Slinton {
4949676Slinton     Stack *savesp, *newsp;
4959676Slinton     Symbol eltype;
4969676Slinton     long elsize;
4979676Slinton     String sep;
4989676Slinton 
4999676Slinton     savesp = sp;
50012544Scsvaf     sp -= (size(a));
5019676Slinton     newsp = sp;
5029676Slinton     eltype = rtype(a->type);
5039676Slinton     elsize = size(eltype);
5049676Slinton     printf("(");
5059676Slinton     if (eltype->class == RECORD or eltype->class == ARRAY or
5069676Slinton       eltype->class == VARNT) {
5079676Slinton 	sep = "\n";
5089676Slinton 	putchar('\n');
5099676Slinton     } else {
5109676Slinton 	sep = ", ";
5119676Slinton     }
5129676Slinton     for (sp += elsize; sp <= savesp; sp += 2*elsize) {
5139676Slinton 	if (sp - elsize != newsp) {
5149676Slinton 	    fputs(sep, stdout);
5159676Slinton 	}
5169676Slinton 	printval(eltype);
5179676Slinton     }
5189676Slinton     sp = newsp;
5199676Slinton     if (streq(sep, "\n")) {
5209676Slinton 	putchar('\n');
5219676Slinton     }
5229676Slinton     printf(")");
5239676Slinton }
5249676Slinton 
5259676Slinton /*
5269676Slinton  * Print out the value of a real number in Pascal notation.
5279676Slinton  * This is, unfortunately, different than what one gets
5289676Slinton  * from "%g" in printf.
5299676Slinton  */
5309676Slinton 
5319676Slinton public prtreal(r)
5329676Slinton double r;
5339676Slinton {
5349676Slinton     extern char *index();
5359676Slinton     char buf[256];
5369676Slinton 
5379676Slinton     sprintf(buf, "%g", r);
5389676Slinton     if (buf[0] == '.') {
5399676Slinton 	printf("0%s", buf);
5409676Slinton     } else if (buf[0] == '-' and buf[1] == '.') {
5419676Slinton 	printf("-0%s", &buf[1]);
5429676Slinton     } else {
5439676Slinton 	printf("%s", buf);
5449676Slinton     }
5459676Slinton     if (index(buf, '.') == nil) {
5469676Slinton 	printf(".0");
5479676Slinton     }
5489676Slinton }
5499676Slinton 
5509676Slinton /*
5519676Slinton  * Print out a character using ^? notation for unprintables.
5529676Slinton  */
5539676Slinton 
5549676Slinton public printchar(c)
5559676Slinton char c;
5569676Slinton {
5579676Slinton     if (c == 0) {
5589676Slinton 	putchar('\\');
5599676Slinton 	putchar('0');
5609676Slinton     } else if (c == '\n') {
5619676Slinton 	putchar('\\');
5629676Slinton 	putchar('n');
5639676Slinton     } else if (c > 0 and c < ' ') {
5649676Slinton 	putchar('^');
5659676Slinton 	putchar(c - 1 + 'A');
5669676Slinton     } else {
5679676Slinton 	putchar(c);
5689676Slinton     }
5699676Slinton }
570