|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 2/2] Add xen-hyp-rw
This allows reading and writing of variables in the hypervisor.
for example (read case -- default 4 bytes):
xen-hyp-rw /boot/System.map-xen* opt_hvm_debug_level
opt_hvm_debug_level @ 0xffff82d080285610 is 0x0(0)
Write case:
xen-hyp-rw /boot/System.map-xen* opt_hvm_debug_level 4 -1
opt_hvm_debug_level @ 0xffff82d080285610 is 0x0(0)
opt_hvm_debug_level @ 0xffff82d080285610 set to 0xffffffff(4294967295)
Signed-off-by: Don Slutz <dslutz@xxxxxxxxxxx>
CC: Don Slutz <don.slutz@xxxxxxxxx>
---
.gitignore | 1 +
tools/debugger/gdbsx/Makefile | 7 +-
tools/debugger/gdbsx/xen-hyp-rw.c | 209 ++++++++++++++++++++++++++++++++++++
tools/debugger/gdbsx/xg/xg_main.c | 28 +++++
tools/debugger/gdbsx/xg/xg_public.h | 2 +
5 files changed, 246 insertions(+), 1 deletion(-)
create mode 100644 tools/debugger/gdbsx/xen-hyp-rw.c
diff --git a/.gitignore b/.gitignore
index 3f42ded..73dce09 100644
--- a/.gitignore
+++ b/.gitignore
@@ -104,6 +104,7 @@ tools/debugger/gdb/gdb-6.2.1-linux-i386-xen/*
tools/debugger/gdb/gdb-6.2.1/*
tools/debugger/gdb/gdb-6.2.1.tar.bz2
tools/debugger/gdbsx/gdbsx
+tools/debugger/gdbsx/xen-hyp-rw
tools/debugger/xenitp/xenitp
tools/firmware/*/biossums
tools/firmware/*.bin
diff --git a/tools/debugger/gdbsx/Makefile b/tools/debugger/gdbsx/Makefile
index 4ed6d76..6a8c4ac 100644
--- a/tools/debugger/gdbsx/Makefile
+++ b/tools/debugger/gdbsx/Makefile
@@ -6,10 +6,11 @@ all:
$(MAKE) -C gx
$(MAKE) -C xg
$(MAKE) gdbsx
+ $(MAKE) xen-hyp-rw
.PHONY: clean
clean:
- rm -f xg_all.a gx_all.a gdbsx
+ rm -f xg_all.a gx_all.a gdbsx xen-hyp-rw
set -e; for d in xg gx; do $(MAKE) -C $$d clean; done
.PHONY: distclean
@@ -20,10 +21,14 @@ distclean: clean
install: all
[ -d $(DESTDIR)$(sbindir) ] || $(INSTALL_DIR) $(DESTDIR)$(sbindir)
$(INSTALL_PROG) gdbsx $(DESTDIR)$(sbindir)/gdbsx
+ $(INSTALL_PROG) xen-hyp-rw $(DESTDIR)$(sbindir)/xen-hyp-rw
gdbsx: gx/gx_all.a xg/xg_all.a
$(CC) -o $@ $^
+xen-hyp-rw: xen-hyp-rw.c gx/gx_all.a xg/xg_all.a
+ $(CC) $(CFLAGS) $(CFLAGS_xeninclude) -o $@ $^
+
xg/xg_all.a:
$(MAKE) -C xg
gx/gx_all.a:
diff --git a/tools/debugger/gdbsx/xen-hyp-rw.c
b/tools/debugger/gdbsx/xen-hyp-rw.c
new file mode 100644
index 0000000..ee10fe9
--- /dev/null
+++ b/tools/debugger/gdbsx/xen-hyp-rw.c
@@ -0,0 +1,209 @@
+/******************************************************************************
+ * tools/debugger/gdbsx/xen-hyp-rw.c
+ *
+ * read and write hypervisor memory.
+ *
+ * Copyright (C) 2014 by Verizon.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <signal.h>
+#include <ctype.h>
+
+#include <xen/xen.h>
+
+typedef unsigned char uchar;
+typedef long long unsigned int u64;
+
+#include "xg/xg_public.h"
+
+void gxprt(const char *fmt, ...);
+
+static u64 read_symbol_table(const char *symtab, const char *who)
+{
+ u64 ret = 0;
+ char type, line[256];
+ char *p;
+ FILE *f;
+ u64 address;
+
+ f = fopen(symtab, "r");
+ if ( f == NULL )
+ {
+ fprintf(stderr, "failed to open symbol table %s\n", symtab);
+ exit(-1);
+ }
+
+ while ( !feof(f) )
+ {
+ if ( fgets(line, 256, f) == NULL )
+ break;
+
+ /* need more checks for syntax here... */
+ address = strtoull(line, &p, 16);
+ if ( !isspace((uint8_t)*p++) )
+ continue;
+ type = *p++;
+ if ( !isalpha((uint8_t)type) && type != '?' )
+ continue;
+ if ( !isspace((uint8_t)*p++) )
+ continue;
+
+ /* in the future we should handle the module name
+ * being appended here, this would allow us to use
+ * /proc/kallsyms as our symbol table
+ */
+ if ( p[strlen(p) - 1] == '\n' )
+ p[strlen(p) - 1] = '\0';
+
+ switch ( type )
+ {
+ case 'A': /* global absolute */
+ case 'a': /* local absolute */
+ break;
+ case 'U': /* undefined */
+ case 'v': /* undefined weak object */
+ case 'w': /* undefined weak function */
+ continue;
+ default:
+ break;
+ }
+
+ if ( strcmp(p, who) == 0 )
+ ret = address;
+ }
+
+ fclose(f);
+
+ return ret;
+}
+
+int
+main(int argc, char *argv[])
+{
+ domid_t domid = DOMID_IDLE;
+ int exit_rc = 0;
+ u64 hyp_va;
+ u64 val = 0;
+ long len = sizeof(int);
+ char *endptr = NULL;
+ int remain;
+
+ if ( strcmp(argv[argc - 1], "-d") == 0 )
+ {
+ xgtrc_on = 1; /* debug trace on */
+ argc--;
+ }
+
+ if ( argc < 3 )
+ {
+ printf("Usage: %s [-d] <symbol file> <symbol> [<length> [<new
value>]]\n",
+ argv[0]);
+ gxprt("ERROR: Need symbol file and symbol\n");
+ exit(1);
+ }
+
+ hyp_va = read_symbol_table(argv[1], argv[2]);
+ if ( !hyp_va )
+ {
+ gxprt("ERROR: failed to find symbol:%s\n", argv[2]);
+ exit(1);
+ }
+
+ if ( argc > 3 )
+ {
+ errno = 0;
+ len = strtol(argv[3], &endptr, 0);
+ if ( endptr == argv[3] ||
+ *endptr )
+ {
+ gxprt("ERROR: Failed to convert '%s' to a long.\n",
+ argv[3]);
+ exit(2);
+ }
+ if ( len < 1 )
+ {
+ gxprt("ERROR: length=%ld too small.\n", len);
+ exit(3);
+ }
+ else if ( len > sizeof(val) )
+ {
+ gxprt("ERROR: length=%ld too big.\n", len);
+ exit(4);
+ }
+ }
+
+ if ( xg_init() == -1 )
+ {
+ gxprt("ERROR: failed to initialize errno:%d\n", errno);
+ exit(1);
+ }
+ if ( (hyp_attach(domid)) == -1 )
+ {
+ gxprt("ERROR: failed to attach to domain:%d errno:%d\n",
+ domid, errno);
+ exit(1);
+ }
+ if ( (remain = xg_read_mem(hyp_va, (char *)&val, len, 0) != 0) )
+ XGERR("Failed read mem. addr:0x%llx len:%d remn:%d errno:%d\n",
+ hyp_va, len, remain, errno);
+ else
+ {
+ printf("%s @ 0x%llx is 0x%llx(%lld)\n",
+ argv[2], hyp_va, val, val);
+ if ( argc > 4 )
+ {
+ u64 new = strtoll(argv[4], &endptr, 0);
+
+ if ( endptr && (*endptr == 0) )
+ {
+ if ( (remain = xg_write_mem(hyp_va, (char *)&new, len, 0)
+ != 0) )
+ XGERR(
+ "Failed write addr:0x%llx len:%d remn:%d errno:%d\n",
+ hyp_va, len, remain, errno);
+ else
+ {
+ if ( (remain = xg_read_mem(hyp_va, (char *)&val, len, 0)
+ != 0) )
+ XGERR(
+ "Failed read addr:0x%llx len:%d remn:%d
errno:%d\n",
+ hyp_va, len, remain, errno);
+ printf("%s @ 0x%llx set to 0x%llx(%lld)\n",
+ argv[2], hyp_va, val, val);
+ }
+ }
+ }
+ }
+
+ hyp_detach();
+ return exit_rc;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/debugger/gdbsx/xg/xg_main.c
b/tools/debugger/gdbsx/xg/xg_main.c
index c95e4ed..32e16a4 100644
--- a/tools/debugger/gdbsx/xg/xg_main.c
+++ b/tools/debugger/gdbsx/xg/xg_main.c
@@ -340,6 +340,7 @@ xg_detach_deinit(void)
_unpause_domain();
close(_dom0_fd);
+ munlock(&domctl, sizeof(domctl));
}
/*
@@ -829,6 +830,33 @@ xg_write_mem(uint64_t guestva, char *frombuf, int buflen,
uint64_t pgd3val)
}
/*
+ * Attach to xen for debugging.
+ */
+int
+hyp_attach(int domid)
+{
+ XGTRC("E:domid:%d\n", domid);
+
+ _dom_id = domctl.domain = domid;
+ domctl.interface_version = XEN_DOMCTL_INTERFACE_VERSION;
+
+ if (mlock(&domctl, sizeof(domctl))) {
+ XGERR("Unable to pin domctl in memory. errno:%d\n", errno);
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Detach from xen for debugger exit */
+void
+hyp_detach(void)
+{
+ close(_dom0_fd);
+ munlock(&domctl, sizeof(domctl));
+}
+
+/*
* Local variables:
* mode: C
* c-file-style: "BSD"
diff --git a/tools/debugger/gdbsx/xg/xg_public.h
b/tools/debugger/gdbsx/xg/xg_public.h
index 6236d08..976cf5e 100644
--- a/tools/debugger/gdbsx/xg/xg_public.h
+++ b/tools/debugger/gdbsx/xg/xg_public.h
@@ -108,3 +108,5 @@ int xg_read_mem(uint64_t, char *, int, uint64_t);
int xg_write_mem(uint64_t, char *, int, uint64_t);
void xgprt(const char *fn, const char *fmt, ...);
void xgtrc(const char *fn, const char *fmt, ...);
+int hyp_attach(int);
+void hyp_detach(void);
--
1.8.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |