Annotation of 43BSDTahoe/ucb/dbx/iris.c, revision 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[] = "@(#)iris.c     5.1 (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: /*
        !            38:  * On the 68000, the pc isn't in a register, but we make believe
        !            39:  * so there's one more register.
        !            40:  *
        !            41:  * Note that there's also no argument pointer, this means code
        !            42:  * involving "ARGP" should always be #ifdef'd.
        !            43:  *
        !            44:  * The address corresponding to the beginning of a function is recorded
        !            45:  * as the address + FUNCOFFSET (skip the link instruction so that
        !            46:  * local information is available).
        !            47:  */
        !            48: 
        !            49: #define NREG 17
        !            50: 
        !            51: #define FRP 14
        !            52: #define STKP 15
        !            53: #define PROGCTR 16
        !            54: 
        !            55: #define CALL_RETADDR   0x800c          /* Return address for 'call' command */
        !            56: #define FUNCOFFSET 4
        !            57: 
        !            58: #ifdef sun
        !            59: #    define CODESTART 0x8000
        !            60: #else /* IRIS */
        !            61: #   define CODESTART 0x1000
        !            62: #endif
        !            63: 
        !            64: #define optab_init()
        !            65: 
        !            66: #define BITSPERBYTE 8
        !            67: #define BITSPERWORD (BITSPERBYTE * sizeof(Word))
        !            68: 
        !            69: /*
        !            70:  * This magic macro enables us to look at the process' registers
        !            71:  * in its user structure.
        !            72:  */
        !            73: 
        !            74: #define regloc(reg)    (ctob(UPAGES) + (sizeof(Word) * ((reg) - PC)) - 10)
        !            75: 
        !            76: #include "source.h"
        !            77: #include "symbols.h"
        !            78: #include <signal.h>
        !            79: #include <sys/param.h>
        !            80: #include <sys/dir.h>
        !            81: #include <machine/psl.h>
        !            82: #include <machine/pte.h>
        !            83: #include <sys/user.h>
        !            84: #undef DELETE /* XXX */
        !            85: #include <sys/vm.h>
        !            86: #include <machine/reg.h>
        !            87: 
        !            88: Address pc;
        !            89: Address prtaddr;
        !            90: 
        !            91: #endif
        !            92: 
        !            93: /*
        !            94:  * Indices into u. for use in collecting registers values.
        !            95:  */
        !            96: public int rloc[] ={
        !            97: #ifdef sun
        !            98:     R0, R1, R2, R3, R4, R5, R6, R7, AR0, AR1, AR2, AR3, AR4, AR5, AR6, AR7, PC
        !            99: #else /* IRIS */
        !           100:     R0, R1, R2, R3, R4, R5, R6, R7, AR0, AR1, AR2, AR3, AR4, AR5, AR6, AR7, 16
        !           101: #endif
        !           102: };
        !           103: 
        !           104: private Address printop();
        !           105: 
        !           106: /*
        !           107:  * Decode and print the instructions within the given address range.
        !           108:  */
        !           109: 
        !           110: public printinst(lowaddr, highaddr)
        !           111: Address lowaddr;
        !           112: Address highaddr;
        !           113: {
        !           114:     register Address addr;
        !           115: 
        !           116:     for (addr = lowaddr; addr <= highaddr; ) {
        !           117:        addr = printop(addr);
        !           118:     }
        !           119:     prtaddr = addr;
        !           120: }
        !           121: 
        !           122: /*
        !           123:  * Another approach:  print n instructions starting at the given address.
        !           124:  */
        !           125: 
        !           126: public printninst(count, addr)
        !           127: int count;
        !           128: Address addr;
        !           129: {
        !           130:     register Integer i;
        !           131:     register Address newaddr;
        !           132: 
        !           133:     if (count <= 0) {
        !           134:        error("non-positive repetition count");
        !           135:     } else {
        !           136:        newaddr = addr;
        !           137:        for (i = 0; i < count; i++) {
        !           138:            newaddr = printop(newaddr);
        !           139:        }
        !           140:        prtaddr = newaddr;
        !           141:     }
        !           142: }
        !           143: 
        !           144: /*
        !           145:  * Print the contents of the addresses within the given range
        !           146:  * according to the given format.
        !           147:  */
        !           148: 
        !           149: typedef struct {
        !           150:     String name;
        !           151:     String printfstring;
        !           152:     int length;
        !           153: } Format;
        !           154: 
        !           155: private Format fmt[] = {
        !           156:     { "d", " %d", sizeof(short) },
        !           157:     { "D", " %ld", sizeof(long) },
        !           158:     { "o", " %o", sizeof(short) },
        !           159:     { "O", " %lo", sizeof(long) },
        !           160:     { "x", " %04x", sizeof(short) },
        !           161:     { "X", " %08x", sizeof(long) },
        !           162:     { "b", " \\%o", sizeof(char) },
        !           163:     { "c", " '%c'", sizeof(char) },
        !           164:     { "s", "%c", sizeof(char) },
        !           165:     { "f", " %f", sizeof(float) },
        !           166:     { "g", " %g", sizeof(double) },
        !           167:     { nil, nil, 0 }
        !           168: };
        !           169: 
        !           170: private Format *findformat(s)
        !           171: String s;
        !           172: {
        !           173:     register Format *f;
        !           174: 
        !           175:     f = &fmt[0];
        !           176:     while (f->name != nil and not streq(f->name, s)) {
        !           177:        ++f;
        !           178:     }
        !           179:     if (f->name == nil) {
        !           180:        error("bad print format \"%s\"", s);
        !           181:     }
        !           182:     return f;
        !           183: }
        !           184: 
        !           185: /*
        !           186:  * Retrieve and print out the appropriate data in the given format.
        !           187:  * Floats have to be handled specially to allow the compiler to
        !           188:  * convert them to doubles when passing to printf.
        !           189:  */
        !           190: 
        !           191: private printformat (f, addr)
        !           192: Format *f;
        !           193: Address addr;
        !           194: {
        !           195:     union {
        !           196:        char charv;
        !           197:        short shortv;
        !           198:        int intv;
        !           199:        float floatv;
        !           200:        double doublev;
        !           201:     } value;
        !           202: 
        !           203:     value.intv = 0;
        !           204:     dread(&value, addr, f->length);
        !           205:     if (streq(f->name, "f")) {
        !           206:        printf(f->printfstring, value.floatv);
        !           207:     } else {
        !           208:        printf(f->printfstring, value);
        !           209:     }
        !           210: }
        !           211: 
        !           212: public Address printdata(lowaddr, highaddr, format)
        !           213: Address lowaddr;
        !           214: Address highaddr;
        !           215: String format;
        !           216: {
        !           217:     int n;
        !           218:     register Address addr;
        !           219:     Format *f;
        !           220: 
        !           221:     if (lowaddr > highaddr) {
        !           222:        error("first address larger than second");
        !           223:     }
        !           224:     f = findformat(format);
        !           225:     n = 0;
        !           226:     for (addr = lowaddr; addr <= highaddr; addr += f->length) {
        !           227:        if (n == 0) {
        !           228:            printf("%08x: ", addr);
        !           229:        }
        !           230:        printformat(f, addr);
        !           231:        ++n;
        !           232:        if (n >= (16 div f->length)) {
        !           233:            printf("\n");
        !           234:            n = 0;
        !           235:        }
        !           236:     }
        !           237:     if (n != 0) {
        !           238:        printf("\n");
        !           239:     }
        !           240:     prtaddr = addr;
        !           241:     return addr;
        !           242: }
        !           243: 
        !           244: /*
        !           245:  * The other approach is to print n items starting with a given address.
        !           246:  */
        !           247: 
        !           248: public printndata(count, startaddr, format)
        !           249: int count;
        !           250: Address startaddr;
        !           251: String format;
        !           252: {
        !           253:     int i, n;
        !           254:     Address addr;
        !           255:     Format *f;
        !           256:     Boolean isstring;
        !           257:     char c;
        !           258: 
        !           259:     if (count <= 0) {
        !           260:        error("non-positive repetition count");
        !           261:     }
        !           262:     f = findformat(format);
        !           263:     isstring = (Boolean) streq(f->name, "s");
        !           264:     n = 0;
        !           265:     addr = startaddr;
        !           266:     for (i = 0; i < count; i++) {
        !           267:        if (n == 0) {
        !           268:            printf("%08x: ", addr);
        !           269:        }
        !           270:        if (isstring) {
        !           271:            printf("\"");
        !           272:            dread(&c, addr, sizeof(char));
        !           273:            while (c != '\0') {
        !           274:                printchar(c);
        !           275:                ++addr;
        !           276:                dread(&c, addr, sizeof(char));
        !           277:            }
        !           278:            printf("\"\n");
        !           279:            n = 0;
        !           280:            addr += sizeof(String);
        !           281:        } else {
        !           282:            printformat(f, addr);
        !           283:            ++n;
        !           284:            if (n >= (16 div f->length)) {
        !           285:                printf("\n");
        !           286:                n = 0;
        !           287:            }
        !           288:            addr += f->length;
        !           289:        }
        !           290:     }
        !           291:     if (n != 0) {
        !           292:        printf("\n");
        !           293:     }
        !           294:     prtaddr = addr;
        !           295: }
        !           296: 
        !           297: /*
        !           298:  * Print out a value according to the given format.
        !           299:  */
        !           300: 
        !           301: public printvalue(v, format)
        !           302: long v;
        !           303: String format;
        !           304: {
        !           305:     Format *f;
        !           306:     char *p, *q;
        !           307: 
        !           308:     f = findformat(format);
        !           309:     if (streq(f->name, "s")) {
        !           310:        putchar('"');
        !           311:        p = (char *) &v;
        !           312:        q = p + sizeof(v);
        !           313:        while (p < q) {
        !           314:            printchar(*p);
        !           315:            ++p;
        !           316:        }
        !           317:        putchar('"');
        !           318:     } else {
        !           319:        printf(f->printfstring, v);
        !           320:     }
        !           321:     putchar('\n');
        !           322: }
        !           323: 
        !           324: /*
        !           325:  * Print out an execution time error.
        !           326:  * Assumes the source position of the error has been calculated.
        !           327:  *
        !           328:  * Have to check if the -r option was specified; if so then
        !           329:  * the object file information hasn't been read in yet.
        !           330:  */
        !           331: 
        !           332: public printerror()
        !           333: {
        !           334:     extern Integer sys_nsig;
        !           335:     extern String sys_siglist[];
        !           336:     integer err;
        !           337: 
        !           338:     if (isfinished(process)) {
        !           339:        err = exitcode(process);
        !           340:        if (err == 0) {
        !           341:            printf("\"%s\" terminated normally\n", objname);
        !           342:        } else {
        !           343:            printf("\"%s\" terminated abnormally (exit code %d)\n",
        !           344:                objname, err
        !           345:            );
        !           346:        }
        !           347:        erecover();
        !           348:     }
        !           349:     err = errnum(process);
        !           350:     putchar('\n');
        !           351:     printsig(err);
        !           352:     putchar(' ');
        !           353:     printloc();
        !           354:     putchar('\n');
        !           355:     if (curline > 0) {
        !           356:        printlines(curline, curline);
        !           357:     } else {
        !           358:        printinst(pc, pc);
        !           359:     }
        !           360:     erecover();
        !           361: }
        !           362: 
        !           363: /*
        !           364:  * Print out a signal.
        !           365:  */
        !           366: 
        !           367: private String illinames[] = {
        !           368:     "reserved addressing fault",
        !           369:     "privileged instruction fault",
        !           370:     "reserved operand fault"
        !           371: };
        !           372: 
        !           373: private String fpenames[] = {
        !           374:     nil,
        !           375:     "integer overflow trap",
        !           376:     "integer divide by zero trap",
        !           377:     "floating overflow trap",
        !           378:     "floating/decimal divide by zero trap",
        !           379:     "floating underflow trap",
        !           380:     "decimal overflow trap",
        !           381:     "subscript out of range trap",
        !           382:     "floating overflow fault",
        !           383:     "floating divide by zero fault",
        !           384:     "floating underflow fault"
        !           385: };
        !           386: 
        !           387: public printsig (signo)
        !           388: integer signo;
        !           389: {
        !           390:     integer code;
        !           391: 
        !           392:     if (signo < 0 or signo > sys_nsig) {
        !           393:        printf("[signal %d]", signo);
        !           394:     } else {
        !           395:        printf("%s", sys_siglist[signo]);
        !           396:     }
        !           397:     code = errcode(process);
        !           398:     if (signo == SIGILL) {
        !           399:        if (code >= 0 and code < sizeof(illinames) / sizeof(illinames[0])) {
        !           400:            printf(" (%s)", illinames[code]);
        !           401:        }
        !           402:     } else if (signo == SIGFPE) {
        !           403:        if (code > 0 and code < sizeof(fpenames) / sizeof(fpenames[0])) {
        !           404:            printf(" (%s)", fpenames[code]);
        !           405:        }
        !           406:     }
        !           407: }
        !           408: 
        !           409: /*
        !           410:  * Note the termination of the program.  We do this so as to avoid
        !           411:  * having the process exit, which would make the values of variables
        !           412:  * inaccessible.  We do want to flush all output buffers here,
        !           413:  * otherwise it'll never get done.
        !           414:  */
        !           415: 
        !           416: public endprogram()
        !           417: {
        !           418:     Integer exitcode;
        !           419: 
        !           420:     stepto(nextaddr(pc, true));
        !           421:     printnews();
        !           422:     exitcode = argn(1, nil);
        !           423:     if (exitcode != 0) {
        !           424:        printf("\nexecution completed (exit code %d)\n", exitcode);
        !           425:     } else {
        !           426:        printf("\nexecution completed\n");
        !           427:     }
        !           428:     getsrcpos();
        !           429:     erecover();
        !           430: }
        !           431: 
        !           432: /*
        !           433:  * Single step the machine a source line (or instruction if "inst_tracing"
        !           434:  * is true).  If "isnext" is true, skip over procedure calls.
        !           435:  */
        !           436: 
        !           437: private Address getcall();
        !           438: 
        !           439: public dostep(isnext)
        !           440: Boolean isnext;
        !           441: {
        !           442:     register Address addr;
        !           443:     register Lineno line;
        !           444:     String filename;
        !           445:     Address startaddr;
        !           446: 
        !           447:     startaddr = pc;
        !           448:     addr = nextaddr(pc, isnext);
        !           449:     if (not inst_tracing and nlhdr.nlines != 0) {
        !           450:        line = linelookup(addr);
        !           451:        while (line == 0) {
        !           452:            addr = nextaddr(addr, isnext);
        !           453:            line = linelookup(addr);
        !           454:        }
        !           455:        curline = line;
        !           456:     } else {
        !           457:        curline = 0;
        !           458:     }
        !           459:     stepto(addr);
        !           460:     filename = srcfilename(addr);
        !           461:     setsource(filename);
        !           462: }
        !           463: 
        !           464: typedef short Bpinst;
        !           465: 
        !           466: extern Bpinst BP_OP;
        !           467: #ifdef sun
        !           468:        asm("_BP_OP: trap #15");
        !           469: #else /* IRIS */
        !           470:        asm("_BP_OP: trap #1");
        !           471: #endif
        !           472: 
        !           473: #define BP_ERRNO    SIGTRAP     /* signal received at a breakpoint */
        !           474: 
        !           475: /*
        !           476:  * Setting a breakpoint at a location consists of saving
        !           477:  * the word at the location and poking a BP_OP there.
        !           478:  *
        !           479:  * We save the locations and words on a list for use in unsetting.
        !           480:  */
        !           481: 
        !           482: typedef struct Savelist *Savelist;
        !           483: 
        !           484: struct Savelist {
        !           485:     Address location;
        !           486:     Bpinst save;
        !           487:     short refcount;
        !           488:     Savelist link;
        !           489: };
        !           490: 
        !           491: private Savelist savelist;
        !           492: 
        !           493: /*
        !           494:  * Set a breakpoint at the given address.  Only save the word there
        !           495:  * if it's not already a breakpoint.
        !           496:  */
        !           497: 
        !           498: public setbp(addr)
        !           499: Address addr;
        !           500: {
        !           501:     Bpinst w, save;
        !           502:     register Savelist newsave, s;
        !           503: 
        !           504:     for (s = savelist; s != nil; s = s->link) {
        !           505:        if (s->location == addr) {
        !           506:            s->refcount++;
        !           507:            return;
        !           508:        }
        !           509:     }
        !           510:     iread(&save, addr, sizeof(save));
        !           511:     newsave = new(Savelist);
        !           512:     newsave->location = addr;
        !           513:     newsave->save = save;
        !           514:     newsave->refcount = 1;
        !           515:     newsave->link = savelist;
        !           516:     savelist = newsave;
        !           517:     w = BP_OP;
        !           518:     iwrite(&w, addr, sizeof(w));
        !           519: }
        !           520: 
        !           521: /*
        !           522:  * Unset a breakpoint; unfortunately we have to search the SAVELIST
        !           523:  * to find the saved value.  The assumption is that the SAVELIST will
        !           524:  * usually be quite small.
        !           525:  */
        !           526: 
        !           527: public unsetbp(addr)
        !           528: Address addr;
        !           529: {
        !           530:     register Savelist s, prev;
        !           531: 
        !           532:     prev = nil;
        !           533:     for (s = savelist; s != nil; s = s->link) {
        !           534:        if (s->location == addr) {
        !           535:            iwrite(&s->save, addr, sizeof(s->save));
        !           536:            s->refcount--;
        !           537:            if (s->refcount == 0) {
        !           538:                if (prev == nil) {
        !           539:                    savelist = s->link;
        !           540:                } else {
        !           541:                    prev->link = s->link;
        !           542:                }
        !           543:                dispose(s);
        !           544:            }
        !           545:            return;
        !           546:        }
        !           547:        prev = s;
        !           548:     }
        !           549:     panic("unsetbp: couldn't find address %d", addr);
        !           550: }
        !           551: 
        !           552: /*
        !           553:  * Instruction decoding routines for 68000, derived from adb.
        !           554:  *
        !           555:  * The shared boolean variable "printing" is true if the decoded
        !           556:  * instruction is to be printed, false if not.  In either case,
        !           557:  * the address of the next instruction after the given one is returned.
        !           558:  */
        !           559: 
        !           560: private Boolean printing;
        !           561: private Boolean following;
        !           562: private Boolean followcalls;
        !           563: private Address instaddr;
        !           564: 
        !           565: #define instread(var) \
        !           566: { \
        !           567:     iread(&var, instaddr, sizeof(var)); \
        !           568:     instaddr += sizeof(var); \
        !           569: }
        !           570: 
        !           571: private Optab *decode(inst, addr)
        !           572: Word inst;
        !           573: Address addr;
        !           574: {
        !           575:     register Optab *o;
        !           576: 
        !           577:     o = &optab[0];
        !           578:     while (o->mask != 0 and (inst&o->mask) != o->match) {
        !           579:        ++o;
        !           580:     }
        !           581:     return o;
        !           582: }
        !           583: 
        !           584: private Address printop(addr)
        !           585: Address addr;
        !           586: {
        !           587:     Optab *o;
        !           588:     short inst;
        !           589: 
        !           590:     printf("%08x  ", addr);
        !           591:     iread(&inst, addr, sizeof(inst));
        !           592:     o = decode(inst, addr);
        !           593:     if (o->mask == 0) {
        !           594:        printf("\tbadop");
        !           595:        instaddr = addr + sizeof(inst);
        !           596:     } else {
        !           597:        printing = true;
        !           598:        following = false;
        !           599:        instaddr = addr + sizeof(inst);
        !           600:        (*o->opfun)(inst, o->farg);
        !           601:        printing = false;
        !           602:     }
        !           603:     printf("\n");
        !           604:     return instaddr;
        !           605: }
        !           606: 
        !           607: /*
        !           608:  * Quickly find the return address of the current procedure or function
        !           609:  * while single stepping.  Just get the word pointed at by sp.
        !           610:  */
        !           611: 
        !           612: private Address currtnaddr ()
        !           613: {
        !           614:     Address retaddr;
        !           615: 
        !           616:     dread(&retaddr, reg(STKP), sizeof(retaddr));
        !           617:     return retaddr;
        !           618: }
        !           619: 
        !           620: /*
        !           621:  * Print out the effective address for the given parameters.
        !           622:  */
        !           623: 
        !           624: private printea(mode, reg, size)
        !           625: long mode, reg;
        !           626: int size;
        !           627: {
        !           628:     long index, disp;
        !           629:     static char *aregs[] = { "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp" };
        !           630:     Byte b;
        !           631:     short w;
        !           632:     long l;
        !           633: 
        !           634:     switch ((int)(mode)) {
        !           635:        case 0:
        !           636:            if (printing) {
        !           637:                printf("d%D", reg);
        !           638:            }
        !           639:            break;
        !           640: 
        !           641:        case 1:
        !           642:            if (printing) {
        !           643:                printf("%s", aregs[reg]);
        !           644:            }
        !           645:            break;
        !           646: 
        !           647:        case 2:
        !           648:            if (printing) {
        !           649:                printf("%s@", aregs[reg]);
        !           650:            }
        !           651:            break;
        !           652: 
        !           653:        case 3:
        !           654:            if (printing) {
        !           655:                printf("%s@+", aregs[reg]);
        !           656:            }
        !           657:            break;
        !           658: 
        !           659:        case 4:
        !           660:            if (printing) {
        !           661:                printf("%s@-", aregs[reg]);
        !           662:            }
        !           663:            break;
        !           664: 
        !           665:        case 5:
        !           666:            instread(w);
        !           667:            if (printing) {
        !           668:                printf("%s@(%D)", aregs[reg], w);
        !           669:            }
        !           670:            break;
        !           671: 
        !           672:        case 6:
        !           673:            instread(w);
        !           674:            if (printing) {
        !           675:                index = w;
        !           676:                disp = (char)(index&0377);
        !           677:                printf("%s@(%d,%c%D:%c)", aregs[reg], disp,
        !           678:                    (index&0100000)?'a':'d',(index>>12)&07,
        !           679:                    (index&04000)?'l':'w');
        !           680:            }
        !           681:            break;
        !           682: 
        !           683:        case 7:
        !           684:            switch ((int)(reg)) {
        !           685:                case 0:
        !           686:                    instread(w);
        !           687:                    if (printing) {
        !           688:                        index = w;
        !           689:                        psymoff(index);
        !           690:                    }
        !           691:                    break;
        !           692: 
        !           693:                case 1:
        !           694:                    instread(l);
        !           695:                    if (printing) {
        !           696:                        index = l;
        !           697:                        psymoff(index);
        !           698:                    }
        !           699:                    break;
        !           700: 
        !           701:                case 2: 
        !           702:                    instread(w);
        !           703:                    if (printing) {
        !           704:                        disp = w;
        !           705:                        psymoff(disp + instaddr);
        !           706:                    }
        !           707:                    break;
        !           708: 
        !           709:                case 3:
        !           710:                    instread(w);
        !           711:                    if (printing) {
        !           712:                        index = w;
        !           713:                        disp = (char)(index&0377);
        !           714:                        printf("pc@(%D,%c%D:%c)", disp,
        !           715:                            (index&0100000)?'a':'d',(index>>12)&07,
        !           716:                            (index&04000)?'l':'w');
        !           717:                    }
        !           718:                    break;
        !           719: 
        !           720:                case 4:
        !           721:                    switch (size) {
        !           722:                        case sizeof(b):
        !           723:                            instread(w);
        !           724:                            index = (w&0xff);
        !           725:                            break;
        !           726: 
        !           727:                        case sizeof(w):
        !           728:                            instread(w);
        !           729:                            index = w;
        !           730:                            break;
        !           731: 
        !           732:                        case sizeof(l):
        !           733:                            instread(l);
        !           734:                            index = l;
        !           735:                            break;
        !           736: 
        !           737:                        default:
        !           738:                            if (printing) {
        !           739:                                printf("unexpected size %d in printea\n", size);
        !           740:                            }
        !           741:                            instread(l);
        !           742:                            index = l;
        !           743:                            break;
        !           744:                    }
        !           745:                    if (printing) {
        !           746:                        printf(IMDF, index);
        !           747:                    }
        !           748:                    break;
        !           749: 
        !           750:                default:
        !           751:                    if (printing) {
        !           752:                        printf("???");
        !           753:                    }
        !           754:                    break;
        !           755:            }
        !           756:            break;
        !           757: 
        !           758:        default:
        !           759:            if (printing) {
        !           760:                printf("???");
        !           761:            }
        !           762:            break;
        !           763:     }
        !           764: }
        !           765: 
        !           766: private printEA(ea, size)
        !           767: long ea;
        !           768: int size;
        !           769: {
        !           770:     printea((ea>>3)&07, ea&07, size);
        !           771: }
        !           772: 
        !           773: private mapsize(inst)
        !           774: register long inst;
        !           775: {
        !           776:     int m;
        !           777: 
        !           778:     inst >>= 6;
        !           779:     inst &= 03;
        !           780:     switch (inst) {
        !           781:        case 0:
        !           782:            m = 1;
        !           783:            break;
        !           784: 
        !           785:        case 1:
        !           786:            m = 2;
        !           787:            break;
        !           788: 
        !           789:        case 2:
        !           790:            m = 4;
        !           791:            break;
        !           792: 
        !           793:        default:
        !           794:            m = -1;
        !           795:            break;
        !           796:     }
        !           797:     return m;
        !           798: }
        !           799: 
        !           800: private char suffix(size)
        !           801: int size;
        !           802: {
        !           803:     char c;
        !           804: 
        !           805:     switch (size) {
        !           806:        case 1:
        !           807:            c = 'b';
        !           808:            break;
        !           809: 
        !           810:        case 2:
        !           811:            c = 'w';
        !           812:            break;
        !           813: 
        !           814:        case 4:
        !           815:            c = 'l';
        !           816:            break;
        !           817: 
        !           818:        default:
        !           819:            panic("bad size %d in suffix", size);
        !           820:     }
        !           821:     return c;
        !           822: }
        !           823: 
        !           824: /*
        !           825:  * Print an address offset.  Eventually this should attempt to be symbolic,
        !           826:  * but for now its just printed in hex.
        !           827:  */
        !           828: 
        !           829: private psymoff (off)
        !           830: Word off;
        !           831: {
        !           832:     Symbol f;
        !           833: 
        !           834:     f = whatblock((Address) (off + FUNCOFFSET));
        !           835:     if (codeloc(f) == off + FUNCOFFSET) {
        !           836:        printf("%s", symname(f));
        !           837:     } else {
        !           838:        printf("0x%x", off);
        !           839:     }
        !           840: }
        !           841: 
        !           842: /*
        !           843:  * Instruction class specific routines.
        !           844:  */
        !           845: 
        !           846: public omove(inst, s)
        !           847: long inst;
        !           848: String s;
        !           849: {
        !           850:     register int c;
        !           851:     int size;
        !           852: 
        !           853:     c = s[0];
        !           854:     if (printing) {
        !           855:        printf("\tmov%c\t", c);
        !           856:     }
        !           857:     size = ((c == 'b') ? 1 : (c == 'w') ? 2 : 4);
        !           858:     printea((inst>>3)&07, inst&07, size);
        !           859:     if (printing) {
        !           860:        printf(",");
        !           861:     }
        !           862:     printea((inst>>6)&07, (inst>>9)&07, size);
        !           863: }
        !           864: 
        !           865: /* 
        !           866:  * Two types: bsr (4 bytes) and bsrs (2 bytes)
        !           867:  */
        !           868: 
        !           869: public obranch(inst, dummy)
        !           870: long inst;
        !           871: {
        !           872:     long disp;
        !           873:     String s; 
        !           874:     short w;
        !           875:     Address startingaddr;      /* address of branch instruction */
        !           876:     int branchtype;            /* type of branch (0 = unconditional) */
        !           877:     Address dest;
        !           878:     Address retaddr;           /* for bsr instruction */
        !           879: 
        !           880:     startingaddr = instaddr - 2;
        !           881:     disp = inst&0377;
        !           882:     s = "s ";
        !           883:     if (disp == 0) {
        !           884:        retaddr = startingaddr + 4;
        !           885:     } else {
        !           886:        retaddr = startingaddr + 2;
        !           887:     }
        !           888:     if (disp > 127) {
        !           889:        disp |= ~0377;
        !           890:     } else if (disp == 0){
        !           891:        s = " ";
        !           892:        instread(w);
        !           893:        disp = w;
        !           894:     }
        !           895:     branchtype = (int)((inst>>8)&017);
        !           896:     dest = startingaddr + 2 + disp;
        !           897:     if (printing) {
        !           898:        printf("\tb%s%s\t", bname[branchtype], s);
        !           899:        psymoff(dest);
        !           900:     }
        !           901:     if (following) {
        !           902:        /*
        !           903:         * If we're to follow the dynamic flow of instructions,
        !           904:         * we must see where the branch leads.  A branchtype of 0
        !           905:         * indicates an unconditional branch which we simply take
        !           906:         * as the new instruction address.  For a conditional branch,
        !           907:         * we continue execution up to the current address, single step,
        !           908:         * and keep going.
        !           909:         */
        !           910:        if (branchtype == 0) {
        !           911:            instaddr = dest;
        !           912:        } else if (branchtype == 01) {          /* bsr */
        !           913:            if (followcalls) {
        !           914:                steppast(startingaddr);
        !           915:                curfunc = whatblock(pc, true);
        !           916:                if (not isbperr()) {
        !           917:                    printstatus();
        !           918:                    /* NOTREACHED */
        !           919:                }
        !           920:                bpact();
        !           921:                if (nosource(curfunc) and canskip(curfunc) and
        !           922:                  nlhdr.nlines != 0) {
        !           923:                    stepto(retaddr);
        !           924:                    instaddr = pc;
        !           925:                    bpact();
        !           926:                } else {
        !           927:                    callnews(/* iscall = */ true);
        !           928:                }
        !           929:            }
        !           930:        } else {
        !           931:            steppast(startingaddr);
        !           932:        }
        !           933:     }
        !           934: }
        !           935: 
        !           936: public odbcc(inst, form)
        !           937: long inst;
        !           938: String form;
        !           939: {
        !           940:     long disp;
        !           941:     short w;
        !           942: 
        !           943:     instread(w);
        !           944:     if (printing) {
        !           945:        printf(form, dbname[(int)((inst>>8)&017)], inst&07);
        !           946:        psymoff(w + sizeof(w));
        !           947:     }
        !           948: }
        !           949: 
        !           950: public oscc(inst, dummy)
        !           951: long inst;
        !           952: long dummy;
        !           953: {
        !           954:     if (printing) {
        !           955:        printf("\ts%s\t", cname[(int)((inst>>8)&017)]);
        !           956:     }
        !           957:     printea((inst>>3)&07, inst&07, 1);
        !           958: }
        !           959: 
        !           960: public biti(inst, dummy)
        !           961: long inst;
        !           962: long dummy;
        !           963: {
        !           964:     short w;
        !           965: 
        !           966:     if (printing) {
        !           967:        printf("\t%s\t", bit[(int)((inst>>6)&03)]);
        !           968:     }
        !           969:     if (inst&0x0100) {
        !           970:        if (printing) {
        !           971:            printf("d%D,", inst>>9);
        !           972:        }
        !           973:     } else {
        !           974:        instread(w);
        !           975:        if (printing) {
        !           976:            printf(IMDF, w);
        !           977:            printf(",");
        !           978:        }
        !           979:     }
        !           980:     printEA(inst);
        !           981: }
        !           982: 
        !           983: public opmode(inst, opcode)
        !           984: long inst;
        !           985: long opcode;
        !           986: {
        !           987:     register int opmode;
        !           988:     register int reg;
        !           989:     int size;
        !           990: 
        !           991:     opmode = (int)((inst>>6) & 07);
        !           992:     reg = (int)((inst>>9) & 07);
        !           993:     if (opmode == 0 or opmode == 4) {
        !           994:        size = 1;
        !           995:     } else if (opmode == 1 or opmode == 3 or opmode == 5) {
        !           996:        size = 2;
        !           997:     } else {
        !           998:        size = 4;
        !           999:     }
        !          1000:     if (printing) {
        !          1001:        printf("\t%s%c\t", opcode, suffix(size));
        !          1002:     }
        !          1003:     if (opmode >= 4 and opmode <= 6) {
        !          1004:        if (printing) {
        !          1005:            printf("d%d,", reg);
        !          1006:        }
        !          1007:        printea((inst>>3)&07, inst&07, size);
        !          1008:     } else {
        !          1009:        printea((inst>>3)&07, inst&07, size);
        !          1010:        if (printing) {
        !          1011:            printf(",%c%d",(opmode<=2) ? 'd' : 'a', reg);
        !          1012:        }
        !          1013:     }
        !          1014: }
        !          1015: 
        !          1016: public shroi(inst, ds)
        !          1017: long inst;
        !          1018: String ds;
        !          1019: {
        !          1020:     int rx, ry;
        !          1021:     String opcode;
        !          1022: 
        !          1023:     if ((inst & 0xC0) == 0xC0) {
        !          1024:        opcode = shro[(int)((inst>>9)&03)];
        !          1025:        if (printing) {
        !          1026:            printf("\t%s%s\t", opcode, ds);
        !          1027:        }
        !          1028:        printEA(inst);
        !          1029:     } else {
        !          1030:        if (printing) {
        !          1031:            opcode = shro[(int)((inst>>3)&03)];
        !          1032:            printf("\t%s%s%c\t", opcode, ds, suffix(mapsize(inst)));
        !          1033:            rx = (int)((inst>>9)&07); ry = (int)(inst&07);
        !          1034:            if ((inst>>5)&01) {
        !          1035:                printf("d%d,d%d", rx, ry);
        !          1036:            } else {
        !          1037:                printf(IMDF, (rx ? rx : 8));
        !          1038:                printf(",d%d", ry);
        !          1039:            }
        !          1040:        }
        !          1041:     }
        !          1042: }              
        !          1043: 
        !          1044: public oimmed(inst, opcode)
        !          1045: long inst;
        !          1046: register String opcode;
        !          1047: {
        !          1048:     register int size;
        !          1049:     long const;
        !          1050:     short w;
        !          1051: 
        !          1052:     size = mapsize(inst);
        !          1053:     if (size > 0) {
        !          1054:        if (size == 4) {
        !          1055:            instread(const);
        !          1056:        } else {
        !          1057:            instread(w);
        !          1058:            const = w;
        !          1059:        }
        !          1060:        if (printing) {
        !          1061:            printf("\t%s%c\t", opcode, suffix(size));
        !          1062:            printf(IMDF, const);
        !          1063:            printf(",");
        !          1064:        }
        !          1065:        printEA(inst, size);
        !          1066:     } else {
        !          1067:        if (printing) {
        !          1068:            printf("\tbadop");
        !          1069:        }
        !          1070:     }
        !          1071: }
        !          1072: 
        !          1073: public oreg(inst, opcode)
        !          1074: long inst;
        !          1075: register String opcode;
        !          1076: {
        !          1077:     if (printing) {
        !          1078:        printf(opcode, (inst & 07));
        !          1079:     }
        !          1080: }
        !          1081: 
        !          1082: public extend(inst, opcode)
        !          1083: long inst;
        !          1084: String opcode;
        !          1085: {
        !          1086:     register int size;
        !          1087:     int ry, rx;
        !          1088:     char c;
        !          1089: 
        !          1090:     if (printing) {
        !          1091:        size = mapsize(inst);
        !          1092:        ry = (inst&07);
        !          1093:        rx = ((inst>>9)&07);
        !          1094:        c = ((inst & 0x1000) ? suffix(size) : ' ');
        !          1095:        printf("\t%s%c\t", opcode, c);
        !          1096:        if (opcode[0] == 'e') {
        !          1097:            if (inst & 0x0080) {
        !          1098:                printf("d%D,a%D", rx, ry);
        !          1099:            } else if (inst & 0x0008) {
        !          1100:                printf("a%D,a%D", rx, ry);
        !          1101:            } else {
        !          1102:                printf("d%D,d%D", rx, ry);
        !          1103:            }
        !          1104:        } else if ((inst & 0xF000) == 0xB000) {
        !          1105:            printf("a%D@+,a%D@+", ry, rx);
        !          1106:        } else if (inst & 0x8) {
        !          1107:            printf("a%D@-,a%D@-", ry, rx);
        !          1108:        } else {
        !          1109:            printf("d%D,d%D", ry, rx);
        !          1110:        }
        !          1111:     }
        !          1112: }
        !          1113: 
        !          1114: public olink(inst, dummy)
        !          1115: long inst;
        !          1116: long dummy;
        !          1117: {
        !          1118:     short w;
        !          1119: 
        !          1120:     instread(w);
        !          1121:     if (printing) {
        !          1122:        printf("\tlink\ta%D,", inst&07);
        !          1123:        printf(IMDF, w);
        !          1124:     }
        !          1125: }
        !          1126: 
        !          1127: public otrap(inst, dummy)
        !          1128: long inst;
        !          1129: {
        !          1130:     if (printing) {
        !          1131:        printf("\ttrap\t");
        !          1132:        printf(IMDF, inst&017);
        !          1133:     }
        !          1134: }
        !          1135: 
        !          1136: public oneop(inst, opcode)
        !          1137: long inst;
        !          1138: register String opcode;
        !          1139: {
        !          1140:     if (printing) {
        !          1141:        printf("\t%s",opcode);
        !          1142:     }
        !          1143:     printEA(inst);
        !          1144: }
        !          1145: 
        !          1146: public jsrop(inst, opcode)
        !          1147: long inst;
        !          1148: register String opcode;
        !          1149: {
        !          1150:     Address startingaddr;      /* beginning of jsr instruction */
        !          1151:     Address retaddr; /* can't call return_addr (frame not set up yet) */
        !          1152: 
        !          1153:     startingaddr = instaddr - 2;
        !          1154:     switch ((inst >> 3) & 07) {
        !          1155:        case 2:
        !          1156:            retaddr = instaddr;         /* two byte instruction */
        !          1157:            break;
        !          1158:        case 5:
        !          1159:        case 6:
        !          1160:            retaddr = instaddr + 2;     /* four byte instruction */
        !          1161:            break;
        !          1162:        case 7:
        !          1163:        default:
        !          1164:            switch (inst & 07) {
        !          1165:                case 0:
        !          1166:                case 2:
        !          1167:                case 3:
        !          1168:                    retaddr = instaddr + 2;
        !          1169:                    break;
        !          1170:                case 1:
        !          1171:                default:
        !          1172:                    retaddr = instaddr + 4;     /* six byte instruction */
        !          1173:                    break;
        !          1174:            }
        !          1175:            break;
        !          1176:     }
        !          1177:     if (printing) {
        !          1178:        printf("\t%s",opcode);
        !          1179:     }
        !          1180:     printEA(inst);
        !          1181:     if (following and followcalls) {
        !          1182:        steppast(startingaddr);
        !          1183:        curfunc = whatblock(pc, true);
        !          1184:        if (not isbperr()) {
        !          1185:            printstatus();
        !          1186:            /* NOTREACHED */
        !          1187:        }
        !          1188:        bpact();
        !          1189:        if (nosource(curfunc) and canskip(curfunc) and nlhdr.nlines != 0) {
        !          1190:            stepto(retaddr);
        !          1191:            instaddr = pc;
        !          1192:            bpact();
        !          1193:        } else {
        !          1194:            callnews(/* iscall = */ true);
        !          1195:        }
        !          1196:     }
        !          1197: }
        !          1198: 
        !          1199: public jmpop(inst, opcode)
        !          1200: long inst;
        !          1201: register String opcode;
        !          1202: {
        !          1203:     Address startingaddr;      /* beginning of jump instruction */
        !          1204: 
        !          1205:     startingaddr = instaddr - 2;
        !          1206:     if (printing) {
        !          1207:        printf("\t%s",opcode);
        !          1208:     }
        !          1209:     printEA(inst);
        !          1210:     if (following) {
        !          1211:        steppast(startingaddr);
        !          1212:     }
        !          1213: }
        !          1214: 
        !          1215: public pregmask(mask)
        !          1216: register int mask;
        !          1217: {
        !          1218:     register int i;
        !          1219:     register int flag = 0;
        !          1220: 
        !          1221:     if (printing) {
        !          1222:        printf("#<");
        !          1223:        for (i=0; i<16; i++) {
        !          1224:            if (mask&1) {
        !          1225:                if (flag) {
        !          1226:                    printf(",");
        !          1227:                } else {
        !          1228:                    ++flag;
        !          1229:                }
        !          1230:                printf("%c%d",(i<8) ? 'd' : 'a', i&07);
        !          1231:            }
        !          1232:            mask >>= 1;
        !          1233:        }
        !          1234:        printf(">");
        !          1235:     }
        !          1236: }
        !          1237: 
        !          1238: public omovem(inst, dummy)
        !          1239: long inst;
        !          1240: long dummy;
        !          1241: {
        !          1242:     register int i, list, mask;
        !          1243:     register int reglist;
        !          1244:     short w;
        !          1245: 
        !          1246:     i = 0;
        !          1247:     list = 0;
        !          1248:     mask = 0100000;
        !          1249:     instread(w);
        !          1250:     reglist = w;
        !          1251:     if ((inst & 070) == 040) { /* predecrement */
        !          1252:        for (i = 15; i > 0; i -= 2) {
        !          1253:            list |= ((mask & reglist) >> i);
        !          1254:            mask >>= 1;
        !          1255:        }
        !          1256:        for (i = 1; i < 16; i += 2) {
        !          1257:            list |= ((mask & reglist) << i);
        !          1258:            mask >>= 1;
        !          1259:        }
        !          1260:        reglist = list;
        !          1261:     }
        !          1262:     if (printing) {
        !          1263:        printf("\tmovem%c\t",(inst&100)?'l':'w');
        !          1264:     }
        !          1265:     if (inst&02000) {
        !          1266:        printEA(inst);
        !          1267:        if (printing) {
        !          1268:            printf(",");
        !          1269:        }
        !          1270:        pregmask(reglist);
        !          1271:     } else {
        !          1272:        pregmask(reglist);
        !          1273:        if (printing) {
        !          1274:            printf(",");
        !          1275:        }
        !          1276:        printEA(inst);
        !          1277:     }
        !          1278: }
        !          1279: 
        !          1280: public ochk(inst, opcode)
        !          1281: long inst;
        !          1282: register String opcode;
        !          1283: {
        !          1284:     if (printing) {
        !          1285:        printf("\t%s\t", opcode);
        !          1286:     }
        !          1287:     printEA(inst, sizeof(Byte));
        !          1288:     if (printing) {
        !          1289:        printf(",%c%D", (opcode[0] == 'l') ? 'a' : 'd', (inst>>9)&07);
        !          1290:     }
        !          1291: }
        !          1292: 
        !          1293: public soneop(inst, opcode)
        !          1294: long inst;
        !          1295: register String opcode;
        !          1296: {
        !          1297:     register int size;
        !          1298: 
        !          1299:     size = mapsize(inst);
        !          1300:     if (size > 0) {
        !          1301:        if (printing) {
        !          1302:            printf("\t%s%c\t", opcode, suffix(size));
        !          1303:        }
        !          1304:        printEA(inst);
        !          1305:     } else {
        !          1306:        if (printing) {
        !          1307:            printf("\tbadop");
        !          1308:        }
        !          1309:     }
        !          1310: }
        !          1311: 
        !          1312: public oquick(inst, opcode)
        !          1313: long inst;
        !          1314: register String opcode;
        !          1315: {
        !          1316:     register int size;
        !          1317:     register int data;
        !          1318: 
        !          1319:     size = mapsize(inst);
        !          1320:     data = (int)((inst>>9) & 07);
        !          1321:     if (data == 0) {
        !          1322:        data = 8;
        !          1323:     }
        !          1324:     if (size > 0) {
        !          1325:        if (printing) {
        !          1326:            printf("\t%s%c\t", opcode, suffix(size));
        !          1327:            printf(IMDF, data);
        !          1328:            printf(",");
        !          1329:        }
        !          1330:        printEA(inst);
        !          1331:     } else {
        !          1332:        if (printing) {
        !          1333:            printf("\tbadop");
        !          1334:        }
        !          1335:     }
        !          1336: }
        !          1337: 
        !          1338: public omoveq(inst, dummy)
        !          1339: long inst;
        !          1340: long dummy;
        !          1341: {
        !          1342:     register int data;
        !          1343: 
        !          1344:     if (printing) {
        !          1345:        data = (int)(inst & 0377);
        !          1346:        if (data > 127) {
        !          1347:            data |= ~0377;
        !          1348:        }
        !          1349:        printf("\tmoveq\t");
        !          1350:        printf(IMDF, data);
        !          1351:        printf(",d%D", (inst>>9)&07);
        !          1352:     }
        !          1353: }
        !          1354: 
        !          1355: public oprint(inst, opcode)
        !          1356: long inst;
        !          1357: register String opcode;
        !          1358: {
        !          1359:     if (printing) {
        !          1360:        printf("\t%s",opcode);
        !          1361:     }
        !          1362: }
        !          1363: 
        !          1364: public ostop(inst, opcode)
        !          1365: long inst;
        !          1366: register String opcode;
        !          1367: {
        !          1368:     short w;
        !          1369: 
        !          1370:     instread(w);
        !          1371:     if (printing) {
        !          1372:        printf(opcode, w);
        !          1373:     }
        !          1374: }
        !          1375: 
        !          1376: public orts(inst, opcode)
        !          1377: long inst;
        !          1378: register String opcode;
        !          1379: {
        !          1380:     Address addr;
        !          1381: 
        !          1382:     if (following) {
        !          1383:        callnews(/* iscall = */ false);
        !          1384:        if (inst_tracing) {
        !          1385:            addr = currtnaddr();
        !          1386:        } else {
        !          1387:            addr = return_addr();
        !          1388:            if (addr == 0) {
        !          1389:                stepto(instaddr - 2);
        !          1390:                addr = currtnaddr();
        !          1391:            }
        !          1392:        }
        !          1393:        stepto(addr);
        !          1394:        instaddr = pc;
        !          1395:     }
        !          1396:     if (printing) {
        !          1397:        printf("\t%s",opcode);
        !          1398:     }
        !          1399: }
        !          1400: 
        !          1401: /*
        !          1402:  * Not used by C compiler; does an rts but before doing so, pops
        !          1403:  * arg bytes from the stack.
        !          1404:  */
        !          1405: 
        !          1406: public ortspop(inst, opcode)
        !          1407: long inst;
        !          1408: register String opcode;
        !          1409: {
        !          1410:     Address addr;
        !          1411:     short w;
        !          1412: 
        !          1413:     instread(w);
        !          1414:     if (following) {
        !          1415:        callnews(/* iscall = */ false);
        !          1416:        if (inst_tracing) {
        !          1417:            addr = currtnaddr();
        !          1418:        } else {
        !          1419:            addr = return_addr();
        !          1420:        }
        !          1421:        stepto(addr);
        !          1422:        instaddr = pc;
        !          1423:     }
        !          1424:     if (printing) {
        !          1425:        printf(opcode, w);
        !          1426:     }
        !          1427: }
        !          1428: 
        !          1429: public omovs(inst, opcode)
        !          1430: long inst;
        !          1431: String opcode;
        !          1432: {
        !          1433:     register int size;
        !          1434:     register unsigned int controlword;
        !          1435:     short w;
        !          1436: 
        !          1437:     size = mapsize(inst);
        !          1438:     instread(w);
        !          1439:     controlword = w >> 11;
        !          1440:     if (printing) {
        !          1441:        printf("\t%s%c\t", opcode, suffix(size));
        !          1442:     }
        !          1443:     if (controlword & 1){
        !          1444:        controlword >>= 1;
        !          1445:        if (printing) {
        !          1446:            printf((controlword&0x8) ? "a%D," : "d%D,", controlword&7 );
        !          1447:        }
        !          1448:        printEA(inst&0xff, size);
        !          1449:     } else {
        !          1450:        controlword >>= 1;
        !          1451:        printEA(inst&0xff, size);
        !          1452:        if (printing) {
        !          1453:            printf((controlword&0x8) ? ",a%D" : ",d%D", controlword&7);
        !          1454:        }
        !          1455:     }
        !          1456: }
        !          1457: 
        !          1458: public omovc(inst, opcode)
        !          1459: long inst;
        !          1460: String opcode;
        !          1461: {
        !          1462:     register unsigned int controlword;
        !          1463:     String creg;
        !          1464:     short w;
        !          1465: 
        !          1466:     instread(w);
        !          1467:     if (printing) {
        !          1468:        controlword = w;
        !          1469:        switch (controlword & 0xfff) {
        !          1470:            case 0:
        !          1471:                creg = "sfc";
        !          1472:                break;
        !          1473: 
        !          1474:            case 1:
        !          1475:                creg = "dfc";
        !          1476:                break;
        !          1477: 
        !          1478:            case 0x800:
        !          1479:                creg = "usp";
        !          1480:                break;
        !          1481: 
        !          1482:            case 0x801:
        !          1483:                creg = "vbr";
        !          1484:                break;
        !          1485: 
        !          1486:            default:
        !          1487:                creg = "???";
        !          1488:                break;
        !          1489:        }
        !          1490:        controlword >>= 12;
        !          1491:        if (inst & 1){
        !          1492:            printf((controlword&0x8) ? "%sa%D,%s" : "%sd%D,%s",
        !          1493:                opcode, controlword&7, creg );
        !          1494:        } else {
        !          1495:            printf((controlword&0x8) ? "%s%s,a%D" : "%s%s,d%D",
        !          1496:                opcode, creg, controlword&7 );
        !          1497:        }
        !          1498:     }
        !          1499: }
        !          1500: 
        !          1501: /*
        !          1502:  * Compute the next address that will be executed from the given one.
        !          1503:  * If "isnext" is true then consider a procedure call as straight line code.
        !          1504:  *
        !          1505:  * Unconditional branches we just follow, for conditional branches
        !          1506:  * we continue execution to the current location and then single step
        !          1507:  * the machine.
        !          1508:  */
        !          1509: 
        !          1510: public Address nextaddr(startaddr, isnext)
        !          1511: Address startaddr;
        !          1512: Boolean isnext;
        !          1513: {
        !          1514:     Optab *o;
        !          1515:     short inst;
        !          1516: 
        !          1517:     instaddr = usignal(process);
        !          1518:     if (instaddr == 0 or instaddr == 1) {
        !          1519:        following = true;
        !          1520:        followcalls = (Boolean) (not isnext);
        !          1521:        printing = false;
        !          1522:        iread(&inst, startaddr, sizeof(inst));
        !          1523:        instaddr = startaddr + sizeof(inst);
        !          1524:        o = decode(inst, startaddr);
        !          1525:        if (o->mask == 0) {
        !          1526:            fprintf(stderr,
        !          1527:                "[internal error: undecodable op at 0x%x]\n", startaddr);
        !          1528:            fflush(stderr);
        !          1529:        } else {
        !          1530:            (*o->opfun)(inst, o->farg);
        !          1531:        }
        !          1532:        following = false;
        !          1533:     }
        !          1534:     return instaddr;
        !          1535: }
        !          1536: 
        !          1537: /*
        !          1538:  * Step to the given address and then execute one instruction past it.
        !          1539:  * Set instaddr to the new instruction address.
        !          1540:  */
        !          1541: 
        !          1542: private steppast(addr)
        !          1543: Address addr;
        !          1544: {
        !          1545:     stepto(addr);
        !          1546:     pstep(process, DEFSIG);
        !          1547:     pc = reg(PROGCTR);
        !          1548:     instaddr = pc;
        !          1549: }
        !          1550: 
        !          1551: /*
        !          1552:  * Enter a procedure by creating and executing a call instruction.
        !          1553:  */
        !          1554: 
        !          1555: #define CALLSIZE 6     /* size of call instruction */
        !          1556: 
        !          1557: public beginproc(p)
        !          1558: Symbol p;
        !          1559: {
        !          1560:     char save[CALLSIZE];
        !          1561:     struct {
        !          1562:        short op;
        !          1563:        char addr[sizeof(long)];        /* unaligned long */
        !          1564:     } call;
        !          1565:     long dest;
        !          1566: 
        !          1567:     pc = CODESTART + 6;
        !          1568:     iread(save, pc, sizeof(save));
        !          1569:     call.op = 0x4eb9;                  /* jsr */
        !          1570:     dest = codeloc(p) - FUNCOFFSET;
        !          1571:     mov(&dest, call.addr, sizeof(call.addr));
        !          1572:     iwrite(&call, pc, sizeof(call));
        !          1573:     setreg(PROGCTR, pc);
        !          1574:     pstep(process, DEFSIG);
        !          1575:     iwrite(save, pc, sizeof(save));
        !          1576:     pc = reg(PROGCTR);
        !          1577:     if (not isbperr()) {
        !          1578:        printstatus();
        !          1579:     }
        !          1580:     /*
        !          1581:      * Execute link instruction so the return addr is visible.
        !          1582:      */
        !          1583:     pstep(process, DEFSIG);
        !          1584:     pc = reg(PROGCTR);
        !          1585:     if (not isbperr()) {
        !          1586:        printstatus();
        !          1587:     }
        !          1588: }
        !          1589: 
        !          1590: /*
        !          1591:  * Special variables for debugging the kernel.
        !          1592:  */
        !          1593: 
        !          1594: public integer masterpcbb;
        !          1595: public integer slr;
        !          1596: public struct pte *sbr;
        !          1597: private struct pcb pcb;
        !          1598: 
        !          1599: public getpcb ()
        !          1600: {
        !          1601:     integer i;
        !          1602: 
        !          1603:     fseek(corefile, masterpcbb & ~0x80000000, 0);
        !          1604:     get(corefile, pcb);
        !          1605:     pcb.pcb_p0lr &= ~AST_CLR;
        !          1606:     printf("p0br %lx p0lr %lx p1br %lx p1lr %lx\n",
        !          1607:        pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr
        !          1608:     );
        !          1609: #   ifdef sun
        !          1610:     for (i = 0; i < 14; i++) {
        !          1611:        setreg(i, pcb.pcb_regs.val[i]);
        !          1612:     }
        !          1613: #   else /* IRIS */
        !          1614:     for (i = 0; i < 14; i++) {
        !          1615:        setreg(i, pcb.pcb_regs[i]);
        !          1616:     }
        !          1617: #   endif
        !          1618: }
        !          1619: 
        !          1620: public copyregs (savreg, reg)
        !          1621: Word savreg[], reg[];
        !          1622: {
        !          1623:     reg[0] = savreg[R0];
        !          1624:     reg[1] = savreg[R1];
        !          1625:     reg[2] = savreg[R2];
        !          1626:     reg[3] = savreg[R3];
        !          1627:     reg[4] = savreg[R4];
        !          1628:     reg[5] = savreg[R5];
        !          1629:     reg[6] = savreg[R6];
        !          1630:     reg[7] = savreg[R7];
        !          1631:     reg[8] = savreg[AR0];
        !          1632:     reg[9] = savreg[AR1];
        !          1633:     reg[10] = savreg[AR2];
        !          1634:     reg[11] = savreg[AR3];
        !          1635:     reg[12] = savreg[AR4];
        !          1636:     reg[13] = savreg[AR5];
        !          1637:     reg[14] = savreg[AR6];
        !          1638:     reg[15] = savreg[AR7];
        !          1639:     reg[PROGCTR] = savreg[PC];
        !          1640: }
        !          1641: 
        !          1642: /*
        !          1643:  * Map a virtual address to a physical address.
        !          1644:  * XXX THIS CAN'T BE RIGHT... XXX
        !          1645:  */
        !          1646: 
        !          1647: public Address vmap (addr)
        !          1648: Address addr;
        !          1649: {
        !          1650:     Address r;
        !          1651:     integer v, n;
        !          1652:     struct pte pte;
        !          1653: 
        !          1654:     r = addr & ~0xc0000000;
        !          1655:     v = btop(r);
        !          1656:     switch (addr&0xc0000000) {
        !          1657:        case 0xc0000000:
        !          1658:        case 0x80000000:
        !          1659:            /*
        !          1660:             * In system space, so get system pte.
        !          1661:             * If it is valid or reclaimable then the physical address
        !          1662:             * is the combination of its page number and the page offset
        !          1663:             * of the original address.
        !          1664:             */
        !          1665:            if (v >= slr) {
        !          1666:                error("address %x out of segment", addr);
        !          1667:            }
        !          1668:            r = ((long) (sbr + v)) & ~0x80000000;
        !          1669:            goto simple;
        !          1670: 
        !          1671:        case 0x40000000:
        !          1672:            /*
        !          1673:             * In p1 space, must not be in shadow region.
        !          1674:             */
        !          1675:            if (v < pcb.pcb_p1lr) {
        !          1676:                error("address %x out of segment", addr);
        !          1677:            }
        !          1678:            r = (Address) (pcb.pcb_p1br + v);
        !          1679:            break;
        !          1680: 
        !          1681:        case 0x00000000:
        !          1682:            /*
        !          1683:             * In p0 space, must not be off end of region.
        !          1684:             */
        !          1685:            if (v >= pcb.pcb_p0lr) {
        !          1686:                error("address %x out of segment", addr);
        !          1687:            }
        !          1688:            r = (Address) (pcb.pcb_p0br + v);
        !          1689:            break;
        !          1690: 
        !          1691:        default:
        !          1692:            /* do nothing */
        !          1693:            break;
        !          1694:     }
        !          1695:     /*
        !          1696:      * For p0/p1 address, user-level page table should be in
        !          1697:      * kernel virtual memory.  Do second-level indirect by recursing.
        !          1698:      */
        !          1699:     if ((r & 0x80000000) == 0) {
        !          1700:        error("bad p0br or p1br in pcb");
        !          1701:     }
        !          1702:     r = vmap(r);
        !          1703: simple:
        !          1704:     /*
        !          1705:      * "r" is now the address of the pte of the page
        !          1706:      * we are interested in; get the pte and paste up the physical address.
        !          1707:      */
        !          1708:     fseek(corefile, r, 0);
        !          1709:     n = fread(&pte, sizeof(pte), 1, corefile);
        !          1710:     if (n != 1) {
        !          1711:        error("page table botch (fread at %x returns %d)", r, n);
        !          1712:     }
        !          1713:     if (pte.pg_v == 0 and (pte.pg_fod != 0 or pte.pg_pfnum == 0)) {
        !          1714:        error("page no valid or reclamable");
        !          1715:     }
        !          1716:     return (addr&PGOFSET) + ((Address) ptob(pte.pg_pfnum));
        !          1717: }
        !          1718: 
        !          1719: /*
        !          1720:  * Extract a bit field from an integer.
        !          1721:  */
        !          1722: 
        !          1723: public integer extractField (s)
        !          1724: Symbol s;
        !          1725: {
        !          1726:     integer nbytes, nbits, n, r, off, len;
        !          1727: 
        !          1728:     off = s->symvalue.field.offset;
        !          1729:     len = s->symvalue.field.length;
        !          1730:     nbytes = size(s);
        !          1731:     n = 0;
        !          1732:     if (nbytes > sizeof(n)) {
        !          1733:        printf("[bad size in extractField -- word assumed]\n");
        !          1734:        nbytes = sizeof(n);
        !          1735:     }
        !          1736:     popn(nbytes, ((char *) &n) + (sizeof(Word) - nbytes));
        !          1737:     nbits = nbytes * BITSPERBYTE;
        !          1738:     r = n >> (nbits - ((off mod nbits) + len));
        !          1739:     r &= ((1 << len) - 1);
        !          1740:     return r;
        !          1741: }
        !          1742: 
        !          1743: /*
        !          1744:  * Change the length of a value in memory according to a given difference
        !          1745:  * in the lengths of its new and old types.
        !          1746:  */
        !          1747: 
        !          1748: public loophole (oldlen, newlen)
        !          1749: integer oldlen, newlen;
        !          1750: {
        !          1751:     integer i, n;
        !          1752:     Stack *oldsp;
        !          1753: 
        !          1754:     n = newlen - oldlen;
        !          1755:     oldsp = sp - oldlen;
        !          1756:     if (n > 0) {
        !          1757:        for (i = oldlen - 1; i >= 0; i--) {
        !          1758:            oldsp[n + i] = oldsp[i];
        !          1759:        }
        !          1760:        for (i = 0; i < n; i++) {
        !          1761:            oldsp[i] = '\0';
        !          1762:        }
        !          1763:     } else {
        !          1764:        for (i = 0; i < newlen; i++) {
        !          1765:            oldsp[i] = oldsp[i - n];
        !          1766:        }
        !          1767:     }
        !          1768:     sp += n;
        !          1769: }

unix.superglobalmegacorp.com

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