Lines Matching +full:suspend +full:- +full:to +full:- +full:ram

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2017-2018 John H. Baldwin <jhb@FreeBSD.org>
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
109 static int xml_dfd = -1;
114 * valid bytes in the buffer. For a write buffer, 'start' is set to
115 * the index of the next byte in 'data' to send, and 'len' contains
116 * the remaining number of valid bytes to send.
132 * When a vCPU stops to due to an event that should be reported to the
141 * An idle vCPU will have all of the boolean fields set to false.
143 * When a vCPU is stepped, 'stepping' is set to true when the vCPU is
144 * released to execute the stepped instruction. When the vCPU reports
148 * 'hit_swbreak' is set to true.
159 static int cur_fd = -1;
198 * Registers past this point are not included in a reply to a 'g' query,
199 * to provide compatibility with debuggers that do not fetch a target
268 if (caph_limit_stream(fileno(logfile), CAPH_WRITE) == -1) {
298 if (vm_get_register_set(vcpu, nitems(regset), regset, regs) == -1)
299 return (-1);
302 * For the debugger, always pretend to be the kernel (CPL 0),
303 * and if long-mode is enabled, always parse addresses as if
304 * in 64-bit mode.
306 paging->cr3 = regs[1];
307 paging->cpl = 0;
309 paging->cpu_mode = CPU_MODE_64BIT;
311 paging->cpu_mode = CPU_MODE_PROTECTED;
313 paging->cpu_mode = CPU_MODE_REAL;
315 paging->paging_mode = PAGING_MODE_FLAT;
317 paging->paging_mode = PAGING_MODE_32;
319 paging->paging_mode = (regs[2] & CR4_LA57) ?
322 paging->paging_mode = PAGING_MODE_PAE;
335 if (vm_get_register_set(vcpu, nitems(regset), regset, regs) == -1)
336 return (-1);
339 paging->ttbr0_addr = regs[0] & ~(TTBR_ASID_MASK | TTBR_CnP);
340 paging->ttbr1_addr = regs[1] & ~(TTBR_ASID_MASK | TTBR_CnP);
341 paging->tcr_el1 = regs[2];
342 paging->tcr2_el1 = regs[3];
343 paging->flags = regs[5] & (PSR_M_MASK | PSR_M_32);
345 paging->flags |= VM_GP_MMU_ENABLED;
352 * Map a guest virtual address to a physical address (for a given vcpu).
355 * return -1.
363 if (guest_paging_info(vcpu, &paging) == -1)
364 return (-1);
371 &fault) == -1)
372 return (-1);
382 return (vme->rip);
384 return (vme->pc);
392 io->start = 0;
393 io->len = 0;
401 return (io->capacity - (io->start + io->len));
408 return (io->data + io->start);
415 return (io->data + io->start + io->len);
422 assert(amount <= io->len);
423 io->start += amount;
424 io->len -= amount;
432 if (io->len == 0) {
433 io->start = 0;
441 memmove(io->data, io_buffer_head(io), io->len);
442 io->start = 0;
455 new_cap = io->capacity + (newsize - avail);
456 new_data = realloc(io->data, new_cap);
458 err(1, "Failed to grow GDB I/O buffer");
459 io->data = new_data;
460 io->capacity = new_cap;
489 cur_fd = -1;
508 return (nibble + 'a' - 10);
516 return (v - '0');
518 return (v - 'a' + 10);
520 return (v - 'A' + 10);
524 /* Parses big-endian hexadecimal. */
535 len--;
557 if (nwritten == -1) {
558 warn("Write to GDB socket failed");
569 /* Append a single character to the output buffer. */
578 /* Append an array of bytes to the output buffer. */
597 * Append a single byte (formatted as two hex characters) to the
623 debug("-> %.*s\n", (int)cur_resp.len, io_buffer_head(&cur_resp));
650 len--;
659 for (; len > 0; data++, len--) {
710 format_byte(value, buf + (len - i - 1) * 2);
769 if (len == 2 && memcmp(data, "-1", 2) == 0)
770 return (-1);
772 return (-2);
777 * Report the current stop event to the debugger. If the stop is due
778 * to an event triggered on a specific vCPU such as a breakpoint or
779 * stepping trap, stopped_vcpu will be set to the vCPU triggering the
780 * stop. If 'set_cur_vcpu' is true, then cur_vcpu will be updated to
789 if (stopped_vcpu == -1) {
801 if (vs->hit_swbreak) {
805 } else if (vs->stepped)
815 * If this stop is due to a vCPU event, clear that event to mark it as
823 if (stopped_vcpu != -1) {
825 vs->hit_swbreak = false;
826 vs->stepped = false;
827 stopped_vcpu = -1;
838 stopped_vcpu = -1;
848 * debug server to pause or report an event. vCPU threads wait here
867 * Requests vCPU single-stepping using a
894 * Checks whether single-stepping is supported for a given vCPU.
904 return (-1);
913 * Invoked at the start of a vCPU thread's execution to inform the
936 * If a vcpu is added while vcpus are stopped, suspend the new
953 * In particular, this refers to the kernel's view of the vCPU
983 assert(vs->hit_swbreak == false);
984 assert(vs->stepped == false);
985 if (vs->stepping) {
992 * Handler for VM_EXITCODE_DEBUG used to suspend a vCPU when the guest
993 * has been suspended due to an event on different vCPU or in response
994 * to a guest-wide suspend such as Ctrl-C or the stop on attach.
1021 * Invoked each time a vmexit handler needs to step a vCPU.
1034 if (vs->stepping) {
1035 vs->stepping = false;
1036 vs->stepped = true;
1040 while (vs->stepped) {
1041 if (stopped_vcpu == -1) {
1054 * A general handler for single-step exceptions.
1065 if (vmexit->u.dbg.trace_trap) {
1075 * Handler for VM_EXITCODE_MTRAP reported when a vCPU single-steps via
1076 * the VT-x-specific MTRAP exit.
1092 if (bp->gpa == gpa)
1117 assert(vs->stepping == false);
1118 assert(vs->stepped == false);
1119 assert(vs->hit_swbreak == false);
1120 vs->hit_swbreak = true;
1123 if (stopped_vcpu == -1) {
1130 if (!vs->hit_swbreak) {
1137 vs->hit_swbreak = false;
1147 vmexit->u.bpt.inst_length);
1154 esr = (EXCP_BRK << ESR_ELx_EC_SHIFT) | vmexit->u.hyp.esr_el2;
1201 regnums, regvals) == -1) {
1230 -1) {
1253 len -= 1;
1261 gva = parse_integer(data, cp - data);
1262 len -= (cp - data) + 1;
1263 data += (cp - data) + 1;
1271 if (error == -1) {
1287 todo = getpagesize() - gpa % getpagesize();
1294 * If this page is guest RAM, read it a byte
1306 resid--;
1307 todo--;
1311 * If this page isn't guest RAM, try to handle
1331 resid -= bytes;
1332 todo -= bytes;
1336 bytes--;
1366 len -= 1;
1374 gva = parse_integer(data, cp - data);
1375 len -= (cp - data) + 1;
1376 data += (cp - data) + 1;
1384 resid = parse_integer(data, cp - data);
1385 len -= (cp - data) + 1;
1386 data += (cp - data) + 1;
1396 if (error == -1) {
1405 /* Write bytes to current page. */
1406 todo = getpagesize() - gpa % getpagesize();
1413 * If this page is guest RAM, write it a byte
1420 len -= 2;
1424 resid--;
1425 todo--;
1429 * If this page isn't guest RAM, try to handle
1449 resid -= bytes;
1450 todo -= bytes;
1452 len -= 2 * bytes;
1473 vcpu = CPU_FFS(&mask) - 1;
1508 debug("remove breakpoint at %#lx\n", bp->gpa);
1509 cp = paddr_guest2host(ctx, bp->gpa, sizeof(bp->shadow_inst));
1510 write_instr(cp, bp->shadow_inst, sizeof(bp->shadow_inst));
1532 if (error == -1) {
1541 cp = paddr_guest2host(ctx, gpa, sizeof(bp->shadow_inst));
1543 /* Only permit breakpoints in guest RAM. */
1554 * requires these packets to be idempotent.
1564 bp->gpa = gpa;
1565 memcpy(bp->shadow_inst, cp, sizeof(bp->shadow_inst));
1566 write_instr(cp, GDB_BP_INSTR, sizeof(bp->shadow_inst));
1573 write_instr(cp, bp->shadow_inst,
1574 sizeof(bp->shadow_inst));
1596 len -= 1;
1604 type = parse_integer(data, cp - data);
1605 len -= (cp - data) + 1;
1606 data += (cp - data) + 1;
1614 gva = parse_integer(data, cp - data);
1615 len -= (cp - data) + 1;
1616 data += (cp - data) + 1;
1686 value = feature + strlen(feature) - 1;
1691 case '-':
1726 * - qSearch
1751 vcpu = CPU_FFS(&mask) - 1;
1766 len -= strlen("qSupported");
1773 len -= strlen("qThreadExtraInfo");
1778 tid = parse_threadid(data + 1, len - 1);
1779 if (tid <= 0 || !CPU_ISSET(tid - 1, &vcpus_active)) {
1784 snprintf(buf, sizeof(buf), "vCPU %d", tid - 1);
1798 len -= strlen("qXfer:features:read:");
1802 (size_t)(pathend - data) >= sizeof(path) - 1) {
1806 memcpy(path, data, pathend - data);
1807 path[pathend - data] = '\0';
1808 data += (pathend - data) + 1;
1809 len -= (pathend - data) + 1;
1811 if (len > sizeof(buf) - 1) {
1846 append_binary_data(xml + doff, xmllen - doff);
1861 /* Reject packets with a sequence-id. */
1887 gdb_read_one_reg(data + 1, len - 1);
1896 tid = parse_threadid(data + 2, len - 2);
1897 if (tid == -2) {
1906 if (tid == -1 || tid == 0)
1907 cur_vcpu = CPU_FFS(&vcpus_active) - 1;
1908 else if (CPU_ISSET(tid - 1, &vcpus_active))
1909 cur_vcpu = tid - 1;
1926 tid = parse_threadid(data + 1, len - 1);
1927 if (tid <= 0 || !CPU_ISSET(tid - 1, &vcpus_active)) {
1983 debug("<- Ctrl-C\n");
1990 debug("<- +\n");
1994 if (stopped_vcpu != -1 && report_next_stop) {
1999 case '-':
2001 debug("<- -\n");
2007 debug("-> %.*s\n", (int)cur_resp.len,
2026 plen = (hash - head + 1) + 2;
2029 debug("<- %.*s\n", (int)plen, head);
2036 debug("-> -\n");
2037 send_char('-');
2043 handle_command(head + 1, hash - (head + 1));
2046 debug("-> +\n");
2051 debug("-> %02x\n", *head);
2065 if (ioctl(fd, FIONREAD, &n) == -1) {
2073 * 'pending' might be zero due to EOF. We need to call read
2074 * with a non-zero length to detect EOF.
2086 } else if (nread == -1) {
2113 if (s == -1) {
2117 /* Silently ignore errors post-startup. */
2123 -1) {
2124 warn("Failed to disable SIGPIPE for GDB connection");
2130 if (cur_fd != -1) {
2138 err(1, "Failed to setup initial GDB connection");
2145 err(1, "Failed to setup initial GDB connection");
2152 stopped_vcpu = -1;
2170 if (caph_rights_limit(s, &rights) == -1)
2171 errx(EX_OSERR, "Unable to apply rights for sandbox");
2172 if (caph_ioctls_limit(s, ioctls, nitems(ioctls)) == -1)
2173 errx(EX_OSERR, "Unable to apply rights for sandbox");
2195 errx(4, "Failed to allocate memory");
2224 s = socket(gdbaddr->ai_family, gdbaddr->ai_socktype, 0);
2231 if (bind(s, gdbaddr->ai_addr, gdbaddr->ai_addrlen) < 0)
2237 stopped_vcpu = -1;
2244 * logic in gdb_cpu_add() to suspend the first vcpu before
2253 if (fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1)
2254 err(1, "Failed to mark gdb socket non-blocking");
2265 if (xml_dfd == -1)
2266 err(1, "Failed to open gdb xml directory");
2269 if (caph_rights_limit(xml_dfd, &rights) == -1)