[BACK]Return to db_machdep.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / amd64 / amd64

Annotation of src/sys/arch/amd64/amd64/db_machdep.c, Revision 1.2

1.2     ! chs         1: /*     $NetBSD: db_machdep.c,v 1.1 2011/04/10 20:36:49 christos Exp $  */
1.1       christos    2:
                      3: /*
                      4:  * Mach Operating System
                      5:  * Copyright (c) 1991,1990 Carnegie Mellon University
                      6:  * All Rights Reserved.
                      7:  *
                      8:  * Permission to use, copy, modify and distribute this software and its
                      9:  * documentation is hereby granted, provided that both the copyright
                     10:  * notice and this permission notice appear in all copies of the
                     11:  * software, derivative works or modified versions, and any portions
                     12:  * thereof, and that both notices appear in supporting documentation.
                     13:  *
                     14:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     15:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     16:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     17:  *
                     18:  * Carnegie Mellon requests users of this software to return to
                     19:  *
                     20:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
                     21:  *  School of Computer Science
                     22:  *  Carnegie Mellon University
                     23:  *  Pittsburgh PA 15213-3890
                     24:  *
                     25:  * any improvements or extensions that they make and grant Carnegie the
                     26:  * rights to redistribute these changes.
                     27:  */
                     28: #include <sys/cdefs.h>
1.2     ! chs        29: __KERNEL_RCSID(0, "$NetBSD: db_machdep.c,v 1.1 2011/04/10 20:36:49 christos Exp $");
1.1       christos   30:
                     31: #include <sys/param.h>
                     32: #include <sys/systm.h>
                     33: #include <sys/proc.h>
                     34:
                     35: #include <machine/frame.h>
                     36: #include <machine/trap.h>
                     37: #include <machine/intrdefs.h>
                     38:
                     39: #include <machine/db_machdep.h>
                     40: #include <ddb/db_sym.h>
                     41: #include <ddb/db_access.h>
                     42: #include <ddb/db_variables.h>
                     43: #include <ddb/db_output.h>
                     44: #include <ddb/db_interface.h>
                     45: #include <ddb/db_user.h>
                     46: #include <ddb/db_proc.h>
                     47: #include <ddb/db_command.h>
                     48: #include <x86/db_machdep.h>
                     49:
                     50: #define dbreg(xx) (long *)offsetof(db_regs_t, tf_ ## xx)
                     51:
                     52: /*
                     53:  * Machine register set.
                     54:  */
                     55: const struct db_variable db_regs[] = {
                     56:        { "ds",         dbreg(ds),     db_x86_regop, NULL },
                     57:        { "es",         dbreg(es),     db_x86_regop, NULL },
                     58:        { "fs",         dbreg(fs),     db_x86_regop, NULL },
                     59:        { "gs",         dbreg(gs),     db_x86_regop, NULL },
                     60:        { "rdi",        dbreg(rdi),    db_x86_regop, NULL },
                     61:        { "rsi",        dbreg(rsi),    db_x86_regop, NULL },
                     62:        { "rbp",        dbreg(rbp),    db_x86_regop, NULL },
                     63:        { "rbx",        dbreg(rbx),    db_x86_regop, NULL },
                     64:        { "rdx",        dbreg(rdx),    db_x86_regop, NULL },
                     65:        { "rcx",        dbreg(rcx),    db_x86_regop, NULL },
                     66:        { "rax",        dbreg(rax),    db_x86_regop, NULL },
                     67:        { "r8",         dbreg(r8),     db_x86_regop, NULL },
                     68:        { "r9",         dbreg(r9),     db_x86_regop, NULL },
                     69:        { "r10",        dbreg(r10),    db_x86_regop, NULL },
                     70:        { "r11",        dbreg(r11),    db_x86_regop, NULL },
                     71:        { "r12",        dbreg(r12),    db_x86_regop, NULL },
                     72:        { "r13",        dbreg(r13),    db_x86_regop, NULL },
                     73:        { "r14",        dbreg(r14),    db_x86_regop, NULL },
                     74:        { "r15",        dbreg(r15),    db_x86_regop, NULL },
                     75:        { "rip",        dbreg(rip),    db_x86_regop, NULL },
                     76:        { "cs",         dbreg(cs),     db_x86_regop, NULL },
                     77:        { "rflags",     dbreg(rflags), db_x86_regop, NULL },
                     78:        { "rsp",        dbreg(rsp),    db_x86_regop, NULL },
                     79:        { "ss",         dbreg(ss),     db_x86_regop, NULL },
                     80: };
                     81: const struct db_variable * const db_eregs =
                     82:        db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
                     83:
                     84: /*
                     85:  * Figure out how many arguments were passed into the frame at "fp".
                     86:  * We can probably figure out how many arguments where passed above
                     87:  * the first 6 (which are in registers), but since we can't
                     88:  * reliably determine the values currently, just return 0.
                     89:  */
                     90: int
                     91: db_numargs(long *retaddrp)
                     92: {
                     93:        return 0;
                     94: }
                     95:
                     96: /*
                     97:  * Figure out the next frame up in the call stack.
                     98:  * For trap(), we print the address of the faulting instruction and
                     99:  *   proceed with the calling frame.  We return the ip that faulted.
                    100:  *   If the trap was caused by jumping through a bogus pointer, then
                    101:  *   the next line in the backtrace will list some random function as
                    102:  *   being called.  It should get the argument list correct, though.
                    103:  *   It might be possible to dig out from the next frame up the name
                    104:  *   of the function that faulted, but that could get hairy.
                    105:  */
                    106: int
                    107: db_nextframe(long **nextframe, long **retaddr, long **arg0, db_addr_t *ip,
                    108:             long *argp, int is_trap, void (*pr)(const char *, ...))
                    109: {
                    110:        struct trapframe *tf;
                    111:        struct x86_64_frame *fp;
                    112:        struct intrframe *ifp;
                    113:        int traptype, trapno, err, i;
                    114:
                    115:        switch (is_trap) {
                    116:            case NONE:
                    117:                *ip = (db_addr_t)
                    118:                        db_get_value((long)*retaddr, 8, false);
                    119:                fp = (struct x86_64_frame *)
                    120:                        db_get_value((long)*nextframe, 8, false);
                    121:                if (fp == NULL)
                    122:                        return 0;
                    123:                *nextframe = (long *)&fp->f_frame;
                    124:                *retaddr = (long *)&fp->f_retaddr;
                    125:                *arg0 = (long *)&fp->f_arg0;
                    126:                break;
                    127:
                    128:            case TRAP:
                    129:            case SYSCALL:
                    130:            case INTERRUPT:
                    131:            default:
                    132:
                    133:                /* The only argument to trap() or syscall() is the trapframe. */
1.2     ! chs       134:                tf = (struct trapframe *)argp;
1.1       christos  135:                switch (is_trap) {
                    136:                case TRAP:
                    137:                        (*pr)("--- trap (number %d) ---\n", tf->tf_trapno);
                    138:                        break;
                    139:                case SYSCALL:
                    140:                        (*pr)("--- syscall (number %ld) ---\n", tf->tf_rax);
                    141:                        break;
                    142:                case INTERRUPT:
                    143:                        (*pr)("--- interrupt ---\n");
                    144:                        break;
                    145:                }
                    146:                *ip = (db_addr_t)tf->tf_rip;
                    147:                fp = (struct x86_64_frame *)tf->tf_rbp;
                    148:                if (fp == NULL)
                    149:                        return 0;
                    150:                *nextframe = (long *)&fp->f_frame;
                    151:                *retaddr = (long *)&fp->f_retaddr;
                    152:                *arg0 = (long *)&fp->f_arg0;
                    153:                break;
                    154:        }
                    155:
                    156:        /*
                    157:         * A bit of a hack. Since %rbp may be used in the stub code,
                    158:         * walk the stack looking for a valid interrupt frame. Such
                    159:         * a frame can be recognized by always having
                    160:         * err 0 or IREENT_MAGIC and trapno T_ASTFLT.
                    161:         */
                    162:        if (db_frame_info(*nextframe, (db_addr_t)*ip, NULL, NULL, &traptype,
                    163:            NULL) != (db_sym_t)0
                    164:            && traptype == INTERRUPT) {
                    165:                for (i = 0; i < 4; i++) {
                    166:                        ifp = (struct intrframe *)(argp + i);
                    167:                        err = db_get_value((long)&ifp->if_tf.tf_err,
                    168:                            sizeof(long), false);
                    169:                        trapno = db_get_value((long)&ifp->if_tf.tf_trapno,
                    170:                            sizeof(long), false);
                    171:                        if ((err == 0 || err == IREENT_MAGIC)
                    172:                            && trapno == T_ASTFLT) {
                    173:                                *nextframe = (long *)ifp - 1;
                    174:                                break;
                    175:                        }
                    176:                }
                    177:                if (i == 4) {
                    178:                        (*pr)("DDB lost frame for ");
                    179:                        db_printsym(*ip, DB_STGY_ANY, pr);
                    180:                        (*pr)(", trying %p\n",argp);
                    181:                        *nextframe = argp;
                    182:                }
                    183:        }
                    184:        return 1;
                    185: }
                    186:
                    187: db_sym_t
                    188: db_frame_info(long *frame, db_addr_t callpc, const char **namep,
                    189:              db_expr_t *offp, int *is_trap, int *nargp)
                    190: {
                    191:        db_expr_t       offset;
                    192:        db_sym_t        sym;
                    193:        int narg;
                    194:        const char *name;
                    195:
                    196:        sym = db_search_symbol(callpc, DB_STGY_ANY, &offset);
                    197:        db_symbol_values(sym, &name, NULL);
                    198:        if (sym == (db_sym_t)0)
                    199:                return (db_sym_t)0;
                    200:
                    201:        *is_trap = NONE;
                    202:        narg = 0;
                    203:
                    204:        if (INKERNEL((long)frame) && name) {
                    205:                /*
                    206:                 * XXX traps should be based off of the Xtrap*
                    207:                 * locations rather than on trap, since some traps
                    208:                 * (e.g., npxdna) don't go through trap()
                    209:                 */
                    210:                if (!strcmp(name, "trap")) {
                    211:                        *is_trap = TRAP;
                    212:                        narg = 0;
                    213:                } else if (!strcmp(name, "syscall_plain") ||
                    214:                           !strcmp(name, "syscall_fancy")) {
                    215:                        *is_trap = SYSCALL;
                    216:                        narg = 0;
                    217:                } else if (name[0] == 'X') {
                    218:                        if (!strncmp(name, "Xintr", 5) ||
                    219:                            !strncmp(name, "Xresume", 7) ||
                    220:                            !strncmp(name, "Xstray", 6) ||
                    221:                            !strncmp(name, "Xhold", 5) ||
                    222:                            !strncmp(name, "Xrecurse", 8) ||
                    223:                            !strcmp(name, "Xdoreti") ||
                    224:                            !strncmp(name, "Xsoft", 5)) {
                    225:                                *is_trap = INTERRUPT;
                    226:                                narg = 0;
                    227:                        }
                    228:                }
                    229:        }
                    230:
                    231:        if (offp != NULL)
                    232:                *offp = offset;
                    233:        if (nargp != NULL)
                    234:                *nargp = narg;
                    235:        if (namep != NULL)
                    236:                *namep = name;
                    237:        return sym;
                    238: }

CVSweb <webmaster@jp.NetBSD.org>