Annotation of 43BSDTahoe/lib/old_compiler/dbx/iris.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1983 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: static char sccsid[] = "@(#)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.