static void gdb_vmm_rd_all_sysregs(uint8_t __unused__ *data, size_t __unused__ len) { size_t rlen = sizeof(uint64_t)*2; gdb_add_number(__cr0.raw, rlen, 1); __pre_access(__cr2); gdb_add_number(__cr2.raw, rlen, 1); gdb_add_number(__cr3.raw, rlen, 1); __pre_access(__cr4); gdb_add_number(__cr4.raw, rlen, 1); gdb_add_number(get_dr0(), rlen, 1); gdb_add_number(get_dr1(), rlen, 1); gdb_add_number(get_dr2(), rlen, 1); gdb_add_number(get_dr3(), rlen, 1); __pre_access(__dr6); gdb_add_number(__dr6.raw, rlen, 1); __pre_access(__dr7); gdb_add_number(__dr7.raw, rlen, 1); __pre_access(__dbgctl); gdb_add_number(__dbgctl.raw, rlen, 1); gdb_add_number(__efer.raw, rlen, 1); gdb_add_number(__cs.base.raw, rlen, 1); gdb_add_number(__ss.base.raw, rlen, 1); __pre_access(__ds.base); gdb_add_number(__ds.base.raw, rlen, 1); __pre_access(__es.base); gdb_add_number(__es.base.raw, rlen, 1); __pre_access(__fs.base); gdb_add_number(__fs.base.raw, rlen, 1); __pre_access(__gs.base); gdb_add_number(__gs.base.raw, rlen, 1); __pre_access(__gdtr.base); gdb_add_number(__gdtr.base.raw, rlen, 1); __pre_access(__idtr.base); gdb_add_number(__idtr.base.raw, rlen, 1); __pre_access(__ldtr.base); gdb_add_number(__ldtr.base.raw, rlen, 1); __pre_access(__tr.base); gdb_add_number(__tr.base.raw, rlen, 1); gdb_send_packet(); }
static void dbg_hard_protect_dr() { debug(DBG_HARD_BRK, "hard protect dr\n"); /* ** XXX: protect DEBUG_CTL_MSR ** vmx: load/save dbgctl + msr intercept ** svm: virt lbr stores dbgctl into vmcb ** else deny rw msr IA32_DEBUG_CTL_MSR */ __pre_access(__dr6); __pre_access(__dr7); __deny_dr_access(); info->vm.dr_shadow[0].raw = get_dr0(); info->vm.dr_shadow[1].raw = get_dr1(); info->vm.dr_shadow[2].raw = get_dr2(); info->vm.dr_shadow[3].raw = get_dr3(); info->vm.dr_shadow[4].low = __dr6.low; info->vm.dr_shadow[5].low = __dr7.low; dbg_hard_dr6_clean(); dbg_hard_brk_dr7_clean(); }
boolean_t kdb_trap( int type, int code, struct i386_saved_state *regs) { spl_t s; s = splhigh(); saved_ipl[cpu_number()] = s; switch (type) { case T_DEBUG: /* single_step */ { int addr; int status = get_dr6(); if (status & 0xf) { /* hmm hdw break */ addr = status & 0x8 ? get_dr3() : status & 0x4 ? get_dr2() : status & 0x2 ? get_dr1() : get_dr0(); regs->efl |= EFL_RF; db_single_step_cmd(addr, 0, 1, "p"); } } case T_INT3: /* breakpoint */ case T_WATCHPOINT: /* watchpoint */ case -1: /* keyboard interrupt */ break; default: if (db_recover) { i386_nested_saved_state = *regs; db_printf("Caught %s (%d), code = %x, pc = %x\n", trap_name(type), type, code, regs->eip); db_error(""); /*NOTREACHED*/ } kdbprinttrap(type, code); } #if NCPUS > 1 if (db_enter()) #endif /* NCPUS > 1 */ { i386_last_saved_statep = regs; i386_last_kdb_sp = (unsigned) &type; /* XXX Should switch to ddb`s own stack here. */ ddb_regs = *regs; if ((regs->cs & 0x3) == KERNEL_RING) { /* * Kernel mode - esp and ss not saved */ ddb_regs.uesp = (int)®s->uesp; /* kernel stack pointer */ ddb_regs.ss = KERNEL_DS; } cnpollc(TRUE); db_task_trap(type, code, (regs->cs & 0x3) != 0); cnpollc(FALSE); regs->eip = ddb_regs.eip; regs->efl = ddb_regs.efl; regs->eax = ddb_regs.eax; regs->ecx = ddb_regs.ecx; regs->edx = ddb_regs.edx; regs->ebx = ddb_regs.ebx; if ((regs->cs & 0x3) != KERNEL_RING) { /* * user mode - saved esp and ss valid */ regs->uesp = ddb_regs.uesp; /* user stack pointer */ regs->ss = ddb_regs.ss & 0xffff; /* user stack segment */ } regs->ebp = ddb_regs.ebp; regs->esi = ddb_regs.esi; regs->edi = ddb_regs.edi; regs->es = ddb_regs.es & 0xffff; regs->cs = ddb_regs.cs & 0xffff; regs->ds = ddb_regs.ds & 0xffff; regs->fs = ddb_regs.fs & 0xffff; regs->gs = ddb_regs.gs & 0xffff; if ((type == T_INT3) && (db_get_task_value(regs->eip, BKPT_SIZE, FALSE, TASK_NULL) == BKPT_INST)) regs->eip += BKPT_SIZE; } #if NCPUS > 1 db_leave(); #endif /* NCPUS > 1 */ splx(s); return 1; }
int __gdb_setup_reg(uint64_t idx, raw64_t **reg, size_t *size, uint8_t sys, uint8_t #ifdef CONFIG_ARCH_AMD __unused__ #endif wr) { loc_t loc; offset_t *cache; if(sys) { debug(GDBSTUB_PKT, "reg_sys_op\n"); *size = sizeof(uint64_t); if(idx >= 22) goto __fail; cache = (offset_t*)info->vm.cpu.insn_cache; goto __sys; } if(cpu_addr_sz() == 64) { *size = sizeof(uint64_t); if(idx < 16) goto __gpr; else if(idx < 24) idx -= 8; else goto __fail; } else { /* XXX: gdb seems to wait for 32 bits regs at least */ *size = sizeof(uint32_t); if(idx < 8) goto __gpr; else if(idx >= 16) goto __fail; } switch(idx) { case 8: loc.u64 = &__rip.raw; __cond_access(wr,__rip); goto __win; case 9: loc.u64 = &__rflags.raw; __cond_access(wr,__rflags); goto __win; case 10: loc.u16 = &__cs.selector.raw;__cond_access(wr,__cs.selector); goto __win16; case 11: loc.u16 = &__ss.selector.raw;__cond_access(wr,__ss.selector); goto __win16; case 12: loc.u16 = &__ds.selector.raw;__cond_access(wr,__ds.selector); goto __win16; case 13: loc.u16 = &__es.selector.raw;__cond_access(wr,__es.selector); goto __win16; case 14: loc.u16 = &__fs.selector.raw;__cond_access(wr,__fs.selector); goto __win16; case 15: loc.u16 = &__gs.selector.raw;__cond_access(wr,__gs.selector); goto __win16; } __sys: switch(idx) { case 0: loc.u64 = &__cr0.raw; __cond_access(wr,__cr0); goto __win; case 1: loc.u64 = &__cr2.raw; __cond_access(wr,__cr2); goto __win; case 2: loc.u64 = &__cr3.raw; __cond_access(wr,__cr3); goto __win; case 3: loc.u64 = &__cr4.raw; __cond_access(wr,__cr4); goto __win; case 4: *cache = get_dr0(); loc.addr = (void*)cache; goto __win; case 5: *cache = get_dr1(); loc.addr = (void*)cache; goto __win; case 6: *cache = get_dr2(); loc.addr = (void*)cache; goto __win; case 7: *cache = get_dr3(); loc.addr = (void*)cache; goto __win; case 8: loc.u64 = &__dr6.raw; __cond_access(wr,__dr6); goto __win; case 9: loc.u64 = &__dr7.raw; __cond_access(wr,__dr7); goto __win; case 10: loc.u64 = &__dbgctl.raw; __cond_access(wr,__dbgctl); goto __win; case 11: loc.u64 = &__efer.raw; /*__cond_access(wr,__efer);*/ goto __win; case 12: loc.u64 = &__cs.base.raw; __cond_access(wr,__cs.base); goto __win; case 13: loc.u64 = &__ss.base.raw; __cond_access(wr,__ss.base); goto __win; case 14: loc.u64 = &__ds.base.raw; __cond_access(wr,__ds.base); goto __win; case 15: loc.u64 = &__es.base.raw; __cond_access(wr,__es.base); goto __win; case 16: loc.u64 = &__fs.base.raw; __cond_access(wr,__fs.base); goto __win; case 17: loc.u64 = &__gs.base.raw; __cond_access(wr,__gs.base); goto __win; case 18: loc.u64 = &__gdtr.base.raw; __cond_access(wr,__gdtr.base); goto __win; case 19: loc.u64 = &__idtr.base.raw; __cond_access(wr,__idtr.base); goto __win; case 20: loc.u64 = &__ldtr.base.raw; __cond_access(wr,__ldtr.base); goto __win; case 21: loc.u64 = &__tr.base.raw; __cond_access(wr,__tr.base); goto __win; } __gpr: loc.u64 = &info->vm.cpu.gpr->raw[GPR64_RAX - idx].raw; goto __win; __win16: *size = sizeof(uint16_t); __win: debug(GDBSTUB_PKT, "reg_op win on %d\n", idx); *reg = (raw64_t*)loc.u64; return 1; __fail: debug(GDBSTUB_PKT, "reg_op failed on %d\n", idx); gdb_unsupported(); return 0; }