xref: /csrg-svn/old/dbx/printsym.c (revision 12544)
19676Slinton /* Copyright (c) 1982 Regents of the University of California */
29676Slinton 
3*12544Scsvaf static char sccsid[] = "@(#)printsym.c 1.5 05/18/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",
44*12544Scsvaf     "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 ");
1039676Slinton     if (s->class == FUNC) {
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:
1819676Slinton 	    t = rtype(s->type);
1829676Slinton 	    b = (Boolean) (
1839676Slinton 		not isparam(s) and
1849676Slinton 		t != nil and t->class != FILET and t->class != SET
1859676Slinton 	    );
1869676Slinton 	    break;
1879676Slinton 
1889676Slinton 	default:
1899676Slinton 	    b = false;
1909676Slinton 	    break;
1919676Slinton     }
1929676Slinton     return b;
1939676Slinton }
1949676Slinton 
1959676Slinton /*
1969676Slinton  * Print the name and value of a variable.
1979676Slinton  */
1989676Slinton 
1999676Slinton public printv(s, frame)
2009676Slinton Symbol s;
2019676Slinton Frame frame;
2029676Slinton {
2039676Slinton     Address addr;
2049676Slinton     int len;
2059676Slinton 
2069676Slinton     if (isambiguous(s) and ismodule(container(s))) {
2079676Slinton 	printname(stdout, s);
2089676Slinton 	printf(" = ");
2099676Slinton     } else {
2109676Slinton 	printf("%s = ", symname(s));
2119676Slinton     }
2129676Slinton     if (isvarparam(s)) {
2139676Slinton 	rpush(address(s, frame), sizeof(Address));
2149676Slinton 	addr = pop(Address);
2159676Slinton 	len = size(s->type);
2169676Slinton     } else {
2179676Slinton 	addr = address(s, frame);
2189676Slinton 	len = size(s);
2199676Slinton     }
2209676Slinton     if (canpush(len)) {
2219676Slinton 	rpush(addr, len);
2229676Slinton 	printval(s->type);
2239676Slinton     } else {
2249676Slinton 	printf("*** expression too large ***");
2259676Slinton     }
2269676Slinton }
2279676Slinton 
2289676Slinton /*
2299676Slinton  * Print out the name of a symbol.
2309676Slinton  */
2319676Slinton 
2329676Slinton public printname(f, s)
2339676Slinton File f;
2349676Slinton Symbol s;
2359676Slinton {
2369676Slinton     if (s == nil) {
2379676Slinton 	fprintf(f, "(noname)");
2389676Slinton     } else if (isredirected() or isambiguous(s)) {
2399676Slinton 	printwhich(f, s);
2409676Slinton     } else {
2419676Slinton 	fprintf(f, "%s", symname(s));
2429676Slinton     }
2439676Slinton }
2449676Slinton 
2459676Slinton /*
2469676Slinton  * Print the fully specified variable that is described by the given identifer.
2479676Slinton  */
2489676Slinton 
2499676Slinton public printwhich(f, s)
2509676Slinton File f;
2519676Slinton Symbol s;
2529676Slinton {
2539676Slinton     printouter(f, container(s));
2549676Slinton     fprintf(f, "%s", symname(s));
2559676Slinton }
2569676Slinton 
2579676Slinton /*
2589676Slinton  * Print the fully qualified name of each symbol that has the same name
2599676Slinton  * as the given symbol.
2609676Slinton  */
2619676Slinton 
2629676Slinton public printwhereis(f, s)
2639676Slinton File f;
2649676Slinton Symbol s;
2659676Slinton {
2669676Slinton     register Name n;
2679676Slinton     register Symbol t;
2689676Slinton 
2699676Slinton     checkref(s);
2709676Slinton     n = s->name;
2719676Slinton     t = lookup(n);
2729676Slinton     printwhich(f, t);
2739676Slinton     t = t->next_sym;
2749676Slinton     while (t != nil) {
2759676Slinton 	if (t->name == n) {
2769676Slinton 	    putc(' ', f);
2779676Slinton 	    printwhich(f, t);
2789676Slinton 	}
2799676Slinton 	t = t->next_sym;
2809676Slinton     }
2819676Slinton     putc('\n', f);
2829676Slinton }
2839676Slinton 
2849676Slinton private printouter(f, s)
2859676Slinton File f;
2869676Slinton Symbol s;
2879676Slinton {
2889676Slinton     Symbol outer;
2899676Slinton 
2909676Slinton     if (s != nil) {
2919676Slinton 	outer = container(s);
2929676Slinton 	if (outer != nil and outer != program) {
2939676Slinton 	    printouter(f, outer);
2949676Slinton 	}
2959676Slinton 	fprintf(f, "%s.", symname(s));
2969676Slinton     }
2979676Slinton }
2989676Slinton 
2999676Slinton public printdecl(s)
3009676Slinton Symbol s;
3019676Slinton {
3029676Slinton     checkref(s);
3039676Slinton     (*language_op(s->language, L_PRINTDECL))(s);
3049676Slinton }
3059676Slinton 
3069676Slinton /*
3079676Slinton  * Straight dump of symbol information.
3089676Slinton  */
3099676Slinton 
3109676Slinton public psym(s)
3119676Slinton Symbol s;
3129676Slinton {
3139676Slinton     printf("name\t%s\n", symname(s));
3149676Slinton     printf("lang\t%s\n", language_name(s->language));
3159676Slinton     printf("level\t%d\n", s->level);
3169676Slinton     printf("class\t%s\n", classname(s));
3179676Slinton     printf("type\t0x%x", s->type);
3189676Slinton     if (s->type != nil and s->type->name != nil) {
3199676Slinton 	printf(" (%s)", symname(s->type));
3209676Slinton     }
3219676Slinton     printf("\nchain\t0x%x", s->chain);
3229676Slinton     if (s->chain != nil and s->chain->name != nil) {
3239676Slinton 	printf(" (%s)", symname(s->chain));
3249676Slinton     }
3259676Slinton     printf("\nblock\t0x%x", s->block);
3269676Slinton     if (s->block->name != nil) {
3279676Slinton 	printf(" (");
3289676Slinton 	printname(stdout, s->block);
3299676Slinton 	putchar(')');
3309676Slinton     }
3319676Slinton     putchar('\n');
3329676Slinton     switch (s->class) {
3339676Slinton 	case VAR:
3349676Slinton 	case REF:
3359676Slinton 	    if (s->level >= 3) {
3369676Slinton 		printf("address\t0x%x\n", s->symvalue.offset);
3379676Slinton 	    } else {
3389676Slinton 		printf("offset\t%d\n", s->symvalue.offset);
3399676Slinton 	    }
3409676Slinton 	    break;
3419676Slinton 
3429676Slinton 	case RECORD:
3439676Slinton 	case VARNT:
3449676Slinton 	    printf("size\t%d\n", s->symvalue.offset);
3459676Slinton 	    break;
3469676Slinton 
3479676Slinton 	case FIELD:
3489676Slinton 	    printf("offset\t%d\n", s->symvalue.field.offset);
3499676Slinton 	    printf("size\t%d\n", s->symvalue.field.length);
3509676Slinton 	    break;
3519676Slinton 
3529676Slinton 	case PROC:
3539676Slinton 	case FUNC:
3549676Slinton 	    printf("address\t0x%x\n", s->symvalue.funcv.beginaddr);
35511863Slinton 	    if (nosource(s)) {
35611863Slinton 		printf("does not have source information\n");
35711863Slinton 	    } else {
35811863Slinton 		printf("has source information\n");
35911863Slinton 	    }
3609676Slinton 	    break;
3619676Slinton 
3629676Slinton 	case RANGE:
363*12544Scsvaf             switch(s->symvalue.rangev.lowertype) {
364*12544Scsvaf 
365*12544Scsvaf 	      case R_CONST :  printf("CONST");
366*12544Scsvaf 		              break;
367*12544Scsvaf 	      case R_ARG :    printf("ARG");
368*12544Scsvaf 			      break;
369*12544Scsvaf 	      case R_TEMP :   printf("TEMP");
370*12544Scsvaf 			      break;
371*12544Scsvaf 	      case R_ADJUST : printf("ADJUST");
372*12544Scsvaf 			      break;
373*12544Scsvaf             }
3749676Slinton 	    printf("lower\t%d\n", s->symvalue.rangev.lower);
375*12544Scsvaf 
376*12544Scsvaf             switch(s->symvalue.rangev.uppertype) {
377*12544Scsvaf 
378*12544Scsvaf 	      case R_CONST :  printf("CONST");
379*12544Scsvaf 		              break;
380*12544Scsvaf 	      case R_ARG :    printf("ARG");
381*12544Scsvaf 			      break;
382*12544Scsvaf 	      case R_TEMP :   printf("TEMP");
383*12544Scsvaf 			      break;
384*12544Scsvaf 	      case R_ADJUST : printf("ADJUST");
385*12544Scsvaf 			      break;
386*12544Scsvaf             }
387*12544Scsvaf 
3889676Slinton 	    printf("upper\t%d\n", s->symvalue.rangev.upper);
3899676Slinton 	    break;
3909676Slinton 
3919676Slinton 	default:
3929676Slinton 	    /* do nothing */
3939676Slinton 	    break;
3949676Slinton     }
3959676Slinton }
3969676Slinton 
3979676Slinton /*
3989676Slinton  * Print out the value on top of the stack according to the given type.
3999676Slinton  */
4009676Slinton 
4019676Slinton public printval(t)
4029676Slinton Symbol t;
4039676Slinton {
4049676Slinton     Symbol s;
4059676Slinton 
4069676Slinton     checkref(t);
4079676Slinton     switch (t->class) {
4089676Slinton 	case PROC:
4099676Slinton 	case FUNC:
4109676Slinton 	    s = pop(Symbol);
4119676Slinton 	    printf("%s", symname(s));
4129676Slinton 	    break;
4139676Slinton 
4149676Slinton 	default:
4159676Slinton 	    if (t->language == nil) {
4169676Slinton 		error("unknown language");
4179676Slinton 	    } else {
4189676Slinton 		(*language_op(t->language, L_PRINTVAL))(t);
4199676Slinton 	    }
4209676Slinton 	    break;
4219676Slinton     }
4229676Slinton }
4239676Slinton 
4249676Slinton /*
4259676Slinton  * Print out the value of a record, field by field.
4269676Slinton  */
4279676Slinton 
4289676Slinton public printrecord(s)
4299676Slinton Symbol s;
4309676Slinton {
4319676Slinton     if (s->chain == nil) {
4329676Slinton 	error("record has no fields");
4339676Slinton     }
4349676Slinton     printf("(");
4359676Slinton     sp -= size(s);
4369676Slinton     printfield(s->chain);
4379676Slinton     printf(")");
4389676Slinton }
4399676Slinton 
4409676Slinton /*
4419676Slinton  * Print out a field, first printing out other fields.
4429676Slinton  * This is done because the fields are chained together backwards.
4439676Slinton  */
4449676Slinton 
4459676Slinton private printfield(s)
4469676Slinton Symbol s;
4479676Slinton {
4489676Slinton     Stack *savesp;
4499676Slinton 
4509676Slinton     if (s->chain != nil) {
4519676Slinton 	printfield(s->chain);
4529676Slinton 	printf(", ");
4539676Slinton     }
4549676Slinton     printf("%s = ", symname(s));
4559676Slinton     savesp = sp;
4569676Slinton     sp += ((s->symvalue.field.offset div BITSPERBYTE) + size(s->type));
4579676Slinton     printval(s);
4589676Slinton     sp = savesp;
4599676Slinton }
4609676Slinton 
4619676Slinton /*
4629676Slinton  * Print out the contents of an array.
4639676Slinton  * Haven't quite figured out what the best format is.
4649676Slinton  *
4659676Slinton  * This is rather inefficient.
4669676Slinton  *
4679676Slinton  * The "2*elsize" is there since "printval" drops the stack by elsize.
4689676Slinton  */
4699676Slinton 
4709676Slinton public printarray(a)
4719676Slinton Symbol a;
4729676Slinton {
4739676Slinton     Stack *savesp, *newsp;
4749676Slinton     Symbol eltype;
4759676Slinton     long elsize;
4769676Slinton     String sep;
4779676Slinton 
4789676Slinton     savesp = sp;
479*12544Scsvaf     sp -= (size(a));
4809676Slinton     newsp = sp;
4819676Slinton     eltype = rtype(a->type);
4829676Slinton     elsize = size(eltype);
4839676Slinton     printf("(");
4849676Slinton     if (eltype->class == RECORD or eltype->class == ARRAY or
4859676Slinton       eltype->class == VARNT) {
4869676Slinton 	sep = "\n";
4879676Slinton 	putchar('\n');
4889676Slinton     } else {
4899676Slinton 	sep = ", ";
4909676Slinton     }
4919676Slinton     for (sp += elsize; sp <= savesp; sp += 2*elsize) {
4929676Slinton 	if (sp - elsize != newsp) {
4939676Slinton 	    fputs(sep, stdout);
4949676Slinton 	}
4959676Slinton 	printval(eltype);
4969676Slinton     }
4979676Slinton     sp = newsp;
4989676Slinton     if (streq(sep, "\n")) {
4999676Slinton 	putchar('\n');
5009676Slinton     }
5019676Slinton     printf(")");
5029676Slinton }
5039676Slinton 
5049676Slinton /*
5059676Slinton  * Print out the value of a real number in Pascal notation.
5069676Slinton  * This is, unfortunately, different than what one gets
5079676Slinton  * from "%g" in printf.
5089676Slinton  */
5099676Slinton 
5109676Slinton public prtreal(r)
5119676Slinton double r;
5129676Slinton {
5139676Slinton     extern char *index();
5149676Slinton     char buf[256];
5159676Slinton 
5169676Slinton     sprintf(buf, "%g", r);
5179676Slinton     if (buf[0] == '.') {
5189676Slinton 	printf("0%s", buf);
5199676Slinton     } else if (buf[0] == '-' and buf[1] == '.') {
5209676Slinton 	printf("-0%s", &buf[1]);
5219676Slinton     } else {
5229676Slinton 	printf("%s", buf);
5239676Slinton     }
5249676Slinton     if (index(buf, '.') == nil) {
5259676Slinton 	printf(".0");
5269676Slinton     }
5279676Slinton }
5289676Slinton 
5299676Slinton /*
5309676Slinton  * Print out a character using ^? notation for unprintables.
5319676Slinton  */
5329676Slinton 
5339676Slinton public printchar(c)
5349676Slinton char c;
5359676Slinton {
5369676Slinton     if (c == 0) {
5379676Slinton 	putchar('\\');
5389676Slinton 	putchar('0');
5399676Slinton     } else if (c == '\n') {
5409676Slinton 	putchar('\\');
5419676Slinton 	putchar('n');
5429676Slinton     } else if (c > 0 and c < ' ') {
5439676Slinton 	putchar('^');
5449676Slinton 	putchar(c - 1 + 'A');
5459676Slinton     } else {
5469676Slinton 	putchar(c);
5479676Slinton     }
5489676Slinton }
549