Lines Matching +full:gpa +full:- +full:1
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2017-2018 John H. Baldwin <jhb@FreeBSD.org>
9 * 1. Redistributions of source code must retain the above copyright
84 #define GDB_BP_SIZE 1
109 static int xml_dfd = -1;
126 uint64_t gpa; member
159 static int cur_fd = -1;
257 static void __printflike(1, 2)
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()
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()
311 paging->cpu_mode = CPU_MODE_PROTECTED; in guest_paging_info()
313 paging->cpu_mode = CPU_MODE_REAL; 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()
335 if (vm_get_register_set(vcpu, nitems(regset), regset, regs) == -1) in guest_paging_info()
336 return (-1); 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()
345 paging->flags |= VM_GP_MMU_ENABLED; in guest_paging_info()
353 * If a guest virtual address is valid, return 1. If the address is
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()
375 return (1); 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()
458 err(1, "Failed to grow GDB I/O buffer"); in io_buffer_grow()
459 io->data = new_data; in io_buffer_grow()
460 io->capacity = new_cap; in io_buffer_grow()
469 if (cur_resp.start + cur_resp.len == 1 && cur_resp.data[0] == '+') in response_pending()
489 cur_fd = -1; in close_connection()
508 return (nibble + 'a' - 10); in hex_digit()
516 return (v - '0'); in parse_digit()
518 return (v - 'a' + 10); in parse_digit()
520 return (v - 'A' + 10); in parse_digit()
524 /* Parses big-endian hexadecimal. */
535 len--; in parse_integer()
544 return (parse_digit(p[0]) << 4 | parse_digit(p[1])); in parse_byte()
557 if (nwritten == -1) { in send_pending_data()
573 io_buffer_grow(&cur_resp, 1); in send_char()
593 buf[1] = hex_digit(v & 0xf); in format_byte()
623 debug("-> %.*s\n", (int)cur_resp.len, io_buffer_head(&cur_resp)); in finish_packet()
650 len--; in append_packet_data()
659 for (; len > 0; data++, len--) { in append_binary_data()
666 buf[1] = *data ^ 0x20; in append_binary_data()
670 append_packet_data(data, 1); in append_binary_data()
710 format_byte(value, buf + (len - i - 1) * 2); in append_unsigned_be()
767 if (len == 1 && *data == '0') in parse_threadid()
769 if (len == 2 && memcmp(data, "-1", 2) == 0) in parse_threadid()
770 return (-1); in parse_threadid()
772 return (-2); in parse_threadid()
789 if (stopped_vcpu == -1) { in report_stop()
799 append_integer(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()
867 * Requests vCPU single-stepping using a
894 * Checks whether single-stepping is supported for a given vCPU.
904 return (-1); in _gdb_check_step()
931 vm_set_capability(vcpu, GDB_BREAKPOINT_CAP, 1); 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()
986 error = _gdb_set_step(vcpu, 1); in gdb_cpu_resume()
994 * to a guest-wide suspend such as Ctrl-C or the stop on attach.
1034 if (vs->stepping) { in gdb_cpu_step()
1035 vs->stepping = false; in gdb_cpu_step()
1036 vs->stepped = true; 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()
1113 assert(error == 1); 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()
1154 esr = (EXCP_BRK << ESR_ELx_EC_SHIFT) | vmexit->u.hyp.esr_el2; in gdb_cpu_breakpoint()
1201 regnums, regvals) == -1) { in gdb_read_regs()
1230 -1) { in gdb_read_one_reg()
1243 uint64_t gpa, gva, val; in gdb_read_mem() local
1249 assert(len >= 1); in gdb_read_mem()
1252 data += 1; in gdb_read_mem()
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()
1270 error = guest_vaddr2paddr(vcpus[cur_vcpu], gva, &gpa); in gdb_read_mem()
1271 if (error == -1) { in gdb_read_mem()
1287 todo = getpagesize() - gpa % getpagesize(); in gdb_read_mem()
1291 cp = paddr_guest2host(ctx, gpa, todo); in gdb_read_mem()
1304 gpa++; in gdb_read_mem()
1306 resid--; in gdb_read_mem()
1307 todo--; in gdb_read_mem()
1316 if (gpa & 1 || todo == 1) in gdb_read_mem()
1317 bytes = 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()
1329 gpa += bytes; in gdb_read_mem()
1331 resid -= bytes; in gdb_read_mem()
1332 todo -= bytes; 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
1362 assert(len >= 1); in gdb_write_mem()
1365 data += 1; in gdb_write_mem()
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()
1395 error = guest_vaddr2paddr(vcpus[cur_vcpu], gva, &gpa); in gdb_write_mem()
1396 if (error == -1) { in gdb_write_mem()
1406 todo = getpagesize() - gpa % getpagesize(); in gdb_write_mem()
1410 cp = paddr_guest2host(ctx, gpa, todo); 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()
1434 if (gpa & 1 || todo == 1) { in gdb_write_mem()
1435 bytes = 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()
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()
1473 vcpu = CPU_FFS(&mask) - 1; in set_breakpoint_caps()
1476 enable ? 1 : 0) < 0) in set_breakpoint_caps()
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()
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()
1595 data += 1; 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()
1663 str = malloc(len + 1); in check_features()
1686 value = feature + strlen(feature) - 1; in check_features()
1691 case '-': in check_features()
1726 * - qSearch in gdb_query()
1730 append_char('1'); in gdb_query()
1735 append_integer(cur_vcpu + 1); in gdb_query()
1751 vcpu = CPU_FFS(&mask) - 1; in gdb_query()
1757 append_integer(vcpu + 1); in gdb_query()
1766 len -= strlen("qSupported"); in gdb_query()
1773 len -= strlen("qThreadExtraInfo"); 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()
1846 append_binary_data(xml + doff, xmllen - doff); in gdb_query()
1861 /* Reject packets with a sequence-id. */ in handle_command()
1870 if (len != 1) { in handle_command()
1887 gdb_read_one_reg(data + 1, len - 1); in handle_command()
1892 if (len < 2 || (data[1] != 'g' && data[1] != 'c')) { 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()
1938 if (len != 1) { in handle_command()
1983 debug("<- Ctrl-C\n"); in check_command()
1984 io_buffer_consume(&cur_comm, 1); in check_command()
1990 debug("<- +\n"); in check_command()
1993 io_buffer_consume(&cur_comm, 1); 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()
2006 io_buffer_advance(&cur_resp, 1); in check_command()
2007 debug("-> %.*s\n", (int)cur_resp.len, in check_command()
2010 io_buffer_consume(&cur_comm, 1); 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()
2034 if (sum != parse_byte(hash + 1)) { 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()
2052 io_buffer_consume(&cur_comm, 1); in check_command()
2065 if (ioctl(fd, FIONREAD, &n) == -1) { in gdb_readable()
2074 * with a non-zero length to detect EOF. in gdb_readable()
2077 pending = 1; in gdb_readable()
2086 } else if (nread == -1) { in gdb_readable()
2113 if (s == -1) { in new_connection()
2115 err(1, "Failed accepting initial GDB connection"); in new_connection()
2117 /* Silently ignore errors post-startup. */ in new_connection()
2121 optval = 1; in new_connection()
2123 -1) { in new_connection()
2130 if (cur_fd != -1) { in new_connection()
2138 err(1, "Failed to setup initial GDB connection"); in new_connection()
2145 err(1, "Failed to setup initial GDB connection"); 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()
2209 errc(1, error, "gdb mutex init"); in init_gdb()
2212 errc(1, error, "gdb cv init"); in init_gdb()
2221 errx(1, "gdb address resolution: %s", gai_strerror(error)); in init_gdb()
2224 s = socket(gdbaddr->ai_family, gdbaddr->ai_socktype, 0); in init_gdb()
2226 err(1, "gdb socket create"); in init_gdb()
2228 optval = 1; in init_gdb()
2231 if (bind(s, gdbaddr->ai_addr, gdbaddr->ai_addrlen) < 0) in init_gdb()
2232 err(1, "gdb socket bind"); in init_gdb()
2234 if (listen(s, 1) < 0) in init_gdb()
2235 err(1, "gdb socket listen"); in init_gdb()
2237 stopped_vcpu = -1; 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()
2266 err(1, "Failed to open gdb xml directory"); in init_gdb()
2269 if (caph_rights_limit(xml_dfd, &rights) == -1) in init_gdb()
2270 err(1, "cap_rights_init"); in init_gdb()