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

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

unix.superglobalmegacorp.com

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