static void gdb_cmd_rd_gpr() { size_t flen, vlen, ngpr, i; if(cpu_addr_sz() == 64) { ngpr = 16; vlen = sizeof(uint64_t)*2; } else /* XXX: gdb seems to wait for 32 bits regs at least */ { ngpr = 8; vlen = sizeof(uint32_t)*2; } flen = sizeof(uint32_t)*2; /* [r/e]ax - [r/e]di */ for(i=GPR64_RAX ; i >= ((GPR64_RAX+1)-ngpr) ; i--) gdb_add_number(info->vm.cpu.gpr->raw[i].raw, vlen, 1); /* [r/e]ip */ gdb_add_number(__rip.raw, vlen, 1); /* fixed length eflags, cs, ss, ds, es, fs, gs */ gdb_add_number(__rflags.raw, flen, 1); gdb_add_number(__cs.selector.raw, flen, 1); __pre_access(__ss.selector); gdb_add_number(__ss.selector.raw, flen, 1); __pre_access(__ds.selector); gdb_add_number(__ds.selector.raw, flen, 1); __pre_access(__es.selector); gdb_add_number(__es.selector.raw, flen, 1); __pre_access(__fs.selector); gdb_add_number(__fs.selector.raw, flen, 1); __pre_access(__gs.selector); gdb_add_number(__gs.selector.raw, flen, 1); gdb_send_packet(); }
int dbg_evt_hard() { ctrl_evt_hdl_t hdlr; uint8_t type; int rc; __pre_access(__dr6); if(__dr6.bs) { type = CTRL_EVT_TYPE_SSTEP; hdlr = 0; rc = dbg_hard_stp_event(); } else { type = CTRL_EVT_TYPE_BRK; rc = dbg_hard_brk_event(&hdlr); } if(rc == CTRL_EVT_DONE) { arg_t arg; arg.addr = &info->vmm.ctrl.dbg.evt; ctrl_evt_setup(type, hdlr, arg); } debug(DBG_EVT, "dbg_evt %d rc = %d\n", type, rc); return rc; }
static int emulate_sysexit() { seg_sel_t cs; __pre_access(__sysenter_cs); cs.raw = __sysenter_cs.wlow; if(__cpl || !__cr0.pe || !cs.index) { debug(EMU_INSN, "sysexit fault: cpl %d cr0.pe %d cs.index %d\n" , __cpl, __cr0.pe, cs.index); __inject_exception(GP_EXCP, 0, 0); return VM_FAULT; } __cs.selector.raw = __sysenter_cs.wlow + 16; __cs.selector.rpl = 3; __cs.base.raw = 0ULL; __cs.limit.raw = 0xffffffff; __cs.attributes.g = 1; __cs.attributes.s = 1; __cs.attributes.type = SEG_DESC_CODE_XRA; __cs.attributes.d = 1; __cs.attributes.dpl = 3; __cs.attributes.p = 1; __cpl = 3; __ss.selector.raw = __sysenter_cs.wlow + 24; __ss.selector.rpl = 3; __ss.base.raw = 0ULL; __ss.limit.raw = 0xffffffff; __ss.attributes.g = 1; __ss.attributes.s = 1; __ss.attributes.type = SEG_DESC_DATA_RWA; __ss.attributes.d = 1; __ss.attributes.dpl = 3; __ss.attributes.p = 1; info->vm.cpu.gpr->rsp.low = info->vm.cpu.gpr->rcx.low; __rip.low = info->vm.cpu.gpr->rdx.low; __post_access(__rip); __post_access(__cs.selector); __post_access(__cs.base); __post_access(__cs.limit); __post_access(__cs.attributes); __post_access(__ss.selector); __post_access(__ss.base); __post_access(__ss.limit); __post_access(__ss.attributes); return VM_DONE_LET_RIP; }
static uint16_t emulate_rmode_pop() { loc_t stack; __pre_access(__ss.base); stack.linear = __ss.base.low + info->vm.cpu.gpr->rsp.wlow; info->vm.cpu.gpr->rsp.wlow += sizeof(uint16_t); return *stack.u16; }
static void emulate_rmode_push(uint16_t value) { loc_t stack; __pre_access(__ss.base); info->vm.cpu.gpr->rsp.wlow -= sizeof(uint16_t); stack.linear = __ss.base.low + info->vm.cpu.gpr->rsp.wlow; *stack.u16 = value; }
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(); }
static void dbg_hard_stp_save_context() { __hstp_ctx.cr3.raw = __cr3.raw; __pre_access(__sysenter_cs); __hstp_ctx.sysenter_cs.raw = __sysenter_cs.raw; }
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(); }