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

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

1.1     ! nbrk        1: /*     $OpenBSD: db_trace.c,v 1.3 2006/11/29 12:24:17 miod Exp $       */
        !             2: /*     $NetBSD: db_trace.c,v 1.8 2003/01/17 22:28:48 thorpej Exp $     */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 2000, 2001 Ben Harris
        !             6:  * Copyright (c) 1996 Scott K. Stevens
        !             7:  *
        !             8:  * Mach Operating System
        !             9:  * Copyright (c) 1991,1990 Carnegie Mellon University
        !            10:  * All Rights Reserved.
        !            11:  *
        !            12:  * Permission to use, copy, modify and distribute this software and its
        !            13:  * documentation is hereby granted, provided that both the copyright
        !            14:  * notice and this permission notice appear in all copies of the
        !            15:  * software, derivative works or modified versions, and any portions
        !            16:  * thereof, and that both notices appear in supporting documentation.
        !            17:  *
        !            18:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            19:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !            20:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            21:  *
        !            22:  * Carnegie Mellon requests users of this software to return to
        !            23:  *
        !            24:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
        !            25:  *  School of Computer Science
        !            26:  *  Carnegie Mellon University
        !            27:  *  Pittsburgh PA 15213-3890
        !            28:  *
        !            29:  * any improvements or extensions that they make and grant Carnegie the
        !            30:  * rights to redistribute these changes.
        !            31:  */
        !            32:
        !            33: #include <sys/param.h>
        !            34:
        !            35: #include <sys/proc.h>
        !            36: #include <sys/user.h>
        !            37: #include <arm/armreg.h>
        !            38: #include <arm/cpufunc.h>
        !            39: #include <machine/db_machdep.h>
        !            40:
        !            41: #include <ddb/db_access.h>
        !            42: #include <ddb/db_interface.h>
        !            43: #include <ddb/db_sym.h>
        !            44: #include <ddb/db_output.h>
        !            45:
        !            46: db_regs_t ddb_regs;
        !            47:
        !            48: #define INKERNEL(va)   (((vaddr_t)(va)) >= VM_MIN_KERNEL_ADDRESS)
        !            49:
        !            50: /*
        !            51:  * APCS stack frames are awkward beasts, so I don't think even trying to use
        !            52:  * a structure to represent them is a good idea.
        !            53:  *
        !            54:  * Here's the diagram from the APCS.  Increasing address is _up_ the page.
        !            55:  *
        !            56:  *          save code pointer       [fp]        <- fp points to here
        !            57:  *          return link value       [fp, #-4]
        !            58:  *          return sp value         [fp, #-8]
        !            59:  *          return fp value         [fp, #-12]
        !            60:  *          [saved v7 value]
        !            61:  *          [saved v6 value]
        !            62:  *          [saved v5 value]
        !            63:  *          [saved v4 value]
        !            64:  *          [saved v3 value]
        !            65:  *          [saved v2 value]
        !            66:  *          [saved v1 value]
        !            67:  *          [saved a4 value]
        !            68:  *          [saved a3 value]
        !            69:  *          [saved a2 value]
        !            70:  *          [saved a1 value]
        !            71:  *
        !            72:  * The save code pointer points twelve bytes beyond the start of the
        !            73:  * code sequence (usually a single STM) that created the stack frame.
        !            74:  * We have to disassemble it if we want to know which of the optional
        !            75:  * fields are actually present.
        !            76:  */
        !            77:
        !            78: #define FR_SCP (0)
        !            79: #define FR_RLV (-1)
        !            80: #define FR_RSP (-2)
        !            81: #define FR_RFP (-3)
        !            82:
        !            83: void
        !            84: db_stack_trace_print(addr, have_addr, count, modif, pr)
        !            85:        db_expr_t       addr;
        !            86:        int             have_addr;
        !            87:        db_expr_t       count;
        !            88:        char            *modif;
        !            89:        int             (*pr) (const char *, ...);
        !            90: {
        !            91:        u_int32_t       *frame, *lastframe;
        !            92:        char c, *cp = modif;
        !            93:        boolean_t       kernel_only = TRUE;
        !            94:        boolean_t       trace_thread = FALSE;
        !            95:        int     scp_offset;
        !            96:
        !            97:        while ((c = *cp++) != 0) {
        !            98:                if (c == 'u')
        !            99:                        kernel_only = FALSE;
        !           100:                if (c == 't')
        !           101:                        trace_thread = TRUE;
        !           102:        }
        !           103:
        !           104:        if (!have_addr)
        !           105:                frame = (u_int32_t *)(DDB_REGS->tf_r11);
        !           106:        else {
        !           107:                if (trace_thread) {
        !           108:                        struct proc *p;
        !           109:                        struct user *u;
        !           110:                        (*pr) ("trace: pid %d ", (int)addr);
        !           111:                        p = pfind(addr);
        !           112:                        if (p == NULL) {
        !           113:                                (*pr)("not found\n");
        !           114:                                return;
        !           115:                        }
        !           116:                        u = p->p_addr;
        !           117: #ifdef acorn26
        !           118:                        frame = (u_int32_t *)(u->u_pcb.pcb_sf->sf_r11);
        !           119: #else
        !           120:                        frame = (u_int32_t *)(u->u_pcb.pcb_un.un_32.pcb32_r11);
        !           121: #endif
        !           122:                        (*pr)("at %p\n", frame);
        !           123:                } else
        !           124:                        frame = (u_int32_t *)(addr);
        !           125:        }
        !           126:        lastframe = NULL;
        !           127:        scp_offset = -(get_pc_str_offset() >> 2);
        !           128:
        !           129:        while (count-- && frame != NULL) {
        !           130:                db_addr_t       scp;
        !           131:                u_int32_t       savecode;
        !           132:                int             r;
        !           133:                u_int32_t       *rp;
        !           134:                const char      *sep;
        !           135:
        !           136:                /*
        !           137:                 * In theory, the SCP isn't guaranteed to be in the function
        !           138:                 * that generated the stack frame.  We hope for the best.
        !           139:                 */
        !           140: #ifdef __PROG26
        !           141:                scp = frame[FR_SCP] & R15_PC;
        !           142: #else
        !           143:                scp = frame[FR_SCP];
        !           144: #endif
        !           145:
        !           146:                db_printsym(scp, DB_STGY_PROC, pr);
        !           147:                (*pr)("\n\t");
        !           148: #ifdef __PROG26
        !           149:                (*pr)("scp=0x%08x rlv=0x%08x (", scp, frame[FR_RLV] & R15_PC);
        !           150:                db_printsym(frame[FR_RLV] & R15_PC, DB_STGY_PROC, pr);
        !           151:                (*pr)(")\n");
        !           152: #else
        !           153:                (*pr)("scp=0x%08x rlv=0x%08x (", scp, frame[FR_RLV]);
        !           154:                db_printsym(frame[FR_RLV], DB_STGY_PROC, pr);
        !           155:                (*pr)(")\n");
        !           156: #endif
        !           157:                (*pr)("\trsp=0x%08x rfp=0x%08x", frame[FR_RSP], frame[FR_RFP]);
        !           158:
        !           159:                savecode = ((u_int32_t *)scp)[scp_offset];
        !           160:                if ((savecode & 0x0e100000) == 0x08000000) {
        !           161:                        /* Looks like an STM */
        !           162:                        rp = frame - 4;
        !           163:                        sep = "\n\t";
        !           164:                        for (r = 10; r >= 0; r--) {
        !           165:                                if (savecode & (1 << r)) {
        !           166:                                        (*pr)("%sr%d=0x%08x",
        !           167:                                            sep, r, *rp--);
        !           168:                                        sep = (frame - rp) % 4 == 2 ?
        !           169:                                            "\n\t" : " ";
        !           170:                                }
        !           171:                        }
        !           172:                }
        !           173:
        !           174:                (*pr)("\n");
        !           175:
        !           176:                /*
        !           177:                 * Switch to next frame up
        !           178:                 */
        !           179:                if (frame[FR_RFP] == 0)
        !           180:                        break; /* Top of stack */
        !           181:
        !           182:                lastframe = frame;
        !           183:                frame = (u_int32_t *)(frame[FR_RFP]);
        !           184:
        !           185:                if (INKERNEL((int)frame)) {
        !           186:                        /* staying in kernel */
        !           187:                        if (frame <= lastframe) {
        !           188:                                (*pr)("Bad frame pointer: %p\n", frame);
        !           189:                                break;
        !           190:                        }
        !           191:                } else if (INKERNEL((int)lastframe)) {
        !           192:                        /* switch from user to kernel */
        !           193:                        if (kernel_only)
        !           194:                                break;  /* kernel stack only */
        !           195:                } else {
        !           196:                        /* in user */
        !           197:                        if (frame <= lastframe) {
        !           198:                                (*pr)("Bad user frame pointer: %p\n",
        !           199:                                          frame);
        !           200:                                break;
        !           201:                        }
        !           202:                }
        !           203:        }
        !           204: }

CVSweb