Lines Matching +full:gpa +full:- +full:0

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2017-2018 John H. Baldwin <jhb@FreeBSD.org>
85 #define GDB_BP_INSTR (uint8_t []){0xcc}
90 #define GDB_BP_INSTR (uint8_t []){0x00, 0x00, 0x20, 0xd4}
109 static int xml_dfd = -1;
126 uint64_t gpa; member
159 static int cur_fd = -1;
268 if (caph_limit_stream(fileno(logfile), CAPH_WRITE) == -1) { in debug()
298 if (vm_get_register_set(vcpu, nitems(regset), regset, regs) == -1) in guest_paging_info()
299 return (-1); in guest_paging_info()
302 * For the debugger, always pretend to be the kernel (CPL 0), in guest_paging_info()
303 * and if long-mode is enabled, always parse addresses as if in guest_paging_info()
304 * in 64-bit mode. in guest_paging_info()
306 paging->cr3 = regs[1]; in guest_paging_info()
307 paging->cpl = 0; in guest_paging_info()
309 paging->cpu_mode = CPU_MODE_64BIT; in guest_paging_info()
310 else if (regs[0] & CR0_PE) in guest_paging_info()
311 paging->cpu_mode = CPU_MODE_PROTECTED; in guest_paging_info()
313 paging->cpu_mode = CPU_MODE_REAL; in guest_paging_info()
314 if (!(regs[0] & CR0_PG)) in guest_paging_info()
315 paging->paging_mode = PAGING_MODE_FLAT; in guest_paging_info()
317 paging->paging_mode = PAGING_MODE_32; in guest_paging_info()
319 paging->paging_mode = (regs[2] & CR4_LA57) ? in guest_paging_info()
322 paging->paging_mode = PAGING_MODE_PAE; in guest_paging_info()
323 return (0); in guest_paging_info()
335 if (vm_get_register_set(vcpu, nitems(regset), regset, regs) == -1) in guest_paging_info()
336 return (-1); in guest_paging_info()
338 memset(paging, 0, sizeof(*paging)); in guest_paging_info()
339 paging->ttbr0_addr = regs[0] & ~(TTBR_ASID_MASK | TTBR_CnP); in guest_paging_info()
340 paging->ttbr1_addr = regs[1] & ~(TTBR_ASID_MASK | TTBR_CnP); in guest_paging_info()
341 paging->tcr_el1 = regs[2]; in guest_paging_info()
342 paging->tcr2_el1 = regs[3]; in guest_paging_info()
343 paging->flags = regs[5] & (PSR_M_MASK | PSR_M_32); in guest_paging_info()
344 if ((regs[4] & SCTLR_M) != 0) in guest_paging_info()
345 paging->flags |= VM_GP_MMU_ENABLED; in guest_paging_info()
347 return (0); in guest_paging_info()
354 * not valid, return 0. If an error occurs obtaining the mapping,
355 * return -1.
363 if (guest_paging_info(vcpu, &paging) == -1) in guest_vaddr2paddr()
364 return (-1); in guest_vaddr2paddr()
371 &fault) == -1) in guest_vaddr2paddr()
372 return (-1); in guest_vaddr2paddr()
374 return (0); in guest_vaddr2paddr()
382 return (vme->rip); in guest_pc()
384 return (vme->pc); in guest_pc()
392 io->start = 0; in io_buffer_reset()
393 io->len = 0; in io_buffer_reset()
401 return (io->capacity - (io->start + io->len)); in io_buffer_avail()
408 return (io->data + io->start); in io_buffer_head()
415 return (io->data + io->start + io->len); in io_buffer_tail()
422 assert(amount <= io->len); in io_buffer_advance()
423 io->start += amount; in io_buffer_advance()
424 io->len -= amount; in io_buffer_advance()
432 if (io->len == 0) { in io_buffer_consume()
433 io->start = 0; in io_buffer_consume()
441 memmove(io->data, io_buffer_head(io), io->len); in io_buffer_consume()
442 io->start = 0; in io_buffer_consume()
455 new_cap = io->capacity + (newsize - avail); in io_buffer_grow()
456 new_data = realloc(io->data, new_cap); in io_buffer_grow()
459 io->data = new_data; in io_buffer_grow()
460 io->capacity = new_cap; in io_buffer_grow()
467 if (cur_resp.start == 0 && cur_resp.len == 0) in response_pending()
469 if (cur_resp.start + cur_resp.len == 1 && cur_resp.data[0] == '+') in response_pending()
489 cur_fd = -1; in close_connection()
494 memset(vcpu_state, 0, guest_ncpus * sizeof(*vcpu_state)); in close_connection()
506 return (nibble + '0'); in hex_digit()
508 return (nibble + 'a' - 10); in hex_digit()
515 if (v >= '0' && v <= '9') in parse_digit()
516 return (v - '0'); in parse_digit()
518 return (v - 'a' + 10); in parse_digit()
520 return (v - 'A' + 10); in parse_digit()
521 return (0xF); in parse_digit()
524 /* Parses big-endian hexadecimal. */
530 v = 0; in parse_integer()
531 while (len > 0) { in parse_integer()
535 len--; in parse_integer()
544 return (parse_digit(p[0]) << 4 | parse_digit(p[1])); in parse_byte()
552 if (cur_resp.len == 0) { in send_pending_data()
557 if (nwritten == -1) { in send_pending_data()
562 if (cur_resp.len == 0) in send_pending_data()
592 buf[0] = hex_digit(v >> 4); in format_byte()
593 buf[1] = hex_digit(v & 0xf); in format_byte()
614 cur_csum = 0; in start_packet()
623 debug("-> %.*s\n", (int)cur_resp.len, io_buffer_head(&cur_resp)); in finish_packet()
647 while (len > 0) { in append_packet_data()
650 len--; in append_packet_data()
659 for (; len > 0; data++, len--) { in append_binary_data()
665 buf[0] = 0x7d; in append_binary_data()
666 buf[1] = *data ^ 0x20; in append_binary_data()
697 for (i = 0; i < len; i++) { in append_unsigned_native()
709 for (i = 0; i < len; i++) { in append_unsigned_be()
710 format_byte(value, buf + (len - i - 1) * 2); in append_unsigned_be()
720 if (value == 0) in append_integer()
721 append_char('0'); in append_integer()
730 while (*str != '\0') { in append_asciihex()
767 if (len == 1 && *data == '0') in parse_threadid()
768 return (0); in parse_threadid()
769 if (len == 2 && memcmp(data, "-1", 2) == 0) in parse_threadid()
770 return (-1); in parse_threadid()
771 if (len == 0) in parse_threadid()
772 return (-2); in parse_threadid()
789 if (stopped_vcpu == -1) { in report_stop()
801 if (vs->hit_swbreak) { in report_stop()
805 } else if (vs->stepped) in report_stop()
823 if (stopped_vcpu != -1) { in discard_stop()
825 vs->hit_swbreak = false; in discard_stop()
826 vs->stepped = false; in discard_stop()
827 stopped_vcpu = -1; in discard_stop()
838 stopped_vcpu = -1; in gdb_finish_suspend_vcpus()
858 if (report_stop && CPU_CMP(&vcpus_waiting, &vcpus_suspended) == 0) in _gdb_cpu_suspend()
867 * Requests vCPU single-stepping using a
881 if (error != 0) in _gdb_set_step()
883 if (error == 0) in _gdb_set_step()
887 if (error == 0) in _gdb_set_step()
894 * Checks whether single-stepping is supported for a given vCPU.
902 if (vm_get_capability(vcpu, VM_CAP_MTRAP_EXIT, &val) != 0) { in _gdb_check_step()
903 if (vm_get_capability(vcpu, VM_CAP_RFLAGS_TF, &val) != 0) in _gdb_check_step()
904 return (-1); in _gdb_check_step()
909 return (0); in _gdb_check_step()
945 assert(error == 0); in gdb_cpu_add()
961 assert(error == 0); in gdb_cpu_add()
983 assert(vs->hit_swbreak == false); in gdb_cpu_resume()
984 assert(vs->stepped == false); in gdb_cpu_resume()
985 if (vs->stepping) { in gdb_cpu_resume()
987 assert(error == 0); in gdb_cpu_resume()
994 * to a guest-wide suspend such as Ctrl-C or the stop on attach.
1016 if (CPU_CMP(&vcpus_waiting, &vcpus_suspended) == 0) in gdb_suspend_vcpus()
1034 if (vs->stepping) { in gdb_cpu_step()
1035 vs->stepping = false; in gdb_cpu_step()
1036 vs->stepped = true; in gdb_cpu_step()
1037 error = _gdb_set_step(vcpu, 0); in gdb_cpu_step()
1038 assert(error == 0); in gdb_cpu_step()
1040 while (vs->stepped) { in gdb_cpu_step()
1041 if (stopped_vcpu == -1) { in gdb_cpu_step()
1054 * A general handler for single-step exceptions.
1065 if (vmexit->u.dbg.trace_trap) { in gdb_cpu_debug()
1075 * Handler for VM_EXITCODE_MTRAP reported when a vCPU single-steps via
1076 * the VT-x-specific MTRAP exit.
1087 find_breakpoint(uint64_t gpa) in find_breakpoint() argument
1092 if (bp->gpa == gpa) in find_breakpoint()
1103 uint64_t gpa; in gdb_cpu_breakpoint() local
1112 error = guest_vaddr2paddr(vcpu, guest_pc(vmexit), &gpa); in gdb_cpu_breakpoint()
1114 bp = find_breakpoint(gpa); in gdb_cpu_breakpoint()
1117 assert(vs->stepping == false); in gdb_cpu_breakpoint()
1118 assert(vs->stepped == false); in gdb_cpu_breakpoint()
1119 assert(vs->hit_swbreak == false); in gdb_cpu_breakpoint()
1120 vs->hit_swbreak = true; in gdb_cpu_breakpoint()
1123 if (stopped_vcpu == -1) { in gdb_cpu_breakpoint()
1130 if (!vs->hit_swbreak) { in gdb_cpu_breakpoint()
1134 bp = find_breakpoint(gpa); in gdb_cpu_breakpoint()
1137 vs->hit_swbreak = false; in gdb_cpu_breakpoint()
1147 vmexit->u.bpt.inst_length); in gdb_cpu_breakpoint()
1148 assert(error == 0); in gdb_cpu_breakpoint()
1149 error = vm_inject_exception(vcpu, IDT_BP, 0, 0, 0); in gdb_cpu_breakpoint()
1150 assert(error == 0); in gdb_cpu_breakpoint()
1154 esr = (EXCP_BRK << ESR_ELx_EC_SHIFT) | vmexit->u.hyp.esr_el2; in gdb_cpu_breakpoint()
1155 error = vm_inject_exception(vcpu, esr, 0); in gdb_cpu_breakpoint()
1156 assert(error == 0); in gdb_cpu_breakpoint()
1170 if (error < 0) in gdb_step_vcpu()
1198 for (size_t i = 0; i < nitems(gdb_regset); i++) in gdb_read_regs()
1201 regnums, regvals) == -1) { in gdb_read_regs()
1207 for (size_t i = 0; i < nitems(gdb_regset); i++) { in gdb_read_regs()
1230 -1) { in gdb_read_one_reg()
1243 uint64_t gpa, gva, val; in gdb_read_mem() local
1253 len -= 1; in gdb_read_mem()
1261 gva = parse_integer(data, cp - data); in gdb_read_mem()
1262 len -= (cp - data) + 1; in gdb_read_mem()
1263 data += (cp - data) + 1; in gdb_read_mem()
1269 while (resid > 0) { in gdb_read_mem()
1270 error = guest_vaddr2paddr(vcpus[cur_vcpu], gva, &gpa); in gdb_read_mem()
1271 if (error == -1) { in gdb_read_mem()
1278 if (error == 0) { in gdb_read_mem()
1287 todo = getpagesize() - gpa % getpagesize(); in gdb_read_mem()
1291 cp = paddr_guest2host(ctx, gpa, todo); in gdb_read_mem()
1301 while (todo > 0) { in gdb_read_mem()
1304 gpa++; in gdb_read_mem()
1306 resid--; in gdb_read_mem()
1307 todo--; in gdb_read_mem()
1315 while (todo > 0) { in gdb_read_mem()
1316 if (gpa & 1 || todo == 1) in gdb_read_mem()
1318 else if (gpa & 2 || todo == 2) in gdb_read_mem()
1322 error = read_mem(vcpus[cur_vcpu], gpa, &val, in gdb_read_mem()
1324 if (error == 0) { in gdb_read_mem()
1329 gpa += bytes; in gdb_read_mem()
1331 resid -= bytes; in gdb_read_mem()
1332 todo -= bytes; in gdb_read_mem()
1333 while (bytes > 0) { in gdb_read_mem()
1336 bytes--; in gdb_read_mem()
1347 assert(resid == 0 || gpa % getpagesize() == 0); in gdb_read_mem()
1357 uint64_t gpa, gva, val; in gdb_write_mem() local
1366 len -= 1; in gdb_write_mem()
1374 gva = parse_integer(data, cp - data); in gdb_write_mem()
1375 len -= (cp - data) + 1; in gdb_write_mem()
1376 data += (cp - data) + 1; in gdb_write_mem()
1384 resid = parse_integer(data, cp - data); in gdb_write_mem()
1385 len -= (cp - data) + 1; in gdb_write_mem()
1386 data += (cp - data) + 1; in gdb_write_mem()
1394 while (resid > 0) { in gdb_write_mem()
1395 error = guest_vaddr2paddr(vcpus[cur_vcpu], gva, &gpa); in gdb_write_mem()
1396 if (error == -1) { in gdb_write_mem()
1400 if (error == 0) { in gdb_write_mem()
1406 todo = getpagesize() - gpa % getpagesize(); in gdb_write_mem()
1410 cp = paddr_guest2host(ctx, gpa, todo); in gdb_write_mem()
1416 while (todo > 0) { in gdb_write_mem()
1420 len -= 2; in gdb_write_mem()
1422 gpa++; in gdb_write_mem()
1424 resid--; in gdb_write_mem()
1425 todo--; in gdb_write_mem()
1433 while (todo > 0) { in gdb_write_mem()
1434 if (gpa & 1 || todo == 1) { in gdb_write_mem()
1437 } else if (gpa & 2 || todo == 2) { in gdb_write_mem()
1444 error = write_mem(vcpus[cur_vcpu], gpa, val, in gdb_write_mem()
1446 if (error == 0) { in gdb_write_mem()
1447 gpa += bytes; in gdb_write_mem()
1449 resid -= bytes; in gdb_write_mem()
1450 todo -= bytes; in gdb_write_mem()
1452 len -= 2 * bytes; in gdb_write_mem()
1459 assert(resid == 0 || gpa % getpagesize() == 0); in gdb_write_mem()
1461 assert(len == 0); in gdb_write_mem()
1473 vcpu = CPU_FFS(&mask) - 1; in set_breakpoint_caps()
1476 enable ? 1 : 0) < 0) in set_breakpoint_caps()
1490 "dc cvau, %0\n" in write_instr()
1508 debug("remove breakpoint at %#lx\n", bp->gpa); in remove_all_sw_breakpoints()
1509 cp = paddr_guest2host(ctx, bp->gpa, sizeof(bp->shadow_inst)); in remove_all_sw_breakpoints()
1510 write_instr(cp, bp->shadow_inst, sizeof(bp->shadow_inst)); in remove_all_sw_breakpoints()
1522 uint64_t gpa; in update_sw_breakpoint() local
1531 error = guest_vaddr2paddr(vcpus[cur_vcpu], gva, &gpa); in update_sw_breakpoint()
1532 if (error == -1) { in update_sw_breakpoint()
1536 if (error == 0) { in update_sw_breakpoint()
1541 cp = paddr_guest2host(ctx, gpa, sizeof(bp->shadow_inst)); in update_sw_breakpoint()
1550 bp = find_breakpoint(gpa); in update_sw_breakpoint()
1564 bp->gpa = gpa; in update_sw_breakpoint()
1565 memcpy(bp->shadow_inst, cp, sizeof(bp->shadow_inst)); in update_sw_breakpoint()
1566 write_instr(cp, GDB_BP_INSTR, sizeof(bp->shadow_inst)); in update_sw_breakpoint()
1568 debug("new breakpoint at %#lx\n", gpa); in update_sw_breakpoint()
1572 debug("remove breakpoint at %#lx\n", gpa); in update_sw_breakpoint()
1573 write_instr(cp, bp->shadow_inst, in update_sw_breakpoint()
1574 sizeof(bp->shadow_inst)); in update_sw_breakpoint()
1592 insert = data[0] == 'Z'; in parse_breakpoint()
1596 len -= 1; in parse_breakpoint()
1604 type = parse_integer(data, cp - data); in parse_breakpoint()
1605 len -= (cp - data) + 1; in parse_breakpoint()
1606 data += (cp - data) + 1; in parse_breakpoint()
1614 gva = parse_integer(data, cp - data); in parse_breakpoint()
1615 len -= (cp - data) + 1; in parse_breakpoint()
1616 data += (cp - data) + 1; in parse_breakpoint()
1636 len = 0; in parse_breakpoint()
1639 case 0: in parse_breakpoint()
1654 return (memcmp(data, cmd, strlen(cmd)) == 0); in command_equals()
1665 str[len] = '\0'; in check_features()
1673 if (strcmp(feature, "") == 0) in check_features()
1682 *value = '\0'; in check_features()
1686 value = feature + strlen(feature) - 1; in check_features()
1691 case '-': in check_features()
1706 if (strcmp(feature, "swbreak") == 0) in check_features()
1726 * - qSearch in gdb_query()
1751 vcpu = CPU_FFS(&mask) - 1; in gdb_query()
1766 len -= strlen("qSupported"); in gdb_query()
1773 len -= strlen("qThreadExtraInfo"); in gdb_query()
1774 if (len == 0 || *data != ',') { in gdb_query()
1778 tid = parse_threadid(data + 1, len - 1); in gdb_query()
1779 if (tid <= 0 || !CPU_ISSET(tid - 1, &vcpus_active)) { in gdb_query()
1784 snprintf(buf, sizeof(buf), "vCPU %d", tid - 1); in gdb_query()
1798 len -= strlen("qXfer:features:read:"); in gdb_query()
1802 (size_t)(pathend - data) >= sizeof(path) - 1) { in gdb_query()
1806 memcpy(path, data, pathend - data); in gdb_query()
1807 path[pathend - data] = '\0'; in gdb_query()
1808 data += (pathend - data) + 1; in gdb_query()
1809 len -= (pathend - data) + 1; in gdb_query()
1811 if (len > sizeof(buf) - 1) { in gdb_query()
1816 buf[len] = '\0'; in gdb_query()
1823 if (fd < 0) { in gdb_query()
1827 if (fstat(fd, &sb) < 0) { in gdb_query()
1832 xml = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0); in gdb_query()
1846 append_binary_data(xml + doff, xmllen - doff); in gdb_query()
1861 /* Reject packets with a sequence-id. */ in handle_command()
1862 if (len >= 3 && data[0] >= '0' && data[0] <= '9' && in handle_command()
1863 data[0] >= '0' && data[0] <= '9' && data[2] == ':') { in handle_command()
1887 gdb_read_one_reg(data + 1, len - 1); in handle_command()
1896 tid = parse_threadid(data + 2, len - 2); in handle_command()
1897 if (tid == -2) { in handle_command()
1906 if (tid == -1 || tid == 0) in handle_command()
1907 cur_vcpu = CPU_FFS(&vcpus_active) - 1; in handle_command()
1908 else if (CPU_ISSET(tid - 1, &vcpus_active)) in handle_command()
1909 cur_vcpu = tid - 1; in handle_command()
1926 tid = parse_threadid(data + 1, len - 1); in handle_command()
1927 if (tid <= 0 || !CPU_ISSET(tid - 1, &vcpus_active)) { in handle_command()
1978 if (avail == 0) in check_command()
1982 case 0x03: in check_command()
1983 debug("<- Ctrl-C\n"); in check_command()
1990 debug("<- +\n"); in check_command()
1994 if (stopped_vcpu != -1 && report_next_stop) { in check_command()
1999 case '-': in check_command()
2001 debug("<- -\n"); in check_command()
2004 cur_resp.start = 0; in check_command()
2005 if (cur_resp.data[0] == '+') in check_command()
2007 debug("-> %.*s\n", (int)cur_resp.len, in check_command()
2026 plen = (hash - head + 1) + 2; in check_command()
2029 debug("<- %.*s\n", (int)plen, head); in check_command()
2032 for (sum = 0, p = head + 1; p < hash; p++) in check_command()
2036 debug("-> -\n"); in check_command()
2037 send_char('-'); in check_command()
2043 handle_command(head + 1, hash - (head + 1)); in check_command()
2046 debug("-> +\n"); in check_command()
2051 debug("-> %02x\n", *head); in check_command()
2065 if (ioctl(fd, FIONREAD, &n) == -1) { in gdb_readable()
2069 assert(n >= 0); in gdb_readable()
2074 * with a non-zero length to detect EOF. in gdb_readable()
2076 if (pending == 0) in gdb_readable()
2084 if (nread == 0) { in gdb_readable()
2086 } else if (nread == -1) { in gdb_readable()
2113 if (s == -1) { in new_connection()
2117 /* Silently ignore errors post-startup. */ in new_connection()
2123 -1) { in new_connection()
2130 if (cur_fd != -1) { in new_connection()
2151 cur_vcpu = 0; in new_connection()
2152 stopped_vcpu = -1; in new_connection()
2170 if (caph_rights_limit(s, &rights) == -1) in limit_gdb_socket()
2172 if (caph_ioctls_limit(s, ioctls, nitems(ioctls)) == -1) in limit_gdb_socket()
2208 if (error != 0) in init_gdb()
2211 if (error != 0) in init_gdb()
2214 memset(&hints, 0, sizeof(hints)); in init_gdb()
2220 if (error != 0) in init_gdb()
2224 s = socket(gdbaddr->ai_family, gdbaddr->ai_socktype, 0); in init_gdb()
2225 if (s < 0) in init_gdb()
2231 if (bind(s, gdbaddr->ai_addr, gdbaddr->ai_addrlen) < 0) in init_gdb()
2234 if (listen(s, 1) < 0) in init_gdb()
2237 stopped_vcpu = -1; in init_gdb()
2243 * Set vcpu 0 in vcpus_suspended. This will trigger the in init_gdb()
2248 CPU_SET(0, &vcpus_suspended); in init_gdb()
2249 stopped_vcpu = 0; in init_gdb()
2253 if (fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1) in init_gdb()
2254 err(1, "Failed to mark gdb socket non-blocking"); in init_gdb()
2265 if (xml_dfd == -1) in init_gdb()
2269 if (caph_rights_limit(xml_dfd, &rights) == -1) in init_gdb()