xref: /netbsd/sys/arch/sparc64/sparc64/db_trace.c (revision 8d36b03f)
1 /*	$NetBSD: db_trace.c,v 1.57 2023/01/24 23:23:31 riastradh Exp $ */
2 
3 /*
4  * Copyright (c) 1996-2002 Eduardo Horvath.  All rights reserved.
5  * Mach Operating System
6  * Copyright (c) 1991,1990 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 the
27  * rights to redistribute these changes.
28  */
29 
30 #include <sys/cdefs.h>
31 __KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.57 2023/01/24 23:23:31 riastradh Exp $");
32 
33 #include <sys/param.h>
34 #include <sys/proc.h>
35 #include <sys/cpu.h>
36 #include <sys/systm.h>
37 #include <machine/db_machdep.h>
38 #include <machine/ctlreg.h>
39 #include <machine/vmparam.h>
40 
41 #include <ddb/db_access.h>
42 #include <ddb/db_proc.h>
43 #include <ddb/db_sym.h>
44 #include <ddb/db_interface.h>
45 #include <ddb/db_output.h>
46 
47 #ifndef _KERNEL
48 #include <stdbool.h>
49 #endif
50 
51 void db_print_window(uint64_t);
52 
53 #if 0
54 #define INKERNEL(va)	(((vaddr_t)(va)) >= USRSTACK) /* Not really true, y'know */
55 #else
56 #define INKERNEL(va)	1	/* Everything's in the kernel now. 8^) */
57 #endif
58 
59 #ifdef _KERNEL
60 #define	KLOAD(x)	probeget((paddr_t)(u_long)&(x), ASI_PRIMARY, sizeof(x))
61 #else
62 static long
kload(db_addr_t addr)63 kload(db_addr_t addr)
64 {
65 	long val;
66 
67 	db_read_bytes(addr, sizeof val, (char *)&val);
68 
69 	return val;
70 }
71 #define	KLOAD(x)	kload((db_addr_t)(u_long)&(x))
72 #endif
73 
74 void
db_stack_trace_print(db_expr_t addr,bool have_addr,db_expr_t count,const char * modif,void (* pr)(const char *,...))75 db_stack_trace_print(db_expr_t addr, bool have_addr, db_expr_t count,
76 	const char *modif, void (*pr) (const char *, ...))
77 {
78 	vaddr_t		frame;
79 	bool		kernel_only = true;
80 	bool		trace_thread = false;
81 	bool		lwpaddr = false;
82 	char		c;
83 	const char	*cp = modif;
84 
85 	while ((c = *cp++) != 0) {
86 		if (c == 'a') {
87 			lwpaddr = true;
88 			trace_thread = true;
89 		}
90 		if (c == 't')
91 			trace_thread = true;
92 		if (c == 'u')
93 			kernel_only = false;
94 	}
95 
96 	if (!have_addr) {
97 #ifndef _KERNEL
98 		extern struct pcb pcb;
99 		frame = (vaddr_t)pcb.pcb_sp;
100 #else
101 		frame = (vaddr_t)DDB_TF->tf_out[6];
102 #endif
103 	} else {
104 		if (trace_thread) {
105 			static proc_t p;
106 			static lwp_t l;
107 			struct pcb *pcb;
108 
109 			if (lwpaddr) {
110 				db_read_bytes(addr, sizeof(l), (char *)&l);
111 				db_read_bytes((db_addr_t)l.l_proc,
112 				    sizeof(p), (char *)&p);
113 
114 				(*pr)("trace: pid %d ", p.p_pid);
115 			} else {
116 				proc_t *pp;
117 				(*pr)("trace: pid %d ", (int)addr);
118 				pp = db_proc_find((pid_t)addr);
119 				if (pp == NULL) {
120 					(*pr)("not found\n");
121 					return;
122 				}
123 				db_read_bytes((db_addr_t)pp, sizeof(p),
124 				    (char *)&p);
125 				addr = (db_addr_t)p.p_lwps.lh_first;
126 				db_read_bytes(addr, sizeof(l), (char *)&l);
127 			}
128 			(*pr)("lid %d ", l.l_lid);
129 			pcb = lwp_getpcb(&l);
130 			db_read_bytes((db_addr_t)&pcb->pcb_sp,
131 			    sizeof(frame), (char *)&frame);
132 			(*pr)("at %p\n", frame);
133 		} else {
134 			frame = (vaddr_t)addr;
135 		}
136 	}
137 
138 	while (count--) {
139 		int		i;
140 		db_expr_t	offset;
141 		const char	*name;
142 		db_addr_t	pc;
143 		struct frame64	*f64;
144 		struct frame32  *f32;
145 
146 		/*
147 		 * Switch to frame that contains arguments
148 		 */
149 		if (frame & 1) {
150 			f64 = (struct frame64 *)(frame + BIAS);
151 			pc = (db_addr_t)KLOAD(f64->fr_pc);
152 
153 			frame = KLOAD(f64->fr_fp);
154 		} else {
155 			f32 = (struct frame32 *)(frame);
156 			pc = (db_addr_t)KLOAD(f32->fr_pc);
157 
158 			frame = (long)KLOAD(f32->fr_fp);
159 		}
160 
161 		if (kernel_only) {
162 			if (pc < KERNBASE || pc >= KERNEND)
163 				break;
164 			if (frame < KERNBASE || frame >= VM_MAX_KERNEL_ADDRESS)
165 				break;
166 		} else {
167 			if (frame == 0 || frame == (vaddr_t)-1)
168 				break;
169 		}
170 #if 0
171 		if (!INKERNEL(frame))
172 			break;
173 #endif
174 
175 		db_find_sym_and_offset(pc, &name, &offset);
176 		if (name == NULL)
177 			name = "?";
178 
179 		(*pr)("%s(", name);
180 
181 		/*
182 		 * Print %i0..%i5; hope these still reflect the
183 		 * actual arguments somewhat...
184 		 */
185 		if (frame & 1) {
186 			f64 = (struct frame64 *)(frame + BIAS);
187 			for (i = 0; i < 5; i++)
188 				(*pr)("%lx, ", (long)KLOAD(f64->fr_arg[i]));
189 			(*pr)("%lx) at ", (long)KLOAD(f64->fr_arg[i]));
190 		} else {
191 			f32 = (struct frame32 *)(frame);
192 			for (i = 0; i < 5; i++)
193 				(*pr)("%x, ", (u_int)KLOAD(f32->fr_arg[i]));
194 			(*pr)("%x) at ", (u_int)KLOAD(f32->fr_arg[i]));
195 		}
196 		db_printsym(pc, DB_STGY_PROC, pr);
197 		(*pr)("\n");
198 	}
199 }
200 
201 
202 #ifdef _KERNEL
203 void
db_dump_window(db_expr_t addr,bool have_addr,db_expr_t count,const char * modif)204 db_dump_window(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
205 {
206 	int i;
207 	uint64_t frame = DDB_TF->tf_out[6];
208 
209 	/* Addr is really window number */
210 	if (!have_addr)
211 		addr = 0;
212 
213 	/* Traverse window stack */
214 	for (i=0; i<addr && frame; i++) {
215 		if (frame & 1)
216 			frame = (uint64_t)((struct frame64 *)(u_long)(frame + BIAS))->fr_fp;
217 		else frame = (uint64_t)((struct frame32 *)(u_long)frame)->fr_fp;
218 	}
219 
220 	db_printf("Window %lx ", (long)addr);
221 	db_print_window(frame);
222 }
223 #endif
224 
225 void
db_print_window(uint64_t frame)226 db_print_window(uint64_t frame)
227 {
228 	if (frame & 1) {
229 		struct frame64* f = (struct frame64*)(u_long)(frame + BIAS);
230 
231 		db_printf("frame64 %p locals, ins:\n", f);
232 		if (INKERNEL(f)) {
233 			db_printf("%llx %llx %llx %llx ",
234 				  (unsigned long long)f->fr_local[0],
235 				  (unsigned long long)f->fr_local[1],
236 				  (unsigned long long)f->fr_local[2],
237 				  (unsigned long long)f->fr_local[3]);
238 			db_printf("%llx %llx %llx %llx\n",
239 				  (unsigned long long)f->fr_local[4],
240 				  (unsigned long long)f->fr_local[5],
241 				  (unsigned long long)f->fr_local[6],
242 				  (unsigned long long)f->fr_local[7]);
243 			db_printf("%llx %llx %llx %llx ",
244 				  (unsigned long long)f->fr_arg[0],
245 				  (unsigned long long)f->fr_arg[1],
246 				  (unsigned long long)f->fr_arg[2],
247 				  (unsigned long long)f->fr_arg[3]);
248 			db_printf("%llx %llx %llx=sp %llx=pc:",
249 				  (unsigned long long)f->fr_arg[4],
250 				  (unsigned long long)f->fr_arg[5],
251 				  (unsigned long long)f->fr_fp,
252 				  (unsigned long long)f->fr_pc);
253 			/* Sometimes this don't work.  Dunno why. */
254 			db_printsym(f->fr_pc, DB_STGY_PROC, db_printf);
255 			db_printf("\n");
256 		} else {
257 			struct frame64 fr;
258 
259 			if (copyin(f, &fr, sizeof(fr))) return;
260 			f = &fr;
261 			db_printf("%llx %llx %llx %llx ",
262 				  (unsigned long long)f->fr_local[0], (unsigned long long)f->fr_local[1], (unsigned long long)f->fr_local[2], (unsigned long long)f->fr_local[3]);
263 			db_printf("%llx %llx %llx %llx\n",
264 				  (unsigned long long)f->fr_local[4], (unsigned long long)f->fr_local[5], (unsigned long long)f->fr_local[6], (unsigned long long)f->fr_local[7]);
265 			db_printf("%llx %llx %llx %llx ",
266 				  (unsigned long long)f->fr_arg[0],
267 				  (unsigned long long)f->fr_arg[1],
268 				  (unsigned long long)f->fr_arg[2],
269 				  (unsigned long long)f->fr_arg[3]);
270 			db_printf("%llx %llx %llx=sp %llx=pc",
271 				  (unsigned long long)f->fr_arg[4],
272 				  (unsigned long long)f->fr_arg[5],
273 				  (unsigned long long)f->fr_fp,
274 				  (unsigned long long)f->fr_pc);
275 			db_printf("\n");
276 		}
277 	} else {
278 		struct frame32* f = (struct frame32*)(u_long)frame;
279 
280 		db_printf("frame %p locals, ins:\n", f);
281 		if (INKERNEL(f)) {
282 			db_printf("%8x %8x %8x %8x %8x %8x %8x %8x\n",
283 				  f->fr_local[0], f->fr_local[1], f->fr_local[2], f->fr_local[3],
284 				  f->fr_local[4], f->fr_local[5], f->fr_local[6], f->fr_local[7]);
285 			db_printf("%8x %8x %8x %8x %8x %8x %8x=sp %8x=pc:",
286 				  f->fr_arg[0], f->fr_arg[1], f->fr_arg[2], f->fr_arg[3],
287 				  f->fr_arg[4], f->fr_arg[5], f->fr_fp, f->fr_pc);
288 			db_printsym(f->fr_pc, DB_STGY_PROC, db_printf);
289 			db_printf("\n");
290 		} else {
291 			struct frame32 fr;
292 
293 			if (copyin(f, &fr, sizeof(fr))) return;
294 			f = &fr;
295 			db_printf("%8x %8x %8x %8x %8x %8x %8x %8x\n",
296 				  f->fr_local[0], f->fr_local[1],
297 				  f->fr_local[2], f->fr_local[3],
298 				  f->fr_local[4], f->fr_local[5],
299 				  f->fr_local[6], f->fr_local[7]);
300 			db_printf("%8x %8x %8x %8x %8x %8x %8x=sp %8x=pc\n",
301 				  f->fr_arg[0], f->fr_arg[1],
302 				  f->fr_arg[2], f->fr_arg[3],
303 				  f->fr_arg[4], f->fr_arg[5],
304 				  f->fr_fp, f->fr_pc);
305 		}
306 	}
307 }
308 
309 #ifdef _KERNEL
310 void
db_dump_stack(db_expr_t addr,bool have_addr,db_expr_t count,const char * modif)311 db_dump_stack(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
312 {
313 	int		i;
314 	uint64_t	frame, oldframe;
315 	bool		kernel_only = true;
316 	char		c;
317 	const char	*cp = modif;
318 
319 	while ((c = *cp++) != 0)
320 		if (c == 'u')
321 			kernel_only = false;
322 
323 	if (count == -1)
324 		count = 65535;
325 
326 	if (!have_addr)
327 		frame = DDB_TF->tf_out[6];
328 	else
329 		frame = addr;
330 
331 	/* Traverse window stack */
332 	oldframe = 0;
333 	for (i=0; i<count && frame; i++) {
334 		if (oldframe == frame) {
335 			db_printf("WARNING: stack loop at %llx\n",
336 			    (unsigned long long) frame);
337 			break;
338 		}
339 		oldframe = frame;
340 		if (frame & 1) {
341 			frame += BIAS;
342 			if (!INKERNEL(((struct frame64 *)(u_long)(frame)))
343 			    && kernel_only) break;
344 			db_printf("Window %x ", i);
345 			db_print_window(frame - BIAS);
346 			if (!INKERNEL(((struct frame64 *)(u_long)(frame))))
347 				copyin(((void *)&((struct frame64 *)(u_long)frame)->fr_fp), &frame, sizeof(frame));
348 			else
349 				frame = ((struct frame64 *)(u_long)frame)->fr_fp;
350 		} else {
351 			uint32_t tmp;
352 			if (!INKERNEL(((struct frame32 *)(u_long)frame))
353 			    && kernel_only) break;
354 			db_printf("Window %x ", i);
355 			db_print_window(frame);
356 			if (!INKERNEL(((struct frame32 *)(u_long)frame))) {
357 				copyin(&((struct frame32 *)(u_long)frame)->fr_fp, &tmp, sizeof(tmp));
358 				frame = (uint64_t)tmp;
359 			} else
360 				frame = (uint64_t)((struct frame32 *)(u_long)frame)->fr_fp;
361 		}
362 	}
363 
364 }
365 
366 
367 void
db_dump_trap(db_expr_t addr,bool have_addr,db_expr_t count,const char * modif)368 db_dump_trap(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
369 {
370 	struct trapframe64 *tf;
371 
372 	/* Use our last trapframe? */
373 	tf = DDB_TF;
374 	{
375 		/* Or the user trapframe? */
376 		register char c;
377 		register const char *cp = modif;
378 		while ((c = *cp++) != 0)
379 			if (c == 'u')
380 				tf = curlwp->l_md.md_tf;
381 	}
382 	/* Or an arbitrary trapframe */
383 	if (have_addr)
384 		tf = (struct trapframe64 *)(uintptr_t)addr;
385 
386 	db_printf("Trapframe %p:\ttstate: %llx\tpc: %llx\tnpc: %llx\n",
387 		  tf, (unsigned long long)tf->tf_tstate,
388 		  (unsigned long long)tf->tf_pc,
389 		  (unsigned long long)tf->tf_npc);
390 	db_printf("y: %x\tpil: %d\toldpil: %d\tfault: %llx\ttt: %x\tGlobals:\n",
391 		  (int)tf->tf_y, (int)tf->tf_pil, (int)tf->tf_oldpil,
392 		  (unsigned long long)tf->tf_fault, (int)tf->tf_tt);
393 	db_printf("%016llx %016llx %016llx %016llx\n",
394 		  (unsigned long long)tf->tf_global[0],
395 		  (unsigned long long)tf->tf_global[1],
396 		  (unsigned long long)tf->tf_global[2],
397 		  (unsigned long long)tf->tf_global[3]);
398 	db_printf("%016llx %016llx %016llx %016llx\nouts:\n",
399 		  (unsigned long long)tf->tf_global[4],
400 		  (unsigned long long)tf->tf_global[5],
401 		  (unsigned long long)tf->tf_global[6],
402 		  (unsigned long long)tf->tf_global[7]);
403 	db_printf("%016llx %016llx %016llx %016llx\n",
404 		  (unsigned long long)tf->tf_out[0],
405 		  (unsigned long long)tf->tf_out[1],
406 		  (unsigned long long)tf->tf_out[2],
407 		  (unsigned long long)tf->tf_out[3]);
408 	db_printf("%016llx %016llx %016llx %016llx\n",
409 		  (unsigned long long)tf->tf_out[4],
410 		  (unsigned long long)tf->tf_out[5],
411 		  (unsigned long long)tf->tf_out[6],
412 		  (unsigned long long)tf->tf_out[7]);
413 #ifdef DEBUG
414 	db_printf("locals:\n%016llx %016llx %016llx %016llx\n",
415 		  (unsigned long long)tf->tf_local[0],
416 		  (unsigned long long)tf->tf_local[1],
417 		  (unsigned long long)tf->tf_local[2],
418 		  (unsigned long long)tf->tf_local[3]);
419 	db_printf("%016llx %016llx %016llx %016llx\nins:\n",
420 		  (unsigned long long)tf->tf_local[4],
421 		  (unsigned long long)tf->tf_local[5],
422 		  (unsigned long long)tf->tf_local[6],
423 		  (unsigned long long)tf->tf_local[7]);
424 	db_printf("%016llx %016llx %016llx %016llx\n",
425 		  (unsigned long long)tf->tf_in[0],
426 		  (unsigned long long)tf->tf_in[1],
427 		  (unsigned long long)tf->tf_in[2],
428 		  (unsigned long long)tf->tf_in[3]);
429 	db_printf("%016llx %016llx %016llx %016llx\n",
430 		  (unsigned long long)tf->tf_in[4],
431 		  (unsigned long long)tf->tf_in[5],
432 		  (unsigned long long)tf->tf_in[6],
433 		  (unsigned long long)tf->tf_in[7]);
434 #endif
435 #if 0
436 	if (tf == curlwp->p_md.md_tf) {
437 		struct rwindow32 *kstack = (struct rwindow32 *)(((void *)tf)+CCFSZ);
438 		db_printf("ins (from stack):\n%016llx %016llx %016llx %016llx\n",
439 			  (int64_t)kstack->rw_local[0], (int64_t)kstack->rw_local[1],
440 			  (int64_t)kstack->rw_local[2], (int64_t)kstack->rw_local[3]);
441 		db_printf("%016llx %016llx %016llx %016llx\n",
442 			  (int64_t)kstack->rw_local[4], (int64_t)kstack->rw_local[5],
443 			  (int64_t)kstack->rw_local[6], (int64_t)kstack->rw_local[7]);
444 	}
445 #endif
446 }
447 
448 void
db_dump_fpstate(db_expr_t addr,bool have_addr,db_expr_t count,const char * modif)449 db_dump_fpstate(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
450 {
451 	struct fpstate64 *fpstate;
452 
453 	/* Use our last trapframe? */
454 	fpstate = DDB_FP;
455 	/* Or an arbitrary trapframe */
456 	if (have_addr)
457 		fpstate = (struct fpstate64 *)(uintptr_t)addr;
458 
459 	db_printf("fpstate %p: fsr = %llx gsr = %lx\nfpregs:\n",
460 		fpstate, (unsigned long long)fpstate->fs_fsr,
461 		(unsigned long)fpstate->fs_gsr);
462 	db_printf(" 0: %08x %08x %08x %08x %08x %08x %08x %08x\n",
463 		(unsigned int)fpstate->fs_regs[0],
464 		(unsigned int)fpstate->fs_regs[1],
465 		(unsigned int)fpstate->fs_regs[2],
466 		(unsigned int)fpstate->fs_regs[3],
467 		(unsigned int)fpstate->fs_regs[4],
468 		(unsigned int)fpstate->fs_regs[5],
469 		(unsigned int)fpstate->fs_regs[6],
470 		(unsigned int)fpstate->fs_regs[7]);
471 	db_printf(" 8: %08x %08x %08x %08x %08x %08x %08x %08x\n",
472 		(unsigned int)fpstate->fs_regs[8],
473 		(unsigned int)fpstate->fs_regs[9],
474 		(unsigned int)fpstate->fs_regs[10],
475 		(unsigned int)fpstate->fs_regs[11],
476 		(unsigned int)fpstate->fs_regs[12],
477 		(unsigned int)fpstate->fs_regs[13],
478 		(unsigned int)fpstate->fs_regs[14],
479 		(unsigned int)fpstate->fs_regs[15]);
480 	db_printf("16: %08x %08x %08x %08x %08x %08x %08x %08x\n",
481 		(unsigned int)fpstate->fs_regs[16],
482 		(unsigned int)fpstate->fs_regs[17],
483 		(unsigned int)fpstate->fs_regs[18],
484 		(unsigned int)fpstate->fs_regs[19],
485 		(unsigned int)fpstate->fs_regs[20],
486 		(unsigned int)fpstate->fs_regs[21],
487 		(unsigned int)fpstate->fs_regs[22],
488 		(unsigned int)fpstate->fs_regs[23]);
489 	db_printf("24: %08x %08x %08x %08x %08x %08x %08x %08x\n",
490 		(unsigned int)fpstate->fs_regs[24],
491 		(unsigned int)fpstate->fs_regs[25],
492 		(unsigned int)fpstate->fs_regs[26],
493 		(unsigned int)fpstate->fs_regs[27],
494 		(unsigned int)fpstate->fs_regs[28],
495 		(unsigned int)fpstate->fs_regs[29],
496 		(unsigned int)fpstate->fs_regs[30],
497 		(unsigned int)fpstate->fs_regs[31]);
498 	db_printf("32: %08x%08x %08x%08x %08x%08x %08x%08x\n",
499 		(unsigned int)fpstate->fs_regs[32],
500 		(unsigned int)fpstate->fs_regs[33],
501 		(unsigned int)fpstate->fs_regs[34],
502 		(unsigned int)fpstate->fs_regs[35],
503 		(unsigned int)fpstate->fs_regs[36],
504 		(unsigned int)fpstate->fs_regs[37],
505 		(unsigned int)fpstate->fs_regs[38],
506 		(unsigned int)fpstate->fs_regs[39]);
507 	db_printf("40: %08x%08x %08x%08x %08x%08x %08x%08x\n",
508 		(unsigned int)fpstate->fs_regs[40],
509 		(unsigned int)fpstate->fs_regs[41],
510 		(unsigned int)fpstate->fs_regs[42],
511 		(unsigned int)fpstate->fs_regs[43],
512 		(unsigned int)fpstate->fs_regs[44],
513 		(unsigned int)fpstate->fs_regs[45],
514 		(unsigned int)fpstate->fs_regs[46],
515 		(unsigned int)fpstate->fs_regs[47]);
516 	db_printf("48: %08x%08x %08x%08x %08x%08x %08x%08x\n",
517 		(unsigned int)fpstate->fs_regs[48],
518 		(unsigned int)fpstate->fs_regs[49],
519 		(unsigned int)fpstate->fs_regs[50],
520 		(unsigned int)fpstate->fs_regs[51],
521 		(unsigned int)fpstate->fs_regs[52],
522 		(unsigned int)fpstate->fs_regs[53],
523 		(unsigned int)fpstate->fs_regs[54],
524 		(unsigned int)fpstate->fs_regs[55]);
525 	db_printf("56: %08x%08x %08x%08x %08x%08x %08x%08x\n",
526 		(unsigned int)fpstate->fs_regs[56],
527 		(unsigned int)fpstate->fs_regs[57],
528 		(unsigned int)fpstate->fs_regs[58],
529 		(unsigned int)fpstate->fs_regs[59],
530 		(unsigned int)fpstate->fs_regs[60],
531 		(unsigned int)fpstate->fs_regs[61],
532 		(unsigned int)fpstate->fs_regs[62],
533 		(unsigned int)fpstate->fs_regs[63]);
534 }
535 
536 void
db_dump_ts(db_expr_t addr,bool have_addr,db_expr_t count,const char * modif)537 db_dump_ts(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
538 {
539 	struct trapstate	*ts;
540 	int			i, tl;
541 
542 	/* Use our last trapframe? */
543 	ts = &DDB_REGS->db_ts[0];
544 	tl = DDB_REGS->db_tl;
545 	for (i=0; i<tl; i++) {
546 		db_printf("%d tt=%lx tstate=%lx tpc=%p tnpc=%p\n",
547 		          i+1, (long)ts[i].tt, (u_long)ts[i].tstate,
548 		          (void*)(u_long)ts[i].tpc, (void*)(u_long)ts[i].tnpc);
549 	}
550 
551 }
552 #endif
553