[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

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