int kdbgetulenv(const char *match, unsigned long *value) { char *ep; ep = kdbgetenv(match); if (!ep) return KDB_NOTENV; if (strlen(ep) == 0) return KDB_NOENVVALUE; *value = simple_strtoul(ep, 0, 0); return 0; }
void kdb_id1(unsigned long pc) { char *mode; int diag; /* * Allow the user to specify that this instruction * should be treated differently. */ kdb_di.fprintf_dummy = kdb_dis_fprintf_dummy; mode = kdbgetenv("IDMODE"); diag = kdba_id_parsemode(mode, &kdb_di); if (diag) { kdb_printf("kdb_id: bad value in 'IDMODE' environment variable ignored\n"); } (void) kdba_id_printinsn(pc, &kdb_di); kdb_printf("\n"); }
int kdb(int reason, int error, struct pt_regs *regs) { char cmdbuf[255]; char *cmd; int diag; unsigned long flags; struct pt_regs func_regs; kdb_new_cpu = -1; /* * Remove the breakpoints to prevent double-faults * if kdb happens to use a function where a breakpoint * has been enabled. */ kdb_bp_remove(); if (reason != KDB_REASON_DEBUG) { kdb_printf("Entering kdb "); #if defined(__SMP__) kdb_printf("on processor %d ", smp_processor_id()); #endif } switch (reason) { case KDB_REASON_DEBUG: /* * If re-entering kdb after a single step * command, don't print the message. */ diag = kdb_db_trap(regs); if (diag == 0) { kdb_printf("Entering kdb "); #if defined(__SMP__) kdb_printf("on processor %d ", smp_processor_id()); #endif } else if (diag == 2) { /* * in middle of ssb command. Just return. */ return 0; } break; case KDB_REASON_FAULT: break; case KDB_REASON_INT: kdb_printf("due to KDB_ENTER() call\n"); break; case KDB_REASON_KEYBOARD: kdb_printf("due to Keyboard Entry\n"); break; case KDB_REASON_SWITCH: kdb_printf("due to cpu switch\n"); break; case KDB_REASON_ENTER: kdb_printf("due to function call\n"); regs = &func_regs; regs->xcs = 0; #if defined(CONFIG_KDB_FRAMEPTR) asm volatile("movl %%ebp,%0":"=m" (*(int *)®s->ebp)); #endif asm volatile("movl %%esp,%0":"=m" (*(int *)®s->esp)); regs->eip = (long) &kdb; /* for traceback. */ break; case KDB_REASON_PANIC: kdb_printf("due to panic @ 0x%8.8x\n", regs->eip); kdbdumpregs(regs, NULL, NULL); break; case KDB_REASON_BREAK: kdb_printf("due to Breakpoint @ 0x%8.8x\n", regs->eip); break; default: break; } #if defined(__SMP__) /* * If SMP, stop other processors */ if (smp_num_cpus > 1) { /* * Stop all other processors */ smp_kdb_stop(1); } #endif /* __SMP__ */ /* * Disable interrupts during kdb command processing */ __save_flags(flags); __cli(); while (1) { /* * Initialize pager context. */ kdb_nextline = 1; /* * Use kdb_setjmp/kdb_longjmp to break out of * the pager early. */ if (kdb_setjmp(&kdbjmpbuf)) { /* * Command aborted (usually in pager) */ /* * XXX - need to abort a SSB ? */ continue; } /* * Fetch command from keyboard */ cmd = kbd_getstr(cmdbuf, sizeof(cmdbuf), kdbgetenv("PROMPT")); diag = kdb_parse(cmd, regs); if (diag == KDB_NOTFOUND) { kdb_printf("Unknown kdb command: '%s'\n", cmd); diag = 0; } if ((diag == KDB_GO) || (diag == KDB_CPUSWITCH)) break; /* Go or cpu switch command */ if (diag) kdb_cmderror(diag); } /* * Set up debug registers. */ kdb_bp_install(); #if defined(__SMP__) if ((diag == KDB_CPUSWITCH) && (kdb_new_cpu != -1)) { /* * Leaving the other CPU's at the barrier, except the * one we are switching to, we'll send ourselves a * kdb IPI before allowing interrupts so it will get * caught ASAP and get this CPU back waiting at the barrier. */ smp_kdb_stop(0); /* Stop ourself */ /* * let the new cpu go. */ clear_bit(kdb_new_cpu, &smp_kdb_wait); } else { /* * Let the other processors continue. */ smp_kdb_wait = 0; } #endif kdb_flags &= ~(KDB_FLAG_SUPRESS|KDB_FLAG_FAULT); __restore_flags(flags); return 0; }
int kdb_id(int argc, const char **argv) { kdb_machreg_t pc; int icount; int diag; int i; char *mode; int nextarg; long offset = 0; static kdb_machreg_t lastpc; struct disassemble_info *dip = &kdb_di; char lastbuf[50]; unsigned long word; kdb_di.fprintf_func = kdb_dis_fprintf; kdba_id_init(&kdb_di); if (argc != 1) { if (lastpc == 0) { return KDB_ARGCOUNT; } else { sprintf(lastbuf, "0x%lx", lastpc); argv[1] = lastbuf; argc = 1; } } /* * Fetch PC. First, check to see if it is a symbol, if not, * try address. */ nextarg = 1; diag = kdbgetaddrarg(argc, argv, &nextarg, &pc, &offset, NULL); if (diag) return diag; kdba_check_pc(&pc); if (kdb_getarea(word, pc)) return(0); /* * Number of lines to display */ diag = kdbgetintenv("IDCOUNT", &icount); if (diag) return diag; mode = kdbgetenv("IDMODE"); diag = kdba_id_parsemode(mode, dip); if (diag) { return diag; } for(i=0; i<icount; i++) { pc += kdba_id_printinsn(pc, &kdb_di); kdb_printf("\n"); } lastpc = pc; return 0; }