19676Slinton /* Copyright (c) 1982 Regents of the University of California */ 29676Slinton 3*12545Scsvaf static char sccsid[] = "@(#)printsym.c 1.6 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", 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 "); 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 } 340*12545Scsvaf printf("size\t%d\n", size(s)); 3419676Slinton break; 3429676Slinton 3439676Slinton case RECORD: 3449676Slinton case VARNT: 3459676Slinton printf("size\t%d\n", s->symvalue.offset); 3469676Slinton break; 3479676Slinton 3489676Slinton case FIELD: 3499676Slinton printf("offset\t%d\n", s->symvalue.field.offset); 3509676Slinton printf("size\t%d\n", s->symvalue.field.length); 3519676Slinton break; 3529676Slinton 3539676Slinton case PROC: 3549676Slinton case FUNC: 3559676Slinton printf("address\t0x%x\n", s->symvalue.funcv.beginaddr); 35611863Slinton if (nosource(s)) { 35711863Slinton printf("does not have source information\n"); 35811863Slinton } else { 35911863Slinton printf("has source information\n"); 36011863Slinton } 3619676Slinton break; 3629676Slinton 3639676Slinton case RANGE: 36412544Scsvaf switch(s->symvalue.rangev.lowertype) { 36512544Scsvaf 36612544Scsvaf case R_CONST : printf("CONST"); 36712544Scsvaf break; 36812544Scsvaf case R_ARG : printf("ARG"); 36912544Scsvaf break; 37012544Scsvaf case R_TEMP : printf("TEMP"); 37112544Scsvaf break; 37212544Scsvaf case R_ADJUST : printf("ADJUST"); 37312544Scsvaf break; 37412544Scsvaf } 3759676Slinton printf("lower\t%d\n", s->symvalue.rangev.lower); 37612544Scsvaf 37712544Scsvaf switch(s->symvalue.rangev.uppertype) { 37812544Scsvaf 37912544Scsvaf case R_CONST : printf("CONST"); 38012544Scsvaf break; 38112544Scsvaf case R_ARG : printf("ARG"); 38212544Scsvaf break; 38312544Scsvaf case R_TEMP : printf("TEMP"); 38412544Scsvaf break; 38512544Scsvaf case R_ADJUST : printf("ADJUST"); 38612544Scsvaf break; 38712544Scsvaf } 38812544Scsvaf 3899676Slinton printf("upper\t%d\n", s->symvalue.rangev.upper); 3909676Slinton break; 3919676Slinton 3929676Slinton default: 3939676Slinton /* do nothing */ 3949676Slinton break; 3959676Slinton } 3969676Slinton } 3979676Slinton 3989676Slinton /* 3999676Slinton * Print out the value on top of the stack according to the given type. 4009676Slinton */ 4019676Slinton 4029676Slinton public printval(t) 4039676Slinton Symbol t; 4049676Slinton { 4059676Slinton Symbol s; 4069676Slinton 4079676Slinton checkref(t); 4089676Slinton switch (t->class) { 4099676Slinton case PROC: 4109676Slinton case FUNC: 4119676Slinton s = pop(Symbol); 4129676Slinton printf("%s", symname(s)); 4139676Slinton break; 4149676Slinton 4159676Slinton default: 4169676Slinton if (t->language == nil) { 4179676Slinton error("unknown language"); 4189676Slinton } else { 4199676Slinton (*language_op(t->language, L_PRINTVAL))(t); 4209676Slinton } 4219676Slinton break; 4229676Slinton } 4239676Slinton } 4249676Slinton 4259676Slinton /* 4269676Slinton * Print out the value of a record, field by field. 4279676Slinton */ 4289676Slinton 4299676Slinton public printrecord(s) 4309676Slinton Symbol s; 4319676Slinton { 4329676Slinton if (s->chain == nil) { 4339676Slinton error("record has no fields"); 4349676Slinton } 4359676Slinton printf("("); 4369676Slinton sp -= size(s); 4379676Slinton printfield(s->chain); 4389676Slinton printf(")"); 4399676Slinton } 4409676Slinton 4419676Slinton /* 4429676Slinton * Print out a field, first printing out other fields. 4439676Slinton * This is done because the fields are chained together backwards. 4449676Slinton */ 4459676Slinton 4469676Slinton private printfield(s) 4479676Slinton Symbol s; 4489676Slinton { 4499676Slinton Stack *savesp; 4509676Slinton 4519676Slinton if (s->chain != nil) { 4529676Slinton printfield(s->chain); 4539676Slinton printf(", "); 4549676Slinton } 4559676Slinton printf("%s = ", symname(s)); 4569676Slinton savesp = sp; 4579676Slinton sp += ((s->symvalue.field.offset div BITSPERBYTE) + size(s->type)); 4589676Slinton printval(s); 4599676Slinton sp = savesp; 4609676Slinton } 4619676Slinton 4629676Slinton /* 4639676Slinton * Print out the contents of an array. 4649676Slinton * Haven't quite figured out what the best format is. 4659676Slinton * 4669676Slinton * This is rather inefficient. 4679676Slinton * 4689676Slinton * The "2*elsize" is there since "printval" drops the stack by elsize. 4699676Slinton */ 4709676Slinton 4719676Slinton public printarray(a) 4729676Slinton Symbol a; 4739676Slinton { 4749676Slinton Stack *savesp, *newsp; 4759676Slinton Symbol eltype; 4769676Slinton long elsize; 4779676Slinton String sep; 4789676Slinton 4799676Slinton savesp = sp; 48012544Scsvaf sp -= (size(a)); 4819676Slinton newsp = sp; 4829676Slinton eltype = rtype(a->type); 4839676Slinton elsize = size(eltype); 4849676Slinton printf("("); 4859676Slinton if (eltype->class == RECORD or eltype->class == ARRAY or 4869676Slinton eltype->class == VARNT) { 4879676Slinton sep = "\n"; 4889676Slinton putchar('\n'); 4899676Slinton } else { 4909676Slinton sep = ", "; 4919676Slinton } 4929676Slinton for (sp += elsize; sp <= savesp; sp += 2*elsize) { 4939676Slinton if (sp - elsize != newsp) { 4949676Slinton fputs(sep, stdout); 4959676Slinton } 4969676Slinton printval(eltype); 4979676Slinton } 4989676Slinton sp = newsp; 4999676Slinton if (streq(sep, "\n")) { 5009676Slinton putchar('\n'); 5019676Slinton } 5029676Slinton printf(")"); 5039676Slinton } 5049676Slinton 5059676Slinton /* 5069676Slinton * Print out the value of a real number in Pascal notation. 5079676Slinton * This is, unfortunately, different than what one gets 5089676Slinton * from "%g" in printf. 5099676Slinton */ 5109676Slinton 5119676Slinton public prtreal(r) 5129676Slinton double r; 5139676Slinton { 5149676Slinton extern char *index(); 5159676Slinton char buf[256]; 5169676Slinton 5179676Slinton sprintf(buf, "%g", r); 5189676Slinton if (buf[0] == '.') { 5199676Slinton printf("0%s", buf); 5209676Slinton } else if (buf[0] == '-' and buf[1] == '.') { 5219676Slinton printf("-0%s", &buf[1]); 5229676Slinton } else { 5239676Slinton printf("%s", buf); 5249676Slinton } 5259676Slinton if (index(buf, '.') == nil) { 5269676Slinton printf(".0"); 5279676Slinton } 5289676Slinton } 5299676Slinton 5309676Slinton /* 5319676Slinton * Print out a character using ^? notation for unprintables. 5329676Slinton */ 5339676Slinton 5349676Slinton public printchar(c) 5359676Slinton char c; 5369676Slinton { 5379676Slinton if (c == 0) { 5389676Slinton putchar('\\'); 5399676Slinton putchar('0'); 5409676Slinton } else if (c == '\n') { 5419676Slinton putchar('\\'); 5429676Slinton putchar('n'); 5439676Slinton } else if (c > 0 and c < ' ') { 5449676Slinton putchar('^'); 5459676Slinton putchar(c - 1 + 'A'); 5469676Slinton } else { 5479676Slinton putchar(c); 5489676Slinton } 5499676Slinton } 550