Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F143075176
D43666.id133606.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
D43666.id133606.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D43666: bhyve: Add support for XML register definitions
Attached
Detach File
Event Timeline
Log In to Comment