Annotation of 42BSD/ucb/dbx/machine.c, revision 1.1

1.1     ! root        1: /* Copyright (c) 1982 Regents of the University of California */
        !             2: 
        !             3: static char sccsid[] = "@(#)machine.c 1.9 8/5/83";
        !             4: 
        !             5: /*
        !             6:  * Target machine dependent stuff.
        !             7:  */
        !             8: 
        !             9: #include "defs.h"
        !            10: #include "machine.h"
        !            11: #include "process.h"
        !            12: #include "events.h"
        !            13: #include "main.h"
        !            14: #include "symbols.h"
        !            15: #include "source.h"
        !            16: #include "mappings.h"
        !            17: #include "object.h"
        !            18: #include "ops.h"
        !            19: #include <signal.h>
        !            20: 
        !            21: #ifndef public
        !            22: typedef unsigned int Address;
        !            23: typedef unsigned char Byte;
        !            24: typedef unsigned int Word;
        !            25: 
        !            26: #define NREG 16
        !            27: 
        !            28: #define ARGP 12
        !            29: #define FRP 13
        !            30: #define STKP 14
        !            31: #define PROGCTR 15
        !            32: 
        !            33: #define BITSPERBYTE 8
        !            34: #define BITSPERWORD (BITSPERBYTE * sizeof(Word))
        !            35: 
        !            36: #define nargspassed(frame) argn(0, frame)
        !            37: 
        !            38: #include "source.h"
        !            39: #include "symbols.h"
        !            40: 
        !            41: Address pc;
        !            42: Address prtaddr;
        !            43: 
        !            44: #endif
        !            45: 
        !            46: private Address printop();
        !            47: 
        !            48: /*
        !            49:  * Decode and print the instructions within the given address range.
        !            50:  */
        !            51: 
        !            52: public printinst(lowaddr, highaddr)
        !            53: Address lowaddr;
        !            54: Address highaddr;
        !            55: {
        !            56:     register Address addr;
        !            57: 
        !            58:     for (addr = lowaddr; addr <= highaddr; ) {
        !            59:        addr = printop(addr);
        !            60:     }
        !            61:     prtaddr = addr;
        !            62: }
        !            63: 
        !            64: /*
        !            65:  * Another approach:  print n instructions starting at the given address.
        !            66:  */
        !            67: 
        !            68: public printninst(count, addr)
        !            69: int count;
        !            70: Address addr;
        !            71: {
        !            72:     register Integer i;
        !            73:     register Address newaddr;
        !            74: 
        !            75:     if (count <= 0) {
        !            76:        error("non-positive repetition count");
        !            77:     } else {
        !            78:        newaddr = addr;
        !            79:        for (i = 0; i < count; i++) {
        !            80:            newaddr = printop(newaddr);
        !            81:        }
        !            82:        prtaddr = newaddr;
        !            83:     }
        !            84: }
        !            85: 
        !            86: /*
        !            87:  * Hacked version of adb's VAX instruction decoder.
        !            88:  */
        !            89: 
        !            90: private Address printop(addr)
        !            91: Address addr;
        !            92: {
        !            93:     Optab op;
        !            94:     VaxOpcode ins;
        !            95:     unsigned char mode;
        !            96:     int argtype, amode, argno, argval;
        !            97:     String reg;
        !            98:     Boolean indexf;
        !            99:     short offset;
        !           100: 
        !           101:     argval = 0;
        !           102:     indexf = false;
        !           103:     printf("%08x  ", addr);
        !           104:     iread(&ins, addr, sizeof(ins));
        !           105:     addr += 1;
        !           106:     op = optab[ins];
        !           107:     printf("%s", op.iname);
        !           108:     for (argno = 0; argno < op.numargs; argno++) {
        !           109:        if (indexf == true) {
        !           110:            indexf = false;
        !           111:        } else if (argno == 0) {
        !           112:            printf("\t");
        !           113:        } else {
        !           114:            printf(",");
        !           115:        }
        !           116:        argtype = op.argtype[argno];
        !           117:        if (is_branch_disp(argtype)) {
        !           118:            mode = 0xAF + (typelen(argtype) << 5);
        !           119:        } else {
        !           120:            iread(&mode, addr, sizeof(mode));
        !           121:            addr += 1;
        !           122:        }
        !           123:        reg = regname[regnm(mode)];
        !           124:        amode = addrmode(mode);
        !           125:        switch (amode) {
        !           126:            case LITSHORT:
        !           127:            case LITUPTO31:
        !           128:            case LITUPTO47:
        !           129:            case LITUPTO63:
        !           130:                if (typelen(argtype) == TYPF || typelen(argtype) ==TYPD)
        !           131:                    printf("$%s", fltimm[mode]);
        !           132:                else
        !           133:                    printf("$%x", mode);
        !           134:                argval = mode;
        !           135:                break;
        !           136: 
        !           137:            case INDEX:
        !           138:                printf("[%s]", reg);
        !           139:                indexf = true;
        !           140:                argno--;
        !           141:                break;
        !           142: 
        !           143:            case REG:
        !           144:                printf("%s", reg);
        !           145:                break;
        !           146: 
        !           147:            case REGDEF:
        !           148:                printf("(%s)", reg);
        !           149:                break;
        !           150: 
        !           151:            case AUTODEC:
        !           152:                printf("-(%s)", reg);
        !           153:                break;
        !           154: 
        !           155:            case AUTOINC:
        !           156:                if (reg != regname[PROGCTR]) {
        !           157:                    printf("(%s)+", reg);
        !           158:                } else {
        !           159:                    printf("$");
        !           160:                    switch (typelen(argtype)) {
        !           161:                        case TYPB:
        !           162:                            argval = printdisp(addr, 1, reg, amode);
        !           163:                            addr += 1;
        !           164:                            break;
        !           165: 
        !           166:                        case TYPW:
        !           167:                            argval = printdisp(addr, 2, reg, amode);
        !           168:                            addr += 2;
        !           169:                            break;
        !           170: 
        !           171:                        case TYPL:
        !           172:                            argval = printdisp(addr, 4, reg, amode);
        !           173:                            addr += 4;
        !           174:                            break;
        !           175: 
        !           176:                        case TYPF:
        !           177:                            iread(&argval, addr, sizeof(argval));
        !           178:                            printf("%06x", argval);
        !           179:                            addr += 4;
        !           180:                            break;
        !           181: 
        !           182:                        case TYPQ:
        !           183:                        case TYPD:
        !           184:                            iread(&argval, addr, sizeof(argval));
        !           185:                            printf("%06x", argval);
        !           186:                            iread(&argval, addr+4, sizeof(argval));
        !           187:                            printf("%06x", argval);
        !           188:                            addr += 8;
        !           189:                            break;
        !           190:                    }
        !           191:                }
        !           192:                break;
        !           193: 
        !           194:            case AUTOINCDEF:
        !           195:                if (reg == regname[PROGCTR]) {
        !           196:                    printf("*$");
        !           197:                    argval = printdisp(addr, 4, reg, amode);
        !           198:                    addr += 4;
        !           199:                } else {
        !           200:                    printf("*(%s)+", reg);
        !           201:                }
        !           202:                break;
        !           203: 
        !           204:            case BYTEDISP:
        !           205:                argval = printdisp(addr, 1, reg, amode);
        !           206:                addr += 1;
        !           207:                break;
        !           208: 
        !           209:            case BYTEDISPDEF:
        !           210:                printf("*");
        !           211:                argval = printdisp(addr, 1, reg, amode);
        !           212:                addr += 1;
        !           213:                break;
        !           214: 
        !           215:            case WORDDISP:
        !           216:                argval = printdisp(addr, 2, reg, amode);
        !           217:                addr += 2;
        !           218:                break;
        !           219: 
        !           220:            case WORDDISPDEF:
        !           221:                printf("*");
        !           222:                argval = printdisp(addr, 2, reg, amode);
        !           223:                addr += 2;
        !           224:                break;
        !           225: 
        !           226:            case LONGDISP:
        !           227:                argval = printdisp(addr, 4, reg, amode);
        !           228:                addr += 4;
        !           229:                break;
        !           230: 
        !           231:            case LONGDISPDEF:
        !           232:                printf("*");
        !           233:                argval = printdisp(addr, 4, reg, amode);
        !           234:                addr += 4;
        !           235:                break;
        !           236:        }
        !           237:     }
        !           238:     if (ins == O_CASEB || ins == O_CASEW || ins == O_CASEL) {
        !           239:        for (argno = 0; argno <= argval; argno++) {
        !           240:            iread(&offset, addr, sizeof(offset));
        !           241:            printf("\n\t\t%d", offset);
        !           242:            addr += 2;
        !           243:        }
        !           244:     }
        !           245:     printf("\n");
        !           246:     return addr;
        !           247: }
        !           248: 
        !           249: /*
        !           250:  * Print the displacement of an instruction that uses displacement
        !           251:  * addressing.
        !           252:  */
        !           253: 
        !           254: private int printdisp(addr, nbytes, reg, mode)
        !           255: Address addr;
        !           256: int nbytes;
        !           257: char *reg;
        !           258: int mode;
        !           259: {
        !           260:     char byte;
        !           261:     short hword;
        !           262:     int argval;
        !           263:     Symbol f;
        !           264: 
        !           265:     switch (nbytes) {
        !           266:        case 1:
        !           267:            iread(&byte, addr, sizeof(byte));
        !           268:            argval = byte;
        !           269:            break;
        !           270: 
        !           271:        case 2:
        !           272:            iread(&hword, addr, sizeof(hword));
        !           273:            argval = hword;
        !           274:            break;
        !           275: 
        !           276:        case 4:
        !           277:            iread(&argval, addr, sizeof(argval));
        !           278:            break;
        !           279:     }
        !           280:     if (reg == regname[PROGCTR] && mode >= BYTEDISP) {
        !           281:        argval += addr + nbytes;
        !           282:     }
        !           283:     if (reg == regname[PROGCTR]) {
        !           284:        f = whatblock((Address) argval + 2);
        !           285:        if (codeloc(f) == argval + 2) {
        !           286:            printf("%s", symname(f));
        !           287:        } else {
        !           288:            printf("%x", argval);
        !           289:        }
        !           290:     } else {
        !           291:        printf("%d(%s)", argval, reg);
        !           292:     }
        !           293:     return argval;
        !           294: }
        !           295: 
        !           296: /*
        !           297:  * Print the contents of the addresses within the given range
        !           298:  * according to the given format.
        !           299:  */
        !           300: 
        !           301: typedef struct {
        !           302:     String name;
        !           303:     String printfstring;
        !           304:     int length;
        !           305: } Format;
        !           306: 
        !           307: private Format fmt[] = {
        !           308:     { "d", " %d", sizeof(short) },
        !           309:     { "D", " %ld", sizeof(long) },
        !           310:     { "o", " %o", sizeof(short) },
        !           311:     { "O", " %lo", sizeof(long) },
        !           312:     { "x", " %04x", sizeof(short) },
        !           313:     { "X", " %08x", sizeof(long) },
        !           314:     { "b", " \\%o", sizeof(char) },
        !           315:     { "c", " '%c'", sizeof(char) },
        !           316:     { "s", "%c", sizeof(char) },
        !           317:     { "f", " %f", sizeof(float) },
        !           318:     { "g", " %g", sizeof(double) },
        !           319:     { nil, nil, 0 }
        !           320: };
        !           321: 
        !           322: private Format *findformat(s)
        !           323: String s;
        !           324: {
        !           325:     register Format *f;
        !           326: 
        !           327:     f = &fmt[0];
        !           328:     while (f->name != nil and not streq(f->name, s)) {
        !           329:        ++f;
        !           330:     }
        !           331:     if (f->name == nil) {
        !           332:        error("bad print format \"%s\"", s);
        !           333:     }
        !           334:     return f;
        !           335: }
        !           336: 
        !           337: public Address printdata(lowaddr, highaddr, format)
        !           338: Address lowaddr;
        !           339: Address highaddr;
        !           340: String format;
        !           341: {
        !           342:     register int n;
        !           343:     register Address addr;
        !           344:     register Format *f;
        !           345:     int value;
        !           346: 
        !           347:     if (lowaddr > highaddr) {
        !           348:        error("first address larger than second");
        !           349:     }
        !           350:     f = findformat(format);
        !           351:     n = 0;
        !           352:     value = 0;
        !           353:     for (addr = lowaddr; addr <= highaddr; addr += f->length) {
        !           354:        if (n == 0) {
        !           355:            printf("%08x: ", addr);
        !           356:        }
        !           357:        dread(&value, addr, f->length);
        !           358:        printf(f->printfstring, value);
        !           359:        ++n;
        !           360:        if (n >= (16 div f->length)) {
        !           361:            putchar('\n');
        !           362:            n = 0;
        !           363:        }
        !           364:     }
        !           365:     if (n != 0) {
        !           366:        putchar('\n');
        !           367:     }
        !           368:     prtaddr = addr;
        !           369:     return addr;
        !           370: }
        !           371: 
        !           372: /*
        !           373:  * The other approach is to print n items starting with a given address.
        !           374:  */
        !           375: 
        !           376: public printndata(count, startaddr, format)
        !           377: int count;
        !           378: Address startaddr;
        !           379: String format;
        !           380: {
        !           381:     register int i, n;
        !           382:     register Address addr;
        !           383:     register Format *f;
        !           384:     register Boolean isstring;
        !           385:     char c;
        !           386:     union {
        !           387:        char charv;
        !           388:        short shortv;
        !           389:        int intv;
        !           390:        float floatv;
        !           391:        double doublev;
        !           392:     } value;
        !           393: 
        !           394:     if (count <= 0) {
        !           395:        error("non-positive repetition count");
        !           396:     }
        !           397:     f = findformat(format);
        !           398:     isstring = (Boolean) streq(f->name, "s");
        !           399:     n = 0;
        !           400:     addr = startaddr;
        !           401:     value.intv = 0;
        !           402:     for (i = 0; i < count; i++) {
        !           403:        if (n == 0) {
        !           404:            printf("%08x: ", addr);
        !           405:        }
        !           406:        if (isstring) {
        !           407:            putchar('"');
        !           408:            dread(&c, addr, sizeof(char));
        !           409:            while (c != '\0') {
        !           410:                printchar(c);
        !           411:                ++addr;
        !           412:                dread(&c, addr, sizeof(char));
        !           413:            }
        !           414:            putchar('"');
        !           415:            putchar('\n');
        !           416:            n = 0;
        !           417:            addr += sizeof(String);
        !           418:        } else {
        !           419:            dread(&value, addr, f->length);
        !           420:            printf(f->printfstring, value);
        !           421:            ++n;
        !           422:            if (n >= (16 div f->length)) {
        !           423:                putchar('\n');
        !           424:                n = 0;
        !           425:            }
        !           426:            addr += f->length;
        !           427:        }
        !           428:     }
        !           429:     if (n != 0) {
        !           430:        putchar('\n');
        !           431:     }
        !           432:     prtaddr = addr;
        !           433: }
        !           434: 
        !           435: /*
        !           436:  * Print out a value according to the given format.
        !           437:  */
        !           438: 
        !           439: public printvalue(v, format)
        !           440: long v;
        !           441: String format;
        !           442: {
        !           443:     Format *f;
        !           444:     char *p, *q;
        !           445: 
        !           446:     f = findformat(format);
        !           447:     if (streq(f->name, "s")) {
        !           448:        putchar('"');
        !           449:        p = (char *) &v;
        !           450:        q = p + sizeof(v);
        !           451:        while (p < q) {
        !           452:            printchar(*p);
        !           453:            ++p;
        !           454:        }
        !           455:        putchar('"');
        !           456:     } else {
        !           457:        printf(f->printfstring, v);
        !           458:     }
        !           459:     putchar('\n');
        !           460: }
        !           461: 
        !           462: /*
        !           463:  * Print out an execution time error.
        !           464:  * Assumes the source position of the error has been calculated.
        !           465:  *
        !           466:  * Have to check if the -r option was specified; if so then
        !           467:  * the object file information hasn't been read in yet.
        !           468:  */
        !           469: 
        !           470: public printerror()
        !           471: {
        !           472:     extern Integer sys_nsig;
        !           473:     extern String sys_siglist[];
        !           474:     Integer err;
        !           475: 
        !           476:     if (isfinished(process)) {
        !           477:        printf("\"%s\" exits with code %d\n", objname, exitcode(process));
        !           478:        erecover();
        !           479:     }
        !           480:     if (runfirst) {
        !           481:        fprintf(stderr, "Entering debugger ...");
        !           482:        init();
        !           483:        fprintf(stderr, " type 'help' for help\n");
        !           484:     }
        !           485:     err = errnum(process);
        !           486:     if (err == SIGINT) {
        !           487:        printf("\n\ninterrupt ");
        !           488:        printloc();
        !           489:     } else if (err == SIGTRAP) {
        !           490:        printf("\nerror ");
        !           491:        printloc();
        !           492:     } else {
        !           493:        if (err < 0 or err > sys_nsig) {
        !           494:            printf("\nsignal %d ", err);
        !           495:        } else {
        !           496:            printf("\n%s ", sys_siglist[err]);
        !           497:        }
        !           498:        printloc();
        !           499:     }
        !           500:     putchar('\n');
        !           501:     if (curline > 0) {
        !           502:        printlines(curline, curline);
        !           503:     } else {
        !           504:        printinst(pc, pc);
        !           505:     }
        !           506:     erecover();
        !           507: }
        !           508: 
        !           509: /*
        !           510:  * Note the termination of the program.  We do this so as to avoid
        !           511:  * having the process exit, which would make the values of variables
        !           512:  * inaccessible.  We do want to flush all output buffers here,
        !           513:  * otherwise it'll never get done.
        !           514:  */
        !           515: 
        !           516: public endprogram()
        !           517: {
        !           518:     Integer exitcode;
        !           519: 
        !           520:     stepto(nextaddr(pc, true));
        !           521:     printnews();
        !           522:     exitcode = argn(1, nil);
        !           523:     printf("\nexecution completed, exit code is %d\n", exitcode);
        !           524:     getsrcpos();
        !           525:     erecover();
        !           526: }
        !           527: 
        !           528: /*
        !           529:  * Single step the machine a source line (or instruction if "inst_tracing"
        !           530:  * is true).  If "isnext" is true, skip over procedure calls.
        !           531:  */
        !           532: 
        !           533: private Address getcall();
        !           534: 
        !           535: public dostep(isnext)
        !           536: Boolean isnext;
        !           537: {
        !           538:     register Address addr;
        !           539:     register Lineno line;
        !           540:     String filename;
        !           541: 
        !           542:     addr = nextaddr(pc, isnext);
        !           543:     if (not inst_tracing and nlhdr.nlines != 0) {
        !           544:        line = linelookup(addr);
        !           545:        while (line == 0) {
        !           546:            addr = nextaddr(addr, isnext);
        !           547:            line = linelookup(addr);
        !           548:        }
        !           549:        curline = line;
        !           550:     } else {
        !           551:        curline = 0;
        !           552:     }
        !           553:     stepto(addr);
        !           554:     filename = srcfilename(addr);
        !           555:     setsource(filename);
        !           556: }
        !           557: 
        !           558: /*
        !           559:  * Compute the next address that will be executed from the given one.
        !           560:  * If "isnext" is true then consider a procedure call as straight line code.
        !           561:  *
        !           562:  * We must unfortunately do much of the same work that is necessary
        !           563:  * to print instructions.  In addition we have to deal with branches.
        !           564:  * Unconditional branches we just follow, for conditional branches
        !           565:  * we continue execution to the current location and then single step
        !           566:  * the machine.  We assume that the last argument in an instruction
        !           567:  * that branches is the branch address (or relative offset).
        !           568:  */
        !           569: 
        !           570: public Address nextaddr(startaddr, isnext)
        !           571: Address startaddr;
        !           572: Boolean isnext;
        !           573: {
        !           574:     register Address addr;
        !           575:     Optab op;
        !           576:     VaxOpcode ins;
        !           577:     unsigned char mode;
        !           578:     int argtype, amode, argno, argval;
        !           579:     String r;
        !           580:     Boolean indexf;
        !           581:     enum { KNOWN, SEQUENTIAL, BRANCH } addrstatus;
        !           582: 
        !           583:     argval = 0;
        !           584:     indexf = false;
        !           585:     addr = startaddr;
        !           586:     iread(&ins, addr, sizeof(ins));
        !           587:     switch (ins) {
        !           588:        case O_BRB:
        !           589:        case O_BRW:
        !           590:        case O_JMP:
        !           591:            addrstatus = BRANCH;
        !           592:            break;
        !           593:            
        !           594:        case O_BSBB:
        !           595:        case O_BSBW:
        !           596:        case O_JSB:
        !           597:        case O_CALLG:
        !           598:        case O_CALLS:
        !           599:            if (isnext) {
        !           600:                addrstatus = SEQUENTIAL;
        !           601:            } else {
        !           602:                addrstatus = KNOWN;
        !           603:                stepto(addr);
        !           604:                pstep(process);
        !           605:                addr = reg(PROGCTR);
        !           606:                pc = addr;
        !           607:                curfunc = whatblock(pc);
        !           608:                if (not isbperr()) {
        !           609:                    printstatus();
        !           610:                    /* NOTREACHED */
        !           611:                }
        !           612:                bpact();
        !           613:                if (nosource(curfunc) and canskip(curfunc) and
        !           614:                  nlhdr.nlines != 0) {
        !           615:                    addrstatus = KNOWN;
        !           616:                    addr = return_addr();
        !           617:                    stepto(addr);
        !           618:                    bpact();
        !           619:                } else {
        !           620:                    callnews(/* iscall = */ true);
        !           621:                }
        !           622:            }
        !           623:            break;
        !           624: 
        !           625:        case O_RSB:
        !           626:        case O_RET:
        !           627:            addrstatus = KNOWN;
        !           628:            callnews(/* iscall = */ false);
        !           629:            addr = return_addr();
        !           630:            stepto(addr);
        !           631:            bpact();
        !           632:            break;
        !           633: 
        !           634:        case O_BNEQ: case O_BEQL: case O_BGTR:
        !           635:        case O_BLEQ: case O_BGEQ: case O_BLSS:
        !           636:        case O_BGTRU: case O_BLEQU: case O_BVC:
        !           637:        case O_BVS: case O_BCC: case O_BCS:
        !           638:        case O_CASEB: case O_CASEW: case O_CASEL:
        !           639:        case O_BBS: case O_BBC: case O_BBSS: case O_BBCS:
        !           640:        case O_BBSC: case O_BBCC: case O_BBSSI:
        !           641:        case O_BBCCI: case O_BLBS: case O_BLBC:
        !           642:        case O_ACBL: case O_AOBLSS: case O_AOBLEQ:
        !           643:        case O_SOBGEQ: case O_SOBGTR:
        !           644:            addrstatus = KNOWN;
        !           645:            stepto(addr);
        !           646:            pstep(process);
        !           647:            addr = reg(PROGCTR);
        !           648:            pc = addr;
        !           649:            if (not isbperr()) {
        !           650:                printstatus();
        !           651:            }
        !           652:            break;
        !           653: 
        !           654:        default:
        !           655:            addrstatus = SEQUENTIAL;
        !           656:            break;
        !           657:     }
        !           658:     if (addrstatus != KNOWN) {
        !           659:        addr += 1;
        !           660:        op = optab[ins];
        !           661:        for (argno = 0; argno < op.numargs; argno++) {
        !           662:            if (indexf == true) {
        !           663:                indexf = false;
        !           664:            }
        !           665:            argtype = op.argtype[argno];
        !           666:            if (is_branch_disp(argtype)) {
        !           667:                mode = 0xAF + (typelen(argtype) << 5);
        !           668:            } else {
        !           669:                iread(&mode, addr, sizeof(mode));
        !           670:                addr += 1;
        !           671:            }
        !           672:            r = regname[regnm(mode)];
        !           673:            amode = addrmode(mode);
        !           674:            switch (amode) {
        !           675:                case LITSHORT:
        !           676:                case LITUPTO31:
        !           677:                case LITUPTO47:
        !           678:                case LITUPTO63:
        !           679:                    argval = mode;
        !           680:                    break;
        !           681: 
        !           682:                case INDEX:
        !           683:                    indexf = true;
        !           684:                    --argno;
        !           685:                    break;
        !           686: 
        !           687:                case REG:
        !           688:                case REGDEF:
        !           689:                case AUTODEC:
        !           690:                    break;
        !           691: 
        !           692:                case AUTOINC:
        !           693:                    if (r == regname[PROGCTR]) {
        !           694:                        switch (typelen(argtype)) {
        !           695:                            case TYPB:
        !           696:                                argval = getdisp(addr, 1, r, amode);
        !           697:                                addr += 1;
        !           698:                                break;
        !           699: 
        !           700:                            case TYPW:
        !           701:                                argval = getdisp(addr, 2, r, amode);
        !           702:                                addr += 2;
        !           703:                                break;
        !           704: 
        !           705:                            case TYPL:
        !           706:                                argval = getdisp(addr, 4, r, amode);
        !           707:                                addr += 4;
        !           708:                                break;
        !           709: 
        !           710:                            case TYPF:
        !           711:                                iread(&argval, addr, sizeof(argval));
        !           712:                                addr += 4;
        !           713:                                break;
        !           714: 
        !           715:                            case TYPQ:
        !           716:                            case TYPD:
        !           717:                                iread(&argval, addr+4, sizeof(argval));
        !           718:                                addr += 8;
        !           719:                                break;
        !           720:                        }
        !           721:                    }
        !           722:                    break;
        !           723: 
        !           724:                case AUTOINCDEF:
        !           725:                    if (r == regname[PROGCTR]) {
        !           726:                        argval = getdisp(addr, 4, r, amode);
        !           727:                        addr += 4;
        !           728:                    }
        !           729:                    break;
        !           730: 
        !           731:                case BYTEDISP:
        !           732:                case BYTEDISPDEF:
        !           733:                    argval = getdisp(addr, 1, r, amode);
        !           734:                    addr += 1;
        !           735:                    break;
        !           736: 
        !           737:                case WORDDISP:
        !           738:                case WORDDISPDEF:
        !           739:                    argval = getdisp(addr, 2, r, amode);
        !           740:                    addr += 2;
        !           741:                    break;
        !           742: 
        !           743:                case LONGDISP:
        !           744:                case LONGDISPDEF:
        !           745:                    argval = getdisp(addr, 4, r, amode);
        !           746:                    addr += 4;
        !           747:                    break;
        !           748:            }
        !           749:        }
        !           750:        if (ins == O_CALLS or ins == O_CALLG) {
        !           751:            argval += 2;
        !           752:        }
        !           753:        if (addrstatus == BRANCH) {
        !           754:            addr = argval;
        !           755:        }
        !           756:     }
        !           757:     return addr;
        !           758: }
        !           759: 
        !           760: /*
        !           761:  * Get the displacement of an instruction that uses displacement addressing.
        !           762:  */
        !           763: 
        !           764: private int getdisp(addr, nbytes, reg, mode)
        !           765: Address addr;
        !           766: int nbytes;
        !           767: String reg;
        !           768: int mode;
        !           769: {
        !           770:     char byte;
        !           771:     short hword;
        !           772:     int argval;
        !           773: 
        !           774:     switch (nbytes) {
        !           775:        case 1:
        !           776:            iread(&byte, addr, sizeof(byte));
        !           777:            argval = byte;
        !           778:            break;
        !           779: 
        !           780:        case 2:
        !           781:            iread(&hword, addr, sizeof(hword));
        !           782:            argval = hword;
        !           783:            break;
        !           784: 
        !           785:        case 4:
        !           786:            iread(&argval, addr, sizeof(argval));
        !           787:            break;
        !           788:     }
        !           789:     if (reg == regname[PROGCTR] && mode >= BYTEDISP) {
        !           790:        argval += addr + nbytes;
        !           791:     }
        !           792:     return argval;
        !           793: }
        !           794: 
        !           795: #define BP_OP       O_BPT       /* breakpoint trap */
        !           796: #define BP_ERRNO    SIGTRAP     /* signal received at a breakpoint */
        !           797: 
        !           798: /*
        !           799:  * Setting a breakpoint at a location consists of saving
        !           800:  * the word at the location and poking a BP_OP there.
        !           801:  *
        !           802:  * We save the locations and words on a list for use in unsetting.
        !           803:  */
        !           804: 
        !           805: typedef struct Savelist *Savelist;
        !           806: 
        !           807: struct Savelist {
        !           808:     Address location;
        !           809:     Byte save;
        !           810:     Byte refcount;
        !           811:     Savelist link;
        !           812: };
        !           813: 
        !           814: private Savelist savelist;
        !           815: 
        !           816: /*
        !           817:  * Set a breakpoint at the given address.  Only save the word there
        !           818:  * if it's not already a breakpoint.
        !           819:  */
        !           820: 
        !           821: public setbp(addr)
        !           822: Address addr;
        !           823: {
        !           824:     Byte w;
        !           825:     Byte save;
        !           826:     register Savelist newsave, s;
        !           827: 
        !           828:     for (s = savelist; s != nil; s = s->link) {
        !           829:        if (s->location == addr) {
        !           830:            s->refcount++;
        !           831:            return;
        !           832:        }
        !           833:     }
        !           834:     iread(&save, addr, sizeof(save));
        !           835:     newsave = new(Savelist);
        !           836:     newsave->location = addr;
        !           837:     newsave->save = save;
        !           838:     newsave->refcount = 1;
        !           839:     newsave->link = savelist;
        !           840:     savelist = newsave;
        !           841:     w = BP_OP;
        !           842:     iwrite(&w, addr, sizeof(w));
        !           843: }
        !           844: 
        !           845: /*
        !           846:  * Unset a breakpoint; unfortunately we have to search the SAVELIST
        !           847:  * to find the saved value.  The assumption is that the SAVELIST will
        !           848:  * usually be quite small.
        !           849:  */
        !           850: 
        !           851: public unsetbp(addr)
        !           852: Address addr;
        !           853: {
        !           854:     register Savelist s, prev;
        !           855: 
        !           856:     prev = nil;
        !           857:     for (s = savelist; s != nil; s = s->link) {
        !           858:        if (s->location == addr) {
        !           859:            iwrite(&s->save, addr, sizeof(s->save));
        !           860:            s->refcount--;
        !           861:            if (s->refcount == 0) {
        !           862:                if (prev == nil) {
        !           863:                    savelist = s->link;
        !           864:                } else {
        !           865:                    prev->link = s->link;
        !           866:                }
        !           867:                dispose(s);
        !           868:            }
        !           869:            return;
        !           870:        }
        !           871:        prev = s;
        !           872:     }
        !           873:     panic("unsetbp: couldn't find address %d", addr);
        !           874: }
        !           875: 
        !           876: /*
        !           877:  * Predicate to test if the reason the process stopped was because
        !           878:  * of a breakpoint.
        !           879:  */
        !           880: 
        !           881: public Boolean isbperr()
        !           882: {
        !           883:     return (Boolean) (not isfinished(process) and errnum(process) == SIGTRAP);
        !           884: }
        !           885: 
        !           886: /*
        !           887:  * Enter a procedure by creating and executing a call instruction.
        !           888:  */
        !           889: 
        !           890: #define CALLSIZE 7     /* size of call instruction */
        !           891: 
        !           892: public beginproc(p, argc)
        !           893: Symbol p;
        !           894: Integer argc;
        !           895: {
        !           896:     char save[CALLSIZE];
        !           897:     struct {
        !           898:        VaxOpcode op;
        !           899:        unsigned char numargs;
        !           900:        unsigned char mode;
        !           901:        char addr[sizeof(long)];        /* unaligned long */
        !           902:     } call;
        !           903:     long dest;
        !           904: 
        !           905:     pc = 2;
        !           906:     iread(save, pc, sizeof(save));
        !           907:     call.op = O_CALLS;
        !           908:     call.numargs = argc;
        !           909:     call.mode = 0xef;
        !           910:     dest = codeloc(p) - 2 - (pc + 7);
        !           911:     mov(&dest, call.addr, sizeof(call.addr));
        !           912:     iwrite(&call, pc, sizeof(call));
        !           913:     setreg(PROGCTR, pc);
        !           914:     pstep(process);
        !           915:     iwrite(save, pc, sizeof(save));
        !           916:     pc = reg(PROGCTR);
        !           917:     if (not isbperr()) {
        !           918:        printstatus();
        !           919:     }
        !           920: }

unix.superglobalmegacorp.com

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