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

Annotation of sys/arch/sh/sh/db_trace.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: db_trace.c,v 1.4 2007/03/17 20:23:05 miod Exp $       */
        !             2: /*     $NetBSD: db_trace.c,v 1.19 2006/01/21 22:10:59 uwe Exp $        */
        !             3:
        !             4: /*-
        !             5:  * Copyright (c) 2000 Tsubai Masanari.  All rights reserved.
        !             6:  *
        !             7:  * Redistribution and use in source and binary forms, with or without
        !             8:  * modification, are permitted provided that the following conditions
        !             9:  * are met:
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer.
        !            12:  * 2. Redistributions in binary form must reproduce the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer in the
        !            14:  *    documentation and/or other materials provided with the distribution.
        !            15:  * 3. The name of the author may not be used to endorse or promote products
        !            16:  *    derived from this software without specific prior written permission.
        !            17:  *
        !            18:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            19:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            20:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            21:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            22:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            23:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            24:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            25:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            26:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        !            27:  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            28:  */
        !            29:
        !            30: #include <sys/param.h>
        !            31: #include <sys/systm.h>
        !            32:
        !            33: #include <machine/db_machdep.h>
        !            34:
        !            35: #include <ddb/db_access.h>
        !            36: #include <ddb/db_interface.h>
        !            37: #include <ddb/db_output.h>
        !            38: #include <ddb/db_sym.h>
        !            39: #include <ddb/db_variables.h>
        !            40:
        !            41: #ifdef TRACE_DEBUG
        !            42: # define DPRINTF printf
        !            43: #else
        !            44: # define DPRINTF while (/* CONSTCOND */ 0) printf
        !            45: #endif
        !            46:
        !            47: extern char start[], etext[];
        !            48: void db_nextframe(db_addr_t, db_addr_t *, db_addr_t *);
        !            49:
        !            50: struct db_variable db_regs[] = {
        !            51:        { "r0",   (long *)&ddb_regs.tf_r0,   FCN_NULL },
        !            52:        { "r1",   (long *)&ddb_regs.tf_r1,   FCN_NULL },
        !            53:        { "r2",   (long *)&ddb_regs.tf_r2,   FCN_NULL },
        !            54:        { "r3",   (long *)&ddb_regs.tf_r3,   FCN_NULL },
        !            55:        { "r4",   (long *)&ddb_regs.tf_r4,   FCN_NULL },
        !            56:        { "r5",   (long *)&ddb_regs.tf_r5,   FCN_NULL },
        !            57:        { "r6",   (long *)&ddb_regs.tf_r6,   FCN_NULL },
        !            58:        { "r7",   (long *)&ddb_regs.tf_r7,   FCN_NULL },
        !            59:        { "r8",   (long *)&ddb_regs.tf_r8,   FCN_NULL },
        !            60:        { "r9",   (long *)&ddb_regs.tf_r9,   FCN_NULL },
        !            61:        { "r10",  (long *)&ddb_regs.tf_r10,  FCN_NULL },
        !            62:        { "r11",  (long *)&ddb_regs.tf_r11,  FCN_NULL },
        !            63:        { "r12",  (long *)&ddb_regs.tf_r12,  FCN_NULL },
        !            64:        { "r13",  (long *)&ddb_regs.tf_r13,  FCN_NULL },
        !            65:        { "r14",  (long *)&ddb_regs.tf_r14,  FCN_NULL },
        !            66:        { "r15",  (long *)&ddb_regs.tf_r15,  FCN_NULL },
        !            67:        { "pr",   (long *)&ddb_regs.tf_pr,   FCN_NULL },
        !            68:        { "spc",  (long *)&ddb_regs.tf_spc,  FCN_NULL },
        !            69:        { "ssr",  (long *)&ddb_regs.tf_ssr,  FCN_NULL },
        !            70:        { "mach", (long *)&ddb_regs.tf_mach, FCN_NULL },
        !            71:        { "macl", (long *)&ddb_regs.tf_macl, FCN_NULL },
        !            72: };
        !            73:
        !            74: struct db_variable *db_eregs =
        !            75:        db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
        !            76:
        !            77: void
        !            78: db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count,
        !            79:     char *modif, int (*print)(const char *, ...))
        !            80: {
        !            81:        db_addr_t callpc, frame, lastframe;
        !            82:        uint32_t vbr;
        !            83:
        !            84:        __asm volatile("stc vbr, %0" : "=r"(vbr));
        !            85:
        !            86:        frame = ddb_regs.tf_r14;
        !            87:        callpc = ddb_regs.tf_spc;
        !            88:
        !            89:        if (count == 0 || count == -1)
        !            90:                count = INT_MAX;
        !            91:
        !            92:        lastframe = 0;
        !            93:        while (count > 0 && frame != 0) {
        !            94:                /* Are we crossing a trap frame? */
        !            95:                if ((callpc & ~PAGE_MASK) == vbr) {
        !            96:                        struct trapframe *tf = (void *)frame;
        !            97:
        !            98:                        frame = tf->tf_r14;
        !            99:                        callpc = tf->tf_spc;
        !           100:
        !           101:                        (*print)("(EXPEVT %03x; SSR=%08x) at ",
        !           102:                                 tf->tf_expevt, tf->tf_ssr);
        !           103:                        db_printsym(callpc, DB_STGY_PROC, print);
        !           104:                        (*print)("\n");
        !           105:
        !           106:                        /* XXX: don't venture into the userland yet */
        !           107:                        if ((tf->tf_ssr & PSL_MD) == 0)
        !           108:                                break;
        !           109:                } else {
        !           110:                        char *name;
        !           111:                        db_expr_t offset;
        !           112:                        db_sym_t sym;
        !           113:
        !           114:
        !           115:                        DPRINTF("    (1)newpc 0x%lx, newfp 0x%lx\n",
        !           116:                                callpc, frame);
        !           117:
        !           118:                        sym = db_search_symbol(callpc, DB_STGY_ANY, &offset);
        !           119:                        db_symbol_values(sym, &name, NULL);
        !           120:
        !           121:                        (*print)("%s() at ", name ? name : "");
        !           122:                        db_printsym(callpc, DB_STGY_PROC, print);
        !           123:                        (*print)("\n");
        !           124:
        !           125:                        if (lastframe == 0 && offset == 0) {
        !           126:                                callpc = ddb_regs.tf_pr;
        !           127:                                continue;
        !           128:                        }
        !           129:
        !           130:                        db_nextframe(callpc - offset, &frame, &callpc);
        !           131:                        DPRINTF("    (2)newpc 0x%lx, newfp 0x%lx\n",
        !           132:                                callpc, frame);
        !           133:
        !           134:                        if (callpc == 0 && lastframe == 0)
        !           135:                                callpc = (db_addr_t)ddb_regs.tf_pr;
        !           136:                        DPRINTF("    (3)newpc 0x%lx, newfp 0x%lx\n",
        !           137:                                callpc, frame);
        !           138:                }
        !           139:
        !           140:                count--;
        !           141:                lastframe = frame;
        !           142:        }
        !           143: }
        !           144:
        !           145: void
        !           146: db_nextframe(
        !           147:        db_addr_t pc,           /* in: entry address of current function */
        !           148:        db_addr_t *fp,          /* in: current fp, out: parent fp */
        !           149:        db_addr_t *pr)          /* out: parent pr */
        !           150: {
        !           151:        int *frame = (void *)*fp;
        !           152:        int i, inst;
        !           153:        int depth, prdepth, fpdepth;
        !           154:
        !           155:        depth = 0;
        !           156:        prdepth = fpdepth = -1;
        !           157:
        !           158:        if (pc < (db_addr_t)start || pc > (db_addr_t)etext)
        !           159:                goto out;
        !           160:
        !           161:        for (i = 0; i < 30; i++) {
        !           162:                inst = db_get_value(pc, 2, FALSE);
        !           163:                pc += 2;
        !           164:
        !           165:                if (inst == 0x6ef3)     /* mov r15,r14 -- end of prologue */
        !           166:                        break;
        !           167:
        !           168:                if (inst == 0x4f22) {                   /* sts.l pr,@-r15 */
        !           169:                        prdepth = depth;
        !           170:                        depth++;
        !           171:                        continue;
        !           172:                }
        !           173:                if (inst == 0x2fe6) {                   /* mov.l r14,@-r15 */
        !           174:                        fpdepth = depth;
        !           175:                        depth++;
        !           176:                        continue;
        !           177:                }
        !           178:                if ((inst & 0xff0f) == 0x2f06) {        /* mov.l r?,@-r15 */
        !           179:                        depth++;
        !           180:                        continue;
        !           181:                }
        !           182:                if ((inst & 0xff00) == 0x7f00) {        /* add #n,r15 */
        !           183:                        int8_t n = inst & 0xff;
        !           184:
        !           185:                        if (n >= 0) {
        !           186:                                printf("add #n,r15  (n > 0)\n");
        !           187:                                break;
        !           188:                        }
        !           189:
        !           190:                        depth += -n/4;
        !           191:                        continue;
        !           192:                }
        !           193:                if ((inst & 0xf000) == 0x9000) {
        !           194:                        if (db_get_value(pc, 2, FALSE) == 0x3f38) {
        !           195:                                /* "mov #n,r3; sub r3,r15" */
        !           196:                                unsigned int disp = (int)(inst & 0xff);
        !           197:                                int r3;
        !           198:
        !           199:                                r3 = db_get_value(pc + 4 - 2 + (disp << 1),
        !           200:                                    2, FALSE);
        !           201:                                if ((r3 & 0x00008000) == 0)
        !           202:                                        r3 &= 0x0000ffff;
        !           203:                                else
        !           204:                                        r3 |= 0xffff0000;
        !           205:                                depth += (r3 / 4);
        !           206:
        !           207:                                pc += 2;
        !           208:                                continue;
        !           209:                        }
        !           210:                }
        !           211:
        !           212: #ifdef TRACE_DEBUG
        !           213:                printf("unknown instruction in prologue\n");
        !           214:                db_disasm(pc - 2, 0);
        !           215: #endif
        !           216:        }
        !           217:
        !           218:  out:
        !           219: #ifdef TRACE_DEBUG
        !           220:        printf("depth=%x fpdepth=0x%x prdepth=0x%x\n", depth, fpdepth, prdepth);
        !           221: #endif
        !           222:        if (fpdepth != -1)
        !           223:                *fp = frame[depth - fpdepth - 1];
        !           224:        else
        !           225:                *fp = 0;
        !           226:
        !           227:        if (prdepth != -1)
        !           228:                *pr = frame[depth - prdepth - 1];
        !           229:        else
        !           230:                *pr = 0;
        !           231: }

CVSweb