Annotation of 43BSDTahoe/lib/old_compiler/dbx/tahoe.c, revision 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.