Page MenuHomeFreeBSD

D43666.id133606.diff
No OneTemporary

D43666.id133606.diff

diff --git a/etc/mtree/BSD.usr.dist b/etc/mtree/BSD.usr.dist
--- a/etc/mtree/BSD.usr.dist
+++ b/etc/mtree/BSD.usr.dist
@@ -184,6 +184,8 @@
atf tags=package=tests
..
bhyve
+ gdb
+ ..
kbdlayout
..
..
diff --git a/usr.sbin/bhyve/Makefile b/usr.sbin/bhyve/Makefile
--- a/usr.sbin/bhyve/Makefile
+++ b/usr.sbin/bhyve/Makefile
@@ -75,6 +75,7 @@
.ifdef GDB_LOG
CFLAGS+=-DGDB_LOG
.endif
+SUBDIR+= gdb
.endif
CFLAGS+=-I${.CURDIR} \
diff --git a/usr.sbin/bhyve/gdb.c b/usr.sbin/bhyve/gdb.c
--- a/usr.sbin/bhyve/gdb.c
+++ b/usr.sbin/bhyve/gdb.c
@@ -34,6 +34,8 @@
#include <sys/mman.h>
#include <sys/queue.h>
#include <sys/socket.h>
+#include <sys/stat.h>
+
#include <machine/atomic.h>
#include <machine/specialreg.h>
#include <machine/vmm.h>
@@ -63,6 +65,8 @@
#include "mem.h"
#include "mevent.h"
+#define _PATH_GDB_XML "/usr/share/bhyve/gdb"
+
/*
* GDB_SIGNAL_* numbers are part of the GDB remote protocol. Most stops
* use SIGTRAP.
@@ -72,7 +76,8 @@
#define GDB_BP_SIZE 1
#define GDB_BP_INSTR (uint8_t []){0xcc}
#define GDB_PC_REGNAME VM_REG_GUEST_RIP
-
+#define GDB_XML_ARCH "i386:x86-64"
+#define GDB_XML_BASE "amd64.xml"
_Static_assert(sizeof(GDB_BP_INSTR) == GDB_BP_SIZE,
"GDB_BP_INSTR has wrong size");
@@ -85,6 +90,7 @@
static pthread_mutex_t gdb_lock;
static pthread_cond_t idle_vcpus;
static bool first_stop, report_next_stop, swbreak_enabled;
+static int xml_dfd = -1;
/*
* An I/O buffer contains 'capacity' bytes of room at 'data'. For a
@@ -169,6 +175,22 @@
{ .id = VM_REG_GUEST_ES, .size = 4 },
{ .id = VM_REG_GUEST_FS, .size = 4 },
{ .id = VM_REG_GUEST_GS, .size = 4 },
+ /*
+ * Registers past this point are not included in a reply to a 'g' query,
+ * to provide compatibility with debuggers that do not fetch a target
+ * description. The debugger can query them individually with 'p' if it
+ * knows about them.
+ */
+#define GDB_REG_FIRST_EXT VM_REG_GUEST_FS_BASE
+ { .id = VM_REG_GUEST_FS_BASE, .size = 8 },
+ { .id = VM_REG_GUEST_GS_BASE, .size = 8 },
+ { .id = VM_REG_GUEST_KGS_BASE, .size = 8 },
+ { .id = VM_REG_GUEST_CR0, .size = 8 },
+ { .id = VM_REG_GUEST_CR2, .size = 8 },
+ { .id = VM_REG_GUEST_CR3, .size = 8 },
+ { .id = VM_REG_GUEST_CR4, .size = 8 },
+ { .id = VM_REG_GUEST_TPR, .size = 8 },
+ { .id = VM_REG_GUEST_EFER, .size = 8 },
};
#ifdef GDB_LOG
@@ -1029,9 +1051,13 @@
send_error(errno);
return;
}
+
start_packet();
- for (size_t i = 0; i < nitems(gdb_regset); i++)
+ for (size_t i = 0; i < nitems(gdb_regset); i++) {
+ if (gdb_regset[i].id == GDB_REG_FIRST_EXT)
+ break;
append_unsigned_native(regvals[i], gdb_regset[i].size);
+ }
finish_packet();
}
@@ -1519,6 +1545,7 @@
/* This is an arbitrary limit. */
append_string("PacketSize=4096");
append_string(";swbreak+");
+ append_string(";qXfer:features:read+");
finish_packet();
}
@@ -1590,6 +1617,94 @@
start_packet();
append_asciihex(buf);
finish_packet();
+ } else if (command_equals(data, len, "qXfer:features:read:")) {
+ const char *xml;
+ const uint8_t *pathend;
+ char buf[64], path[PATH_MAX];
+ size_t xmllen;
+ unsigned int doff, dlen;
+ bool unmap;
+
+ data += strlen("qXfer:features:read:");
+ len -= strlen("qXfer:features:read:");
+
+ pathend = memchr(data, ':', len);
+ if (pathend == NULL ||
+ (size_t)(pathend - data) >= sizeof(path) - 1) {
+ send_error(EINVAL);
+ return;
+ }
+ memcpy(path, data, pathend - data);
+ path[pathend - data] = '\0';
+ data += (pathend - data) + 1;
+ len -= (pathend - data) + 1;
+
+ if (len > sizeof(buf) - 1) {
+ send_error(EINVAL);
+ return;
+ }
+ memcpy(buf, data, len);
+ buf[len] = '\0';
+ if (sscanf(buf, "%x,%x", &doff, &dlen) != 2) {
+ send_error(EINVAL);
+ return;
+ }
+
+ /*
+ * "target.xml" is the base target description, which is
+ * hard-coded here. It references other files which may be
+ * accessed via xml_dfd.
+ */
+ if (strcmp(path, "target.xml") == 0) {
+ xml =
+ "<?xml version=\"1.0\"?>"
+ "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
+ "<target>"
+ "<architecture>" GDB_XML_ARCH "</architecture>"
+ "<xi:include href=\"" GDB_XML_BASE "\"/>"
+ "</target>";
+ xmllen = strlen(xml);
+ unmap = false;
+ } else {
+ struct stat sb;
+ int fd;
+
+ fd = openat(xml_dfd, path, O_RDONLY);
+ if (fd < 0) {
+ send_error(errno);
+ return;
+ }
+ if (fstat(fd, &sb) < 0) {
+ send_error(errno);
+ close(fd);
+ return;
+ }
+ xml = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED,
+ fd, 0);
+ if (xml == MAP_FAILED) {
+ send_error(errno);
+ close(fd);
+ return;
+ }
+ close(fd);
+ xmllen = sb.st_size;
+ unmap = true;
+ }
+
+ start_packet();
+ if (doff >= xmllen) {
+ append_char('l');
+ dlen = 0;
+ } else if (doff + dlen >= xmllen) {
+ append_char('l');
+ append_packet_data(xml + doff, xmllen - doff);
+ } else {
+ append_char('m');
+ append_packet_data(xml + doff, dlen);
+ }
+ finish_packet();
+ if (unmap)
+ (void)munmap(__DECONST(void *, xml), xmllen);
} else
send_empty_response();
}
@@ -1917,6 +2032,9 @@
void
init_gdb(struct vmctx *_ctx)
{
+#ifndef WITHOUT_CAPSICUM
+ cap_rights_t rights;
+#endif
int error, flags, optval, s;
struct addrinfo hints;
struct addrinfo *gdbaddr;
@@ -1997,4 +2115,13 @@
gdb_active = true;
freeaddrinfo(gdbaddr);
free(sport);
+
+ xml_dfd = open(_PATH_GDB_XML, O_DIRECTORY);
+ if (xml_dfd == -1)
+ err(1, "Failed to open gdb xml directory");
+#ifndef WITHOUT_CAPSICUM
+ cap_rights_init(&rights, CAP_FSTAT, CAP_LOOKUP, CAP_MMAP_R, CAP_PREAD);
+ if (caph_rights_limit(xml_dfd, &rights) == -1)
+ err(1, "cap_rights_init");
+#endif
}
diff --git a/usr.sbin/bhyve/gdb/Makefile b/usr.sbin/bhyve/gdb/Makefile
new file mode 100644
--- /dev/null
+++ b/usr.sbin/bhyve/gdb/Makefile
@@ -0,0 +1,8 @@
+PACKAGE= bhyve
+FILESDIR= ${SHAREDIR}/bhyve/gdb
+
+.if ${MACHINE_ARCH} == "amd64"
+FILES+= amd64.xml
+.endif
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/bhyve/gdb/amd64.xml b/usr.sbin/bhyve/gdb/amd64.xml
new file mode 100644
--- /dev/null
+++ b/usr.sbin/bhyve/gdb/amd64.xml
@@ -0,0 +1,216 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010-2017 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!-- x86_64 64bit -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+
+<feature name="org.gnu.gdb.i386.core">
+ <flags id="x64_eflags" size="4">
+ <field name="" start="22" end="31"/>
+ <field name="ID" start="21" end="21"/>
+ <field name="VIP" start="20" end="20"/>
+ <field name="VIF" start="19" end="19"/>
+ <field name="AC" start="18" end="18"/>
+ <field name="VM" start="17" end="17"/>
+ <field name="RF" start="16" end="16"/>
+ <field name="" start="15" end="15"/>
+ <field name="NT" start="14" end="14"/>
+ <field name="IOPL" start="12" end="13"/>
+ <field name="OF" start="11" end="11"/>
+ <field name="DF" start="10" end="10"/>
+ <field name="IF" start="9" end="9"/>
+ <field name="TF" start="8" end="8"/>
+ <field name="SF" start="7" end="7"/>
+ <field name="ZF" start="6" end="6"/>
+ <field name="" start="5" end="5"/>
+ <field name="AF" start="4" end="4"/>
+ <field name="" start="3" end="3"/>
+ <field name="PF" start="2" end="2"/>
+ <field name="" start="1" end="1"/>
+ <field name="CF" start="0" end="0"/>
+ </flags>
+
+ <!-- General registers -->
+
+ <reg name="rax" bitsize="64" type="int64" regnum="0"/>
+ <reg name="rbx" bitsize="64" type="int64"/>
+ <reg name="rcx" bitsize="64" type="int64"/>
+ <reg name="rdx" bitsize="64" type="int64"/>
+ <reg name="rsi" bitsize="64" type="int64"/>
+ <reg name="rdi" bitsize="64" type="int64"/>
+ <reg name="rbp" bitsize="64" type="data_ptr"/>
+ <reg name="rsp" bitsize="64" type="data_ptr"/>
+ <reg name="r8" bitsize="64" type="int64"/>
+ <reg name="r9" bitsize="64" type="int64"/>
+ <reg name="r10" bitsize="64" type="int64"/>
+ <reg name="r11" bitsize="64" type="int64"/>
+ <reg name="r12" bitsize="64" type="int64"/>
+ <reg name="r13" bitsize="64" type="int64"/>
+ <reg name="r14" bitsize="64" type="int64"/>
+ <reg name="r15" bitsize="64" type="int64"/>
+
+ <reg name="rip" bitsize="64" type="code_ptr"/>
+ <reg name="eflags" bitsize="32" type="x64_eflags"/>
+
+ <!-- Segment registers -->
+
+ <reg name="cs" bitsize="32" type="int32"/>
+ <reg name="ss" bitsize="32" type="int32"/>
+ <reg name="ds" bitsize="32" type="int32"/>
+ <reg name="es" bitsize="32" type="int32"/>
+ <reg name="fs" bitsize="32" type="int32"/>
+ <reg name="gs" bitsize="32" type="int32"/>
+
+ <!-- Segment descriptor caches and TLS base MSRs -->
+
+ <!--reg name="cs_base" bitsize="64" type="int64"/>
+ <reg name="ss_base" bitsize="64" type="int64"/>
+ <reg name="ds_base" bitsize="64" type="int64"/>
+ <reg name="es_base" bitsize="64" type="int64"/-->
+ <reg name="fs_base" bitsize="64" type="int64"/>
+ <reg name="gs_base" bitsize="64" type="int64"/>
+ <reg name="k_gs_base" bitsize="64" type="int64"/>
+
+ <!-- Control registers -->
+
+ <flags id="x64_cr0" size="8">
+ <field name="PG" start="31" end="31"/>
+ <field name="CD" start="30" end="30"/>
+ <field name="NW" start="29" end="29"/>
+ <field name="AM" start="18" end="18"/>
+ <field name="WP" start="16" end="16"/>
+ <field name="NE" start="5" end="5"/>
+ <field name="ET" start="4" end="4"/>
+ <field name="TS" start="3" end="3"/>
+ <field name="EM" start="2" end="2"/>
+ <field name="MP" start="1" end="1"/>
+ <field name="PE" start="0" end="0"/>
+ </flags>
+
+ <flags id="x64_cr3" size="8">
+ <field name="PDBR" start="12" end="63"/>
+ <!--field name="" start="3" end="11"/>
+ <field name="WT" start="2" end="2"/>
+ <field name="CD" start="1" end="1"/>
+ <field name="" start="0" end="0"/-->
+ <field name="PCID" start="0" end="11"/>
+ </flags>
+
+ <flags id="x64_cr4" size="8">
+ <field name="PKE" start="22" end="22"/>
+ <field name="SMAP" start="21" end="21"/>
+ <field name="SMEP" start="20" end="20"/>
+ <field name="OSXSAVE" start="18" end="18"/>
+ <field name="PCIDE" start="17" end="17"/>
+ <field name="FSGSBASE" start="16" end="16"/>
+ <field name="SMXE" start="14" end="14"/>
+ <field name="VMXE" start="13" end="13"/>
+ <field name="LA57" start="12" end="12"/>
+ <field name="UMIP" start="11" end="11"/>
+ <field name="OSXMMEXCPT" start="10" end="10"/>
+ <field name="OSFXSR" start="9" end="9"/>
+ <field name="PCE" start="8" end="8"/>
+ <field name="PGE" start="7" end="7"/>
+ <field name="MCE" start="6" end="6"/>
+ <field name="PAE" start="5" end="5"/>
+ <field name="PSE" start="4" end="4"/>
+ <field name="DE" start="3" end="3"/>
+ <field name="TSD" start="2" end="2"/>
+ <field name="PVI" start="1" end="1"/>
+ <field name="VME" start="0" end="0"/>
+ </flags>
+
+ <flags id="x64_efer" size="8">
+ <field name="TCE" start="15" end="15"/>
+ <field name="FFXSR" start="14" end="14"/>
+ <field name="LMSLE" start="13" end="13"/>
+ <field name="SVME" start="12" end="12"/>
+ <field name="NXE" start="11" end="11"/>
+ <field name="LMA" start="10" end="10"/>
+ <field name="LME" start="8" end="8"/>
+ <field name="SCE" start="0" end="0"/>
+ </flags>
+
+ <reg name="cr0" bitsize="64" type="x64_cr0"/>
+ <reg name="cr2" bitsize="64" type="int64"/>
+ <reg name="cr3" bitsize="64" type="x64_cr3"/>
+ <reg name="cr4" bitsize="64" type="x64_cr4"/>
+ <reg name="cr8" bitsize="64" type="int64"/>
+ <reg name="efer" bitsize="64" type="x64_efer"/>
+
+ <!-- x87 FPU -->
+
+ <reg name="st0" bitsize="80" type="i387_ext"/>
+ <reg name="st1" bitsize="80" type="i387_ext"/>
+ <reg name="st2" bitsize="80" type="i387_ext"/>
+ <reg name="st3" bitsize="80" type="i387_ext"/>
+ <reg name="st4" bitsize="80" type="i387_ext"/>
+ <reg name="st5" bitsize="80" type="i387_ext"/>
+ <reg name="st6" bitsize="80" type="i387_ext"/>
+ <reg name="st7" bitsize="80" type="i387_ext"/>
+
+ <reg name="fctrl" bitsize="32" type="int" group="float"/>
+ <reg name="fstat" bitsize="32" type="int" group="float"/>
+ <reg name="ftag" bitsize="32" type="int" group="float"/>
+ <reg name="fiseg" bitsize="32" type="int" group="float"/>
+ <reg name="fioff" bitsize="32" type="int" group="float"/>
+ <reg name="foseg" bitsize="32" type="int" group="float"/>
+ <reg name="fooff" bitsize="32" type="int" group="float"/>
+ <reg name="fop" bitsize="32" type="int" group="float"/>
+
+ <vector id="v4f" type="ieee_single" count="4"/>
+ <vector id="v2d" type="ieee_double" count="2"/>
+ <vector id="v16i8" type="int8" count="16"/>
+ <vector id="v8i16" type="int16" count="8"/>
+ <vector id="v4i32" type="int32" count="4"/>
+ <vector id="v2i64" type="int64" count="2"/>
+ <union id="vec128">
+ <field name="v4_float" type="v4f"/>
+ <field name="v2_double" type="v2d"/>
+ <field name="v16_int8" type="v16i8"/>
+ <field name="v8_int16" type="v8i16"/>
+ <field name="v4_int32" type="v4i32"/>
+ <field name="v2_int64" type="v2i64"/>
+ <field name="uint128" type="uint128"/>
+ </union>
+ <flags id="x64_mxcsr" size="4">
+ <field name="IE" start="0" end="0"/>
+ <field name="DE" start="1" end="1"/>
+ <field name="ZE" start="2" end="2"/>
+ <field name="OE" start="3" end="3"/>
+ <field name="UE" start="4" end="4"/>
+ <field name="PE" start="5" end="5"/>
+ <field name="DAZ" start="6" end="6"/>
+ <field name="IM" start="7" end="7"/>
+ <field name="DM" start="8" end="8"/>
+ <field name="ZM" start="9" end="9"/>
+ <field name="OM" start="10" end="10"/>
+ <field name="UM" start="11" end="11"/>
+ <field name="PM" start="12" end="12"/>
+ <field name="FZ" start="15" end="15"/>
+ </flags>
+
+ <reg name="xmm0" bitsize="128" type="vec128"/>
+ <reg name="xmm1" bitsize="128" type="vec128"/>
+ <reg name="xmm2" bitsize="128" type="vec128"/>
+ <reg name="xmm3" bitsize="128" type="vec128"/>
+ <reg name="xmm4" bitsize="128" type="vec128"/>
+ <reg name="xmm5" bitsize="128" type="vec128"/>
+ <reg name="xmm6" bitsize="128" type="vec128"/>
+ <reg name="xmm7" bitsize="128" type="vec128"/>
+ <reg name="xmm8" bitsize="128" type="vec128"/>
+ <reg name="xmm9" bitsize="128" type="vec128"/>
+ <reg name="xmm10" bitsize="128" type="vec128"/>
+ <reg name="xmm11" bitsize="128" type="vec128"/>
+ <reg name="xmm12" bitsize="128" type="vec128"/>
+ <reg name="xmm13" bitsize="128" type="vec128"/>
+ <reg name="xmm14" bitsize="128" type="vec128"/>
+ <reg name="xmm15" bitsize="128" type="vec128"/>
+
+ <reg name="mxcsr" bitsize="32" type="x64_mxcsr" group="vector"/>
+</feature>

File Metadata

Mime Type
text/plain
Expires
Mon, Jan 26, 4:35 PM (17 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28040888
Default Alt Text
D43666.id133606.diff (14 KB)

Event Timeline