void gdb_send_stop_reason(uint8_t reason) { size_t rlen; uint32_t s_rip; uint64_t mode = (uint64_t)cpu_addr_sz(); if(mode == 64) { s_rip = 0x3a36313b; rlen = sizeof(uint64_t)*2; } else /* XXX: gdb seems to wait for 32 bits regs at least */ { s_rip = 0x3a38303b; rlen = sizeof(uint32_t)*2; } gdb_add_str("T", 1); gdb_add_byte(reason); gdb_add_str("md:", 3); gdb_add_number(mode, 2, 0); gdb_add_str(";04:", 4); gdb_add_number(info->vm.cpu.gpr->rsp.raw, rlen, 1); gdb_add_str(";05:", 4); gdb_add_number(info->vm.cpu.gpr->rbp.raw, rlen, 1); gdb_add_str((char*)&s_rip, 4); gdb_add_number(__rip.raw, rlen, 1); gdb_add_str(";", 1); gdb_send_packet(); }
static void gdb_vmm_get_fault(uint8_t __unused__ *data, size_t __unused__ len) { fault_ctx_t *fault = &info->vm.cpu.fault; gdb_add_number(fault->excp.err, 8, 0); gdb_add_number(fault->npf.err.raw, 16, 0); gdb_add_number(fault->npf.vaddr, 16, 0); gdb_add_number(fault->npf.paddr, 16, 0); gdb_send_packet(); }
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(); }
static void gdb_vmm_translate(uint8_t *data, size_t len) { offset_t vaddr, paddr; size_t psz, sz; if(!gdb_get_number(data, len, (uint64_t*)&vaddr, 0)) { gdb_nak(); return; } debug(GDBSTUB_CMD, "translating 0x%X\n", vaddr); if(!__paging()) paddr = vaddr; else if(!__pg_walk(info->vmm.ctrl.active_cr3, vaddr, &paddr, &psz, 1)) { debug(GDBSTUB, "memory translation failure\n"); gdb_err_mem(); return; } debug(GDBSTUB_CMD, "sending 0x%X\n", paddr); if(cpu_addr_sz() == 64) sz = sizeof(uint64_t)*2; else /* XXX: gdb seems to wait for 32 bits regs at least */ sz = sizeof(uint32_t)*2; gdb_add_number(paddr, sz, 0); gdb_send_packet(); }
static void gdb_vmm_rd_cr_wr_mask(uint8_t __unused__ *data, size_t __unused__ len) { raw64_t val; size_t rlen; rlen = sizeof(uint16_t)*2; val.wlow = info->vmm.ctrl.usr.cr_wr; gdb_add_number(val.raw, rlen, 0); gdb_send_packet(); }
static void gdb_cmd_rd_reg(uint8_t *data, size_t len) { raw64_t *reg; size_t size; if(!__gdb_setup_reg_op(data, len, ®, &size, 0, 0, 0)) return; size *= 2; /* to nibbles */ gdb_add_number(reg->raw, size, 1); gdb_send_packet(); }
static void gdb_vmm_can_cli(uint8_t __unused__ *data, size_t __unused__ len) { bool_t can; if(__interrupt_shadow || (__injecting_event() && __injected_event_type == 0)) can = 0; else can = 1; gdb_add_number(can, sizeof(uint8_t)*2, 0); gdb_send_packet(); }
static void gdb_vmm_rd_sysreg(uint8_t *data, size_t len) { raw64_t *reg; size_t size; if(!__gdb_setup_reg_op(data, len, ®, &size, 0, 0, 1)) { debug(GDBSTUB_CMD, "read sysreg failed\n"); return; } size *= 2; /* to nibbles */ gdb_add_number(reg->raw, size, 1); gdb_send_packet(); }
static void gdb_vmm_get_lbr(uint8_t __unused__ *data, size_t __unused__ len) { int i; size_t rlen; offset_t ips[4]; rlen = sizeof(uint64_t)*2; __setup_lbr(); ips[0] = __lbr_from(); ips[1] = __lbr_to(); ips[2] = __lbr_from_excp(); ips[3] = __lbr_to_excp(); for(i=0 ; i<4 ; i++) gdb_add_number(ips[i], rlen, 0); gdb_send_packet(); }
/* ** Try to get a nested pte for the given addr ** Directly try to remap VM memory with finest ** granularity to return a nested pte */ static void gdb_vmm_npg_get_pte(uint8_t *data, size_t len) { loc_t addr; npg_pte64_t *pte; if(!gdb_get_number(data, len, (uint64_t*)&addr.raw, 0)) { gdb_nak(); return; } pte = _npg_remap_finest_4K(addr.linear); if(!pte) { debug(GDBSTUB_CMD, "no npg pte for 0x%x\n", addr.raw); gdb_err_mem(); return; } npg_invlpg(addr.linear); gdb_add_number(pte->raw, sizeof(uint64_t)*2, 0); gdb_send_packet(); }
static void gdb_vmm_npg_translate(uint8_t *data, size_t len) { offset_t paddr, saddr; if(!gdb_get_number(data, len, (uint64_t*)&paddr, 0)) { gdb_nak(); return; } debug(GDBSTUB_CMD, "(nested) translating 0x%X\n", paddr); if(!npg_walk(paddr, &saddr)) { debug(GDBSTUB, "(nested) memory translation failure\n"); gdb_err_mem(); return; } debug(GDBSTUB_CMD, "sending 0x%X\n", saddr); gdb_add_number(saddr, sizeof(uint64_t)*2, 0); gdb_send_packet(); }
static void gdb_vmm_rdtsc(uint8_t __unused__ *data, size_t __unused__ len) { gdb_add_number(rdtsc(), sizeof(uint64_t)*2, 0); gdb_send_packet(); }
static void gdb_vmm_get_idt_event(uint8_t __unused__ *data, size_t __unused__ len) { gdb_add_number(__injected_event(), sizeof(uint64_t)*2, 0); gdb_send_packet(); }
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(); }