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

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

unix.superglobalmegacorp.com

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