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

unix.superglobalmegacorp.com

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