Annotation of 43BSDReno/pgrm/dbx/tahoe.c, revision 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.