| @@ -1,310 +1,317 @@ | | | @@ -1,310 +1,317 @@ |
1 | /* $NetBSD: db_trace.c,v 1.58 2018/02/28 20:11:09 mrg Exp $ */ | | 1 | /* $NetBSD: db_trace.c,v 1.59 2020/07/06 08:30:10 rin Exp $ */ |
2 | /* $OpenBSD: db_trace.c,v 1.3 1997/03/21 02:10:48 niklas Exp $ */ | | 2 | /* $OpenBSD: db_trace.c,v 1.3 1997/03/21 02:10:48 niklas Exp $ */ |
3 | | | 3 | |
4 | /* | | 4 | /* |
5 | * Mach Operating System | | 5 | * Mach Operating System |
6 | * Copyright (c) 1992 Carnegie Mellon University | | 6 | * Copyright (c) 1992 Carnegie Mellon University |
7 | * All Rights Reserved. | | 7 | * All Rights Reserved. |
8 | * | | 8 | * |
9 | * Permission to use, copy, modify and distribute this software and its | | 9 | * Permission to use, copy, modify and distribute this software and its |
10 | * documentation is hereby granted, provided that both the copyright | | 10 | * documentation is hereby granted, provided that both the copyright |
11 | * notice and this permission notice appear in all copies of the | | 11 | * notice and this permission notice appear in all copies of the |
12 | * software, derivative works or modified versions, and any portions | | 12 | * software, derivative works or modified versions, and any portions |
13 | * thereof, and that both notices appear in supporting documentation. | | 13 | * thereof, and that both notices appear in supporting documentation. |
14 | * | | 14 | * |
15 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" | | 15 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" |
16 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR | | 16 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR |
17 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. | | 17 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. |
18 | * | | 18 | * |
19 | * Carnegie Mellon requests users of this software to return to | | 19 | * Carnegie Mellon requests users of this software to return to |
20 | * | | 20 | * |
21 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU | | 21 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU |
22 | * School of Computer Science | | 22 | * School of Computer Science |
23 | * Carnegie Mellon University | | 23 | * Carnegie Mellon University |
24 | * Pittsburgh PA 15213-3890 | | 24 | * Pittsburgh PA 15213-3890 |
25 | * | | 25 | * |
26 | * any improvements or extensions that they make and grant Carnegie Mellon | | 26 | * any improvements or extensions that they make and grant Carnegie Mellon |
27 | * the rights to redistribute these changes. | | 27 | * the rights to redistribute these changes. |
28 | */ | | 28 | */ |
29 | | | 29 | |
30 | #include <sys/cdefs.h> | | 30 | #include <sys/cdefs.h> |
31 | __KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.58 2018/02/28 20:11:09 mrg Exp $"); | | 31 | __KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.59 2020/07/06 08:30:10 rin Exp $"); |
32 | | | 32 | |
33 | #include "opt_ppcarch.h" | | 33 | #include "opt_ppcarch.h" |
34 | | | 34 | |
35 | #include <sys/param.h> | | 35 | #include <sys/param.h> |
36 | #include <sys/proc.h> | | 36 | #include <sys/proc.h> |
37 | #include <sys/kernel.h> | | 37 | #include <sys/kernel.h> |
38 | | | 38 | |
39 | #include <uvm/uvm_extern.h> | | 39 | #include <uvm/uvm_extern.h> |
40 | | | 40 | |
41 | #include <machine/db_machdep.h> | | 41 | #include <machine/db_machdep.h> |
42 | #include <machine/pmap.h> | | 42 | #include <machine/pmap.h> |
43 | | | 43 | |
44 | #include <powerpc/pcb.h> | | 44 | #include <powerpc/pcb.h> |
45 | #include <powerpc/psl.h> | | 45 | #include <powerpc/psl.h> |
46 | #include <powerpc/spr.h> | | 46 | #include <powerpc/spr.h> |
47 | #if defined (PPC_OEA) || defined(PPC_OEA64) || defined (PPC_OEA64_BRIDGE) | | 47 | #if defined (PPC_OEA) || defined(PPC_OEA64) || defined (PPC_OEA64_BRIDGE) |
48 | #include <powerpc/oea/spr.h> | | 48 | #include <powerpc/oea/spr.h> |
49 | #elif defined(PPC_IBM4XX) | | 49 | #elif defined(PPC_IBM4XX) |
50 | #include <powerpc/ibm4xx/spr.h> | | 50 | #include <powerpc/ibm4xx/spr.h> |
51 | #elif defined(PPC_BOOKE) | | 51 | #elif defined(PPC_BOOKE) |
52 | #include <powerpc/booke/spr.h> | | 52 | #include <powerpc/booke/spr.h> |
53 | #else | | 53 | #else |
54 | #include unknown powerpc variants | | 54 | #include unknown powerpc variants |
55 | #endif | | 55 | #endif |
56 | | | 56 | |
57 | #include <ddb/db_access.h> | | 57 | #include <ddb/db_access.h> |
58 | #include <ddb/db_interface.h> | | 58 | #include <ddb/db_interface.h> |
59 | #include <ddb/db_sym.h> | | 59 | #include <ddb/db_sym.h> |
60 | #include <ddb/db_variables.h> | | 60 | #include <ddb/db_variables.h> |
61 | | | 61 | |
62 | const struct db_variable db_regs[] = { | | 62 | const struct db_variable db_regs[] = { |
63 | { "r0", (long *)&ddb_regs.r[0], FCN_NULL, NULL }, | | 63 | { "r0", (long *)&ddb_regs.r[0], FCN_NULL, NULL }, |
64 | { "r1", (long *)&ddb_regs.r[1], FCN_NULL, NULL }, | | 64 | { "r1", (long *)&ddb_regs.r[1], FCN_NULL, NULL }, |
65 | { "r2", (long *)&ddb_regs.r[2], FCN_NULL, NULL }, | | 65 | { "r2", (long *)&ddb_regs.r[2], FCN_NULL, NULL }, |
66 | { "r3", (long *)&ddb_regs.r[3], FCN_NULL, NULL }, | | 66 | { "r3", (long *)&ddb_regs.r[3], FCN_NULL, NULL }, |
67 | { "r4", (long *)&ddb_regs.r[4], FCN_NULL, NULL }, | | 67 | { "r4", (long *)&ddb_regs.r[4], FCN_NULL, NULL }, |
68 | { "r5", (long *)&ddb_regs.r[5], FCN_NULL, NULL }, | | 68 | { "r5", (long *)&ddb_regs.r[5], FCN_NULL, NULL }, |
69 | { "r6", (long *)&ddb_regs.r[6], FCN_NULL, NULL }, | | 69 | { "r6", (long *)&ddb_regs.r[6], FCN_NULL, NULL }, |
70 | { "r7", (long *)&ddb_regs.r[7], FCN_NULL, NULL }, | | 70 | { "r7", (long *)&ddb_regs.r[7], FCN_NULL, NULL }, |
71 | { "r8", (long *)&ddb_regs.r[8], FCN_NULL, NULL }, | | 71 | { "r8", (long *)&ddb_regs.r[8], FCN_NULL, NULL }, |
72 | { "r9", (long *)&ddb_regs.r[9], FCN_NULL, NULL }, | | 72 | { "r9", (long *)&ddb_regs.r[9], FCN_NULL, NULL }, |
73 | { "r10", (long *)&ddb_regs.r[10], FCN_NULL, NULL }, | | 73 | { "r10", (long *)&ddb_regs.r[10], FCN_NULL, NULL }, |
74 | { "r11", (long *)&ddb_regs.r[11], FCN_NULL, NULL }, | | 74 | { "r11", (long *)&ddb_regs.r[11], FCN_NULL, NULL }, |
75 | { "r12", (long *)&ddb_regs.r[12], FCN_NULL, NULL }, | | 75 | { "r12", (long *)&ddb_regs.r[12], FCN_NULL, NULL }, |
76 | { "r13", (long *)&ddb_regs.r[13], FCN_NULL, NULL }, | | 76 | { "r13", (long *)&ddb_regs.r[13], FCN_NULL, NULL }, |
77 | { "r14", (long *)&ddb_regs.r[14], FCN_NULL, NULL }, | | 77 | { "r14", (long *)&ddb_regs.r[14], FCN_NULL, NULL }, |
78 | { "r15", (long *)&ddb_regs.r[15], FCN_NULL, NULL }, | | 78 | { "r15", (long *)&ddb_regs.r[15], FCN_NULL, NULL }, |
79 | { "r16", (long *)&ddb_regs.r[16], FCN_NULL, NULL }, | | 79 | { "r16", (long *)&ddb_regs.r[16], FCN_NULL, NULL }, |
80 | { "r17", (long *)&ddb_regs.r[17], FCN_NULL, NULL }, | | 80 | { "r17", (long *)&ddb_regs.r[17], FCN_NULL, NULL }, |
81 | { "r18", (long *)&ddb_regs.r[18], FCN_NULL, NULL }, | | 81 | { "r18", (long *)&ddb_regs.r[18], FCN_NULL, NULL }, |
82 | { "r19", (long *)&ddb_regs.r[19], FCN_NULL, NULL }, | | 82 | { "r19", (long *)&ddb_regs.r[19], FCN_NULL, NULL }, |
83 | { "r20", (long *)&ddb_regs.r[20], FCN_NULL, NULL }, | | 83 | { "r20", (long *)&ddb_regs.r[20], FCN_NULL, NULL }, |
84 | { "r21", (long *)&ddb_regs.r[21], FCN_NULL, NULL }, | | 84 | { "r21", (long *)&ddb_regs.r[21], FCN_NULL, NULL }, |
85 | { "r22", (long *)&ddb_regs.r[22], FCN_NULL, NULL }, | | 85 | { "r22", (long *)&ddb_regs.r[22], FCN_NULL, NULL }, |
86 | { "r23", (long *)&ddb_regs.r[23], FCN_NULL, NULL }, | | 86 | { "r23", (long *)&ddb_regs.r[23], FCN_NULL, NULL }, |
87 | { "r24", (long *)&ddb_regs.r[24], FCN_NULL, NULL }, | | 87 | { "r24", (long *)&ddb_regs.r[24], FCN_NULL, NULL }, |
88 | { "r25", (long *)&ddb_regs.r[25], FCN_NULL, NULL }, | | 88 | { "r25", (long *)&ddb_regs.r[25], FCN_NULL, NULL }, |
89 | { "r26", (long *)&ddb_regs.r[26], FCN_NULL, NULL }, | | 89 | { "r26", (long *)&ddb_regs.r[26], FCN_NULL, NULL }, |
90 | { "r27", (long *)&ddb_regs.r[27], FCN_NULL, NULL }, | | 90 | { "r27", (long *)&ddb_regs.r[27], FCN_NULL, NULL }, |
91 | { "r28", (long *)&ddb_regs.r[28], FCN_NULL, NULL }, | | 91 | { "r28", (long *)&ddb_regs.r[28], FCN_NULL, NULL }, |
92 | { "r29", (long *)&ddb_regs.r[29], FCN_NULL, NULL }, | | 92 | { "r29", (long *)&ddb_regs.r[29], FCN_NULL, NULL }, |
93 | { "r30", (long *)&ddb_regs.r[30], FCN_NULL, NULL }, | | 93 | { "r30", (long *)&ddb_regs.r[30], FCN_NULL, NULL }, |
94 | { "r31", (long *)&ddb_regs.r[31], FCN_NULL, NULL }, | | 94 | { "r31", (long *)&ddb_regs.r[31], FCN_NULL, NULL }, |
95 | { "iar", (long *)&ddb_regs.iar, FCN_NULL, NULL }, | | 95 | { "iar", (long *)&ddb_regs.iar, FCN_NULL, NULL }, |
96 | { "msr", (long *)&ddb_regs.msr, FCN_NULL, NULL }, | | 96 | { "msr", (long *)&ddb_regs.msr, FCN_NULL, NULL }, |
97 | { "lr", (long *)&ddb_regs.lr, FCN_NULL, NULL }, | | 97 | { "lr", (long *)&ddb_regs.lr, FCN_NULL, NULL }, |
98 | { "ctr", (long *)&ddb_regs.ctr, FCN_NULL, NULL }, | | 98 | { "ctr", (long *)&ddb_regs.ctr, FCN_NULL, NULL }, |
99 | { "cr", (long *)&ddb_regs.cr, FCN_NULL, NULL }, | | 99 | { "cr", (long *)&ddb_regs.cr, FCN_NULL, NULL }, |
100 | { "xer", (long *)&ddb_regs.xer, FCN_NULL, NULL }, | | 100 | { "xer", (long *)&ddb_regs.xer, FCN_NULL, NULL }, |
101 | { "mq", (long *)&ddb_regs.mq, FCN_NULL, NULL }, | | 101 | { "mq", (long *)&ddb_regs.mq, FCN_NULL, NULL }, |
102 | #ifdef PPC_IBM4XX | | 102 | #ifdef PPC_IBM4XX |
103 | { "dear", (long *)&ddb_regs.dear, FCN_NULL, NULL }, | | 103 | { "dear", (long *)&ddb_regs.dear, FCN_NULL, NULL }, |
104 | { "esr", (long *)&ddb_regs.esr, FCN_NULL, NULL }, | | 104 | { "esr", (long *)&ddb_regs.esr, FCN_NULL, NULL }, |
105 | { "pid", (long *)&ddb_regs.pid, FCN_NULL, NULL }, | | 105 | { "pid", (long *)&ddb_regs.pid, FCN_NULL, NULL }, |
106 | #endif | | 106 | #endif |
107 | }; | | 107 | }; |
108 | const struct db_variable * const db_eregs = db_regs + sizeof (db_regs)/sizeof (db_regs[0]); | | 108 | const struct db_variable * const db_eregs = db_regs + sizeof (db_regs)/sizeof (db_regs[0]); |
109 | | | 109 | |
110 | /* | | 110 | /* |
111 | * Frame tracing. | | 111 | * Frame tracing. |
112 | */ | | 112 | */ |
113 | void | | 113 | void |
114 | db_stack_trace_print(db_expr_t addr, bool have_addr, db_expr_t count, | | 114 | db_stack_trace_print(db_expr_t addr, bool have_addr, db_expr_t count, |
115 | const char *modif, void (*pr)(const char *, ...)) | | 115 | const char *modif, void (*pr)(const char *, ...)) |
116 | { | | 116 | { |
117 | db_addr_t frame, lr, *args; | | 117 | db_addr_t frame, lr, *args; |
118 | db_expr_t diff; | | 118 | db_expr_t diff; |
119 | db_sym_t sym; | | 119 | db_sym_t sym; |
120 | const char *symname; | | 120 | const char *symname; |
121 | const char *cp = modif; | | 121 | const char *cp = modif; |
122 | char c; | | 122 | char c; |
123 | bool kernel_only = true; | | 123 | bool kernel_only = true; |
124 | bool trace_thread = false; | | 124 | bool trace_thread = false; |
125 | bool lwpaddr = false; | | 125 | bool lwpaddr = false; |
126 | extern int trapexit[], sctrapexit[]; | | 126 | extern int trapexit[], sctrapexit[]; |
127 | #ifdef PPC_BOOKE | | 127 | #ifdef PPC_BOOKE |
128 | extern int intrcall[]; | | 128 | extern int intrcall[]; |
129 | #endif | | 129 | #endif |
130 | bool full = false; | | 130 | bool full = false; |
131 | bool in_kernel = true; | | 131 | bool in_kernel = true; |
132 | | | 132 | |
133 | while ((c = *cp++) != 0) { | | 133 | while ((c = *cp++) != 0) { |
134 | if (c == 'a') { | | 134 | if (c == 'a') { |
135 | lwpaddr = true; | | 135 | lwpaddr = true; |
136 | trace_thread = true; | | 136 | trace_thread = true; |
137 | } | | 137 | } |
138 | if (c == 't') | | 138 | if (c == 't') |
139 | trace_thread = true; | | 139 | trace_thread = true; |
140 | if (c == 'u') | | 140 | if (c == 'u') |
141 | kernel_only = false; | | 141 | kernel_only = false; |
142 | if (c == 'f') | | 142 | if (c == 'f') |
143 | full = true; | | 143 | full = true; |
144 | } | | 144 | } |
145 | | | 145 | |
146 | if (have_addr) { | | 146 | if (have_addr) { |
147 | if (trace_thread) { | | 147 | if (trace_thread) { |
148 | struct proc *p; | | 148 | struct proc *p; |
149 | struct lwp *l; | | 149 | struct lwp *l; |
150 | struct pcb *pcb; | | 150 | struct pcb *pcb; |
151 | | | 151 | |
152 | if (lwpaddr) { | | 152 | if (lwpaddr) { |
153 | l = (struct lwp *)addr; | | 153 | l = (struct lwp *)addr; |
154 | p = l->l_proc; | | 154 | p = l->l_proc; |
155 | (*pr)("trace: pid %d ", p->p_pid); | | 155 | (*pr)("trace: pid %d ", p->p_pid); |
156 | } else { | | 156 | } else { |
157 | (*pr)("trace: pid %d ", (int)addr); | | 157 | (*pr)("trace: pid %d ", (int)addr); |
158 | p = proc_find_raw(addr); | | 158 | p = proc_find_raw(addr); |
159 | if (p == NULL) { | | 159 | if (p == NULL) { |
160 | (*pr)("not found\n"); | | 160 | (*pr)("not found\n"); |
161 | return; | | 161 | return; |
162 | } | | 162 | } |
163 | l = LIST_FIRST(&p->p_lwps); | | 163 | l = LIST_FIRST(&p->p_lwps); |
164 | if (l == NULL) { | | 164 | if (l == NULL) { |
165 | (*pr)("trace: no LWP?\n"); | | 165 | (*pr)("trace: no LWP?\n"); |
166 | return; | | 166 | return; |
167 | } | | 167 | } |
168 | } | | 168 | } |
169 | (*pr)("lid %d ", l->l_lid); | | 169 | (*pr)("lid %d ", l->l_lid); |
170 | pcb = lwp_getpcb(l); | | 170 | pcb = lwp_getpcb(l); |
171 | frame = (db_addr_t)pcb->pcb_sp; | | 171 | frame = (db_addr_t)pcb->pcb_sp; |
172 | (*pr)("at %p\n", frame); | | 172 | (*pr)("at %p\n", frame); |
173 | } else | | 173 | } else |
174 | frame = (db_addr_t)addr; | | 174 | frame = (db_addr_t)addr; |
175 | } else { | | 175 | } else { |
176 | frame = (db_addr_t)ddb_regs.r[1]; | | 176 | frame = (db_addr_t)ddb_regs.r[1]; |
177 | } | | 177 | } |
178 | for (;;) { | | 178 | for (;;) { |
179 | if (frame < PAGE_SIZE) | | 179 | if (frame < PAGE_SIZE) |
180 | break; | | 180 | break; |
181 | frame = *(db_addr_t *)frame; | | 181 | frame = *(db_addr_t *)frame; |
182 | next_frame: | | 182 | next_frame: |
183 | args = (db_addr_t *)(frame + 8); | | 183 | args = (db_addr_t *)(frame + 8); |
184 | if (frame < PAGE_SIZE) | | 184 | if (frame < PAGE_SIZE) |
185 | break; | | 185 | break; |
186 | if (count-- == 0) | | 186 | if (count-- == 0) |
187 | break; | | 187 | break; |
188 | | | 188 | |
189 | lr = *(db_addr_t *)(frame + 4) - 4; | | 189 | lr = *(db_addr_t *)(frame + 4) - 4; |
190 | if ((lr & 3) || (lr < 0x100)) { | | 190 | if ((lr & 3) || (lr < 0x100)) { |
191 | (*pr)("saved LR(0x%x) is invalid.", lr); | | 191 | (*pr)("saved LR(0x%x) is invalid.", lr); |
192 | break; | | 192 | break; |
193 | } | | 193 | } |
194 | | | 194 | |
195 | (*pr)("0x%08lx: ", frame); | | 195 | (*pr)("0x%08lx: ", frame); |
196 | if (lr + 4 == (db_addr_t) trapexit || | | 196 | if (lr + 4 == (db_addr_t) trapexit || |
197 | #ifdef PPC_BOOKE | | 197 | #ifdef PPC_BOOKE |
198 | lr + 4 == (db_addr_t) intrcall || | | 198 | lr + 4 == (db_addr_t) intrcall || |
199 | #endif | | 199 | #endif |
200 | lr + 4 == (db_addr_t) sctrapexit) { | | 200 | lr + 4 == (db_addr_t) sctrapexit) { |
201 | const char *trapstr; | | 201 | const char *trapstr; |
202 | struct trapframe *tf = &((struct ktrapframe *)frame)->ktf_tf; | | 202 | struct trapframe *tf = &((struct ktrapframe *)frame)->ktf_tf; |
203 | (*pr)("%s ", tf->tf_srr1 & PSL_PR ? "user" : "kernel"); | | 203 | (*pr)("%s ", tf->tf_srr1 & PSL_PR ? "user" : "kernel"); |
204 | if (lr + 4 == (db_addr_t) sctrapexit) { | | 204 | if (lr + 4 == (db_addr_t) sctrapexit) { |
205 | (*pr)("SC trap #%d by ", tf->tf_fixreg[0]); | | 205 | (*pr)("SC trap #%d by ", tf->tf_fixreg[0]); |
206 | goto print_trap; | | 206 | goto print_trap; |
207 | } | | 207 | } |
208 | switch (tf->tf_exc) { | | 208 | switch (tf->tf_exc) { |
209 | case EXC_DSI: | | 209 | case EXC_DSI: |
210 | #ifdef PPC_OEA | | 210 | #ifdef PPC_OEA |
211 | (*pr)("DSI %s trap @ %#x by ", | | 211 | (*pr)("DSI %s trap @ %#x by ", |
212 | tf->tf_dsisr & DSISR_STORE ? "write" : "read", | | 212 | tf->tf_dsisr & DSISR_STORE ? "write" : "read", |
213 | tf->tf_dar); | | 213 | tf->tf_dar); |
214 | #endif | | 214 | #endif |
215 | #ifdef PPC_IBM4XX | | 215 | #ifdef PPC_IBM4XX |
216 | (*pr)("DSI %s trap @ %#x by ", | | 216 | trapstr = "DSI"; |
| | | 217 | dsi: |
| | | 218 | (*pr)("%s %s trap @ %#x by ", trapstr, |
217 | tf->tf_esr & ESR_DST ? "write" : "read", | | 219 | tf->tf_esr & ESR_DST ? "write" : "read", |
218 | tf->tf_dear); | | 220 | tf->tf_dear); |
219 | #endif | | 221 | #endif |
220 | goto print_trap; | | 222 | goto print_trap; |
221 | case EXC_ALI: | | 223 | case EXC_ALI: |
222 | #ifdef PPC_OEA | | 224 | #ifdef PPC_OEA |
223 | (*pr)("ALI trap @ %#x (DSISR %#x) ", | | 225 | (*pr)("ALI trap @ %#x (DSISR %#x) ", |
224 | tf->tf_dar, tf->tf_dsisr); | | 226 | tf->tf_dar, tf->tf_dsisr); |
225 | goto print_trap; | | 227 | goto print_trap; |
226 | #else | | 228 | #else |
227 | trapstr = "ALI"; break; | | 229 | trapstr = "ALI"; break; |
228 | #endif | | 230 | #endif |
229 | case EXC_ISI: trapstr = "ISI"; break; | | 231 | case EXC_ISI: trapstr = "ISI"; break; |
230 | case EXC_PGM: trapstr = "PGM"; break; | | 232 | case EXC_PGM: trapstr = "PGM"; break; |
231 | case EXC_SC: trapstr = "SC"; break; | | 233 | case EXC_SC: trapstr = "SC"; break; |
232 | case EXC_EXI: trapstr = "EXI"; break; | | 234 | case EXC_EXI: trapstr = "EXI"; break; |
233 | case EXC_MCHK: trapstr = "MCHK"; break; | | 235 | case EXC_MCHK: trapstr = "MCHK"; break; |
234 | case EXC_VEC: trapstr = "VEC"; break; | | 236 | case EXC_VEC: trapstr = "VEC"; break; |
235 | case EXC_FPU: trapstr = "FPU"; break; | | 237 | case EXC_FPU: trapstr = "FPU"; break; |
236 | case EXC_FPA: trapstr = "FPA"; break; | | 238 | case EXC_FPA: trapstr = "FPA"; break; |
237 | case EXC_DECR: trapstr = "DECR"; break; | | 239 | case EXC_DECR: trapstr = "DECR"; break; |
238 | case EXC_BPT: trapstr = "BPT"; break; | | 240 | case EXC_BPT: trapstr = "BPT"; break; |
239 | case EXC_TRC: trapstr = "TRC"; break; | | 241 | case EXC_TRC: trapstr = "TRC"; break; |
240 | case EXC_RUNMODETRC: trapstr = "RUNMODETRC"; break; | | 242 | case EXC_RUNMODETRC: trapstr = "RUNMODETRC"; break; |
241 | case EXC_PERF: trapstr = "PERF"; break; | | 243 | case EXC_PERF: trapstr = "PERF"; break; |
242 | case EXC_SMI: trapstr = "SMI"; break; | | 244 | case EXC_SMI: trapstr = "SMI"; break; |
243 | case EXC_RST: trapstr = "RST"; break; | | 245 | case EXC_RST: trapstr = "RST"; break; |
244 | case EXC_DTMISS: trapstr = "DTMISS"; break; | | 246 | case EXC_DTMISS: trapstr = "DTMISS"; |
| | | 247 | #ifdef PPC_IBM4XX |
| | | 248 | goto dsi; |
| | | 249 | #endif |
| | | 250 | break; |
245 | case EXC_ITMISS: trapstr = "ITMISS"; break; | | 251 | case EXC_ITMISS: trapstr = "ITMISS"; break; |
246 | case EXC_FIT: trapstr = "FIT"; break; | | 252 | case EXC_FIT: trapstr = "FIT"; break; |
247 | case EXC_PIT: trapstr = "PIT"; break; | | 253 | case EXC_PIT: trapstr = "PIT"; break; |
248 | case EXC_WDOG: trapstr = "WDOG"; break; | | 254 | case EXC_WDOG: trapstr = "WDOG"; break; |
249 | default: trapstr = NULL; break; | | 255 | default: trapstr = NULL; break; |
250 | } | | 256 | } |
251 | if (trapstr != NULL) { | | 257 | if (trapstr != NULL) { |
252 | (*pr)("%s trap by ", trapstr); | | 258 | (*pr)("%s trap by ", trapstr); |
253 | } else { | | 259 | } else { |
254 | (*pr)("trap %#x by ", tf->tf_exc); | | 260 | (*pr)("trap %#x by ", tf->tf_exc); |
255 | } | | 261 | } |
256 | print_trap: | | 262 | print_trap: |
257 | lr = (db_addr_t) tf->tf_srr0; | | 263 | lr = (db_addr_t) tf->tf_srr0; |
258 | diff = 0; | | 264 | diff = 0; |
259 | symname = NULL; | | 265 | symname = NULL; |
260 | if (in_kernel && (tf->tf_srr1 & PSL_PR) == 0) { | | 266 | if (in_kernel && (tf->tf_srr1 & PSL_PR) == 0) { |
261 | sym = db_search_symbol(lr, DB_STGY_ANY, &diff); | | 267 | sym = db_search_symbol(lr, DB_STGY_ANY, &diff); |
262 | db_symbol_values(sym, &symname, 0); | | 268 | db_symbol_values(sym, &symname, 0); |
263 | } | | 269 | } |
264 | if (symname == NULL || !strcmp(symname, "end")) { | | 270 | if (symname == NULL || !strcmp(symname, "end")) { |
265 | (*pr)("%p: srr1=%#x\n", lr, tf->tf_srr1); | | 271 | (*pr)("%p: srr1=%#x\n", lr, tf->tf_srr1); |
266 | } else { | | 272 | } else { |
267 | (*pr)("%s+%#x: srr1=%#x\n", symname, | | 273 | (*pr)("%s+%#x: srr1=%#x\n", symname, |
268 | diff, tf->tf_srr1); | | 274 | diff, tf->tf_srr1); |
269 | } | | 275 | } |
270 | (*pr)("%-10s r1=%#x cr=%#x xer=%#x ctr=%#x", | | 276 | (*pr)("%-10s r1=%#x cr=%#x xer=%#x ctr=%#x", |
271 | "", tf->tf_fixreg[1], tf->tf_cr, tf->tf_xer, tf->tf_ctr); | | 277 | "", tf->tf_fixreg[1], tf->tf_cr, tf->tf_xer, tf->tf_ctr); |
272 | #ifdef PPC_OEA | | 278 | #ifdef PPC_OEA |
273 | if (tf->tf_exc == EXC_DSI) | | 279 | if (tf->tf_exc == EXC_DSI) |
274 | (*pr)(" dsisr=%#x", tf->tf_dsisr); | | 280 | (*pr)(" dsisr=%#x", tf->tf_dsisr); |
275 | #ifdef PPC_OEA601 | | 281 | #ifdef PPC_OEA601 |
276 | if ((mfpvr() >> 16) == MPC601) | | 282 | if ((mfpvr() >> 16) == MPC601) |
277 | (*pr)(" mq=%#x", tf->tf_mq); | | 283 | (*pr)(" mq=%#x", tf->tf_mq); |
278 | #endif /* PPC_OEA601 */ | | 284 | #endif /* PPC_OEA601 */ |
279 | #endif /* PPC_OEA */ | | 285 | #endif /* PPC_OEA */ |
280 | #ifdef PPC_IBM4XX | | 286 | #ifdef PPC_IBM4XX |
281 | if (tf->tf_exc == EXC_DSI) | | 287 | if (tf->tf_exc == EXC_DSI || |
| | | 288 | tf->tf_exc == EXC_DTMISS) |
282 | (*pr)(" dear=%#x", tf->tf_dear); | | 289 | (*pr)(" dear=%#x", tf->tf_dear); |
283 | (*pr)(" esr=%#x pid=%#x", tf->tf_esr, tf->tf_pid); | | 290 | (*pr)(" esr=%#x pid=%#x", tf->tf_esr, tf->tf_pid); |
284 | #endif | | 291 | #endif |
285 | (*pr)("\n"); | | 292 | (*pr)("\n"); |
286 | frame = (db_addr_t) tf->tf_fixreg[1]; | | 293 | frame = (db_addr_t) tf->tf_fixreg[1]; |
287 | in_kernel = !(tf->tf_srr1 & PSL_PR); | | 294 | in_kernel = !(tf->tf_srr1 & PSL_PR); |
288 | if (kernel_only && !in_kernel) | | 295 | if (kernel_only && !in_kernel) |
289 | break; | | 296 | break; |
290 | goto next_frame; | | 297 | goto next_frame; |
291 | } | | 298 | } |
292 | | | 299 | |
293 | diff = 0; | | 300 | diff = 0; |
294 | symname = NULL; | | 301 | symname = NULL; |
295 | if (in_kernel) { | | 302 | if (in_kernel) { |
296 | sym = db_search_symbol(lr, DB_STGY_ANY, &diff); | | 303 | sym = db_search_symbol(lr, DB_STGY_ANY, &diff); |
297 | db_symbol_values(sym, &symname, 0); | | 304 | db_symbol_values(sym, &symname, 0); |
298 | } | | 305 | } |
299 | if (symname == NULL || !strcmp(symname, "end")) | | 306 | if (symname == NULL || !strcmp(symname, "end")) |
300 | (*pr)("at %p", lr); | | 307 | (*pr)("at %p", lr); |
301 | else | | 308 | else |
302 | (*pr)("at %s+%#x", symname, diff); | | 309 | (*pr)("at %s+%#x", symname, diff); |
303 | if (full) | | 310 | if (full) |
304 | /* Print all the args stored in that stackframe. */ | | 311 | /* Print all the args stored in that stackframe. */ |
305 | (*pr)("(%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx)", | | 312 | (*pr)("(%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx)", |
306 | args[0], args[1], args[2], args[3], | | 313 | args[0], args[1], args[2], args[3], |
307 | args[4], args[5], args[6], args[7]); | | 314 | args[4], args[5], args[6], args[7]); |
308 | (*pr)("\n"); | | 315 | (*pr)("\n"); |
309 | } | | 316 | } |
310 | } | | 317 | } |