19676Slinton /* Copyright (c) 1982 Regents of the University of California */ 29676Slinton 3*12628Scsvaf static char sccsid[] = "@(#)printsym.c 1.7 05/20/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 "); 103*12628Scsvaf 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: 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 } 212*12628Scsvaf if(s->type->class == ARRAY && (! istypename(s->type->type,"char")) ) { 213*12628Scsvaf printf(" ARRAY "); 2149676Slinton } else { 215*12628Scsvaf if (isvarparam(s)) { 216*12628Scsvaf rpush(address(s, frame), sizeof(Address)); 217*12628Scsvaf addr = pop(Address); 218*12628Scsvaf len = size(s->type); 219*12628Scsvaf } else { 220*12628Scsvaf addr = address(s, frame); 221*12628Scsvaf len = size(s); 222*12628Scsvaf } 223*12628Scsvaf if (canpush(len)) { 224*12628Scsvaf rpush(addr, len); 225*12628Scsvaf printval(s->type); 226*12628Scsvaf } else { 227*12628Scsvaf printf("*** expression too large ***"); 228*12628Scsvaf } 229*12628Scsvaf } 2309676Slinton } 2319676Slinton 2329676Slinton /* 2339676Slinton * Print out the name of a symbol. 2349676Slinton */ 2359676Slinton 2369676Slinton public printname(f, s) 2379676Slinton File f; 2389676Slinton Symbol s; 2399676Slinton { 2409676Slinton if (s == nil) { 2419676Slinton fprintf(f, "(noname)"); 2429676Slinton } else if (isredirected() or isambiguous(s)) { 2439676Slinton printwhich(f, s); 2449676Slinton } else { 2459676Slinton fprintf(f, "%s", symname(s)); 2469676Slinton } 2479676Slinton } 2489676Slinton 2499676Slinton /* 2509676Slinton * Print the fully specified variable that is described by the given identifer. 2519676Slinton */ 2529676Slinton 2539676Slinton public printwhich(f, s) 2549676Slinton File f; 2559676Slinton Symbol s; 2569676Slinton { 2579676Slinton printouter(f, container(s)); 2589676Slinton fprintf(f, "%s", symname(s)); 2599676Slinton } 2609676Slinton 2619676Slinton /* 2629676Slinton * Print the fully qualified name of each symbol that has the same name 2639676Slinton * as the given symbol. 2649676Slinton */ 2659676Slinton 2669676Slinton public printwhereis(f, s) 2679676Slinton File f; 2689676Slinton Symbol s; 2699676Slinton { 2709676Slinton register Name n; 2719676Slinton register Symbol t; 2729676Slinton 2739676Slinton checkref(s); 2749676Slinton n = s->name; 2759676Slinton t = lookup(n); 2769676Slinton printwhich(f, t); 2779676Slinton t = t->next_sym; 2789676Slinton while (t != nil) { 2799676Slinton if (t->name == n) { 2809676Slinton putc(' ', f); 2819676Slinton printwhich(f, t); 2829676Slinton } 2839676Slinton t = t->next_sym; 2849676Slinton } 2859676Slinton putc('\n', f); 2869676Slinton } 2879676Slinton 2889676Slinton private printouter(f, s) 2899676Slinton File f; 2909676Slinton Symbol s; 2919676Slinton { 2929676Slinton Symbol outer; 2939676Slinton 2949676Slinton if (s != nil) { 2959676Slinton outer = container(s); 2969676Slinton if (outer != nil and outer != program) { 2979676Slinton printouter(f, outer); 2989676Slinton } 2999676Slinton fprintf(f, "%s.", symname(s)); 3009676Slinton } 3019676Slinton } 3029676Slinton 3039676Slinton public printdecl(s) 3049676Slinton Symbol s; 3059676Slinton { 3069676Slinton checkref(s); 3079676Slinton (*language_op(s->language, L_PRINTDECL))(s); 3089676Slinton } 3099676Slinton 3109676Slinton /* 3119676Slinton * Straight dump of symbol information. 3129676Slinton */ 3139676Slinton 3149676Slinton public psym(s) 3159676Slinton Symbol s; 3169676Slinton { 3179676Slinton printf("name\t%s\n", symname(s)); 3189676Slinton printf("lang\t%s\n", language_name(s->language)); 3199676Slinton printf("level\t%d\n", s->level); 3209676Slinton printf("class\t%s\n", classname(s)); 3219676Slinton printf("type\t0x%x", s->type); 3229676Slinton if (s->type != nil and s->type->name != nil) { 3239676Slinton printf(" (%s)", symname(s->type)); 3249676Slinton } 3259676Slinton printf("\nchain\t0x%x", s->chain); 3269676Slinton if (s->chain != nil and s->chain->name != nil) { 3279676Slinton printf(" (%s)", symname(s->chain)); 3289676Slinton } 3299676Slinton printf("\nblock\t0x%x", s->block); 3309676Slinton if (s->block->name != nil) { 3319676Slinton printf(" ("); 3329676Slinton printname(stdout, s->block); 3339676Slinton putchar(')'); 3349676Slinton } 3359676Slinton putchar('\n'); 3369676Slinton switch (s->class) { 3379676Slinton case VAR: 3389676Slinton case REF: 3399676Slinton if (s->level >= 3) { 3409676Slinton printf("address\t0x%x\n", s->symvalue.offset); 3419676Slinton } else { 3429676Slinton printf("offset\t%d\n", s->symvalue.offset); 3439676Slinton } 34412545Scsvaf printf("size\t%d\n", size(s)); 3459676Slinton break; 3469676Slinton 3479676Slinton case RECORD: 3489676Slinton case VARNT: 3499676Slinton printf("size\t%d\n", s->symvalue.offset); 3509676Slinton break; 3519676Slinton 3529676Slinton case FIELD: 3539676Slinton printf("offset\t%d\n", s->symvalue.field.offset); 3549676Slinton printf("size\t%d\n", s->symvalue.field.length); 3559676Slinton break; 3569676Slinton 3579676Slinton case PROC: 3589676Slinton case FUNC: 3599676Slinton printf("address\t0x%x\n", s->symvalue.funcv.beginaddr); 36011863Slinton if (nosource(s)) { 36111863Slinton printf("does not have source information\n"); 36211863Slinton } else { 36311863Slinton printf("has source information\n"); 36411863Slinton } 3659676Slinton break; 3669676Slinton 3679676Slinton case RANGE: 36812544Scsvaf switch(s->symvalue.rangev.lowertype) { 36912544Scsvaf 37012544Scsvaf case R_CONST : printf("CONST"); 37112544Scsvaf break; 37212544Scsvaf case R_ARG : printf("ARG"); 37312544Scsvaf break; 37412544Scsvaf case R_TEMP : printf("TEMP"); 37512544Scsvaf break; 37612544Scsvaf case R_ADJUST : printf("ADJUST"); 37712544Scsvaf break; 37812544Scsvaf } 3799676Slinton printf("lower\t%d\n", s->symvalue.rangev.lower); 38012544Scsvaf 38112544Scsvaf switch(s->symvalue.rangev.uppertype) { 38212544Scsvaf 38312544Scsvaf case R_CONST : printf("CONST"); 38412544Scsvaf break; 38512544Scsvaf case R_ARG : printf("ARG"); 38612544Scsvaf break; 38712544Scsvaf case R_TEMP : printf("TEMP"); 38812544Scsvaf break; 38912544Scsvaf case R_ADJUST : printf("ADJUST"); 39012544Scsvaf break; 39112544Scsvaf } 39212544Scsvaf 3939676Slinton printf("upper\t%d\n", s->symvalue.rangev.upper); 3949676Slinton break; 3959676Slinton 3969676Slinton default: 3979676Slinton /* do nothing */ 3989676Slinton break; 3999676Slinton } 4009676Slinton } 4019676Slinton 4029676Slinton /* 4039676Slinton * Print out the value on top of the stack according to the given type. 4049676Slinton */ 4059676Slinton 4069676Slinton public printval(t) 4079676Slinton Symbol t; 4089676Slinton { 4099676Slinton Symbol s; 4109676Slinton 4119676Slinton checkref(t); 4129676Slinton switch (t->class) { 4139676Slinton case PROC: 4149676Slinton case FUNC: 4159676Slinton s = pop(Symbol); 4169676Slinton printf("%s", symname(s)); 4179676Slinton break; 4189676Slinton 4199676Slinton default: 4209676Slinton if (t->language == nil) { 4219676Slinton error("unknown language"); 4229676Slinton } else { 4239676Slinton (*language_op(t->language, L_PRINTVAL))(t); 4249676Slinton } 4259676Slinton break; 4269676Slinton } 4279676Slinton } 4289676Slinton 4299676Slinton /* 4309676Slinton * Print out the value of a record, field by field. 4319676Slinton */ 4329676Slinton 4339676Slinton public printrecord(s) 4349676Slinton Symbol s; 4359676Slinton { 4369676Slinton if (s->chain == nil) { 4379676Slinton error("record has no fields"); 4389676Slinton } 4399676Slinton printf("("); 4409676Slinton sp -= size(s); 4419676Slinton printfield(s->chain); 4429676Slinton printf(")"); 4439676Slinton } 4449676Slinton 4459676Slinton /* 4469676Slinton * Print out a field, first printing out other fields. 4479676Slinton * This is done because the fields are chained together backwards. 4489676Slinton */ 4499676Slinton 4509676Slinton private printfield(s) 4519676Slinton Symbol s; 4529676Slinton { 4539676Slinton Stack *savesp; 4549676Slinton 4559676Slinton if (s->chain != nil) { 4569676Slinton printfield(s->chain); 4579676Slinton printf(", "); 4589676Slinton } 4599676Slinton printf("%s = ", symname(s)); 4609676Slinton savesp = sp; 4619676Slinton sp += ((s->symvalue.field.offset div BITSPERBYTE) + size(s->type)); 4629676Slinton printval(s); 4639676Slinton sp = savesp; 4649676Slinton } 4659676Slinton 4669676Slinton /* 4679676Slinton * Print out the contents of an array. 4689676Slinton * Haven't quite figured out what the best format is. 4699676Slinton * 4709676Slinton * This is rather inefficient. 4719676Slinton * 4729676Slinton * The "2*elsize" is there since "printval" drops the stack by elsize. 4739676Slinton */ 4749676Slinton 4759676Slinton public printarray(a) 4769676Slinton Symbol a; 4779676Slinton { 4789676Slinton Stack *savesp, *newsp; 4799676Slinton Symbol eltype; 4809676Slinton long elsize; 4819676Slinton String sep; 4829676Slinton 4839676Slinton savesp = sp; 48412544Scsvaf sp -= (size(a)); 4859676Slinton newsp = sp; 4869676Slinton eltype = rtype(a->type); 4879676Slinton elsize = size(eltype); 4889676Slinton printf("("); 4899676Slinton if (eltype->class == RECORD or eltype->class == ARRAY or 4909676Slinton eltype->class == VARNT) { 4919676Slinton sep = "\n"; 4929676Slinton putchar('\n'); 4939676Slinton } else { 4949676Slinton sep = ", "; 4959676Slinton } 4969676Slinton for (sp += elsize; sp <= savesp; sp += 2*elsize) { 4979676Slinton if (sp - elsize != newsp) { 4989676Slinton fputs(sep, stdout); 4999676Slinton } 5009676Slinton printval(eltype); 5019676Slinton } 5029676Slinton sp = newsp; 5039676Slinton if (streq(sep, "\n")) { 5049676Slinton putchar('\n'); 5059676Slinton } 5069676Slinton printf(")"); 5079676Slinton } 5089676Slinton 5099676Slinton /* 5109676Slinton * Print out the value of a real number in Pascal notation. 5119676Slinton * This is, unfortunately, different than what one gets 5129676Slinton * from "%g" in printf. 5139676Slinton */ 5149676Slinton 5159676Slinton public prtreal(r) 5169676Slinton double r; 5179676Slinton { 5189676Slinton extern char *index(); 5199676Slinton char buf[256]; 5209676Slinton 5219676Slinton sprintf(buf, "%g", r); 5229676Slinton if (buf[0] == '.') { 5239676Slinton printf("0%s", buf); 5249676Slinton } else if (buf[0] == '-' and buf[1] == '.') { 5259676Slinton printf("-0%s", &buf[1]); 5269676Slinton } else { 5279676Slinton printf("%s", buf); 5289676Slinton } 5299676Slinton if (index(buf, '.') == nil) { 5309676Slinton printf(".0"); 5319676Slinton } 5329676Slinton } 5339676Slinton 5349676Slinton /* 5359676Slinton * Print out a character using ^? notation for unprintables. 5369676Slinton */ 5379676Slinton 5389676Slinton public printchar(c) 5399676Slinton char c; 5409676Slinton { 5419676Slinton if (c == 0) { 5429676Slinton putchar('\\'); 5439676Slinton putchar('0'); 5449676Slinton } else if (c == '\n') { 5459676Slinton putchar('\\'); 5469676Slinton putchar('n'); 5479676Slinton } else if (c > 0 and c < ' ') { 5489676Slinton putchar('^'); 5499676Slinton putchar(c - 1 + 'A'); 5509676Slinton } else { 5519676Slinton putchar(c); 5529676Slinton } 5539676Slinton } 554