static void kdb_printbp(kdb_bp_t *bp, int i) { if (bp->bp_forcehw) { kdb_printf("Forced "); } if (!bp->bp_template.bph_free) { kdb_printf("%s ", kdba_bptype(&bp->bp_template)); } else { kdb_printf("Instruction(i) "); } kdb_printf("BP #%d at ", i); kdb_symbol_print(bp->bp_addr, NULL, KDB_SP_DEFAULT); if (bp->bp_enabled) { kdba_printbp(bp); if (bp->bp_global) kdb_printf(" globally"); else kdb_printf(" on cpu %d", bp->bp_cpu); if (bp->bp_adjust) kdb_printf(" adjust %d", bp->bp_adjust); } else { kdb_printf("\n is disabled"); } kdb_printf("\taddr at %016lx, hardtype=%d, forcehw=%d, installed=%d, hard=%p\n", bp->bp_addr, bp->bp_hardtype, bp->bp_forcehw, bp->bp_installed, bp->bp_hard); kdb_printf("\n"); }
static void kdb_printbp(kdb_bp_t *bp, int i) { kdb_printf("%s ", kdb_bptype(bp)); kdb_printf("BP #%d at ", i); kdb_symbol_print(bp->bp_addr, NULL, KDB_SP_DEFAULT); if (bp->bp_enabled) kdb_printf("\n is enabled "); else kdb_printf("\n is disabled"); kdb_printf(" addr at %016lx, hardtype=%d installed=%d\n", bp->bp_addr, bp->bp_type, bp->bp_installed); kdb_printf("\n"); }
kdb_dbtrap_t kdba_db_trap(struct pt_regs *regs, int error_unused) { kdb_machreg_t dr6; kdb_machreg_t dr7; int rw, reg; int i; kdb_dbtrap_t rv = KDB_DB_BPT; kdb_bp_t *bp; if (KDB_NULL_REGS(regs)) return KDB_DB_NOBPT; dr6 = kdba_getdr6(); dr7 = kdba_getdr7(); if (KDB_DEBUG(BP)) kdb_printf("kdb: dr6 0x%lx dr7 0x%lx\n", dr6, dr7); if (dr6 & DR6_BS) { if (KDB_STATE(SSBPT)) { if (KDB_DEBUG(BP)) kdb_printf("ssbpt\n"); KDB_STATE_CLEAR(SSBPT); for(i=0,bp=kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) { if (KDB_DEBUG(BP)) kdb_printf("bp 0x%p enabled %d delayed %d global %d cpu %d\n", bp, bp->bp_enabled, bp->bp_delayed, bp->bp_global, bp->bp_cpu); if (!bp->bp_enabled) continue; if (!bp->bp_global && bp->bp_cpu != smp_processor_id()) continue; if (KDB_DEBUG(BP)) kdb_printf("bp for this cpu\n"); if (bp->bp_delayed) { bp->bp_delayed = 0; if (KDB_DEBUG(BP)) kdb_printf("kdba_installbp\n"); kdba_installbp(regs, bp); if (!KDB_STATE(DOING_SS)) { regs->eflags &= ~EF_TF; return(KDB_DB_SSBPT); } break; } } if (i == KDB_MAXBPT) { kdb_printf("kdb: Unable to find delayed breakpoint\n"); } if (!KDB_STATE(DOING_SS)) { regs->eflags &= ~EF_TF; return(KDB_DB_NOBPT); } /* FALLTHROUGH */ } /* * KDB_STATE_DOING_SS is set when the kernel debugger is using * the processor trap flag to single-step a processor. If a * single step trap occurs and this flag is clear, the SS trap * will be ignored by KDB and the kernel will be allowed to deal * with it as necessary (e.g. for ptrace). */ if (!KDB_STATE(DOING_SS)) goto unknown; /* single step */ rv = KDB_DB_SS; /* Indicate single step */ if (KDB_STATE(DOING_SSB)) { unsigned char instruction[2]; kdb_id1(regs->rip); if (kdb_getarea(instruction, regs->rip) || (instruction[0]&0xf0) == 0xe0 || /* short disp jumps */ (instruction[0]&0xf0) == 0x70 || /* Misc. jumps */ instruction[0] == 0xc2 || /* ret */ instruction[0] == 0x9a || /* call */ (instruction[0]&0xf8) == 0xc8 || /* enter, leave, iret, int, */ ((instruction[0] == 0x0f) && ((instruction[1]&0xf0)== 0x80)) ) { /* * End the ssb command here. */ KDB_STATE_CLEAR(DOING_SSB); KDB_STATE_CLEAR(DOING_SS); } else { rv = KDB_DB_SSB; /* Indicate ssb - dismiss immediately */ } } else { /* * Print current insn */ kdb_printf("SS trap at "); kdb_symbol_print(regs->rip, NULL, KDB_SP_DEFAULT|KDB_SP_NEWLINE); kdb_id1(regs->rip); KDB_STATE_CLEAR(DOING_SS); } if (rv != KDB_DB_SSB) regs->eflags &= ~EF_TF; } if (dr6 & DR6_B0) { rw = DR7_RW0(dr7); reg = 0; goto handle; } if (dr6 & DR6_B1) { rw = DR7_RW1(dr7); reg = 1; goto handle; } if (dr6 & DR6_B2) { rw = DR7_RW2(dr7); reg = 2; goto handle; } if (dr6 & DR6_B3) { rw = DR7_RW3(dr7); reg = 3; goto handle; } if (rv > 0) goto handled; goto unknown; /* dismiss */ handle: /* * Set Resume Flag */ regs->eflags |= EF_RF; /* * Determine which breakpoint was encountered. */ for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) { if (!(bp->bp_free) && (bp->bp_global || bp->bp_cpu == smp_processor_id()) && (bp->bp_hard) && (bp->bp_hard->bph_reg == reg)) { /* * Hit this breakpoint. */ kdb_printf("%s breakpoint #%d at " kdb_bfd_vma_fmt "\n", kdba_rwtypes[rw], i, bp->bp_addr); /* * For an instruction breakpoint, disassemble * the current instruction. */ if (rw == 0) { kdb_id1(regs->rip); } goto handled; } } unknown: regs->eflags |= EF_RF; /* Supress further faults */ rv = KDB_DB_NOBPT; /* Cause kdb() to return */ handled: /* * Clear the pending exceptions. */ kdba_putdr6(0); return rv; }