Annotation of 43BSDReno/bin/adb/adb.tahoe/machdep.c, revision 1.1.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.