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

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

unix.superglobalmegacorp.com

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