1 /* $OpenBSD: db_trace.c,v 1.4 2003/10/15 01:06:13 drahn Exp $ */ 2 /* $NetBSD: db_trace.c,v 1.15 1996/02/22 23:23:41 gwr Exp $ */ 3 4 /* 5 * Mach Operating System 6 * Copyright (c) 1992 Carnegie Mellon University 7 * All Rights Reserved. 8 * 9 * Permission to use, copy, modify and distribute this software and its 10 * documentation is hereby granted, provided that both the copyright 11 * notice and this permission notice appear in all copies of the 12 * software, derivative works or modified versions, and any portions 13 * thereof, and that both notices appear in supporting documentation. 14 * 15 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 16 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 17 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 18 * 19 * Carnegie Mellon requests users of this software to return to 20 * 21 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 22 * School of Computer Science 23 * Carnegie Mellon University 24 * Pittsburgh PA 15213-3890 25 * 26 * any improvements or extensions that they make and grant Carnegie Mellon 27 * the rights to redistribute these changes. 28 */ 29 30 #include <sys/param.h> 31 #include <sys/systm.h> 32 #include <sys/proc.h> 33 34 #include <machine/db_machdep.h> 35 #include <machine/signal.h> 36 #include <machine/pcb.h> 37 38 #include <ddb/db_access.h> 39 #include <ddb/db_sym.h> 40 #include <ddb/db_variables.h> 41 #include <ddb/db_interface.h> 42 #include <ddb/db_output.h> 43 44 int db_read32(u_int32_t paddr, u_int32_t *value); 45 46 db_regs_t ddb_regs; 47 48 struct db_variable db_regs[] = { 49 { "r0", (long *)&(DDB_REGS->tf.fixreg[0]), FCN_NULL }, 50 { "r1", (long *)&(DDB_REGS->tf.fixreg[1]), FCN_NULL }, 51 { "r2", (long *)&(DDB_REGS->tf.fixreg[2]), FCN_NULL }, 52 { "r3", (long *)&(DDB_REGS->tf.fixreg[3]), FCN_NULL }, 53 { "r4", (long *)&(DDB_REGS->tf.fixreg[4]), FCN_NULL }, 54 { "r5", (long *)&(DDB_REGS->tf.fixreg[5]), FCN_NULL }, 55 { "r6", (long *)&(DDB_REGS->tf.fixreg[6]), FCN_NULL }, 56 { "r7", (long *)&(DDB_REGS->tf.fixreg[7]), FCN_NULL }, 57 { "r8", (long *)&(DDB_REGS->tf.fixreg[8]), FCN_NULL }, 58 { "r9", (long *)&(DDB_REGS->tf.fixreg[9]), FCN_NULL }, 59 { "r10", (long *)&(DDB_REGS->tf.fixreg[10]), FCN_NULL }, 60 { "r11", (long *)&(DDB_REGS->tf.fixreg[11]), FCN_NULL }, 61 { "r12", (long *)&(DDB_REGS->tf.fixreg[12]), FCN_NULL }, 62 { "r13", (long *)&(DDB_REGS->tf.fixreg[13]), FCN_NULL }, 63 { "r14", (long *)&(DDB_REGS->tf.fixreg[13]), FCN_NULL }, 64 { "r15", (long *)&(DDB_REGS->tf.fixreg[13]), FCN_NULL }, 65 { "r16", (long *)&(DDB_REGS->tf.fixreg[13]), FCN_NULL }, 66 { "r17", (long *)&(DDB_REGS->tf.fixreg[17]), FCN_NULL }, 67 { "r18", (long *)&(DDB_REGS->tf.fixreg[18]), FCN_NULL }, 68 { "r19", (long *)&(DDB_REGS->tf.fixreg[19]), FCN_NULL }, 69 { "r20", (long *)&(DDB_REGS->tf.fixreg[20]), FCN_NULL }, 70 { "r21", (long *)&(DDB_REGS->tf.fixreg[21]), FCN_NULL }, 71 { "r22", (long *)&(DDB_REGS->tf.fixreg[22]), FCN_NULL }, 72 { "r23", (long *)&(DDB_REGS->tf.fixreg[23]), FCN_NULL }, 73 { "r24", (long *)&(DDB_REGS->tf.fixreg[24]), FCN_NULL }, 74 { "r25", (long *)&(DDB_REGS->tf.fixreg[25]), FCN_NULL }, 75 { "r26", (long *)&(DDB_REGS->tf.fixreg[26]), FCN_NULL }, 76 { "r27", (long *)&(DDB_REGS->tf.fixreg[27]), FCN_NULL }, 77 { "r28", (long *)&(DDB_REGS->tf.fixreg[28]), FCN_NULL }, 78 { "r29", (long *)&(DDB_REGS->tf.fixreg[29]), FCN_NULL }, 79 { "r30", (long *)&(DDB_REGS->tf.fixreg[30]), FCN_NULL }, 80 { "r31", (long *)&(DDB_REGS->tf.fixreg[31]), FCN_NULL }, 81 { "lr", (long *)&(DDB_REGS->tf.lr), FCN_NULL }, 82 { "cr", (long *)&(DDB_REGS->tf.cr), FCN_NULL }, 83 { "xer", (long *)&(DDB_REGS->tf.xer), FCN_NULL }, 84 { "ctr", (long *)&(DDB_REGS->tf.ctr), FCN_NULL }, 85 { "iar", (long *)&(DDB_REGS->tf.srr0), FCN_NULL }, 86 { "msr", (long *)&(DDB_REGS->tf.srr1), FCN_NULL }, 87 }; 88 89 struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]); 90 91 extern label_t *db_recover; 92 93 /* 94 * this is probably hackery. 95 */ 96 void 97 db_save_regs(struct trapframe *frame) 98 { 99 bcopy(frame, &(ddb_regs.tf), sizeof (struct trapframe)); 100 } 101 102 int 103 db_read32(u_int32_t paddr, u_int32_t *value) 104 { 105 faultbuf env; 106 faultbuf *old_onfault = curpcb->pcb_onfault; 107 if (setfault(&env)) { 108 curpcb->pcb_onfault = old_onfault; 109 return EFAULT; 110 } 111 *value = *(u_int32_t *)paddr; 112 curpcb->pcb_onfault = old_onfault; 113 return 0; 114 } 115 116 db_expr_t 117 db_dumpframe(u_int32_t pframe, int (*pr)(const char *, ...)) 118 { 119 u_int32_t nextframe; 120 u_int32_t lr; 121 char *name; 122 db_expr_t offset; 123 124 if (db_read32(pframe, &nextframe) == EFAULT) { 125 return 0; 126 } 127 128 if (db_read32(pframe+4, &lr) == EFAULT) { 129 return 0; 130 } 131 132 db_find_sym_and_offset(lr-4, &name, &offset); 133 if (!name) { 134 name = "0"; 135 offset = lr-4; 136 } 137 (*pr)("%08x: %s+0x%x fp %x nfp %x\n", 138 lr-4, name, offset, pframe, nextframe); 139 140 return nextframe; 141 } 142 143 /* 144 * Frame tracing. 145 */ 146 void 147 db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count, 148 char *modif, int (*pr)(const char *, ...)) 149 { 150 151 if (count == 0 || count == -1) 152 count = INT_MAX; 153 if (have_addr == 0){ 154 addr = ddb_regs.tf.fixreg[1]; 155 } 156 while (addr != 0 && count > 0) { 157 addr = db_dumpframe(addr, pr); 158 count --; 159 } 160 } 161