Annotation of sys/arch/hppa64/hppa64/db_interface.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: db_interface.c,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
2:
3: /*
4: * Copyright (c) 2005 Michael Shalayeff
5: * All rights reserved.
6: *
7: * Permission to use, copy, modify, and distribute this software for any
8: * purpose with or without fee is hereby granted, provided that the above
9: * copyright notice and this permission notice appear in all copies.
10: *
11: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15: * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
16: * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17: * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18: */
19:
20: #define DDB_DEBUG
21:
22: #include <sys/param.h>
23: #include <sys/systm.h>
24:
25: #include <machine/db_machdep.h>
26: #include <machine/frame.h>
27:
28: #include <ddb/db_access.h>
29: #include <ddb/db_command.h>
30: #include <ddb/db_output.h>
31: #include <ddb/db_run.h>
32: #include <ddb/db_sym.h>
33: #include <ddb/db_var.h>
34: #include <ddb/db_variables.h>
35: #include <ddb/db_extern.h>
36: #include <ddb/db_interface.h>
37:
38: #include <dev/cons.h>
39:
40: void kdbprinttrap(int, int);
41:
42: extern char *trap_type[];
43: extern int trap_types;
44:
45: db_regs_t ddb_regs;
46: struct db_variable db_regs[] = {
47: { "flags", (long *)&ddb_regs.tf_flags, FCN_NULL },
48: { "r1", (long *)&ddb_regs.tf_r1, FCN_NULL },
49: { "rp", (long *)&ddb_regs.tf_rp, FCN_NULL },
50: { "r3", (long *)&ddb_regs.tf_r3, FCN_NULL },
51: { "r4", (long *)&ddb_regs.tf_r4, FCN_NULL },
52: { "r5", (long *)&ddb_regs.tf_r5, FCN_NULL },
53: { "r6", (long *)&ddb_regs.tf_r6, FCN_NULL },
54: { "r7", (long *)&ddb_regs.tf_r7, FCN_NULL },
55: { "r8", (long *)&ddb_regs.tf_r8, FCN_NULL },
56: { "r9", (long *)&ddb_regs.tf_r9, FCN_NULL },
57: { "r10", (long *)&ddb_regs.tf_r10, FCN_NULL },
58: { "r11", (long *)&ddb_regs.tf_r11, FCN_NULL },
59: { "r12", (long *)&ddb_regs.tf_r12, FCN_NULL },
60: { "r13", (long *)&ddb_regs.tf_r13, FCN_NULL },
61: { "r14", (long *)&ddb_regs.tf_r14, FCN_NULL },
62: { "r15", (long *)&ddb_regs.tf_r15, FCN_NULL },
63: { "r16", (long *)&ddb_regs.tf_r16, FCN_NULL },
64: { "r17", (long *)&ddb_regs.tf_r17, FCN_NULL },
65: { "r18", (long *)&ddb_regs.tf_r18, FCN_NULL },
66: { "r19", (long *)&ddb_regs.tf_args[7], FCN_NULL },
67: { "r20", (long *)&ddb_regs.tf_args[6], FCN_NULL },
68: { "r21", (long *)&ddb_regs.tf_args[5], FCN_NULL },
69: { "r22", (long *)&ddb_regs.tf_args[4], FCN_NULL },
70: { "r23", (long *)&ddb_regs.tf_args[3], FCN_NULL },
71: { "r24", (long *)&ddb_regs.tf_args[2], FCN_NULL },
72: { "r25", (long *)&ddb_regs.tf_args[1], FCN_NULL },
73: { "r26", (long *)&ddb_regs.tf_args[0], FCN_NULL },
74: { "r27", (long *)&ddb_regs.tf_dp, FCN_NULL },
75: { "r28", (long *)&ddb_regs.tf_ret0, FCN_NULL },
76: { "r29", (long *)&ddb_regs.tf_ret1, FCN_NULL },
77: { "r30", (long *)&ddb_regs.tf_sp, FCN_NULL },
78: { "r31", (long *)&ddb_regs.tf_r31, FCN_NULL },
79: { "sar", (long *)&ddb_regs.tf_sar, FCN_NULL },
80:
81: { "rctr", (long *)&ddb_regs.tf_rctr, FCN_NULL },
82: { "ccr", (long *)&ddb_regs.tf_ccr, FCN_NULL },
83: { "eirr", (long *)&ddb_regs.tf_eirr, FCN_NULL },
84: { "eiem", (long *)&ddb_regs.tf_eiem, FCN_NULL },
85: { "iir", (long *)&ddb_regs.tf_iir, FCN_NULL },
86: { "isr", (long *)&ddb_regs.tf_isr, FCN_NULL },
87: { "ior", (long *)&ddb_regs.tf_ior, FCN_NULL },
88: { "ipsw", (long *)&ddb_regs.tf_ipsw, FCN_NULL },
89: { "iisqh", (long *)&ddb_regs.tf_iisq[0], FCN_NULL },
90: { "iioqh", (long *)&ddb_regs.tf_iioq[0], FCN_NULL },
91: { "iisqt", (long *)&ddb_regs.tf_iisq[1], FCN_NULL },
92: { "iioqt", (long *)&ddb_regs.tf_iioq[1], FCN_NULL },
93: { "ci", (long *)&ddb_regs.tf_ci, FCN_NULL },
94: { "vtop", (long *)&ddb_regs.tf_vtop, FCN_NULL },
95: { "cr27", (long *)&ddb_regs.tf_cr27, FCN_NULL },
96: { "cr30", (long *)&ddb_regs.tf_cr30, FCN_NULL },
97:
98: { "sr0", (long *)&ddb_regs.tf_sr0, FCN_NULL },
99: { "sr1", (long *)&ddb_regs.tf_sr1, FCN_NULL },
100: { "sr2", (long *)&ddb_regs.tf_sr2, FCN_NULL },
101: { "sr3", (long *)&ddb_regs.tf_sr3, FCN_NULL },
102: { "sr4", (long *)&ddb_regs.tf_sr4, FCN_NULL },
103: { "sr5", (long *)&ddb_regs.tf_sr5, FCN_NULL },
104: { "sr6", (long *)&ddb_regs.tf_sr6, FCN_NULL },
105: { "sr7", (long *)&ddb_regs.tf_sr7, FCN_NULL },
106:
107: { "pidr1", (long *)&ddb_regs.tf_pidr1, FCN_NULL },
108: { "pidr2", (long *)&ddb_regs.tf_pidr2, FCN_NULL },
109: };
110: struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
111: int db_active = 0;
112:
113: void
114: Debugger()
115: {
116: __asm __volatile ("break %0, %1"
117: :: "i" (HPPA_BREAK_KERNEL), "i" (HPPA_BREAK_KGDB));
118: }
119:
120: void
121: db_read_bytes(addr, size, data)
122: vaddr_t addr;
123: size_t size;
124: char *data;
125: {
126: register char *src = (char *)addr;
127:
128: while (size--)
129: *data++ = *src++;
130: }
131:
132: void
133: db_write_bytes(addr, size, data)
134: vaddr_t addr;
135: size_t size;
136: char *data;
137: {
138: register char *dst = (char *)addr;
139:
140: while (size--)
141: *dst++ = *data++;
142:
143: /* unfortunately ddb does not provide any hooks for these */
144: ficache(HPPA_SID_KERNEL, (vaddr_t)data, size);
145: fdcache(HPPA_SID_KERNEL, (vaddr_t)data, size);
146: }
147:
148:
149: /*
150: * Print trap reason.
151: */
152: void
153: kdbprinttrap(type, code)
154: int type, code;
155: {
156: type &= ~T_USER; /* just in case */
157: db_printf("kernel: ");
158: if (type >= trap_types || type < 0)
159: db_printf("type 0x%x", type);
160: else
161: db_printf("%s", trap_type[type]);
162: db_printf(" trap, code=0x%x\n", code);
163: }
164:
165: /*
166: * kdb_trap - field a BPT trap
167: */
168: int
169: kdb_trap(type, code, regs)
170: int type, code;
171: db_regs_t *regs;
172: {
173: extern label_t *db_recover;
174: int s;
175:
176: switch (type) {
177: case T_IBREAK:
178: case T_DBREAK:
179: case -1:
180: break;
181: default:
182: if (!db_panic)
183: return (0);
184:
185: kdbprinttrap(type, code);
186: if (db_recover != 0) {
187: db_error("Caught exception in DDB; continuing...\n");
188: /* NOT REACHED */
189: }
190: }
191:
192: /* XXX Should switch to kdb`s own stack here. */
193:
194: s = splhigh();
195: bcopy(regs, &ddb_regs, sizeof(ddb_regs));
196: db_active++;
197: cnpollc(TRUE);
198: db_trap(type, code);
199: cnpollc(FALSE);
200: db_active--;
201: bcopy(&ddb_regs, regs, sizeof(*regs));
202: splx(s);
203:
204: return (1);
205: }
206:
207: /*
208: * Validate an address for use as a breakpoint.
209: * Any address is allowed for now.
210: */
211: int
212: db_valid_breakpoint(addr)
213: db_addr_t addr;
214: {
215: return (1);
216: }
217:
218: void
219: db_stack_trace_print(addr, have_addr, count, modif, pr)
220: db_expr_t addr;
221: int have_addr;
222: db_expr_t count;
223: char *modif;
224: int (*pr)(const char *, ...);
225: {
226: register_t *fp, pc, rp, *argp;
227: db_sym_t sym;
228: db_expr_t off;
229: char *name;
230: char **argnp, *argnames[8];
231: int nargs;
232:
233: if (count < 0)
234: count = 65536;
235:
236: if (!have_addr) {
237: fp = (register_t *)ddb_regs.tf_r3;
238: pc = ddb_regs.tf_iioq[0];
239: rp = ddb_regs.tf_rp;
240: } else {
241: fp = (register_t *)addr;
242: pc = 0;
243: rp = ((register_t *)fp)[-5];
244: }
245:
246: #ifdef DDB_DEBUG
247: (*pr) (">> %p, 0x%lx, 0x%lx\t", fp, pc, rp);
248: #endif
249: while (fp && count--) {
250:
251: if (USERMODE(pc))
252: return;
253:
254: sym = db_search_symbol(pc, DB_STGY_ANY, &off);
255: db_symbol_values (sym, &name, NULL);
256:
257: (*pr)("%s(", name);
258:
259: /* args */
260: nargs = 8;
261: argnp = NULL;
262: if (db_sym_numargs(sym, &nargs, argnames))
263: argnp = argnames;
264: else
265: nargs = 4;
266: /*
267: * XXX first eight args are passed on registers, and may not
268: * be stored on stack, dunno how to recover their values yet
269: */
270: for (argp = &fp[-9]; nargs--; argp--) {
271: if (argnp)
272: (*pr)("%s=", *argnp++);
273: (*pr)("%x%s", db_get_value((long)argp, 8, FALSE),
274: nargs? ",":"");
275: }
276: (*pr)(") at ");
277: db_printsym(pc, DB_STGY_PROC, pr);
278: (*pr)("\n");
279:
280: /* TODO: print locals */
281:
282: /* next frame */
283: pc = rp;
284: rp = fp[-2];
285:
286: /* if a terminal frame and not a start of a page
287: * then skip the trapframe and the terminal frame */
288: if (!fp[0]) {
289: struct trapframe *tf;
290:
291: tf = (struct trapframe *)((char *)fp - sizeof(*tf));
292:
293: if (tf->tf_flags & TFF_SYS)
294: (*pr)("-- syscall #%d(%lx, %lx, %lx, %lx, ...)\n",
295: tf->tf_r1, tf->tf_args[0], tf->tf_args[1],
296: tf->tf_args[2], tf->tf_args[3],
297: tf->tf_args[4], tf->tf_args[5],
298: tf->tf_args[6], tf->tf_args[7]);
299: else
300: (*pr)("-- trap #%d%s\n", tf->tf_flags & 0x3f,
301: (tf->tf_flags & T_USER)? " from user" : "");
302:
303: if (!(tf->tf_flags & TFF_LAST)) {
304: fp = (register_t *)tf->tf_r3;
305: pc = tf->tf_iioq[0];
306: rp = tf->tf_rp;
307: } else
308: fp = 0;
309: } else
310: fp = (register_t *)fp[0];
311: #ifdef DDB_DEBUG
312: (*pr) (">> %p, 0x%lx, 0x%lx\t", fp, pc, rp);
313: #endif
314: }
315:
316: if (count && pc) {
317: db_printsym(pc, DB_STGY_XTRN, pr);
318: (*pr)(":\n");
319: }
320: }
CVSweb