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