Annotation of 43BSDReno/pgrm/dbx/vax.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1983 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted
                      6:  * provided that: (1) source distributions retain this entire copyright
                      7:  * notice and comment, and (2) distributions including binaries display
                      8:  * the following acknowledgement:  ``This product includes software
                      9:  * developed by the University of California, Berkeley and its contributors''
                     10:  * in the documentation or other materials provided with the distribution
                     11:  * and in all advertising materials mentioning features or use of this
                     12:  * software. Neither the name of the University nor the names of its
                     13:  * contributors may be used to endorse or promote products derived
                     14:  * from this software without specific prior written permission.
                     15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     16:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     18:  */
                     19: 
                     20: #ifndef lint
                     21: static char sccsid[] = "@(#)vax.c      5.8 (Berkeley) 6/1/90";
                     22: #endif /* not lint */
                     23: 
                     24: /*
                     25:  * Target machine dependent stuff.
                     26:  */
                     27: 
                     28: #include "defs.h"
                     29: #include "machine.h"
                     30: #include "process.h"
                     31: #include "runtime.h"
                     32: #include "events.h"
                     33: #include "main.h"
                     34: #include "symbols.h"
                     35: #include "source.h"
                     36: #include "mappings.h"
                     37: #include "object.h"
                     38: #include "tree.h"
                     39: #include "eval.h"
                     40: #include "keywords.h"
                     41: #include "ops.h"
                     42: 
                     43: #ifndef public
                     44: typedef unsigned int Address;
                     45: typedef unsigned char Byte;
                     46: typedef unsigned int Word;
                     47: 
                     48: #define NREG 16
                     49: 
                     50: #define ARGP 12
                     51: #define FRP 13
                     52: #define STKP 14
                     53: #define PROGCTR 15
                     54: 
                     55: #define CODESTART 0
                     56: #define FUNCOFFSET 2
                     57: 
                     58: #define nargspassed(frame) argn(0, frame)
                     59: 
                     60: #define BITSPERBYTE 8
                     61: #define BITSPERWORD (BITSPERBYTE * sizeof(Word))
                     62: 
                     63: /*
                     64:  * This magic macro enables us to look at the process' registers
                     65:  * in its user structure.
                     66:  */
                     67: 
                     68: #define regloc(reg)    (ctob(UPAGES) + (sizeof(Word) * (reg)))
                     69: 
                     70: #include "source.h"
                     71: #include "symbols.h"
                     72: #include <signal.h>
                     73: #include <sys/param.h>
                     74: #include <machine/psl.h>
                     75: #include <machine/pte.h>
                     76: #include <sys/user.h>
                     77: #undef DELETE /* XXX */
                     78: #include <sys/vm.h>
                     79: #include <machine/reg.h>
                     80: 
                     81: Address pc;
                     82: Address prtaddr;
                     83: 
                     84: #endif
                     85: 
                     86: /*
                     87:  * Indices into u. for use in collecting registers values.
                     88:  */
                     89: public int rloc[] ={
                     90:     R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, AP, FP, SP, PC
                     91: };
                     92: 
                     93: private Address printop();
                     94: 
                     95: private Optab *ioptab[256];    /* index by opcode to optab */
                     96: private Optab *esctab[256];    /* for extended opcodes */
                     97: 
                     98: /*
                     99:  * Initialize the opcode lookup table.
                    100:  */
                    101: public optab_init()
                    102: {
                    103:     register Optab *p;
                    104: 
                    105:     for (p = optab; p->iname; p++) {
                    106:        if (p->format == O_ESCD) {
                    107:            esctab[p->val] = p;
                    108:        } else if (p->format != O_ESCD && p->format != O_ESCE) {
                    109:            ioptab[p->val] = p;
                    110:        }
                    111:     }
                    112: }
                    113: 
                    114: /*
                    115:  * Decode and print the instructions within the given address range.
                    116:  */
                    117: 
                    118: public printinst(lowaddr, highaddr)
                    119: Address lowaddr;
                    120: Address highaddr;
                    121: {
                    122:     register Address addr;
                    123: 
                    124:     for (addr = lowaddr; addr <= highaddr; ) {
                    125:        addr = printop(addr);
                    126:     }
                    127:     prtaddr = addr;
                    128: }
                    129: 
                    130: /*
                    131:  * Another approach:  print n instructions starting at the given address.
                    132:  */
                    133: 
                    134: public printninst(count, addr)
                    135: int count;
                    136: Address addr;
                    137: {
                    138:     register Integer i;
                    139:     register Address newaddr;
                    140: 
                    141:     if (count <= 0) {
                    142:        error("non-positive repetition count");
                    143:     } else {
                    144:        newaddr = addr;
                    145:        for (i = 0; i < count; i++) {
                    146:            newaddr = printop(newaddr);
                    147:        }
                    148:        prtaddr = newaddr;
                    149:     }
                    150: }
                    151: 
                    152: /*
                    153:  * Print the contents of the addresses within the given range
                    154:  * according to the given format.
                    155:  */
                    156: 
                    157: typedef struct {
                    158:     String name;
                    159:     String printfstring;
                    160:     int length;
                    161: } Format;
                    162: 
                    163: private Format fmt[] = {
                    164:     { "d", " %d", sizeof(short) },
                    165:     { "D", " %ld", sizeof(long) },
                    166:     { "o", " %o", sizeof(short) },
                    167:     { "O", " %lo", sizeof(long) },
                    168:     { "x", " %04x", sizeof(short) },
                    169:     { "X", " %08x", sizeof(long) },
                    170:     { "b", " \\%o", sizeof(char) },
                    171:     { "c", " '%c'", sizeof(char) },
                    172:     { "s", "%c", sizeof(char) },
                    173:     { "f", " %f", sizeof(float) },
                    174:     { "g", " %g", sizeof(double) },
                    175:     { nil, nil, 0 }
                    176: };
                    177: 
                    178: private Format *findformat(s)
                    179: String s;
                    180: {
                    181:     register Format *f;
                    182: 
                    183:     f = &fmt[0];
                    184:     while (f->name != nil and not streq(f->name, s)) {
                    185:        ++f;
                    186:     }
                    187:     if (f->name == nil) {
                    188:        error("bad print format \"%s\"", s);
                    189:     }
                    190:     return f;
                    191: }
                    192: 
                    193: /*
                    194:  * Retrieve and print out the appropriate data in the given format.
                    195:  * Floats have to be handled specially to allow the compiler to
                    196:  * convert them to doubles when passing to printf.
                    197:  */
                    198: 
                    199: private printformat (f, addr)
                    200: Format *f;
                    201: Address addr;
                    202: {
                    203:     union {
                    204:        char charv;
                    205:        short shortv;
                    206:        int intv;
                    207:        float floatv;
                    208:        double doublev;
                    209:     } value;
                    210: 
                    211:     value.intv = 0;
                    212:     dread(&value, addr, f->length);
                    213:     if (streq(f->name, "f")) {
                    214:        printf(f->printfstring, value.floatv);
                    215:     } else {
                    216:        printf(f->printfstring, value);
                    217:     }
                    218: }
                    219: 
                    220: public Address printdata(lowaddr, highaddr, format)
                    221: Address lowaddr;
                    222: Address highaddr;
                    223: String format;
                    224: {
                    225:     int n;
                    226:     register Address addr;
                    227:     Format *f;
                    228: 
                    229:     if (lowaddr > highaddr) {
                    230:        error("first address larger than second");
                    231:     }
                    232:     f = findformat(format);
                    233:     n = 0;
                    234:     for (addr = lowaddr; addr <= highaddr; addr += f->length) {
                    235:        if (n == 0) {
                    236:            printf("%08x: ", addr);
                    237:        }
                    238:        printformat(f, addr);
                    239:        ++n;
                    240:        if (n >= (16 div f->length)) {
                    241:            printf("\n");
                    242:            n = 0;
                    243:        }
                    244:     }
                    245:     if (n != 0) {
                    246:        printf("\n");
                    247:     }
                    248:     prtaddr = addr;
                    249:     return addr;
                    250: }
                    251: 
                    252: /*
                    253:  * The other approach is to print n items starting with a given address.
                    254:  */
                    255: 
                    256: public printndata(count, startaddr, format)
                    257: int count;
                    258: Address startaddr;
                    259: String format;
                    260: {
                    261:     int i, n;
                    262:     Address addr;
                    263:     Format *f;
                    264:     Boolean isstring;
                    265:     char c;
                    266: 
                    267:     if (count <= 0) {
                    268:        error("non-positive repetition count");
                    269:     }
                    270:     f = findformat(format);
                    271:     isstring = (Boolean) streq(f->name, "s");
                    272:     n = 0;
                    273:     addr = startaddr;
                    274:     for (i = 0; i < count; i++) {
                    275:        if (n == 0) {
                    276:            printf("%08x: ", addr);
                    277:        }
                    278:        if (isstring) {
                    279:            printf("\"");
                    280:            dread(&c, addr, sizeof(char));
                    281:            while (c != '\0') {
                    282:                printchar(c);
                    283:                ++addr;
                    284:                dread(&c, addr, sizeof(char));
                    285:            }
                    286:            printf("\"\n");
                    287:            n = 0;
                    288:            addr += sizeof(String);
                    289:        } else {
                    290:            printformat(f, addr);
                    291:            ++n;
                    292:            if (n >= (16 div f->length)) {
                    293:                printf("\n");
                    294:                n = 0;
                    295:            }
                    296:            addr += f->length;
                    297:        }
                    298:     }
                    299:     if (n != 0) {
                    300:        printf("\n");
                    301:     }
                    302:     prtaddr = addr;
                    303: }
                    304: 
                    305: /*
                    306:  * Print out a value according to the given format.
                    307:  */
                    308: 
                    309: public printvalue(v, format)
                    310: long v;
                    311: String format;
                    312: {
                    313:     Format *f;
                    314:     char *p, *q;
                    315: 
                    316:     f = findformat(format);
                    317:     if (streq(f->name, "s")) {
                    318:        putchar('"');
                    319:        p = (char *) &v;
                    320:        q = p + sizeof(v);
                    321:        while (p < q) {
                    322:            printchar(*p);
                    323:            ++p;
                    324:        }
                    325:        putchar('"');
                    326:     } else {
                    327:        printf(f->printfstring, v);
                    328:     }
                    329:     putchar('\n');
                    330: }
                    331: 
                    332: /*
                    333:  * Print out an execution time error.
                    334:  * Assumes the source position of the error has been calculated.
                    335:  *
                    336:  * Have to check if the -r option was specified; if so then
                    337:  * the object file information hasn't been read in yet.
                    338:  */
                    339: 
                    340: public printerror()
                    341: {
                    342:     extern Integer sys_nsig;
                    343:     extern String sys_siglist[];
                    344:     integer err;
                    345: 
                    346:     if (isfinished(process)) {
                    347:        err = exitcode(process);
                    348:        if (err == 0) {
                    349:            printf("\"%s\" terminated normally\n", objname);
                    350:        } else {
                    351:            printf("\"%s\" terminated abnormally (exit code %d)\n",
                    352:                objname, err
                    353:            );
                    354:        }
                    355:        erecover();
                    356:     }
                    357:     err = errnum(process);
                    358:     putchar('\n');
                    359:     printsig(err);
                    360:     putchar(' ');
                    361:     printloc();
                    362:     putchar('\n');
                    363:     if (curline > 0) {
                    364:        printlines(curline, curline);
                    365:     } else {
                    366:        printinst(pc, pc);
                    367:     }
                    368:     erecover();
                    369: }
                    370: 
                    371: /*
                    372:  * Print out a signal.
                    373:  */
                    374: 
                    375: private String illinames[] = {
                    376:     "reserved addressing fault",
                    377:     "privileged instruction fault",
                    378:     "reserved operand fault"
                    379: };
                    380: 
                    381: private String fpenames[] = {
                    382:     nil,
                    383:     "integer overflow trap",
                    384:     "integer divide by zero trap",
                    385:     "floating overflow trap",
                    386:     "floating/decimal divide by zero trap",
                    387:     "floating underflow trap",
                    388:     "decimal overflow trap",
                    389:     "subscript out of range trap",
                    390:     "floating overflow fault",
                    391:     "floating divide by zero fault",
                    392:     "floating underflow fault"
                    393: };
                    394: 
                    395: public printsig (signo)
                    396: integer signo;
                    397: {
                    398:     integer code;
                    399: 
                    400:     if (signo < 0 or signo > sys_nsig) {
                    401:        printf("[signal %d]", signo);
                    402:     } else {
                    403:        printf("%s", sys_siglist[signo]);
                    404:     }
                    405:     code = errcode(process);
                    406:     if (signo == SIGILL) {
                    407:        if (code >= 0 and code < sizeof(illinames) / sizeof(illinames[0])) {
                    408:            printf(" (%s)", illinames[code]);
                    409:        }
                    410:     } else if (signo == SIGFPE) {
                    411:        if (code > 0 and code < sizeof(fpenames) / sizeof(fpenames[0])) {
                    412:            printf(" (%s)", fpenames[code]);
                    413:        }
                    414:     }
                    415: }
                    416: 
                    417: /*
                    418:  * Note the termination of the program.  We do this so as to avoid
                    419:  * having the process exit, which would make the values of variables
                    420:  * inaccessible.  We do want to flush all output buffers here,
                    421:  * otherwise it'll never get done.
                    422:  */
                    423: 
                    424: public endprogram()
                    425: {
                    426:     Integer exitcode;
                    427: 
                    428:     stepto(nextaddr(pc, true));
                    429:     printnews();
                    430:     exitcode = argn(1, nil);
                    431:     if (exitcode != 0) {
                    432:        printf("\nexecution completed (exit code %d)\n", exitcode);
                    433:     } else {
                    434:        printf("\nexecution completed\n");
                    435:     }
                    436:     getsrcpos();
                    437:     erecover();
                    438: }
                    439: 
                    440: /*
                    441:  * Single step the machine a source line (or instruction if "inst_tracing"
                    442:  * is true).  If "isnext" is true, skip over procedure calls.
                    443:  */
                    444: 
                    445: private Address getcall();
                    446: 
                    447: public dostep(isnext)
                    448: Boolean isnext;
                    449: {
                    450:     register Address addr;
                    451:     register Lineno line;
                    452:     String filename;
                    453:     Address startaddr;
                    454: 
                    455:     startaddr = pc;
                    456:     addr = nextaddr(pc, isnext);
                    457:     if (not inst_tracing and nlhdr.nlines != 0) {
                    458:        line = linelookup(addr);
                    459:        while (line == 0) {
                    460:            addr = nextaddr(addr, isnext);
                    461:            line = linelookup(addr);
                    462:        }
                    463:        curline = line;
                    464:     } else {
                    465:        curline = 0;
                    466:     }
                    467:     stepto(addr);
                    468:     filename = srcfilename(addr);
                    469:     setsource(filename);
                    470: }
                    471: 
                    472: typedef char Bpinst;
                    473: 
                    474: #define BP_OP       O_BPT       /* breakpoint trap */
                    475: 
                    476: #define BP_ERRNO    SIGTRAP     /* signal received at a breakpoint */
                    477: 
                    478: /*
                    479:  * Setting a breakpoint at a location consists of saving
                    480:  * the word at the location and poking a BP_OP there.
                    481:  *
                    482:  * We save the locations and words on a list for use in unsetting.
                    483:  */
                    484: 
                    485: typedef struct Savelist *Savelist;
                    486: 
                    487: struct Savelist {
                    488:     Address location;
                    489:     Bpinst save;
                    490:     short refcount;
                    491:     Savelist link;
                    492: };
                    493: 
                    494: private Savelist savelist;
                    495: 
                    496: /*
                    497:  * Set a breakpoint at the given address.  Only save the word there
                    498:  * if it's not already a breakpoint.
                    499:  */
                    500: 
                    501: public setbp(addr)
                    502: Address addr;
                    503: {
                    504:     Bpinst w, save;
                    505:     register Savelist newsave, s;
                    506: 
                    507:     for (s = savelist; s != nil; s = s->link) {
                    508:        if (s->location == addr) {
                    509:            s->refcount++;
                    510:            return;
                    511:        }
                    512:     }
                    513:     iread(&save, addr, sizeof(save));
                    514:     newsave = new(Savelist);
                    515:     newsave->location = addr;
                    516:     newsave->save = save;
                    517:     newsave->refcount = 1;
                    518:     newsave->link = savelist;
                    519:     savelist = newsave;
                    520:     w = BP_OP;
                    521:     iwrite(&w, addr, sizeof(w));
                    522: }
                    523: 
                    524: /*
                    525:  * Unset a breakpoint; unfortunately we have to search the SAVELIST
                    526:  * to find the saved value.  The assumption is that the SAVELIST will
                    527:  * usually be quite small.
                    528:  */
                    529: 
                    530: public unsetbp(addr)
                    531: Address addr;
                    532: {
                    533:     register Savelist s, prev;
                    534: 
                    535:     prev = nil;
                    536:     for (s = savelist; s != nil; s = s->link) {
                    537:        if (s->location == addr) {
                    538:            iwrite(&s->save, addr, sizeof(s->save));
                    539:            s->refcount--;
                    540:            if (s->refcount == 0) {
                    541:                if (prev == nil) {
                    542:                    savelist = s->link;
                    543:                } else {
                    544:                    prev->link = s->link;
                    545:                }
                    546:                dispose(s);
                    547:            }
                    548:            return;
                    549:        }
                    550:        prev = s;
                    551:     }
                    552:     panic("unsetbp: couldn't find address %d", addr);
                    553: }
                    554: 
                    555: /*
                    556:  * VAX instruction decoder, derived from adb.
                    557:  */
                    558: 
                    559: private Address printop(addr)
                    560: Address addr;
                    561: {
                    562:     register Optab *op;
                    563:     VaxOpcode ins;
                    564:     unsigned char mode;
                    565:     int argtype, amode, argno, argval;
                    566:     String reg;
                    567:     Boolean indexf;
                    568:     short offset;
                    569: 
                    570:     argval = 0;
                    571:     indexf = false;
                    572:     printf("%08x  ", addr);
                    573:     iread(&ins, addr, sizeof(ins));
                    574:     addr += 1;
                    575:     if (ins == O_ESCF) {
                    576:        iread(&ins, addr, sizeof(ins));
                    577:        addr += 1;
                    578:        op = ioptab[ins];
                    579:     } else if (ins == O_ESCD) {
                    580:        iread(&ins, addr, sizeof(ins));
                    581:        addr += 1;
                    582:        op = esctab[ins];
                    583:     } else {
                    584:        op = ioptab[ins];
                    585:     }
                    586:     if (op == nil) {
                    587:        printf("[unrecognized opcode %#0x]\n", ins);
                    588:        return addr;
                    589:     }
                    590:     printf("%s", op->iname);
                    591:     for (argno = 0; argno < op->numargs; argno++) {
                    592:        if (indexf == true) {
                    593:            indexf = false;
                    594:        } else if (argno == 0) {
                    595:            printf("\t");
                    596:        } else {
                    597:            printf(",");
                    598:        }
                    599:        argtype = op->argtype[argno];
                    600:        if (is_branch_disp(argtype)) {
                    601:            mode = 0xAF + (typelen(argtype) << 5);
                    602:        } else {
                    603:            iread(&mode, addr, sizeof(mode));
                    604:            addr += 1;
                    605:        }
                    606:        reg = regname[regnm(mode)];
                    607:        amode = addrmode(mode);
                    608:        switch (amode) {
                    609:            case LITSHORT:
                    610:            case LITUPTO31:
                    611:            case LITUPTO47:
                    612:            case LITUPTO63:
                    613:                if (typelen(argtype) == TYPF || typelen(argtype) == TYPD ||
                    614:                    typelen(argtype) == TYPG || typelen(argtype) == TYPH)
                    615:                    printf("$%s", fltimm[mode]);
                    616:                else
                    617:                    printf("$%x", mode);
                    618:                argval = mode;
                    619:                break;
                    620: 
                    621:            case INDEX:
                    622:                printf("[%s]", reg);
                    623:                indexf = true;
                    624:                argno--;
                    625:                break;
                    626: 
                    627:            case REG:
                    628:                printf("%s", reg);
                    629:                break;
                    630: 
                    631:            case REGDEF:
                    632:                printf("(%s)", reg);
                    633:                break;
                    634: 
                    635:            case AUTODEC:
                    636:                printf("-(%s)", reg);
                    637:                break;
                    638: 
                    639:            case AUTOINC:
                    640:                if (reg != regname[PROGCTR]) {
                    641:                    printf("(%s)+", reg);
                    642:                } else {
                    643:                    printf("$");
                    644:                    switch (typelen(argtype)) {
                    645:                        case TYPB:
                    646:                            argval = printdisp(addr, 1, reg, amode);
                    647:                            addr += 1;
                    648:                            break;
                    649: 
                    650:                        case TYPW:
                    651:                            argval = printdisp(addr, 2, reg, amode);
                    652:                            addr += 2;
                    653:                            break;
                    654: 
                    655:                        case TYPL:
                    656:                            argval = printdisp(addr, 4, reg, amode);
                    657:                            addr += 4;
                    658:                            break;
                    659: 
                    660:                        case TYPF:
                    661:                            iread(&argval, addr, sizeof(argval));
                    662:                            if ((argval & 0xffff007f) == 0x8000) {
                    663:                                printf("[reserved operand]");
                    664:                            } else {
                    665:                                printf("%g", *(float *)&argval);
                    666:                            }
                    667:                            addr += 4;
                    668:                            break;
                    669: 
                    670:                        case TYPD:
                    671:                            /* XXX this bags the low order bits */
                    672:                            iread(&argval, addr, sizeof(argval));
                    673:                            if ((argval & 0xffff007f) == 0x8000) {
                    674:                                printf("[reserved operand]");
                    675:                            } else {
                    676:                                printf("%g", *(float *)&argval);
                    677:                            }
                    678:                            addr += 8;
                    679:                            break;
                    680: 
                    681:                        case TYPG:
                    682:                        case TYPQ:
                    683:                            iread(&argval, addr+4, sizeof(argval));
                    684:                            printf("%08x", argval);
                    685:                            iread(&argval, addr, sizeof(argval));
                    686:                            printf("%08x", argval);
                    687:                            addr += 8;
                    688:                            break;
                    689: 
                    690:                        case TYPH:
                    691:                        case TYPO:
                    692:                            iread(&argval, addr+12, sizeof(argval));
                    693:                            printf("%08x", argval);
                    694:                            iread(&argval, addr+8, sizeof(argval));
                    695:                            printf("%08x", argval);
                    696:                            iread(&argval, addr+4, sizeof(argval));
                    697:                            printf("%08x", argval);
                    698:                            iread(&argval, addr, sizeof(argval));
                    699:                            printf("%08x", argval);
                    700:                            addr += 16;
                    701:                            break;
                    702:                    }
                    703:                }
                    704:                break;
                    705: 
                    706:            case AUTOINCDEF:
                    707:                if (reg == regname[PROGCTR]) {
                    708:                    printf("*$");
                    709:                    argval = printdisp(addr, 4, reg, amode);
                    710:                    addr += 4;
                    711:                } else {
                    712:                    printf("*(%s)+", reg);
                    713:                }
                    714:                break;
                    715: 
                    716:            case BYTEDISP:
                    717:                argval = printdisp(addr, 1, reg, amode);
                    718:                addr += 1;
                    719:                break;
                    720: 
                    721:            case BYTEDISPDEF:
                    722:                printf("*");
                    723:                argval = printdisp(addr, 1, reg, amode);
                    724:                addr += 1;
                    725:                break;
                    726: 
                    727:            case WORDDISP:
                    728:                argval = printdisp(addr, 2, reg, amode);
                    729:                addr += 2;
                    730:                break;
                    731: 
                    732:            case WORDDISPDEF:
                    733:                printf("*");
                    734:                argval = printdisp(addr, 2, reg, amode);
                    735:                addr += 2;
                    736:                break;
                    737: 
                    738:            case LONGDISP:
                    739:                argval = printdisp(addr, 4, reg, amode);
                    740:                addr += 4;
                    741:                break;
                    742: 
                    743:            case LONGDISPDEF:
                    744:                printf("*");
                    745:                argval = printdisp(addr, 4, reg, amode);
                    746:                addr += 4;
                    747:                break;
                    748:        }
                    749:     }
                    750:     if (ins == O_CASEB || ins == O_CASEW || ins == O_CASEL) {
                    751:        for (argno = 0; argno <= argval; argno++) {
                    752:            iread(&offset, addr, sizeof(offset));
                    753:            printf("\n\t\t%d", offset);
                    754:            addr += 2;
                    755:        }
                    756:     }
                    757:     printf("\n");
                    758:     return addr;
                    759: }
                    760: 
                    761: /*
                    762:  * Print the displacement of an instruction that uses displacement
                    763:  * addressing.
                    764:  */
                    765: 
                    766: private int printdisp(addr, nbytes, reg, mode)
                    767: Address addr;
                    768: int nbytes;
                    769: char *reg;
                    770: int mode;
                    771: {
                    772:     char byte;
                    773:     short hword;
                    774:     int argval;
                    775:     Symbol f;
                    776: 
                    777:     switch (nbytes) {
                    778:        case 1:
                    779:            iread(&byte, addr, sizeof(byte));
                    780:            argval = byte;
                    781:            break;
                    782: 
                    783:        case 2:
                    784:            iread(&hword, addr, sizeof(hword));
                    785:            argval = hword;
                    786:            break;
                    787: 
                    788:        case 4:
                    789:            iread(&argval, addr, sizeof(argval));
                    790:            break;
                    791:     }
                    792:     if (reg == regname[PROGCTR] && mode >= BYTEDISP) {
                    793:        argval += addr + nbytes;
                    794:     }
                    795:     if (reg == regname[PROGCTR]) {
                    796:        f = whatblock((Address) argval + 2);
                    797:        if (codeloc(f) == argval + 2) {
                    798:            printf("%s", symname(f));
                    799:        } else {
                    800:            printf("%x", argval);
                    801:        }
                    802:     } else {
                    803:        if (varIsSet("$hexoffsets")) {
                    804:            if (argval < 0) {
                    805:                printf("-%x(%s)", -(argval), reg);
                    806:            } else {
                    807:                printf("%x(%s)", argval, reg);
                    808:            }
                    809:        } else {
                    810:            printf("%d(%s)", argval, reg);
                    811:        }
                    812:     }
                    813:     return argval;
                    814: }
                    815: 
                    816: /*
                    817:  * Compute the next address that will be executed from the given one.
                    818:  * If "isnext" is true then consider a procedure call as straight line code.
                    819:  *
                    820:  * We must unfortunately do much of the same work that is necessary
                    821:  * to print instructions.  In addition we have to deal with branches.
                    822:  * Unconditional branches we just follow, for conditional branches
                    823:  * we continue execution to the current location and then single step
                    824:  * the machine.  We assume that the last argument in an instruction
                    825:  * that branches is the branch address (or relative offset).
                    826:  */
                    827: 
                    828: private Address findnextaddr();
                    829: 
                    830: public Address nextaddr(startaddr, isnext)
                    831: Address startaddr;
                    832: boolean isnext;
                    833: {
                    834:     Address addr;
                    835: 
                    836:     addr = usignal(process);
                    837:     if (addr == 0 or addr == 1) {
                    838:        addr = findnextaddr(startaddr, isnext);
                    839:     }
                    840:     return addr;
                    841: }
                    842: 
                    843: /*
                    844:  * Determine if it's ok to skip function f entered by instruction ins.
                    845:  * If so, we're going to compute the return address and step to it.
                    846:  * Therefore we cannot skip over a function entered by a jsb or bsb,
                    847:  * since the return address is not easily computed for them.
                    848:  */
                    849: 
                    850: private boolean skipfunc (ins, f)
                    851: VaxOpcode ins;
                    852: Symbol f;
                    853: {
                    854:     boolean b;
                    855: 
                    856:     b = (boolean) (
                    857:        ins != O_JSB and ins != O_BSBB and ins != O_BSBW and
                    858:        not inst_tracing and nlhdr.nlines != 0 and
                    859:        nosource(curfunc) and canskip(curfunc)
                    860:     );
                    861:     return b;
                    862: }
                    863: 
                    864: private Address findnextaddr(startaddr, isnext)
                    865: Address startaddr;
                    866: Boolean isnext;
                    867: {
                    868:     register Address addr;
                    869:     register Optab *op;
                    870:     VaxOpcode ins, ins2;
                    871:     unsigned char mode;
                    872:     int argtype, amode, argno, argval;
                    873:     String r;
                    874:     Boolean indexf;
                    875:     enum { KNOWN, SEQUENTIAL, BRANCH } addrstatus;
                    876: 
                    877:     argval = 0;
                    878:     indexf = false;
                    879:     addr = startaddr;
                    880:     iread(&ins, addr, sizeof(ins));
                    881:     switch (ins) {
                    882:        /*
                    883:         * It used to be that unconditional jumps and branches were handled
                    884:         * by taking their destination address as the next address.  While
                    885:         * saving the cost of starting up the process, this approach
                    886:         * doesn't work when jumping indirect (since the value in the
                    887:         * register might not yet have been set).
                    888:         *
                    889:         * So unconditional jumps and branches are now handled the same way
                    890:         * as conditional jumps and branches.
                    891:         *
                    892:        case O_BRB:
                    893:        case O_BRW:
                    894:            addrstatus = BRANCH;
                    895:            break;
                    896:         *
                    897:         */
                    898:            
                    899:        case O_BSBB:
                    900:        case O_BSBW:
                    901:        case O_JSB:
                    902:        case O_CALLG:
                    903:        case O_CALLS:
                    904:            addrstatus = KNOWN;
                    905:            stepto(addr);
                    906:            pstep(process, DEFSIG);
                    907:            addr = reg(PROGCTR);
                    908:            pc = addr;
                    909:            setcurfunc(whatblock(pc));
                    910:            if (not isbperr()) {
                    911:                printstatus();
                    912:                /* NOTREACHED */
                    913:            }
                    914:            bpact();
                    915:            if (isnext or skipfunc(ins, curfunc)) {
                    916:                addrstatus = KNOWN;
                    917:                addr = return_addr();
                    918:                stepto(addr);
                    919:                bpact();
                    920:            } else {
                    921:                callnews(/* iscall = */ true);
                    922:            }
                    923:            break;
                    924: 
                    925:        case O_RSB:
                    926:        case O_RET:
                    927:            addrstatus = KNOWN;
                    928:            stepto(addr);
                    929:            callnews(/* iscall = */ false);
                    930:            pstep(process, DEFSIG);
                    931:            addr = reg(PROGCTR);
                    932:            pc = addr;
                    933:            if (not isbperr()) {
                    934:                printstatus();
                    935:            }
                    936:            bpact();
                    937:            break;
                    938: 
                    939:        case O_BRB: case O_BRW:
                    940:        case O_JMP: /* because it may be jmp (r1) */
                    941:        case O_BNEQ: case O_BEQL: case O_BGTR:
                    942:        case O_BLEQ: case O_BGEQ: case O_BLSS:
                    943:        case O_BGTRU: case O_BLEQU: case O_BVC:
                    944:        case O_BVS: case O_BCC: case O_BCS:
                    945:        case O_CASEB: case O_CASEW: case O_CASEL:
                    946:        case O_BBS: case O_BBC: case O_BBSS: case O_BBCS:
                    947:        case O_BBSC: case O_BBCC: case O_BBSSI:
                    948:        case O_BBCCI: case O_BLBS: case O_BLBC:
                    949:        case O_ACBL: case O_AOBLSS: case O_AOBLEQ:
                    950:        case O_SOBGEQ: case O_SOBGTR:
                    951:        case O_ESCF: /* bugchecks */
                    952:        branches:
                    953:            addrstatus = KNOWN;
                    954:            stepto(addr);
                    955:            pstep(process, DEFSIG);
                    956:            addr = reg(PROGCTR);
                    957:            pc = addr;
                    958:            if (not isbperr()) {
                    959:                printstatus();
                    960:            }
                    961:            break;
                    962: 
                    963:        case O_ESCD:
                    964:            iread(&ins2, addr+1, sizeof(ins2));
                    965:            if (ins2 == O_ACBF || ins2 == O_ACBD)
                    966:                /* actually ACBG and ACBH */
                    967:                goto branches;
                    968:            /* fall through */
                    969: 
                    970:        default:
                    971:            addrstatus = SEQUENTIAL;
                    972:            break;
                    973:     }
                    974:     if (addrstatus != KNOWN) {
                    975:        addr += 1;
                    976:        if (ins == O_ESCD) {
                    977:            ins = ins2;
                    978:            addr += 1;
                    979:            op = esctab[ins];
                    980:            if (op == nil) {
                    981:                printf("[bad extended opcode %#x in findnextaddr]\n", ins);
                    982:                return addr;
                    983:            }
                    984:        } else {
                    985:            op = ioptab[ins];
                    986:            if (op == nil) {
                    987:                printf("[bad opcode %#x in findnextaddr]\n", ins);
                    988:                return addr;
                    989:            }
                    990:        }
                    991:        for (argno = 0; argno < op->numargs; argno++) {
                    992:            if (indexf == true) {
                    993:                indexf = false;
                    994:            }
                    995:            argtype = op->argtype[argno];
                    996:            if (is_branch_disp(argtype)) {
                    997:                mode = 0xAF + (typelen(argtype) << 5);
                    998:            } else {
                    999:                iread(&mode, addr, sizeof(mode));
                   1000:                addr += 1;
                   1001:            }
                   1002:            r = regname[regnm(mode)];
                   1003:            amode = addrmode(mode);
                   1004:            switch (amode) {
                   1005:                case LITSHORT:
                   1006:                case LITUPTO31:
                   1007:                case LITUPTO47:
                   1008:                case LITUPTO63:
                   1009:                    argval = mode;
                   1010:                    break;
                   1011: 
                   1012:                case INDEX:
                   1013:                    indexf = true;
                   1014:                    --argno;
                   1015:                    break;
                   1016: 
                   1017:                case REG:
                   1018:                case REGDEF:
                   1019:                case AUTODEC:
                   1020:                    break;
                   1021: 
                   1022:                case AUTOINC:
                   1023:                    if (r == regname[PROGCTR]) {
                   1024:                        switch (typelen(argtype)) {
                   1025:                            case TYPB:
                   1026:                                argval = getdisp(addr, 1, r, amode);
                   1027:                                addr += 1;
                   1028:                                break;
                   1029: 
                   1030:                            case TYPW:
                   1031:                                argval = getdisp(addr, 2, r, amode);
                   1032:                                addr += 2;
                   1033:                                break;
                   1034: 
                   1035:                            case TYPL:
                   1036:                                argval = getdisp(addr, 4, r, amode);
                   1037:                                addr += 4;
                   1038:                                break;
                   1039: 
                   1040:                            case TYPF:
                   1041:                                iread(&argval, addr, sizeof(argval));
                   1042:                                addr += 4;
                   1043:                                break;
                   1044: 
                   1045:                            case TYPQ:
                   1046:                            case TYPD:
                   1047:                            case TYPG:
                   1048:                                iread(&argval, addr+4, sizeof(argval));
                   1049:                                addr += 8;
                   1050:                                break;
                   1051: 
                   1052:                            case TYPO:
                   1053:                            case TYPH:
                   1054:                                iread(&argval, addr+12, sizeof(argval));
                   1055:                                addr += 16;
                   1056:                                break;
                   1057:                        }
                   1058:                    }
                   1059:                    break;
                   1060: 
                   1061:                case AUTOINCDEF:
                   1062:                    if (r == regname[PROGCTR]) {
                   1063:                        argval = getdisp(addr, 4, r, amode);
                   1064:                        addr += 4;
                   1065:                    }
                   1066:                    break;
                   1067: 
                   1068:                case BYTEDISP:
                   1069:                case BYTEDISPDEF:
                   1070:                    argval = getdisp(addr, 1, r, amode);
                   1071:                    addr += 1;
                   1072:                    break;
                   1073: 
                   1074:                case WORDDISP:
                   1075:                case WORDDISPDEF:
                   1076:                    argval = getdisp(addr, 2, r, amode);
                   1077:                    addr += 2;
                   1078:                    break;
                   1079: 
                   1080:                case LONGDISP:
                   1081:                case LONGDISPDEF:
                   1082:                    argval = getdisp(addr, 4, r, amode);
                   1083:                    addr += 4;
                   1084:                    break;
                   1085:            }
                   1086:        }
                   1087:        if (ins == O_CALLS or ins == O_CALLG) {
                   1088:            argval += 2;
                   1089:        }
                   1090:        if (addrstatus == BRANCH) {
                   1091:            addr = argval;
                   1092:        }
                   1093:     }
                   1094:     return addr;
                   1095: }
                   1096: 
                   1097: /*
                   1098:  * Get the displacement of an instruction that uses displacement addressing.
                   1099:  */
                   1100: 
                   1101: private int getdisp(addr, nbytes, reg, mode)
                   1102: Address addr;
                   1103: int nbytes;
                   1104: String reg;
                   1105: int mode;
                   1106: {
                   1107:     char byte;
                   1108:     short hword;
                   1109:     int argval;
                   1110: 
                   1111:     switch (nbytes) {
                   1112:        case 1:
                   1113:            iread(&byte, addr, sizeof(byte));
                   1114:            argval = byte;
                   1115:            break;
                   1116: 
                   1117:        case 2:
                   1118:            iread(&hword, addr, sizeof(hword));
                   1119:            argval = hword;
                   1120:            break;
                   1121: 
                   1122:        case 4:
                   1123:            iread(&argval, addr, sizeof(argval));
                   1124:            break;
                   1125:     }
                   1126:     if (reg == regname[PROGCTR] && mode >= BYTEDISP) {
                   1127:        argval += addr + nbytes;
                   1128:     }
                   1129:     return argval;
                   1130: }
                   1131: 
                   1132: /*
                   1133:  * Enter a procedure by creating and executing a call instruction.
                   1134:  */
                   1135: 
                   1136: #define CALLSIZE 7     /* size of call instruction */
                   1137: 
                   1138: public beginproc(p, argc)
                   1139: Symbol p;
                   1140: Integer argc;
                   1141: {
                   1142:     char save[CALLSIZE];
                   1143:     struct {
                   1144:        VaxOpcode op;
                   1145:        unsigned char numargs;
                   1146:        unsigned char mode;
                   1147:        char addr[sizeof(long)];        /* unaligned long */
                   1148:     } call;
                   1149:     long dest;
                   1150: 
                   1151:     pc = 2;
                   1152:     iread(save, pc, sizeof(save));
                   1153:     call.op = O_CALLS;
                   1154:     call.numargs = argc;
                   1155:     call.mode = 0xef;
                   1156:     dest = codeloc(p) - 2 - (pc + 7);
                   1157:     mov(&dest, call.addr, sizeof(call.addr));
                   1158:     iwrite(&call, pc, sizeof(call));
                   1159:     setreg(PROGCTR, pc);
                   1160:     pstep(process, DEFSIG);
                   1161:     iwrite(save, pc, sizeof(save));
                   1162:     pc = reg(PROGCTR);
                   1163:     if (not isbperr()) {
                   1164:        printstatus();
                   1165:     }
                   1166: }
                   1167: 
                   1168: /*
                   1169:  * Special variables for debugging the kernel.
                   1170:  */
                   1171: 
                   1172: public integer masterpcbb;
                   1173: public integer slr;
                   1174: public struct pte *sbr;
                   1175: private struct pcb pcb;
                   1176: 
                   1177: public getpcb ()
                   1178: {
                   1179:     integer i;
                   1180: 
                   1181:     fseek(corefile, masterpcbb & ~0x80000000, 0);
                   1182:     get(corefile, pcb);
                   1183:     pcb.pcb_p0lr &= ~AST_CLR;
                   1184:     printf("p0br %lx p0lr %lx p1br %lx p1lr %lx\n",
                   1185:        pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr
                   1186:     );
                   1187:     setreg(0, pcb.pcb_r0);
                   1188:     setreg(1, pcb.pcb_r1);
                   1189:     setreg(2, pcb.pcb_r2);
                   1190:     setreg(3, pcb.pcb_r3);
                   1191:     setreg(4, pcb.pcb_r4);
                   1192:     setreg(5, pcb.pcb_r5);
                   1193:     setreg(6, pcb.pcb_r6);
                   1194:     setreg(7, pcb.pcb_r7);
                   1195:     setreg(8, pcb.pcb_r8);
                   1196:     setreg(9, pcb.pcb_r9);
                   1197:     setreg(10, pcb.pcb_r10);
                   1198:     setreg(11, pcb.pcb_r11);
                   1199:     setreg(ARGP, pcb.pcb_ap);
                   1200:     setreg(FRP, pcb.pcb_fp);
                   1201:     setreg(STKP, pcb.pcb_ksp);
                   1202:     setreg(PROGCTR, pcb.pcb_pc);
                   1203: }
                   1204: 
                   1205: public copyregs (savreg, reg)
                   1206: Word savreg[], reg[];
                   1207: {
                   1208:     reg[0] = savreg[R0];
                   1209:     reg[1] = savreg[R1];
                   1210:     reg[2] = savreg[R2];
                   1211:     reg[3] = savreg[R3];
                   1212:     reg[4] = savreg[R4];
                   1213:     reg[5] = savreg[R5];
                   1214:     reg[6] = savreg[R6];
                   1215:     reg[7] = savreg[R7];
                   1216:     reg[8] = savreg[R8];
                   1217:     reg[9] = savreg[R9];
                   1218:     reg[10] = savreg[R10];
                   1219:     reg[11] = savreg[R11];
                   1220:     reg[ARGP] = savreg[AP];
                   1221:     reg[FRP] = savreg[FP];
                   1222:     reg[STKP] = savreg[SP];
                   1223:     reg[PROGCTR] = savreg[PC];
                   1224: }
                   1225: 
                   1226: /*
                   1227:  * Map a virtual address to a physical address.
                   1228:  */
                   1229: 
                   1230: public Address vmap (addr)
                   1231: Address addr;
                   1232: {
                   1233:     Address r;
                   1234:     integer v, n;
                   1235:     struct pte pte;
                   1236: 
                   1237:     r = addr & ~0xc0000000;
                   1238:     v = btop(r);
                   1239:     switch (addr&0xc0000000) {
                   1240:        case 0xc0000000:
                   1241:        case 0x80000000:
                   1242:            /*
                   1243:             * In system space, so get system pte.
                   1244:             * If it is valid or reclaimable then the physical address
                   1245:             * is the combination of its page number and the page offset
                   1246:             * of the original address.
                   1247:             */
                   1248:            if (v >= slr) {
                   1249:                error("address %x out of segment", addr);
                   1250:            }
                   1251:            r = ((long) (sbr + v)) & ~0x80000000;
                   1252:            goto simple;
                   1253: 
                   1254:        case 0x40000000:
                   1255:            /*
                   1256:             * In p1 space, must not be in shadow region.
                   1257:             */
                   1258:            if (v < pcb.pcb_p1lr) {
                   1259:                error("address %x out of segment", addr);
                   1260:            }
                   1261:            r = (Address) (pcb.pcb_p1br + v);
                   1262:            break;
                   1263: 
                   1264:        case 0x00000000:
                   1265:            /*
                   1266:             * In p0 space, must not be off end of region.
                   1267:             */
                   1268:            if (v >= pcb.pcb_p0lr) {
                   1269:                error("address %x out of segment", addr);
                   1270:            }
                   1271:            r = (Address) (pcb.pcb_p0br + v);
                   1272:            break;
                   1273: 
                   1274:        default:
                   1275:            /* do nothing */
                   1276:            break;
                   1277:     }
                   1278:     /*
                   1279:      * For p0/p1 address, user-level page table should be in
                   1280:      * kernel virtual memory.  Do second-level indirect by recursing.
                   1281:      */
                   1282:     if ((r & 0x80000000) == 0) {
                   1283:        error("bad p0br or p1br in pcb");
                   1284:     }
                   1285:     r = vmap(r);
                   1286: simple:
                   1287:     /*
                   1288:      * "r" is now the address of the pte of the page
                   1289:      * we are interested in; get the pte and paste up the physical address.
                   1290:      */
                   1291:     fseek(corefile, r, 0);
                   1292:     n = fread(&pte, sizeof(pte), 1, corefile);
                   1293:     if (n != 1) {
                   1294:        error("page table botch (fread at %x returns %d)", r, n);
                   1295:     }
                   1296:     if (pte.pg_v == 0 and (pte.pg_fod != 0 or pte.pg_pfnum == 0)) {
                   1297:        error("page no valid or reclamable");
                   1298:     }
                   1299:     return (addr&PGOFSET) + ((Address) ptob(pte.pg_pfnum));
                   1300: }
                   1301: 
                   1302: /*
                   1303:  * Extract a bit field from an integer.
                   1304:  */
                   1305: 
                   1306: public integer extractField (s)
                   1307: Symbol s;
                   1308: {
                   1309:     integer n, nbytes, r;
                   1310: 
                   1311:     n = 0;
                   1312:     nbytes = size(s);
                   1313:     if (nbytes > sizeof(n)) {
                   1314:        printf("[bad size in extractField -- word assumed]\n");
                   1315:        nbytes = sizeof(n);
                   1316:     }
                   1317:     popn(nbytes, &n);
                   1318:     r = n >> (s->symvalue.field.offset mod BITSPERBYTE);
                   1319:     r &= ((1 << s->symvalue.field.length) - 1);
                   1320:     return r;
                   1321: }
                   1322: 
                   1323: /*
                   1324:  * Change the length of a value in memory according to a given difference
                   1325:  * in the lengths of its new and old types.
                   1326:  */
                   1327: 
                   1328: public loophole (oldlen, newlen)
                   1329: integer oldlen, newlen;
                   1330: {
                   1331:     integer n, i;
                   1332: 
                   1333:     n = newlen - oldlen;
                   1334:     if (n > 0) {
                   1335:        for (i = 0; i < n; i++) {
                   1336:            sp[i] = '\0';
                   1337:        }
                   1338:     }
                   1339:     sp += n;
                   1340: }

unix.superglobalmegacorp.com

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