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