Annotation of 43BSDReno/bin/adb/adb.tahoe/machdep.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)machdep.c  5.4 (Berkeley) 9/26/89";
        !             3: #endif
        !             4: 
        !             5: /*
        !             6:  * adb - miscellaneous machine dependent routines.
        !             7:  */
        !             8: 
        !             9: #define        RLOCALS                 /* enable alternate $C stack trace */
        !            10: 
        !            11: #include "defs.h"
        !            12: #include "bkpt.h"
        !            13: #include <machine/pte.h>
        !            14: #include <machine/frame.h>
        !            15: #include <machine/reg.h>
        !            16: #include <machine/vmparam.h>
        !            17: #include <sys/ptrace.h>
        !            18: #include <sys/vmmac.h>
        !            19: #include <stab.h>
        !            20: 
        !            21: struct pte *sbr;
        !            22: int    slr;
        !            23: struct pcb pcb;
        !            24: int    masterpcbb;
        !            25: 
        !            26: /*
        !            27:  * Activation records.
        !            28:  */
        !            29: 
        !            30: /*
        !            31:  * Set up a stack frame based on the registers in the core image
        !            32:  * (or in the kernel core file ... not yet!).
        !            33:  */
        !            34: a_init(ap)
        !            35:        register struct activation *ap;
        !            36: {
        !            37: 
        !            38:        ap->a_valid = 1;
        !            39:        if (kcore) {
        !            40:                ap->a_fp = pcb.pcb_fp;
        !            41:                ap->a_pc = pcb.pcb_pc;
        !            42:        } else {
        !            43:                ap->a_fp = u.u_ar0[FP];
        !            44:                ap->a_pc = u.u_ar0[PC];
        !            45:        }
        !            46: }
        !            47: 
        !            48: /*
        !            49:  * Back up one stack frame in the call stack.
        !            50:  * ap points to the activation record from the previous frame.
        !            51:  * Clear a_valid field if we ran out of frames.
        !            52:  */
        !            53: a_back(ap)
        !            54:        register struct activation *ap;
        !            55: {
        !            56:        struct frame fr;
        !            57: 
        !            58:        if (adbread(SP_DATA, ap->a_fp - FRAMEOFF, &fr, sizeof fr) != sizeof fr)
        !            59:                ap->a_valid = 0;
        !            60:        else {
        !            61:                ap->a_fp = fr.fr_savfp;
        !            62:                ap->a_pc = fr.fr_savpc;
        !            63:                if (ap->a_fp == 0)
        !            64:                        ap->a_valid = 0;
        !            65:        }
        !            66: }
        !            67: 
        !            68: /*
        !            69:  * Evaluate a local symbol (N_LSYM or N_PSYM) using the activation
        !            70:  * record pointed to by ap.
        !            71:  */
        !            72: addr_t
        !            73: eval_localsym(sp, ap)
        !            74:        register struct nlist *sp;
        !            75:        struct activation *ap;
        !            76: {
        !            77: 
        !            78:        switch (sp->n_type) {
        !            79: 
        !            80:        case N_LSYM:
        !            81:                return (ap->a_fp - sp->n_value);
        !            82: 
        !            83:        case N_PSYM:
        !            84:                return (ap->a_fp + sp->n_value);
        !            85:        }
        !            86:        panic("eval_localsym");
        !            87:        /* NOTREACHED */
        !            88: }
        !            89: 
        !            90: 
        !            91: /* true iff address a is in instruction space */
        !            92: #define        ispace(a) ((a) < txtmap.m1.e)
        !            93: 
        !            94: /*
        !            95:  * Delete a (single) breakpoint.  Return 0 on success.
        !            96:  */
        !            97: int
        !            98: clr_bpt(b)
        !            99:        struct bkpt *b;
        !           100: {
        !           101:        addr_t a = b->loc;
        !           102: 
        !           103:        return (adbwrite(ispace(a) ? SP_INSTR : SP_DATA, a, &b->ins, 1) != 1);
        !           104: }
        !           105: 
        !           106: /*
        !           107:  * Set a (single) breakpoint.  Return 0 on success.
        !           108:  */
        !           109: set_bpt(b)
        !           110:        struct bkpt *b;
        !           111: {
        !           112:        addr_t a = b->loc;
        !           113:        int space;
        !           114:        char bpt = 0x30;                /* breakpoint instruction */
        !           115: 
        !           116:        space = ispace(a) ? SP_INSTR : SP_DATA;
        !           117:        return (adbread(space, a, &b->ins, 1) != 1 ||
        !           118:                adbwrite(space, a, &bpt, 1) != 1);
        !           119: }
        !           120: 
        !           121: /*
        !           122:  * Check a float for `correctness' (reserved patterns, etc).  Return
        !           123:  * a pointer to a character string to be printed instead of the float,
        !           124:  * or NULL to print the float as-is.
        !           125:  *
        !           126:  * The string returned, if any, should be no longer than 16 characters.
        !           127:  *
        !           128:  * On the Tahoe, we can simply check the second two bytes.  Byte two
        !           129:  * contains one bit of the exponent, and byte 3 has the remaining 7
        !           130:  * exponent bits and the sign bit.  If the sign bit is set and the
        !           131:  * exponent is zero, the value is reserved.
        !           132:  *
        !           133:  * PLEASE CHECK THE ABOVE, IT IS PROBABLY WRONG
        !           134:  */
        !           135: /* ARGSUSED */
        !           136: char *
        !           137: checkfloat(fp, isdouble)
        !           138:        caddr_t fp;
        !           139:        int isdouble;
        !           140: {
        !           141: 
        !           142:        return ((((short *)fp)[1] & 0xff80) == 0x8000 ?
        !           143:                "(reserved oprnd)" : NULL);
        !           144: }
        !           145: 
        !           146: /*
        !           147:  * Convert a value in `expr_t' format to float or double.
        !           148:  */
        !           149: etofloat(e, fp, isdouble)
        !           150:        expr_t e;
        !           151:        caddr_t fp;
        !           152:        int isdouble;
        !           153: {
        !           154: 
        !           155:        if (isdouble)
        !           156:                ((int *)fp)[1] = 0;
        !           157:        *(int *)fp = e;
        !           158: }
        !           159: 
        !           160: mch_init()
        !           161: {
        !           162: 
        !           163:        mkioptab();
        !           164: }
        !           165: 
        !           166: /* quietly read object obj from address addr */
        !           167: #define        GET(obj, addr)  (void) adbread(SP_DATA, addr, &(obj), sizeof(obj))
        !           168: 
        !           169: /* set `current process' pcb */
        !           170: setpcb(addr)
        !           171:        addr_t addr;
        !           172: {
        !           173:        int pte;
        !           174: 
        !           175:        GET(pte, addr);
        !           176:        masterpcbb = (pte & PG_PFNUM) * NBPG;
        !           177: }
        !           178: 
        !           179: getpcb()
        !           180: {
        !           181: 
        !           182:        /* maybe use adbread() here ... */
        !           183:        (void) readcore((off_t)masterpcbb & ~KERNBASE,
        !           184:                (char *)&pcb, sizeof(struct pcb));
        !           185:        adbprintf("p0br %R p0lr %R p2br %R p2lr %R\n",
        !           186:            pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p2br, pcb.pcb_p2lr);
        !           187: }
        !           188: 
        !           189: /*
        !           190:  * Convert a kernel virtual address to a physical address,
        !           191:  * a la the Tahoe hardware.  Set *err if the resulting address
        !           192:  * is invalid.
        !           193:  */
        !           194: addr_t
        !           195: vtophys(addr, err)
        !           196:        addr_t addr;
        !           197:        char **err;
        !           198: {
        !           199:        register unsigned v = btop(addr & ~KERNBASE);
        !           200:        register addr_t pteaddr;
        !           201:        struct pte pte;
        !           202: 
        !           203:        switch ((int)(addr >> 30)) {    /* select space */
        !           204: 
        !           205:        case 3:
        !           206:                /* system space: get system pte */
        !           207:                if (v >= slr)
        !           208:                        goto oor;
        !           209:                pteaddr = (addr_t)(sbr + v) & ~KERNBASE;
        !           210:                goto direct;
        !           211: 
        !           212:        case 2:
        !           213:                /* P2 space: must not be in shadow region */
        !           214:                if (v < pcb.pcb_p2lr)
        !           215:                        goto oor;
        !           216:                pteaddr = (addr_t)(pcb.pcb_p2br + v);
        !           217:                break;
        !           218: 
        !           219:        case 1:
        !           220:                /* P1 space: verboten (for now) */
        !           221:                goto oor;
        !           222: 
        !           223:        case 0:
        !           224:                /* P0 space: must not be off end of region */
        !           225:                if (v >= pcb.pcb_p0lr)
        !           226:                        goto oor;
        !           227:                pteaddr = (addr_t)(pcb.pcb_p0br + v);
        !           228:                break;
        !           229: 
        !           230: oor:
        !           231:                *err = "address out of segment";
        !           232:                return (0);
        !           233:        }
        !           234: 
        !           235:        /* in P0/P1/P2 space, pte should be in kernel virtual space */
        !           236:        if ((pteaddr & KERNBASE) != KERNBASE) {
        !           237:                *err = "bad p0br, p1br, or p2br in pcb";
        !           238:                return (0);
        !           239:        }
        !           240:        pteaddr = vtophys(pteaddr, err);
        !           241:        if (*err)
        !           242:                return (0);
        !           243: 
        !           244: direct:
        !           245:        /*
        !           246:         * Read system pte.  If valid or reclaimable,
        !           247:         * physical address is combination of its page number and
        !           248:         * the page offset of the original address.
        !           249:         */
        !           250:        if (readcore((off_t)pteaddr, (caddr_t)&pte, 4) != 4) {
        !           251:                *err = "page table botch";
        !           252:                return (0);
        !           253:        }
        !           254:        /* SHOULD CHECK NOT I/O ADDRESS; NEED CPU TYPE! */
        !           255:        if (pte.pg_v == 0 && (pte.pg_fod || pte.pg_pfnum == 0)) {
        !           256:                *err = "page not valid/reclaimable";
        !           257:                return (0);
        !           258:        }
        !           259:        return ((addr_t)(ptob(pte.pg_pfnum) + (addr & PGOFSET)));
        !           260: }
        !           261: 
        !           262: /*
        !           263:  * Print a stack trace ($c, $C).  Trace backwards through nback
        !           264:  * frames; if locals is set, print local variables.
        !           265:  */
        !           266: printstack(locals, nback)
        !           267:        int locals, nback;
        !           268: {
        !           269:        register int i;
        !           270:        register addr_t a;
        !           271:        struct nlist *sym;
        !           272:        char *s;
        !           273:        addr_t callpc;          /* pc that called this frame */
        !           274:        int narg;               /* number of arguments to this frame */
        !           275:        struct activation cur;  /* this frame itself */
        !           276:        struct frame fr;        /* the frame above this frame */
        !           277:        addr_t dummy;           /* a variable to scribble on */
        !           278: #define        UNKNOWN -1
        !           279: 
        !           280: #ifdef RLOCALS
        !           281:        /* if locals variables are broken, use an alternate strategy */
        !           282:        register int r;
        !           283:        addr_t sp, prev_sp;
        !           284:        int regs[13];
        !           285:        static char unknown[] = "<unknown>";
        !           286: #endif
        !           287: 
        !           288: #ifdef RLOCALS
        !           289:        /* grab registers */
        !           290:        bcopy((caddr_t)(kcore ? &pcb.pcb_r0 : &u.u_ar0[R0]), (caddr_t)regs,
        !           291:                sizeof(regs));
        !           292: #endif
        !           293: 
        !           294:        /* set up the current stack frame */
        !           295:        if (gavedot) {
        !           296:                cur.a_fp = dot;
        !           297:                cur.a_pc = UNKNOWN;
        !           298: #ifdef RLOCALS
        !           299:                sp = UNKNOWN;
        !           300: #endif
        !           301:        } else if (kcore) {
        !           302:                cur.a_fp = pcb.pcb_fp;
        !           303:                cur.a_pc = pcb.pcb_pc;
        !           304: #ifdef RLOCALS
        !           305:                sp = pcb.pcb_ksp;
        !           306: #endif
        !           307:        } else {
        !           308:                cur.a_fp = u.u_ar0[FP];
        !           309:                cur.a_pc = u.u_ar0[PC];
        !           310: #ifdef RLOCALS
        !           311:                sp = u.u_ar0[SP];
        !           312: #endif
        !           313:        }
        !           314: 
        !           315:        /* now back up through the stack */
        !           316:        while (nback-- && cur.a_fp != 0) {
        !           317:                /* read this frame, but defer error check */
        !           318:                GET(fr, cur.a_fp - FRAMEOFF);
        !           319: 
        !           320:                /* where are we? ... if u. area, signal trampoline code */
        !           321:                if (cur.a_pc >= USRSTACK && cur.a_pc < KERNBASE) {
        !           322:                        narg = 0;
        !           323:                        GET(callpc, cur.a_fp + 44);     /* XXX magic 44 */
        !           324:                        s = "sigtramp";
        !           325:                } else {
        !           326:                        narg = (fr.fr_removed >> 2) - 1;
        !           327:                        callpc = fr.fr_savpc;
        !           328:                        if (cur.a_pc != UNKNOWN &&
        !           329:                            (sym = findsym(cur.a_pc, SP_INSTR, &dummy)) != 0) {
        !           330:                                s = sym->n_un.n_name;
        !           331:                                if (eqstr(s, "start")) {
        !           332:                                        errflag = NULL;
        !           333:                                        break;
        !           334:                                }
        !           335:                        } else
        !           336:                                s = "?";
        !           337:                }
        !           338:                /* safe at last to check for error reading frame */
        !           339:                checkerr();
        !           340: 
        !           341:                /* arguments */
        !           342:                adbprintf("%s(", s);
        !           343:                a = cur.a_fp;
        !           344:                for (i = narg > 20 ? 20 : narg; i;) {
        !           345:                        prfrom(a += 4, --i ? ',' : 0);
        !           346:                        checkerr();
        !           347:                }
        !           348:                printc(')');
        !           349:                if (cur.a_pc != UNKNOWN) {
        !           350:                        prints(" at ");
        !           351:                        psymoff("%R", cur.a_pc, SP_INSTR, -(addr_t)1, "");
        !           352:                }
        !           353:                printc('\n');
        !           354: 
        !           355:                /* local variables */
        !           356:                if (locals) {
        !           357: #ifdef busted
        !           358:                        if (cur.a_pc != UNKNOWN) {
        !           359:                                sym = findsym(cur.a_pc, SP_INSTR, &dummy);
        !           360:                                while ((sym = nextlocal(sym)) != NULL) {
        !           361:                                        adbprintf("%8t");
        !           362:                                        printlsym(sym->n_un.n_name);
        !           363:                                        adbprintf(":%12t");
        !           364:                                        prfrom(eval_localsym(sym, &cur), '\n');
        !           365:                                }
        !           366:                        }
        !           367: #endif
        !           368: #ifdef RLOCALS
        !           369:                        adbprintf("\
        !           370: fp: %R\%16tsp:  %?s%?R%32tpc:  %?s%?R%48tr0:  %R\n\
        !           371: r1: %R\%16tr2:  %R\%32tr3:  %R\%48tr4:  %R\n\
        !           372: r5: %R\%16tr6:  %R\%32tr7:  %R\%48tr8:  %R\n\
        !           373: r9: %R\%16tr10: %R\%32tr11: %R\%48tr12: %R\n",
        !           374: #define q(s) s == UNKNOWN, unknown, s != UNKNOWN, s
        !           375:                            cur.a_fp, q(sp), q(cur.a_pc), regs[0],
        !           376: #undef q
        !           377:                            regs[1], regs[2], regs[3], regs[4],
        !           378:                            regs[5], regs[6], regs[7], regs[8],
        !           379:                            regs[9], regs[10], regs[11], regs[12]);
        !           380: 
        !           381:                        /* update registers, and find previous frame's sp */
        !           382:                        a = cur.a_fp + 4;
        !           383:                        for (r = 0, i = fr.fr_mask; i != 0; r++, i >>= 1)
        !           384:                                if (i & 1)
        !           385:                                        GET(regs[r], a += 4);
        !           386:                        a += narg * 4;
        !           387:                        prev_sp = a;
        !           388: 
        !           389:                        /* now print automatics */
        !           390:                        if (sp != UNKNOWN) {
        !           391: #define        MAXPRINT 30             /* max # words to print */
        !           392:                                /* XXX should be settable */
        !           393:                                i = (cur.a_fp - sp) >> 2;
        !           394:                                if (i > MAXPRINT)
        !           395:                                        i = MAXPRINT;
        !           396:                                for (a = cur.a_fp; --i >= 0;) {
        !           397:                                        a -= 4;
        !           398:                                        adbprintf("%R: %V(fp):%24t",
        !           399:                                                a, a - cur.a_fp);
        !           400:                                        prfrom(a, '\n');
        !           401:                                }
        !           402:                                if (a > sp)
        !           403:                                        adbprintf("\
        !           404: %R: %V(fp) .. %R: %V(fp) not displayed\n",
        !           405:                                                a, a - cur.a_fp,
        !           406:                                                sp, sp - cur.a_fp);
        !           407:                        }
        !           408: #endif /* RLOCALS */
        !           409:                }
        !           410: 
        !           411:                errflag = NULL;         /* clobber any read errors */
        !           412: 
        !           413:                /* back up one frame */
        !           414:                if (fr.fr_savfp == 0)
        !           415:                        break;
        !           416:                cur.a_fp = fr.fr_savfp;
        !           417: #ifdef RLOCALS
        !           418:                sp = prev_sp;
        !           419: #endif
        !           420:                cur.a_pc = callpc;
        !           421: 
        !           422:                if (!gavedot && !INSTACK(cur.a_fp) && !kcore)
        !           423:                        break;
        !           424: 
        !           425:                /* make sure we returned somewhere... */
        !           426:                (void) adbread(kcore ? SP_DATA : SP_INSTR, cur.a_pc, &dummy, 1);
        !           427:                checkerr();
        !           428:        }
        !           429: }
        !           430: 
        !           431: /*
        !           432:  * Register offset to u. pointer, and register offset to ptrace value
        !           433:  */
        !           434: #define        otoua(o) \
        !           435:        ((int *)(((o) < 0 ? (int)u.u_ar0 : (int)&u.u_pcb) + (o)))
        !           436: #define        otopt(o) \
        !           437:        ((int *)((o) < 0 ? (o) + ctob(UPAGES) : (o)))
        !           438: 
        !           439: /*
        !           440:  * Return the value of some register.
        !           441:  */
        !           442: expr_t
        !           443: getreg(reg)
        !           444:        register struct reglist *reg;
        !           445: {
        !           446: 
        !           447:        return (kcore ? *reg->r_pcbaddr : *otoua(reg->r_offset));
        !           448: }
        !           449: 
        !           450: 
        !           451: /*
        !           452:  * Set the value of some register.  Return 0 if all goes well.
        !           453:  */
        !           454: setreg(reg, val)
        !           455:        register struct reglist *reg;
        !           456:        expr_t val;
        !           457: {
        !           458: 
        !           459:        if (kcore)
        !           460:                *reg->r_pcbaddr = val;
        !           461:        else {
        !           462:                *otoua(reg->r_offset) = val;
        !           463:                if (pid) {
        !           464:                        errno = 0;
        !           465:                        if (ptrace(PT_WRITE_U, pid, otopt(reg->r_offset),
        !           466:                                        (int)val) == -1 && errno)
        !           467:                                return (-1);
        !           468:                }
        !           469:        }
        !           470:        return (0);
        !           471: }
        !           472: 
        !           473: /*
        !           474:  * Read registers from current process.
        !           475:  */
        !           476: readregs()
        !           477: {
        !           478:        register struct reglist *reg;
        !           479:        extern struct reglist reglist[];
        !           480: 
        !           481:        for (reg = reglist; reg->r_name != NULL; reg++)
        !           482:                *otoua(reg->r_offset) =
        !           483:                        ptrace(PT_READ_U, pid, otopt(reg->r_offset), 0);
        !           484: }
        !           485: 
        !           486: addr_t
        !           487: getpc()
        !           488: {
        !           489: 
        !           490:        return (kcore ? pcb.pcb_pc : u.u_ar0[PC]);
        !           491: }
        !           492: 
        !           493: setpc(where)
        !           494:        addr_t where;
        !           495: {
        !           496: 
        !           497:        if (kcore)
        !           498:                pcb.pcb_pc = where;
        !           499:        else
        !           500:                u.u_ar0[PC] = where;
        !           501: }
        !           502: 
        !           503: /*
        !           504:  * udot returns true if u.u_pcb appears correct.  More extensive
        !           505:  * checking is possible....
        !           506:  */
        !           507: udot()
        !           508: {
        !           509: 
        !           510:        /* user stack should be in stack segment */
        !           511:        if (!INSTACK(u.u_pcb.pcb_usp))
        !           512:                return (0);
        !           513:        /* kernel stack should be in u. area */
        !           514:        if (u.u_pcb.pcb_ksp < USRSTACK || u.u_pcb.pcb_ksp >= KERNBASE)
        !           515:                return (0);
        !           516:        /* looks good to us... */
        !           517:        return (1);
        !           518: }
        !           519: 
        !           520: sigprint()
        !           521: {
        !           522:        extern char *sys_siglist[];
        !           523:        extern char *illinames[], *fpenames[];
        !           524:        extern int nillinames, nfpenames;
        !           525: 
        !           526:        if ((u_int)signo - 1 < NSIG - 1)
        !           527:                prints(sys_siglist[signo]);
        !           528:        switch (signo) {
        !           529: 
        !           530:        case SIGFPE:
        !           531:                if ((u_int)sigcode < nfpenames)
        !           532:                        prints(fpenames[sigcode]);
        !           533:                break;
        !           534: 
        !           535:        case SIGILL:
        !           536:                if ((u_int)sigcode < nillinames)
        !           537:                        prints(illinames[sigcode]);
        !           538:                break;
        !           539:        }
        !           540: }

unix.superglobalmegacorp.com

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