static void gdb_vmm_npg_set_pte(uint8_t *data, size_t len) { uint64_t args[2]; loc_t addr; npg_pte64_t npte, *opte; if(!__gdb_vmm_parse_args(data, len, args, 2)) { gdb_nak(); return; } addr.raw = args[0]; opte = _npg_get_pte(addr.linear); if(!opte) { debug(GDBSTUB_CMD, "no npg pte for 0x%x\n", addr.raw); gdb_err_mem(); return; } npte.raw = args[1]; opte->raw = npte.raw; npg_invlpg(addr.linear); gdb_ok(); }
static void gdb_cmd_rm_brk(uint8_t *data, size_t len) { uint64_t type; size_t size; offset_t addr; int rc; if(!__gdb_setup_brk_op(data, len, &type, &size, &addr)) return; switch(type) { case GDB_BRK_TYPE_MEM: rc = dbg_soft_del(addr); break; case GDB_BRK_TYPE_HRD_X: case GDB_BRK_TYPE_HRD_W: case GDB_BRK_TYPE_HRD_RW: rc = dbg_hard_brk_del(addr, type-1, size-1); break; default: gdb_unsupported(); return; } if(rc == DBG_BRK_OK) { gdb_ok(); return; } gdb_err_mem(); }
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_rw_pmem(offset_t addr, size_t sz, uint8_t wr) { vm_access_t access; access.addr = addr; access.len = sz; access.wr = wr; if(!__vm_remote_access_pmem(&access)) { debug(GDBSTUB, "memory access failure\n"); gdb_err_mem(); } }
static void gdb_vmm_wr_vmem(uint8_t *data, size_t len) { loc_t addr; size_t sz; if(!__gdb_vmm_mem_rw_parse(data, len, &addr, &sz)) return; debug(GDBSTUB_CMD, "writing virtual memory @ 0x%X sz %d\n", addr.linear, sz); if(!gdb_mem_recv(addr.linear, sz)) { debug(GDBSTUB, "memory access failure\n"); gdb_err_mem(); return; } }
static void gdb_cmd_wr_mem(uint8_t *data, size_t len) { offset_t addr; loc_t bytes; size_t size, lbytes, can, i; uint8_t store[128]; if(!__gdb_setup_mem_op(data, len, &addr, &size, &bytes)) return; debug(GDBSTUB_CMD, "write mem: addr 0x%X size %D\n", addr, size); lbytes = (size_t)data + len - bytes.linear; if(lbytes/2 != size) { debug(GDBSTUB_CMD, "gdb cmd_wr_mem missing bytes\n"); gdb_unsupported(); } while(size) { can = min(size, sizeof(store)); for(i=0 ; i<can ; i++, bytes.u16++) { if(!__hex_to_uint8(bytes.u8, &store[i])) { debug(GDBSTUB_CMD, "gdb cmd_wr_mem invalid byte\n"); gdb_unsupported(); } } if(!gdb_mem_write(addr, store, can)) { debug(GDBSTUB_CMD, "access failure\n"); gdb_err_mem(); return; } addr += can; size -= can; } gdb_ok(); }
/* ** 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_cmd_rd_mem(uint8_t *data, size_t len) { offset_t addr; size_t size, need, i; uint8_t store[128]; if(!__gdb_setup_mem_op(data, len, &addr, &size, 0)) return; debug(GDBSTUB_CMD, "read mem: addr 0x%X size %D\n", addr, size); if(size > ((GDB_ANSWER_SZ - GDB_ACKPKT_SZ)/2)) { debug(GDBSTUB_CMD, "gdb buffer too small for cmd_rd_mem\n"); gdb_unsupported(); } while(size) { need = min(size, sizeof(store)); if(!gdb_mem_read(addr, store, need)) { debug(GDBSTUB_CMD, "access failure\n"); gdb_err_mem(); return; } for(i=0 ; i<need ; i++) gdb_add_byte(store[i]); addr += need; size -= need; } 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(); }