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

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

unix.superglobalmegacorp.com

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