Annotation of sys/arch/hppa64/hppa64/db_interface.c, Revision 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