@@ -6,3 +6,4 @@ target-obj-y += qmp.o
target-obj-$(CONFIG_INSTRUMENT) += control.o
target-obj-$(CONFIG_INSTRUMENT) += trace.o
+target-obj-$(CONFIG_INSTRUMENT) += state.o
new file mode 100644
@@ -0,0 +1,104 @@
+/*
+ * Interface for accessing guest state.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef QI__STATE_H
+#define QI__STATE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <qemu-instr/types.h>
+
+
+/**
+ * qi_mem_read_virt:
+ * @vcpu: CPU to use for address translation.
+ * @vaddr: Starting virtual address to read from.
+ * @size: Number of bytes to read.
+ * @buf: Buffer to write into.
+ *
+ * Read contents from virtual memory.
+ *
+ * Returns: Whether the range of virtual addresses to read could be translated.
+ *
+ * Warning: Even on error, some of the destination buffer might have been
+ * modified.
+ *
+ * Precondition: The output buffer has at least "size" bytes.
+ */
+bool qi_mem_read_virt(QICPU vcpu, uint64_t vaddr, size_t size, void *buf);
+
+/**
+ * qi_mem_write_virt:
+ * @vcpu: CPU to use for address translation.
+ * @vaddr: Starting virtual address to write into.
+ * @size: Number of bytes to write.
+ * @buf: Buffer with the contents to write from.
+ *
+ * Write contents into virtual memory.
+ *
+ * Returns: Whether the range of virtual addresses to write could be translated.
+ *
+ * Warning: Even on error, some of the destination memory might have been
+ * modified.
+ * Precondition: The input buffer has at least "size" bytes.
+ */
+bool qi_mem_write_virt(QICPU vcpu, uint64_t vaddr, size_t size, void *buf);
+
+/**
+ * qi_mem_virt_to_phys:
+ * @vcpu: CPU to use for address translation.
+ * @vaddr: Virtual address to translate.
+ * @paddr: Pointer to output physical address.
+ *
+ * Translate a virtual address into a physical address.
+ *
+ * Returns: Whether the address could be translated.
+ */
+bool qi_mem_virt_to_phys(QICPU vcpu, uint64_t vaddr, uint64_t *paddr);
+
+/**
+ * qi_mem_read_phys:
+ * @paddr: Starting physical address to read from.
+ * @size: Number of bytes to read.
+ * @buf: Buffer to write into.
+ *
+ * Read contents from physical memory.
+ *
+ * Returns: Whether the range of physical addresses is valid.
+ *
+ * Warning: Even on error, some of the destination buffer might have been
+ * modified.
+ * Precondition: The output buffer has at least "size" bytes.
+ */
+bool qi_mem_read_phys(uint64_t paddr, size_t size, void *buf);
+
+/**
+ * qi_mem_write_phys:
+ * @paddr: Starting physical address to write into.
+ * @size: Number of bytes to write.
+ * @buf: Buffer with the contents to write from.
+ *
+ * Write contents into virtual memory.
+ *
+ * Returns: Whether the range of physical addresses is valid.
+ *
+ * Warning: Even on error, some of the destination memory might have been
+ * modified.
+ *
+ * Precondition: The input buffer has at least "size" bytes.
+ */
+bool qi_mem_write_phys(uint64_t paddr, size_t size, void *buf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* QI__STATE_H */
new file mode 100644
@@ -0,0 +1,72 @@
+/*
+ * Interface for accessing guest state.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "exec/cpu-all.h"
+#include "instrument/control.h"
+#include "instrument/error.h"
+#include "instrument/qemu-instr/state.h"
+#include "instrument/qemu-instr/visibility.h"
+
+
+QI_VPUBLIC bool qi_mem_read_virt(QICPU vcpu, uint64_t vaddr,
+ size_t size, void *buf)
+{
+ CPUState *vcpu_ = instr_cpu_get(vcpu);
+ ERROR_IF_RET(!instr_get_state(), false, "called outside instrumentation");
+ ERROR_IF_RET(!vcpu_, false, "invalid QICPU");
+ return cpu_memory_rw_debug(vcpu_, vaddr, buf, size, 0) == 0;
+}
+
+QI_VPUBLIC bool qi_mem_write_virt(QICPU vcpu, uint64_t vaddr,
+ size_t size, void *buf)
+{
+ CPUState *vcpu_ = instr_cpu_get(vcpu);
+ ERROR_IF_RET(!instr_get_state(), false, "called outside instrumentation");
+ ERROR_IF_RET(!vcpu_, false, "invalid QICPU");
+ return cpu_memory_rw_debug(vcpu_, vaddr, buf, size, 1) == 0;
+}
+
+QI_VPUBLIC bool qi_mem_virt_to_phys(QICPU vcpu, uint64_t vaddr, uint64_t *paddr)
+{
+ CPUState *vcpu_ = instr_cpu_get(vcpu);
+ ERROR_IF_RET(!instr_get_state(), false, "called outside instrumentation");
+ ERROR_IF_RET(!vcpu_, false, "invalid QICPU");
+
+#if defined(CONFIG_USER_ONLY)
+ *paddr = vaddr;
+ return true;
+#else
+ *paddr = cpu_get_phys_page_debug(vcpu_, vaddr);
+ return *paddr != -1;
+#endif
+}
+
+QI_VPUBLIC bool qi_mem_read_phys(uint64_t paddr, size_t size, void *buf)
+{
+ ERROR_IF_RET(!instr_get_state(), false, "called outside instrumentation");
+#if defined(CONFIG_USER_ONLY)
+ return cpu_memory_rw_debug(NULL, paddr, buf, size, 0) == 0;
+#else
+ cpu_physical_memory_read(paddr, buf, size);
+ return true;
+#endif
+}
+
+QI_VPUBLIC bool qi_mem_write_phys(uint64_t paddr, size_t size, void *buf)
+{
+ ERROR_IF_RET(!instr_get_state(), false, "called outside instrumentation");
+#if defined(CONFIG_USER_ONLY)
+ return cpu_memory_rw_debug(NULL, paddr, buf, size, 1) == 0;
+#else
+ cpu_physical_memory_write(paddr, buf, size);
+ return true;
+#endif
+}
It includes access to the guest's memory and vCPU registers. Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu> --- instrument/Makefile.objs | 1 instrument/qemu-instr/state.h | 104 +++++++++++++++++++++++++++++++++++++++++ instrument/state.c | 72 ++++++++++++++++++++++++++++ 3 files changed, 177 insertions(+) create mode 100644 instrument/qemu-instr/state.h create mode 100644 instrument/state.c