Annotation of 43BSD/ucb/dbx/printsym.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1983 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: static char sccsid[] = "@(#)printsym.c 5.3 (Berkeley) 3/5/86";
                      9: #endif not lint
                     10: 
                     11: static char rcsid[] = "$Header: printsym.c,v 1.5 84/12/26 10:41:28 linton Exp $";
                     12: 
                     13: /*
                     14:  * Printing of symbolic information.
                     15:  */
                     16: 
                     17: #include "defs.h"
                     18: #include "symbols.h"
                     19: #include "languages.h"
                     20: #include "printsym.h"
                     21: #include "tree.h"
                     22: #include "eval.h"
                     23: #include "mappings.h"
                     24: #include "process.h"
                     25: #include "runtime.h"
                     26: #include "machine.h"
                     27: #include "names.h"
                     28: #include "keywords.h"
                     29: #include "main.h"
                     30: 
                     31: #ifndef public
                     32: #endif
                     33: 
                     34: /*
                     35:  * Maximum number of arguments to a function.
                     36:  * This is used as a check for the possibility that the stack has been
                     37:  * overwritten and therefore a saved argument pointer might indicate
                     38:  * to an absurdly large number of arguments.
                     39:  */
                     40: 
                     41: #define MAXARGSPASSED 20
                     42: 
                     43: /*
                     44:  * Return a pointer to the string for the name of the class that
                     45:  * the given symbol belongs to.
                     46:  */
                     47: 
                     48: private String clname[] = {
                     49:     "bad use", "constant", "type", "variable", "array", "@dynarray",
                     50:     "@subarray", "fileptr", "record", "field",
                     51:     "procedure", "function", "funcvar",
                     52:     "ref", "pointer", "file", "set", "range", "label", "withptr",
                     53:     "scalar", "string", "program", "improper", "variant",
                     54:     "procparam", "funcparam", "module", "tag", "common", "extref", "typeref"
                     55: };
                     56: 
                     57: public String classname(s)
                     58: Symbol s;
                     59: {
                     60:     return clname[ord(s->class)];
                     61: }
                     62: 
                     63: /*
                     64:  * Note the entry of the given block, unless it's the main program.
                     65:  */
                     66: 
                     67: public printentry(s)
                     68: Symbol s;
                     69: {
                     70:     if (s != program) {
                     71:        printf("\nentering %s ", classname(s));
                     72:        printname(stdout, s);
                     73:        printf("\n");
                     74:     }
                     75: }
                     76: 
                     77: /*
                     78:  * Note the exit of the given block
                     79:  */
                     80: 
                     81: public printexit(s)
                     82: Symbol s;
                     83: {
                     84:     if (s != program) {
                     85:        printf("leaving %s ", classname(s));
                     86:        printname(stdout, s);
                     87:        printf("\n\n");
                     88:     }
                     89: }
                     90: 
                     91: /*
                     92:  * Note the call of s from t.
                     93:  */
                     94: 
                     95: public printcall(s, t)
                     96: Symbol s, t;
                     97: {
                     98:     printf("calling ");
                     99:     printname(stdout, s);
                    100:     printparams(s, nil);
                    101:     printf(" from %s ", classname(t));
                    102:     printname(stdout, t);
                    103:     printf("\n");
                    104: }
                    105: 
                    106: /*
                    107:  * Note the return from s.  If s is a function, print the value
                    108:  * it is returning.  This is somewhat painful, since the function
                    109:  * has actually just returned.
                    110:  */
                    111: 
                    112: public printrtn(s)
                    113: Symbol s;
                    114: {
                    115:     register Symbol t;
                    116:     register int len;
                    117:     Boolean isindirect;
                    118: 
                    119:     printf("returning ");
                    120:     if (s->class == FUNC && (!istypename(s->type,"void"))) {
                    121:        len = size(s->type);
                    122:        if (canpush(len)) {
                    123:            t = rtype(s->type);
                    124:            isindirect = (Boolean) (t->class == RECORD or t->class == VARNT);
                    125:            pushretval(len, isindirect);
                    126:            printval(s->type);
                    127:            putchar(' ');
                    128:        } else {
                    129:            printf("(value too large) ");
                    130:        }
                    131:     }
                    132:     printf("from ");
                    133:     printname(stdout, s);
                    134:     printf("\n");
                    135: }
                    136: 
                    137: /*
                    138:  * Print the values of the parameters of the given procedure or function.
                    139:  * The frame distinguishes recursive instances of a procedure.
                    140:  *
                    141:  * If the procedure or function is internal, the argument count is
                    142:  * not valid so we ignore it.
                    143:  */
                    144: 
                    145: public printparams(f, frame)
                    146: Symbol f;
                    147: Frame frame;
                    148: {
                    149:     Symbol param;
                    150:     int n, m, s;
                    151: 
                    152:     n = nargspassed(frame);
                    153:     if (isinternal(f)) {
                    154:        n = 0;
                    155:     }
                    156:     printf("(");
                    157:     param = f->chain;
                    158:     if (param != nil or n > 0) {
                    159:        m = n;
                    160:        if (param != nil) {
                    161:            for (;;) {
                    162:                s = psize(param) div sizeof(Word);
                    163:                if (s == 0) {
                    164:                    s = 1;
                    165:                }
                    166:                m -= s;
                    167:                if (showaggrs) {
                    168:                    printv(param, frame);
                    169:                } else {
                    170:                    printparamv(param, frame);
                    171:                }
                    172:                param = param->chain;
                    173:            if (param == nil) break;
                    174:                printf(", ");
                    175:            }
                    176:        }
                    177:        if (m > 0) {
                    178:            if (m > MAXARGSPASSED) {
                    179:                m = MAXARGSPASSED;
                    180:            }
                    181:            if (f->chain != nil) {
                    182:                printf(", ");
                    183:            }
                    184:            for (;;) {
                    185:                --m;
                    186:                printf("0x%x", argn(n - m, frame));
                    187:            if (m <= 0) break;
                    188:                printf(", ");
                    189:            }
                    190:        }
                    191:     }
                    192:     printf(")");
                    193: }
                    194: 
                    195: /*
                    196:  * Test if a symbol should be printed.  We don't print files,
                    197:  * for example, simply because there's no good way to do it.
                    198:  * The symbol must be within the given function.
                    199:  */
                    200: 
                    201: public Boolean should_print(s)
                    202: Symbol s;
                    203: {
                    204:     Boolean b;
                    205:     register Symbol t;
                    206: 
                    207:     switch (s->class) {
                    208:        case VAR:
                    209:        case FVAR:
                    210:            if (isparam(s)) {
                    211:                b = false;
                    212:            } else {
                    213:                t = rtype(s->type);
                    214:                if (t == nil) {
                    215:                    b = false;
                    216:                } else {
                    217:                    switch (t->class) {
                    218:                        case FILET:
                    219:                        case SET:
                    220:                        case BADUSE:
                    221:                            b = false;
                    222:                            break;
                    223: 
                    224:                        default:
                    225:                            b = true;
                    226:                            break;
                    227:                    }
                    228:                }
                    229:            }
                    230:            break;
                    231: 
                    232:        default:
                    233:            b = false;
                    234:            break;
                    235:     }
                    236:     return b;
                    237: }
                    238: 
                    239: /*
                    240:  * Print out a parameter value.
                    241:  *
                    242:  * Since this is intended to be printed on a single line with other information
                    243:  * aggregate values are not printed.
                    244:  */
                    245: 
                    246: public printparamv (p, frame)
                    247: Symbol p;
                    248: Frame frame;
                    249: {
                    250:     Symbol t;
                    251: 
                    252:     t = rtype(p->type);
                    253:     switch (t->class) {
                    254:        case ARRAY:
                    255:        case DYNARRAY:
                    256:        case SUBARRAY:
                    257:            t = rtype(t->type);
                    258:            if (compatible(t, t_char)) {
                    259:                printv(p, frame);
                    260:            } else {
                    261:                printf("%s = (...)", symname(p));
                    262:            }
                    263:            break;
                    264: 
                    265:        case RECORD:
                    266:            printf("%s = (...)", symname(p));
                    267:            break;
                    268: 
                    269:        default:
                    270:            printv(p, frame);
                    271:            break;
                    272:     }
                    273: }
                    274: 
                    275: /*
                    276:  * Print the name and value of a variable.
                    277:  */
                    278: 
                    279: public printv(s, frame)
                    280: Symbol s;
                    281: Frame frame;
                    282: {
                    283:     Address addr;
                    284:     int len;
                    285: 
                    286:     if (isambiguous(s) and ismodule(container(s))) {
                    287:        printname(stdout, s);
                    288:        printf(" = ");
                    289:     } else {
                    290:        printf("%s = ", symname(s));
                    291:     }
                    292:     if (isvarparam(s) and not isopenarray(s)) {
                    293:        rpush(address(s, frame), sizeof(Address));
                    294:        addr = pop(Address);
                    295:     } else {
                    296:        addr = address(s, frame);
                    297:     }
                    298:     len = size(s);
                    299:     if (not canpush(len)) {
                    300:        printf("*** expression too large ***");
                    301:     } else if (isreg(s)) {
                    302:        push(Address, addr);
                    303:        printval(s->type);
                    304:     } else {
                    305:        rpush(addr, len);
                    306:        printval(s->type);
                    307:     }
                    308: }
                    309: 
                    310: /*
                    311:  * Print out the name of a symbol.
                    312:  */
                    313: 
                    314: public printname(f, s)
                    315: File f;
                    316: Symbol s;
                    317: {
                    318:     if (s == nil) {
                    319:        fprintf(f, "(noname)");
                    320:     } else if (s == program) {
                    321:        fprintf(f, ".");
                    322:     } else if (isredirected() or isambiguous(s)) {
                    323:        printwhich(f, s);
                    324:     } else {
                    325:        fprintf(f, "%s", symname(s));
                    326:     }
                    327: }
                    328: 
                    329: /*
                    330:  * Print the fully specified variable that is described by the given identifer.
                    331:  */
                    332: 
                    333: public printwhich(f, s)
                    334: File f;
                    335: Symbol s;
                    336: {
                    337:     printouter(f, container(s));
                    338:     fprintf(f, "%s", symname(s));
                    339: }
                    340: 
                    341: /*
                    342:  * Print the fully qualified name of each symbol that has the same name
                    343:  * as the given symbol.
                    344:  */
                    345: 
                    346: public printwhereis(f, s)
                    347: File f;
                    348: Symbol s;
                    349: {
                    350:     register Name n;
                    351:     register Symbol t;
                    352: 
                    353:     checkref(s);
                    354:     n = s->name;
                    355:     t = lookup(n);
                    356:     printwhich(f, t);
                    357:     t = t->next_sym;
                    358:     while (t != nil) {
                    359:        if (t->name == n) {
                    360:            putc(' ', f);
                    361:            printwhich(f, t);
                    362:        }
                    363:        t = t->next_sym;
                    364:     }
                    365:     putc('\n', f);
                    366: }
                    367: 
                    368: private printouter(f, s)
                    369: File f;
                    370: Symbol s;
                    371: {
                    372:     Symbol outer;
                    373: 
                    374:     if (s != nil) {
                    375:        outer = container(s);
                    376:        if (outer != nil and outer != program) {
                    377:            printouter(f, outer);
                    378:        }
                    379:        fprintf(f, "%s.", symname(s));
                    380:     }
                    381: }
                    382: 
                    383: public printdecl(s)
                    384: Symbol s;
                    385: {
                    386:     Language lang;
                    387: 
                    388:     checkref(s);
                    389:     if (s->language == nil or s->language == primlang) {
                    390:        lang = findlanguage(".s");
                    391:     } else {
                    392:        lang = s->language;
                    393:     }
                    394:     (*language_op(lang, L_PRINTDECL))(s);
                    395: }
                    396: 
                    397: /*
                    398:  * Straight dump of symbol information.
                    399:  */
                    400: 
                    401: public psym(s)
                    402: Symbol s;
                    403: {
                    404:     printf("name\t%s\n", symname(s));
                    405:     printf("lang\t%s\n", language_name(s->language));
                    406:     printf("level\t%d\n", s->level);
                    407:     printf("class\t%s\n", classname(s));
                    408:     printf("type\t0x%x", s->type);
                    409:     if (s->type != nil and s->type->name != nil) {
                    410:        printf(" (%s)", symname(s->type));
                    411:     }
                    412:     printf("\nchain\t0x%x", s->chain);
                    413:     if (s->chain != nil and s->chain->name != nil) {
                    414:        printf(" (%s)", symname(s->chain));
                    415:     }
                    416:     printf("\nblock\t0x%x", s->block);
                    417:     if (s->block->name != nil) {
                    418:        printf(" (");
                    419:        printname(stdout, s->block);
                    420:        putchar(')');
                    421:     }
                    422:     putchar('\n');
                    423:     switch (s->class) {
                    424:        case TYPE:
                    425:            printf("size\t%d\n", size(s));
                    426:            break;
                    427: 
                    428:        case VAR:
                    429:        case REF:
                    430:            if (s->level >= 3) {
                    431:                printf("address\t0x%x\n", s->symvalue.offset);
                    432:            } else {
                    433:                printf("offset\t%d\n", s->symvalue.offset);
                    434:            }
                    435:            printf("size\t%d\n", size(s));
                    436:            break;
                    437: 
                    438:        case RECORD:
                    439:        case VARNT:
                    440:            printf("size\t%d\n", s->symvalue.offset);
                    441:            break;
                    442: 
                    443:        case FIELD:
                    444:            printf("offset\t%d\n", s->symvalue.field.offset);
                    445:            printf("size\t%d\n", s->symvalue.field.length);
                    446:            break;
                    447: 
                    448:        case PROG:
                    449:        case PROC:
                    450:        case FUNC:
                    451:            printf("address\t0x%x\n", s->symvalue.funcv.beginaddr);
                    452:            if (isinline(s)) {
                    453:                printf("inline procedure\n");
                    454:            }
                    455:            if (nosource(s)) {
                    456:                printf("does not have source information\n");
                    457:            } else {
                    458:                printf("has source information\n");
                    459:            }
                    460:            break;
                    461: 
                    462:        case RANGE:
                    463:            prangetype(s->symvalue.rangev.lowertype);
                    464:            printf("lower\t%d\n", s->symvalue.rangev.lower);
                    465:            prangetype(s->symvalue.rangev.uppertype);
                    466:            printf("upper\t%d\n", s->symvalue.rangev.upper);
                    467:            break;
                    468: 
                    469:        default:
                    470:            /* do nothing */
                    471:            break;
                    472:     }
                    473: }
                    474: 
                    475: private prangetype(r)
                    476: Rangetype r;
                    477: {
                    478:     switch (r) {
                    479:        case R_CONST:
                    480:            printf("CONST");
                    481:            break;
                    482: 
                    483:        case R_ARG:
                    484:            printf("ARG");
                    485:            break;
                    486: 
                    487:        case R_TEMP:
                    488:            printf("TEMP");
                    489:            break;
                    490: 
                    491:        case R_ADJUST:
                    492:            printf("ADJUST");
                    493:            break;
                    494:     }
                    495: }
                    496: 
                    497: /*
                    498:  * Print out the value on top of the stack according to the given type.
                    499:  */
                    500: 
                    501: public printval(t)
                    502: Symbol t;
                    503: {
                    504:     Symbol s;
                    505: 
                    506:     checkref(t);
                    507:     if (t->class == TYPEREF) {
                    508:        resolveRef(t);
                    509:     }
                    510:     switch (t->class) {
                    511:        case PROC:
                    512:        case FUNC:
                    513:            s = pop(Symbol);
                    514:            printf("%s", symname(s));
                    515:            break;
                    516: 
                    517:        default:
                    518:            if (t->language == nil or t->language == primlang) {
                    519:                (*language_op(findlanguage(".c"), L_PRINTVAL))(t);
                    520:            } else {
                    521:                (*language_op(t->language, L_PRINTVAL))(t);
                    522:            }
                    523:            break;
                    524:     }
                    525: }
                    526: 
                    527: /*
                    528:  * Print out the value of a record, field by field.
                    529:  */
                    530: 
                    531: public printrecord(s)
                    532: Symbol s;
                    533: {
                    534:     Symbol f;
                    535: 
                    536:     if (s->chain == nil) {
                    537:        error("record has no fields");
                    538:     }
                    539:     printf("(");
                    540:     sp -= size(s);
                    541:     f = s->chain;
                    542:     if (f != nil) {
                    543:        for (;;) {
                    544:            printfield(f);
                    545:            f = f->chain;
                    546:        if (f == nil) break;
                    547:            printf(", ");
                    548:        }
                    549:     }
                    550:     printf(")");
                    551: }
                    552: 
                    553: /*
                    554:  * Print out a field.
                    555:  */
                    556: 
                    557: private printfield(f)
                    558: Symbol f;
                    559: {
                    560:     Stack *savesp;
                    561:     register int off, len;
                    562: 
                    563:     printf("%s = ", symname(f));
                    564:     savesp = sp;
                    565:     off = f->symvalue.field.offset;
                    566:     len = f->symvalue.field.length;
                    567:     sp += ((off + len + BITSPERBYTE - 1) div BITSPERBYTE);
                    568:     printval(f);
                    569:     sp = savesp;
                    570: }
                    571: 
                    572: /*
                    573:  * Print out the contents of an array.
                    574:  * Haven't quite figured out what the best format is.
                    575:  *
                    576:  * This is rather inefficient.
                    577:  *
                    578:  * The "2*elsize" is there since "printval" drops the stack by elsize.
                    579:  */
                    580: 
                    581: public printarray(a)
                    582: Symbol a;
                    583: {
                    584:     Stack *savesp, *newsp;
                    585:     Symbol eltype;
                    586:     long elsize;
                    587:     String sep;
                    588: 
                    589:     savesp = sp;
                    590:     sp -= (size(a));
                    591:     newsp = sp;
                    592:     eltype = rtype(a->type);
                    593:     elsize = size(eltype);
                    594:     printf("(");
                    595:     if (eltype->class == RECORD or eltype->class == ARRAY or
                    596:       eltype->class == VARNT) {
                    597:        sep = "\n";
                    598:        putchar('\n');
                    599:     } else {
                    600:        sep = ", ";
                    601:     }
                    602:     for (sp += elsize; sp <= savesp; sp += 2*elsize) {
                    603:        if (sp - elsize != newsp) {
                    604:            fputs(sep, stdout);
                    605:        }
                    606:        printval(eltype);
                    607:     }
                    608:     sp = newsp;
                    609:     if (streq(sep, "\n")) {
                    610:        putchar('\n');
                    611:     }
                    612:     printf(")");
                    613: }
                    614: 
                    615: /*
                    616:  * Print out the value of a real number in Pascal notation.
                    617:  * This is, unfortunately, different than what one gets
                    618:  * from "%g" in printf.
                    619:  */
                    620: 
                    621: public prtreal(r)
                    622: double r;
                    623: {
                    624:     extern char *index();
                    625:     char buf[256];
                    626: 
                    627:     sprintf(buf, "%g", r);
                    628:     if (buf[0] == '.') {
                    629:        printf("0%s", buf);
                    630:     } else if (buf[0] == '-' and buf[1] == '.') {
                    631:        printf("-0%s", &buf[1]);
                    632:     } else {
                    633:        printf("%s", buf);
                    634:     }
                    635:     if (index(buf, '.') == nil) {
                    636:        printf(".0");
                    637:     }
                    638: }
                    639: 
                    640: /*
                    641:  * Print out a character using ^? notation for unprintables.
                    642:  */
                    643: 
                    644: public printchar(c)
                    645: char c;
                    646: {
                    647:     if (c == 0) {
                    648:        putchar('\\');
                    649:        putchar('0');
                    650:     } else if (c == '\n') {
                    651:        putchar('\\');
                    652:        putchar('n');
                    653:     } else if (c > 0 and c < ' ') {
                    654:        putchar('^');
                    655:        putchar(c - 1 + 'A');
                    656:     } else if (c >= ' ' && c <= '~') {
                    657:        putchar(c);
                    658:     } else {
                    659:        printf("\\0%o",c);
                    660:     }
                    661: }
                    662: 
                    663: /*
                    664:  * Print out a value for a range type (integer, char, or boolean).
                    665:  */
                    666: 
                    667: public printRangeVal (val, t)
                    668: long val;
                    669: Symbol t;
                    670: {
                    671:     if (t == t_boolean->type or istypename(t->type, "boolean")) {
                    672:        if ((boolean) val) {
                    673:            printf("true");
                    674:        } else {
                    675:            printf("false");
                    676:        }
                    677:     } else if (t == t_char->type or istypename(t->type, "char")) {
                    678:        if (varIsSet("$hexchars")) {
                    679:            printf("0x%lx", val);
                    680:        } else {
                    681:            putchar('\'');
                    682:            printchar(val);
                    683:            putchar('\'');
                    684:        }
                    685:     } else if (varIsSet("$hexints")) {
                    686:        printf("0x%lx", val);
                    687:     } else if (t->symvalue.rangev.lower >= 0) {
                    688:        printf("%lu", val);
                    689:     } else {
                    690:        printf("%ld", val);
                    691:     }
                    692: }
                    693: 
                    694: /*
                    695:  * Print out an enumerated value by finding the corresponding
                    696:  * name in the enumeration list.
                    697:  */
                    698: 
                    699: public printEnum (i, t)
                    700: integer i;
                    701: Symbol t;
                    702: {
                    703:     register Symbol e;
                    704: 
                    705:     e = t->chain;
                    706:     while (e != nil and e->symvalue.constval->value.lcon != i) {
                    707:        e = e->chain;
                    708:     }
                    709:     if (e != nil) {
                    710:        printf("%s", symname(e));
                    711:     } else {
                    712:        printf("%d", i);
                    713:     }
                    714: }
                    715: 
                    716: /*
                    717:  * Print out a null-terminated string (pointer to char)
                    718:  * starting at the given address.
                    719:  */
                    720: 
                    721: public printString (addr, quotes)
                    722: Address addr;
                    723: boolean quotes;
                    724: {
                    725:     register Address a;
                    726:     register integer i, len;
                    727:     register boolean endofstring;
                    728:     union {
                    729:        char ch[sizeof(Word)];
                    730:        int word;
                    731:     } u;
                    732: 
                    733:     if (varIsSet("$hexstrings")) {
                    734:        printf("0x%x", addr);
                    735:     } else {
                    736:        if (quotes) {
                    737:            putchar('"');
                    738:        }
                    739:        a = addr;
                    740:        endofstring = false;
                    741:        while (not endofstring) {
                    742:            dread(&u, a, sizeof(u));
                    743:            i = 0;
                    744:            do {
                    745:                if (u.ch[i] == '\0') {
                    746:                    endofstring = true;
                    747:                } else {
                    748:                    printchar(u.ch[i]);
                    749:                }
                    750:                ++i;
                    751:            } while (i < sizeof(Word) and not endofstring);
                    752:            a += sizeof(Word);
                    753:        }
                    754:        if (quotes) {
                    755:            putchar('"');
                    756:        }
                    757:     }
                    758: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.