[BACK]Return to db_trace.c CVS log [TXT][DIR] Up to [local] / sys / arch / m68k / m68k

Annotation of sys/arch/m68k/m68k/db_trace.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: db_trace.c,v 1.17 2002/05/18 09:49:17 art Exp $       */
                      2: /*     $NetBSD: db_trace.c,v 1.20 1997/02/05 05:10:25 scottr Exp $     */
                      3:
                      4: /*
                      5:  * Mach Operating System
                      6:  * Copyright (c) 1992 Carnegie Mellon University
                      7:  * All Rights Reserved.
                      8:  *
                      9:  * Permission to use, copy, modify and distribute this software and its
                     10:  * documentation is hereby granted, provided that both the copyright
                     11:  * notice and this permission notice appear in all copies of the
                     12:  * software, derivative works or modified versions, and any portions
                     13:  * thereof, and that both notices appear in supporting documentation.
                     14:  *
                     15:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     16:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     17:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     18:  *
                     19:  * Carnegie Mellon requests users of this software to return to
                     20:  *
                     21:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
                     22:  *  School of Computer Science
                     23:  *  Carnegie Mellon University
                     24:  *  Pittsburgh PA 15213-3890
                     25:  *
                     26:  * any improvements or extensions that they make and grant Carnegie Mellon
                     27:  * the rights to redistribute these changes.
                     28:  */
                     29:
                     30: #include <sys/param.h>
                     31: #include <sys/proc.h>
                     32: #include <sys/systm.h>
                     33:
                     34: #include <machine/db_machdep.h>
                     35:
                     36: #include <ddb/db_interface.h>
                     37: #include <ddb/db_output.h>
                     38: #include <ddb/db_access.h>
                     39: #include <ddb/db_sym.h>
                     40: #include <ddb/db_variables.h>
                     41:
                     42: extern label_t *db_recover;
                     43:
                     44: /*
                     45:  * Register list
                     46:  */
                     47: static int db_var_short(struct db_variable *, db_expr_t *, int);
                     48:
                     49: struct db_variable db_regs[] = {
                     50:        /* D0-D7 */
                     51:        { "d0", (long *)&ddb_regs.tf_regs[0],   FCN_NULL },
                     52:        { "d1", (long *)&ddb_regs.tf_regs[1],   FCN_NULL },
                     53:        { "d2", (long *)&ddb_regs.tf_regs[2],   FCN_NULL },
                     54:        { "d3", (long *)&ddb_regs.tf_regs[3],   FCN_NULL },
                     55:        { "d4", (long *)&ddb_regs.tf_regs[4],   FCN_NULL },
                     56:        { "d5", (long *)&ddb_regs.tf_regs[5],   FCN_NULL },
                     57:        { "d6", (long *)&ddb_regs.tf_regs[6],   FCN_NULL },
                     58:        { "d7", (long *)&ddb_regs.tf_regs[7],   FCN_NULL },
                     59:        /* A0-A7 */
                     60:        { "a0", (long *)&ddb_regs.tf_regs[8+0], FCN_NULL },
                     61:        { "a1", (long *)&ddb_regs.tf_regs[8+1], FCN_NULL },
                     62:        { "a2", (long *)&ddb_regs.tf_regs[8+2], FCN_NULL },
                     63:        { "a3", (long *)&ddb_regs.tf_regs[8+3], FCN_NULL },
                     64:        { "a4", (long *)&ddb_regs.tf_regs[8+4], FCN_NULL },
                     65:        { "a5", (long *)&ddb_regs.tf_regs[8+5], FCN_NULL },
                     66:        { "a6", (long *)&ddb_regs.tf_regs[8+6], FCN_NULL },
                     67:        { "sp", (long *)&ddb_regs.tf_regs[8+7], FCN_NULL },
                     68:        /* misc. */
                     69:        { "pc", (long *)&ddb_regs.tf_pc,        FCN_NULL },
                     70:        { "sr", (long *)&ddb_regs.tf_sr,        db_var_short }
                     71: };
                     72: struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
                     73:
                     74: static int
                     75: db_var_short(varp, valp, op)
                     76:     struct db_variable *varp;
                     77:     db_expr_t *valp;
                     78:     int op;
                     79: {
                     80:     if (op == DB_VAR_GET)
                     81:        *valp = (db_expr_t) *((short *)varp->valuep);
                     82:     else
                     83:        *((short *)varp->valuep) = (short) *valp;
                     84:     return(0);
                     85: }
                     86:
                     87: #define        MAXINT  0x7fffffff
                     88:
                     89: #if 0
                     90: #define        INKERNEL(va)    (((vaddr_t)(va)) >= VM_MIN_KERNEL_ADDRESS && \
                     91:                         (((vaddr_t)(va)) < (USRSTACK - MAXSSIZ) || \
                     92:                          ((vaddr_t)(va)) >= USRSTACK))
                     93: #else
                     94: /* XXX - Slight hack... */
                     95: extern int curpcb;
                     96: #define        INKERNEL(va)    (((int)(va) > curpcb) && \
                     97:                         ((int)(va) < (curpcb + USPACE)))
                     98: #endif
                     99:
                    100: #define        get(addr, space) \
                    101:                (db_get_value((db_addr_t)(addr), sizeof(int), FALSE))
                    102: #define        get16(addr, space) \
                    103:                (db_get_value((db_addr_t)(addr), sizeof(u_short), FALSE))
                    104:
                    105: #define        NREGISTERS      16
                    106:
                    107: struct stackpos {
                    108:         int    k_pc;
                    109:         int    k_fp;
                    110:         int    k_nargs;
                    111:         int    k_entry;
                    112:         int    k_caller;
                    113:         int    k_flags;
                    114:         int    k_regloc[NREGISTERS];
                    115: };
                    116:
                    117: static void findentry(struct stackpos *);
                    118: static void findregs(struct stackpos *, db_addr_t);
                    119: static int  nextframe(struct stackpos *, int);
                    120: static void stacktop(db_regs_t *, struct stackpos *);
                    121:
                    122:
                    123: #define FR_SAVFP       0
                    124: #define FR_SAVPC       4
                    125: #define K_CALLTRAMP    1       /* for k_flags: caller is __sigtramp */
                    126: #define K_SIGTRAMP     2       /* for k_flags: this is   __sigtramp */
                    127:
                    128: static void
                    129: stacktop(regs, sp)
                    130:        db_regs_t *regs;
                    131:        struct stackpos *sp;
                    132: {
                    133:        int i;
                    134:
                    135:        /* Note: leave out a6, a7 */
                    136:        for (i = 0; i < (8+6); i++) {
                    137:                sp->k_regloc[i] = (int) &regs->tf_regs[i];
                    138:        }
                    139:
                    140:        sp->k_fp = get(&regs->tf_regs[8+6], 0);
                    141:        /* skip sp (a7) */
                    142:        sp->k_pc = get(&regs->tf_pc, 0);
                    143:        sp->k_flags = 0;
                    144:
                    145:        findentry(sp);
                    146: }
                    147:
                    148:
                    149: /*
                    150:  * The VAX has a very nice calling convention, and it is quite easy to
                    151:  * find saved registers, and the number of parameters. We are not nearly
                    152:  * so lucky. We must grub around in code for much of this information
                    153:  * (remember the PDP-11?), and the saved register list seems to be
                    154:  * especially hard to find.
                    155:  */
                    156:
                    157: #define HIWORD 0xffff0000
                    158: #define LOWORD 0x0000ffff
                    159: #define LINKLA6        0x480e0000      /* linkl a6,#x    */
                    160: #define LINKWA6        0x4e560000      /* linkw a6,#x    */
                    161: #define ADDLSP 0xdffc0000      /* addl #x,sp    */
                    162: #define ADDWSP 0xdefc0000      /* addw #x,sp    */
                    163: #define LEASP  0x4fef0000      /* lea  sp@(x),sp*/
                    164: #define TSTBSP 0x4a2f0000      /* tstb sp@(x)   */
                    165: #define INSMSK 0xfff80000
                    166: #define MOVLSP 0x2e800000      /* movl dx,sp@   */
                    167: #define MOVLD0 0x20000000      /* movl d0,dx    */
                    168: #define MOVLA0 0x20400000      /* movl d0,ax    */
                    169: #define MVLMSK 0xf1ff0000
                    170: #define MOVEML 0x48d70000      /* moveml #x,sp@ */
                    171: #define JSR    0x4eb80000      /* jsr x.[WL]    */
                    172: #define JSRPC  0x4eba0000      /* jsr PC@( )    */
                    173: #define LONGBIT 0x00010000
                    174: #define BSR    0x61000000      /* bsr x         */
                    175: #define BSRL   0x61ff0000      /* bsrl x        */
                    176: #define BYTE3  0x0000ff00
                    177: #define LOBYTE 0x000000ff
                    178: #define ADQMSK 0xf1ff0000
                    179: #define ADDQSP 0x508f0000      /* addql #x,sp   */
                    180: #define ADDQWSP        0x504f0000      /* addqw #x,sp   */
                    181:
                    182: struct nlist * trampsym = 0;
                    183: struct nlist * funcsym = 0;
                    184:
                    185: static int
                    186: nextframe(sp, kerneltrace)
                    187:        struct stackpos *sp;
                    188:        int kerneltrace;
                    189: {
                    190:        int             i;
                    191:        db_addr_t       addr;
                    192:        db_addr_t       calladdr;
                    193:        db_addr_t       oldfp = sp->k_fp;
                    194:
                    195:        /*
                    196:         * Find our entry point. Then find out
                    197:         * which registers we saved, and map them.
                    198:         * Our entry point is the address our caller called.
                    199:         */
                    200:
                    201:        calladdr = sp->k_caller;
                    202:        addr     = sp->k_entry;
                    203:        if (sp->k_flags & K_CALLTRAMP) {
                    204: #if    0
                    205:        /* we never set CALLTRAMP */
                    206:                /*
                    207:                 * Caller was sigtramp.  Therefore:
                    208:                 *   - no registers were saved;
                    209:                 *   - no new frame-pointer
                    210:                 *   - caller found in sigcontext structure.
                    211:                 *   - WE become sigtramp
                    212:                 *   - we have no parameters
                    213:                 * MUCH MAGIC USED IN FINDING CALLER'S PC.
                    214:                 */
                    215:                sp->k_pc = sp->k_caller;
                    216:                sp->k_entry = trampsym->n_value;
                    217:                sp->k_flags = 0;
                    218:                addr = get(sp->k_fp + sizeof(int) * 11, DSP);
                    219:                sp->k_nargs = 0;
                    220: #if DEBUG
                    221:                db_printf("nextframe: sigcontext at 0x%x, signaled at 0x%x\n",
                    222:                    addr, sp->k_caller);
                    223: #endif
                    224:                errflg = 0;
                    225: #endif /* 0 */
                    226:        } else {
                    227:                if (addr == MAXINT) {
                    228:                        /* we don't know what registers are involved here--
                    229:                           invalidate all */
                    230:                        for (i = 0; i < NREGISTERS; i++)
                    231:                                sp->k_regloc[i] = -1;
                    232:                } else
                    233:                        findregs(sp, addr);
                    234:
                    235:                /* find caller's pc and fp */
                    236:                sp->k_pc = calladdr;
                    237:                sp->k_fp = get(sp->k_fp + FR_SAVFP, DSP);
                    238:
                    239:                /*
                    240:                 * Now that we have assumed the identity of our caller, find
                    241:                 * how many longwords of argument WE were called with.
                    242:                 */
                    243:                sp->k_flags = 0;
                    244:
                    245:                /*
                    246:                 * Don't dig around in user stack to find no. of args and
                    247:                 * entry point if just tracing the kernel
                    248:                 */
                    249:                if (kerneltrace && !INKERNEL(sp->k_fp)) {
                    250:                        sp->k_nargs = 0;
                    251:                        sp->k_entry = MAXINT;
                    252:                } else
                    253:                        findentry(sp);
                    254:        }
                    255:
                    256:        if (sp->k_fp == 0 || oldfp == sp->k_fp)
                    257:                return 0;
                    258:        return (sp->k_fp);
                    259: }
                    260:
                    261: static void
                    262: findentry(sp)
                    263:        struct stackpos *sp;
                    264: {
                    265:        /*
                    266:         * Set the k_nargs and k_entry fields in the stackpos structure.  This
                    267:         * is called from stacktop() and from nextframe().  Our caller will do
                    268:         * an addq or addl or addw to sp just after we return to pop off our
                    269:         * arguments.  Find that instruction and extract the value.
                    270:         */
                    271:        int             instruc;
                    272:        int             val;
                    273:        db_addr_t       addr, nextword;
                    274:        label_t         db_jmpbuf;
                    275:        label_t         *savejmp;
                    276:
                    277:        savejmp = db_recover;
                    278:        db_recover = &db_jmpbuf;
                    279:        if (setjmp(&db_jmpbuf)) {
                    280:                /* oops -- we touched something we ought not to have */
                    281:                /* cannot trace caller of "start" */
                    282:                sp->k_entry = MAXINT;
                    283:                sp->k_nargs = 0;
                    284:                db_recover = savejmp;
                    285:                return;
                    286:        }
                    287:
                    288:        addr = get(sp->k_fp + FR_SAVPC, DSP);
                    289:        if (addr == 0) {
                    290:                /* oops -- we touched something we ought not to have */
                    291:                /* cannot trace caller of "start" */
                    292:                sp->k_entry = MAXINT;
                    293:                sp->k_nargs = 0;
                    294:                db_recover = savejmp;
                    295:                return;
                    296:        }
                    297:        instruc  = get(addr - 6, ISP);
                    298:        nextword = get(addr - 4, ISP);
                    299:
                    300:        db_recover = savejmp;
                    301:
                    302:        if ((instruc & HIWORD) == (JSR | LONGBIT)) {
                    303:                /* longword offset here */
                    304:                sp->k_caller = addr - 6;
                    305:                sp->k_entry  = nextword;
                    306:        } else if ((instruc & HIWORD) == BSRL) {
                    307:                /* longword self-relative offset */
                    308:                sp->k_caller = addr - 6;
                    309:                sp->k_entry  = nextword + (addr - 4);
                    310:        } else {
                    311:                instruc = nextword;
                    312:                if ((instruc & HIWORD) == JSR) {
                    313:                        /* short word offset */
                    314:                        sp->k_caller = addr - 4;
                    315:                        sp->k_entry  = instruc & LOWORD;
                    316:                } else if ((instruc & HIWORD) == BSR) {
                    317:                        /* short word, self-relative offset */
                    318:                        sp->k_caller = addr - 4;
                    319:                        sp->k_entry  = (addr - 2) + (short)(instruc & LOWORD);
                    320:                } else if ((instruc & HIWORD) == JSRPC) {
                    321:                        /* PC-relative, short word offset */
                    322:                        sp->k_caller = addr - 4;
                    323:                        sp->k_entry  = (addr - 2) + (instruc & LOWORD);
                    324:                } else {
                    325:                        if ((instruc & BYTE3) == (BSR >> 16)) {
                    326:                                /* byte, self-relative offset */
                    327:                                sp->k_caller = addr - 2;
                    328:                                sp->k_entry  = addr + (char)(instruc & LOBYTE);
                    329:                        } else {
                    330:                                /* was a call through a proc parameter */
                    331:                                sp->k_caller = addr - 2;
                    332:                                sp->k_entry  = MAXINT;
                    333:                                /*
                    334:                                 * We know that sigtramp calls your signal
                    335:                                 * catcher this way -- see if this is the
                    336:                                 * tramp: if so then:
                    337:                                 *   - set the K_CALLTRAMP flag, for use by
                    338:                                 *     nextframe();
                    339:                                 *   - take k_entry from __sigfunc array.
                    340:                                 */
                    341: #if    0
                    342:        /* not in kernel */
                    343:                                /*
                    344:                                 * The number (9) in the below expression is
                    345:                                 * magic: it is the number of stack items below
                    346:                                 * callee`s fp and sigtramp`s copy of the
                    347:                                 * signal number.
                    348:                                 */
                    349:                                if (trampsym &&
                    350:                                    (findsym(sp->k_caller, ISYM), cursym == trampsym)) {
                    351:                                        int signl;
                    352:                                        sp->k_flags |= K_CALLTRAMP;
                    353:                                        if (funcsym) {
                    354:                                                signl = get(sp->k_fp + sizeof(int) * 9, DSP);
                    355:                                                sp->k_entry = get(funcsym->n_value+(sizeof(int(*)()))*signl, DSP);
                    356:                                        } else
                    357:                                                sp->k_entry = -1;
                    358:
                    359:                                        errflg = 0;
                    360: #ifdef DEBUG
                    361:                                        db_printf("Caller is sigtramp: signal is %d: entry is %x\n",
                    362:                                            signl, sp->k_entry);
                    363: #endif
                    364:                                }
                    365: #ifdef DEBUG
                    366:                                else
                    367:                                db_printf("Non-tramp jsr a0@\n");
                    368: #endif
                    369: #endif /* 0 */
                    370:                        }
                    371:                }
                    372:        }
                    373:        instruc = get(addr, ISP);
                    374:        /* on bad days, the compiler dumps a register move here */
                    375:        if ((instruc & MVLMSK) == MOVLA0 ||
                    376:            (instruc & MVLMSK) == MOVLD0)
                    377:                instruc = get(addr += 2, ISP);
                    378:        if ((instruc & ADQMSK) == ADDQSP ||
                    379:            (instruc & ADQMSK) == ADDQWSP) {
                    380:                val = 0;
                    381:                do {
                    382:                        int n;
                    383:                        n = (instruc >> (16+9)) & 07;
                    384:                        if (n == 0)
                    385:                                n = 8;
                    386:                        val += n;
                    387:                        instruc = get(addr += 2, ISP);
                    388:                } while ((instruc & ADQMSK) == ADDQSP ||
                    389:                         (instruc & ADQMSK) == ADDQWSP);
                    390:        } else if ((instruc & HIWORD) == ADDLSP)
                    391:                val = get(addr + 2, ISP);
                    392:        else if ((instruc & HIWORD) == ADDWSP ||
                    393:                 (instruc & HIWORD) == LEASP)
                    394:                val = instruc & LOWORD;
                    395:        else
                    396:                val = 20;
                    397:        sp->k_nargs = val / 4;
                    398: }
                    399:
                    400: /*
                    401:  * Look at the procedure prolog of the current called procedure.
                    402:  * Figure out which registers we saved, and where they are
                    403:  */
                    404: static void
                    405: findregs(sp, addr)
                    406:        struct stackpos *sp;
                    407:        db_addr_t addr;
                    408: {
                    409:        long instruc, val, i;
                    410:        int  regp;
                    411:
                    412:        regp = 0;
                    413:        instruc = get(addr, ISP);
                    414:        if ((instruc & HIWORD) == LINKLA6) {
                    415:                instruc = get(addr + 2, ISP);
                    416:                addr += 6;
                    417:                regp = sp->k_fp + instruc;
                    418:        } else if ((instruc & HIWORD) == LINKWA6) {
                    419:                addr += 4;
                    420:                if ((instruc &= LOWORD) == 0) {
                    421:                        /* look for addl */
                    422:                        instruc = get(addr, ISP);
                    423:                        if ((instruc & HIWORD) == ADDLSP) {
                    424:                                instruc = get(addr + 2, ISP);
                    425:                                addr += 6;
                    426:                        }
                    427:                        /* else frame is really size 0 */
                    428:                } else {
                    429:                        /* link offset was non-zero -- sign extend it */
                    430:                        instruc <<= 16;
                    431:                        instruc >>= 16;
                    432:                }
                    433:                /* we now have the negative frame size */
                    434:                regp = sp->k_fp + instruc;
                    435:        }
                    436:
                    437:        /* find which registers were saved */
                    438:        /* (expecting probe instruction next) */
                    439:        instruc = get(addr, ISP);
                    440:        if ((instruc & HIWORD) == TSTBSP)
                    441:                addr += 4;
                    442:
                    443:        /* now we expect either a moveml or a movl */
                    444:        instruc = get(addr, ISP);
                    445:        if ((instruc & INSMSK) == MOVLSP) {
                    446:                /* only saving one register */
                    447:                i = (instruc >> 16) & 07;
                    448:                sp->k_regloc[i] = regp;
                    449:        } else if ((instruc & HIWORD) == MOVEML) {
                    450:                /* saving multiple registers or unoptimized code */
                    451:                val = instruc & LOWORD;
                    452:                i = 0;
                    453:                while (val) {
                    454:                        if (val & 1) {
                    455:                                sp->k_regloc[i] = regp;
                    456:                                regp += sizeof(int);
                    457:                        }
                    458:                        val >>= 1;
                    459:                        i++;
                    460:                }
                    461:        }
                    462:        /* else no registers saved */
                    463: }
                    464:
                    465: /*
                    466:  *     Frame tracing.
                    467:  */
                    468: void
                    469: db_stack_trace_print(addr, have_addr, count, modif, pr)
                    470:        db_expr_t       addr;
                    471:        int             have_addr;
                    472:        db_expr_t       count;
                    473:        char            *modif;
                    474:        int             (*pr)(const char *, ...);
                    475: {
                    476:        int i, nargs;
                    477:        long val;
                    478:        db_addr_t       regp;
                    479:        char *          name;
                    480:        struct stackpos pos;
                    481:        boolean_t       kernel_only = TRUE;
                    482:        int             fault_pc = 0;
                    483:
                    484:        {
                    485:                char *cp = modif;
                    486:                char c;
                    487:
                    488:                while ((c = *cp++) != 0)
                    489:                        if (c == 'u')
                    490:                                kernel_only = FALSE;
                    491:        }
                    492:
                    493:        if (count == -1)
                    494:                count = 65535;
                    495:
                    496:        if (!have_addr)
                    497:                stacktop(&ddb_regs, &pos);
                    498: #if 0
                    499:        else {
                    500:
                    501:                /*
                    502:                 * Only have user register state.
                    503:                 */
                    504:                pcb_t   t_pcb;
                    505:                db_regs_t *user_regs;
                    506:
                    507:                t_pcb = (pcb_t) get(&th->pcb, 0);
                    508:                user_regs = (db_regs_t *)
                    509:                        get(&t_pcb->user_regs, 0);
                    510:
                    511:                stacktop(user_regs, &pos);
                    512:
                    513:                /* foo*/
                    514:        }
                    515: #endif
                    516:        else {
                    517:                pos.k_flags = 0;
                    518:                pos.k_fp = addr;
                    519:
                    520:                pos.k_nargs = 0;
                    521:                pos.k_pc = MAXINT;
                    522:                pos.k_entry = MAXINT;
                    523:                /* sorry, we cannot find our registers without knowing our pc */
                    524:                for (i = 0; i < NREGISTERS; i++)
                    525:                        pos.k_regloc[i] = 0;
                    526:                findentry(&pos);
                    527:        }
                    528:
                    529:        while (count) {
                    530:                count--;
                    531:
                    532:                /* HACK */
                    533:                if (pos.k_pc == MAXINT) {
                    534:                        name = "?";
                    535:                        pos.k_pc = 0;
                    536:                } else {
                    537:                        db_find_sym_and_offset(pos.k_pc, &name, &val);
                    538:                        if (name == 0) {
                    539:                                val = MAXINT;
                    540:                                name = "?";
                    541:                        }
                    542:                }
                    543:
                    544:                /*
                    545:                 * Since faultstkadj doesn't set up a valid stack frame,
                    546:                 * we would assume it was the source of the fault. To
                    547:                 * get around this we peek at the fourth argument of
                    548:                 * "trap()" (the stack frame at the time of the fault)
                    549:                 * to determine the _real_ value of PC when things wen
                    550:                 * wrong.
                    551:                 *
                    552:                 * NOTE: If the argument list for 'trap()' ever changes,
                    553:                 * we lose.
                    554:                 */
                    555:                if (strcmp("_trap", name) == 0) {
                    556:                        int tfp;
                    557:
                    558:                        /* Point to 'trap()'s 4th argument (frame structure) */
                    559:                        tfp = pos.k_fp + FR_SAVFP + 4 + (4 * 4);
                    560:
                    561:                        /* Determine if fault was from kernel or user mode */
                    562:                        regp = tfp + offsetof(struct frame, f_sr);
                    563:                        if (!USERMODE(get16(regp, DSP))) {
                    564:                                /*
                    565:                                 * Definitely a kernel mode fault,
                    566:                                 * so get the PC at the time of the fault.
                    567:                                 */
                    568:                                regp = tfp + offsetof(struct frame, f_pc);
                    569:                                fault_pc = get(regp, DSP);
                    570:                        }
                    571:                } else
                    572:                if (fault_pc) {
                    573:                        if (strcmp("faultstkadj", name) == 0) {
                    574:                                db_find_sym_and_offset(fault_pc, &name, &val);
                    575:                                if (name == 0) {
                    576:                                        val = MAXINT;
                    577:                                        name = "?";
                    578:                                }
                    579:                        }
                    580:                        fault_pc = 0;
                    581:                }
                    582:
                    583:                (*pr)("%s", name);
                    584:                if (pos.k_entry != MAXINT && name) {
                    585:                        char *  entry_name;
                    586:                        long    e_val;
                    587:
                    588:                        db_find_sym_and_offset(pos.k_entry, &entry_name,
                    589:                            &e_val);
                    590:                        if (entry_name != 0 && entry_name != name &&
                    591:                            e_val != val) {
                    592:                                (*pr)("(?)\n%s", entry_name);
                    593:                        }
                    594:                }
                    595:                (*pr)("(");
                    596:                regp = pos.k_fp + FR_SAVFP + 4;
                    597:                if ((nargs = pos.k_nargs)) {
                    598:                        while (nargs--) {
                    599:                                (*pr)("%lx", get(regp += 4, DSP));
                    600:                                if (nargs)
                    601:                                        (*pr)(",");
                    602:                        }
                    603:                }
                    604:                if (val == MAXINT)
                    605:                        (*pr)(") at %x\n", pos.k_pc);
                    606:                else
                    607:                        (*pr)(") + %lx\n", val);
                    608:
                    609:                /*
                    610:                 * Stop tracing if frame ptr no longer points into kernel
                    611:                 * stack.
                    612:                 */
                    613:                if (kernel_only && !INKERNEL(pos.k_fp))
                    614:                        break;
                    615:                if (nextframe(&pos, kernel_only) == 0)
                    616:                        break;
                    617:        }
                    618: }
                    619:

CVSweb