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