* [Qemu-devel] [PATCH 01/18] backdoor: Handle config-time activation
2010-10-22 18:53 ` Lluís
@ 2010-10-18 17:24 ` Lluís
2010-10-18 17:40 ` [Qemu-devel] [PATCH 04/18] backdoor: Declare guest-side interface macros Lluís
` (16 subsequent siblings)
17 siblings, 0 replies; 33+ messages in thread
From: Lluís @ 2010-10-18 17:24 UTC (permalink / raw)
To: qemu-devel
Add a '--with-backdoor' configuration option pointing to user-provided backdoor
callback implementation.
Make is invoked on the user-provided directory, which must build a static
library containing, at least, the implementation of the backdoor helpers.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
Makefile.target | 40 ++++++++++++++++++++++++++++++++++++----
configure | 21 +++++++++++++++++++++
2 files changed, 57 insertions(+), 4 deletions(-)
diff --git a/Makefile.target b/Makefile.target
index c48cbcc..9152723 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -29,7 +29,7 @@ QEMU_PROG=qemu-system-$(TARGET_ARCH2)$(EXESUF)
endif
endif
-PROGS=$(QEMU_PROG)
+PROGS=$(QEMU_PROG)-prepare $(QEMU_PROG)
ifndef CONFIG_HAIKU
LIBS+=-lm
@@ -323,8 +323,40 @@ endif # CONFIG_SOFTMMU
obj-y += $(addprefix ../, $(trace-obj-y))
obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o
-$(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)
- $(call LINK,$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y))
+
+.PHONY: force
+force:
+
+#########################################################
+# backdoor communication channel
+ifdef CONFIG_BACKDOOR
+VPATH := $(VPATH):$(BACKDOOR_PATH)
+
+LIBBACKDOOR_LIB = libbackdoor/libbackdoor.a
+LIBBACKDOOR_CLEAN = libbackdoor-clean
+
+libbackdoor/Makefile:
+ $(call quiet-command, mkdir -p libbackdoor, " CREAT $(TARGET_DIR)$@")
+ $(call quiet-command, rm -f libbackdoor/Makefile)
+ $(call quiet-command, ln -s $(BACKDOOR_PATH)/Makefile libbackdoor/Makefile)
+
+libbackdoor/libbackdoor.a: libbackdoor/Makefile force
+ $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libbackdoor \
+ QEMU_CFLAGS="$(QEMU_CFLAGS) -I../target-$(TARGET_BASE_ARCH)" \
+ TARGET_DIR=$(TARGET_DIR)libbackdoor/ VPATH=$(VPATH) \
+ SRC_PATH=$(SRC_PATH) V="$(V)" libbackdoor.a)
+
+libbackdoor-clean:
+ $(MAKE) $(SUBDIR_MAKEFLAGS) -C $(LIBBACKDOOR_DIR) \
+ VPATH=$(VPATH) SRC_PATH=$(SRC_PATH) V="$(V)" clean || true
+endif
+
+
+
+$(QEMU_PROG)-prepare: $(GENERATED_HEADERS) $(LIBBACKDOOR_LIB) $(QEMU_PROG)
+
+$(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y) $(LIBBACKDOOR_LIB)
+ $(call LINK,$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)) $(LIBBACKDOOR_LIB)
gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/feature_to_c.sh
@@ -336,7 +368,7 @@ hmp-commands.h: $(SRC_PATH)/hmp-commands.hx
qmp-commands.h: $(SRC_PATH)/qmp-commands.hx
$(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@")
-clean:
+clean: $(LIBBACKDOOR_CLEAN)
rm -f *.o *.a *~ $(PROGS) nwfpe/*.o fpu/*.o
rm -f *.d */*.d tcg/*.o ide/*.o
rm -f hmp-commands.h qmp-commands.h gdbstub-xml.c
diff --git a/configure b/configure
index a079a49..0de937e 100755
--- a/configure
+++ b/configure
@@ -332,6 +332,8 @@ trace_backend="nop"
trace_file="trace"
spice=""
+backdoor=""
+
# OS specific
if check_define __linux__ ; then
targetos="Linux"
@@ -740,6 +742,14 @@ for opt do
;;
--*dir)
;;
+ --with-backdoor=*) backdoor="$optarg"
+ if test ! -f "$backdoor/Makefile"; then
+ echo "ERROR: cannot make into $backdoor"
+ show_help="yes"
+ else
+ backdoor=`readlink -f $backdoor`
+ fi
+ ;;
*) echo "ERROR: unknown option $opt"; show_help="yes"
;;
esac
@@ -931,6 +941,7 @@ echo " --trace-file=NAME Full PATH,NAME of file to store traces"
echo " Default:trace-<pid>"
echo " --disable-spice disable spice"
echo " --enable-spice enable spice"
+echo " --with-backdoor=PATH enable backdoor communication and compile implementation in PATH"
echo ""
echo "NOTE: The object files are built at the place where configure is launched"
exit 1
@@ -2321,6 +2332,10 @@ echo "Trace backend $trace_backend"
echo "Trace output file $trace_file-<pid>"
echo "spice support $spice"
+if test -n "$backdoor"; then
+ echo "Backdoor comm. $backdoor"
+fi
+
if test $sdl_too_old = "yes"; then
echo "-> Your SDL version is too old - please upgrade to have SDL support"
fi
@@ -2579,6 +2594,12 @@ if test "$spice" = "yes" ; then
echo "CONFIG_SPICE=y" >> $config_host_mak
fi
+if test -n "$backdoor"; then
+ echo "CONFIG_BACKDOOR=y" >> $config_host_mak
+ echo "BACKDOOR_PATH=$backdoor" >> $config_host_mak
+ rm -rf *-{linux-user,softmmu}/libbackdoor/
+fi
+
# XXX: suppress that
if [ "$bsd" = "yes" ] ; then
echo "CONFIG_BSD=y" >> $config_host_mak
--
1.7.1
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Qemu-devel] [PATCH 04/18] backdoor: Declare guest-side interface macros
2010-10-22 18:53 ` Lluís
2010-10-18 17:24 ` [Qemu-devel] [PATCH 01/18] backdoor: Handle config-time activation Lluís
@ 2010-10-18 17:40 ` Lluís
2010-10-18 18:08 ` [Qemu-devel] [PATCH 06/18] backdoor: [i386] " Lluís
` (15 subsequent siblings)
17 siblings, 0 replies; 33+ messages in thread
From: Lluís @ 2010-10-18 17:40 UTC (permalink / raw)
To: qemu-devel
Header for the user to include when compiling guest applications that want to
communicate with QEMU through backdoor instructions.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
backdoor/guest.h | 36 ++++++++++++++++++++++++++++++++++++
1 files changed, 36 insertions(+), 0 deletions(-)
create mode 100644 backdoor/guest.h
diff --git a/backdoor/guest.h b/backdoor/guest.h
new file mode 100644
index 0000000..58847e2
--- /dev/null
+++ b/backdoor/guest.h
@@ -0,0 +1,36 @@
+/*
+ * Guest-side interface for instruction-based backdoor communication.
+ *
+ * Copyright (c) 2010 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef BACKDOOR_GUEST_H
+#define BACKDOOR_GUEST_H
+
+/* Backdoor macro names define the types of its arguments:
+ *
+ * - i8: immediate of 8 bits
+ * - V: value passed in register
+ */
+
+#error Undefined instruction-based backdoor interface for guest architecture
+
+#define __str(s) #s
+#define __xstr(s) __str(s)
+
+#define __BACKDOOR_i8(b) asm volatile (".byte " __xstr(b))
+
+#endif /* BACKDOOR_GUEST_H */
--
1.7.1
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Qemu-devel] [PATCH 06/18] backdoor: [i386] Declare guest-side interface macros
2010-10-22 18:53 ` Lluís
2010-10-18 17:24 ` [Qemu-devel] [PATCH 01/18] backdoor: Handle config-time activation Lluís
2010-10-18 17:40 ` [Qemu-devel] [PATCH 04/18] backdoor: Declare guest-side interface macros Lluís
@ 2010-10-18 18:08 ` Lluís
2010-10-18 18:27 ` [Qemu-devel] [PATCH 08/18] instrument: Handle config-time activation Lluís
` (14 subsequent siblings)
17 siblings, 0 replies; 33+ messages in thread
From: Lluís @ 2010-10-18 18:08 UTC (permalink / raw)
To: qemu-devel
Guest-side macros to generate backdoor instructions.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
backdoor/guest.h | 24 ++++++++++++++++++++++++
1 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/backdoor/guest.h b/backdoor/guest.h
index 58847e2..17029d3 100644
--- a/backdoor/guest.h
+++ b/backdoor/guest.h
@@ -26,8 +26,32 @@
* - V: value passed in register
*/
+#if __i386__ || __i486__ || __x86_64__
+
+#define __BACKDOOR_BASE asm volatile (".byte 0x0f, 0x04")
+#define __BACKDOOR_V(v) asm volatile ("movl %0, %%eax" : : "g"(v) : "%eax")
+
+#define BACKDOOR_i8(cmd) \
+ do { \
+ __BACKDOOR_BASE; \
+ __BACKDOOR_i8(0x00); \
+ __BACKDOOR_i8(cmd); \
+ } while (0)
+
+#define BACKDOOR_i8_V(cmd, value) \
+ do { \
+ __BACKDOOR_V(value); \
+ __BACKDOOR_BASE; \
+ __BACKDOOR_i8(0x01); \
+ __BACKDOOR_i8(cmd); \
+ } while (0)
+
+#else
+
#error Undefined instruction-based backdoor interface for guest architecture
+#endif
+
#define __str(s) #s
#define __xstr(s) __str(s)
--
1.7.1
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Qemu-devel] [PATCH 08/18] instrument: Handle config-time activation
2010-10-22 18:53 ` Lluís
` (2 preceding siblings ...)
2010-10-18 18:08 ` [Qemu-devel] [PATCH 06/18] backdoor: [i386] " Lluís
@ 2010-10-18 18:27 ` Lluís
2010-10-19 19:14 ` [Qemu-devel] [PATCH 05/18] backdoor: [i386] Decode backdoor instructions Lluís
` (13 subsequent siblings)
17 siblings, 0 replies; 33+ messages in thread
From: Lluís @ 2010-10-18 18:27 UTC (permalink / raw)
To: qemu-devel
Add a '--with-instrument' configuration option pointing to user-provided
instrumentation callbacks.
Make is invoked on the user-provided directory, which must build a static
library that might contain extra code needed by the user-provided
instrumentation.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
Makefile.target | 29 ++++++++++++++++++++++++++---
configure | 19 +++++++++++++++++++
2 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/Makefile.target b/Makefile.target
index 9152723..90867e7 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -351,12 +351,35 @@ libbackdoor-clean:
VPATH=$(VPATH) SRC_PATH=$(SRC_PATH) V="$(V)" clean || true
endif
+#########################################################
+# static instrumentation
+ifdef CONFIG_INSTRUMENT
+VPATH := $(VPATH):$(INSTRUMENT_PATH)
+
+LIBINSTRUMENT_LIB = libinstrument/libinstrument.a
+LIBINSTRUMENT_CLEAN = libinstrument-clean
+
+libinstrument/Makefile:
+ $(call quiet-command, mkdir -p libinstrument, " CREAT $(TARGET_DIR)$@")
+ $(call quiet-command, rm -f libinstrument/Makefile)
+ $(call quiet-command, ln -s $(INSTRUMENT_PATH)/Makefile libinstrument/Makefile)
+
+libinstrument/libinstrument.a: libinstrument/Makefile force
+ $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libinstrument \
+ QEMU_CFLAGS="$(QEMU_CFLAGS) -I../target-$(TARGET_BASE_ARCH)" \
+ TARGET_DIR=$(TARGET_DIR)libinstrument/ VPATH=$(VPATH) \
+ SRC_PATH=$(SRC_PATH) V="$(V)" libinstrument.a)
+
+libinstrument-clean:
+ $(MAKE) $(SUBDIR_MAKEFLAGS) -C $(LIBINSTRUMENT_DIR) \
+ VPATH=$(VPATH) SRC_PATH=$(SRC_PATH) V="$(V)" clean || true
+endif
-$(QEMU_PROG)-prepare: $(GENERATED_HEADERS) $(LIBBACKDOOR_LIB) $(QEMU_PROG)
+$(QEMU_PROG)-prepare: $(GENERATED_HEADERS) $(LIBBACKDOOR_LIB) $(LIBINSTRUMENT_LIB) $(QEMU_PROG)
-$(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y) $(LIBBACKDOOR_LIB)
- $(call LINK,$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)) $(LIBBACKDOOR_LIB)
+$(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y) $(LIBBACKDOOR_LIB) $(LIBINSTRUMENT_LIB)
+ $(call LINK,$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)) $(LIBBACKDOOR_LIB) $(LIBINSTRUMENT_LIB)
gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/feature_to_c.sh
diff --git a/configure b/configure
index 0de937e..454124c 100755
--- a/configure
+++ b/configure
@@ -333,6 +333,7 @@ trace_file="trace"
spice=""
backdoor=""
+instrument=""
# OS specific
if check_define __linux__ ; then
@@ -750,6 +751,14 @@ for opt do
backdoor=`readlink -f $backdoor`
fi
;;
+ --with-instrument=*) instrument="$optarg"
+ if test ! -f "$instrument/Makefile"; then
+ echo "ERROR: cannot make into $instrument"
+ show_help="yes"
+ else
+ instrument=`readlink -f $instrument`
+ fi
+ ;;
*) echo "ERROR: unknown option $opt"; show_help="yes"
;;
esac
@@ -942,6 +951,7 @@ echo " Default:trace-<pid>"
echo " --disable-spice disable spice"
echo " --enable-spice enable spice"
echo " --with-backdoor=PATH enable backdoor communication and compile implementation in PATH"
+echo " --with-instrument=PATH enable static instrumentation and compile user code in PATH"
echo ""
echo "NOTE: The object files are built at the place where configure is launched"
exit 1
@@ -2335,6 +2345,9 @@ echo "spice support $spice"
if test -n "$backdoor"; then
echo "Backdoor comm. $backdoor"
fi
+if test -n "$instrument"; then
+ echo "Instrumentation $instrument"
+fi
if test $sdl_too_old = "yes"; then
echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -2599,6 +2612,12 @@ if test -n "$backdoor"; then
echo "BACKDOOR_PATH=$backdoor" >> $config_host_mak
rm -rf *-{linux-user,softmmu}/libbackdoor/
fi
+if test -n "$instrument"; then
+ echo "CONFIG_INSTRUMENT=y" >> $config_host_mak
+ echo "INSTRUMENT_PATH=$instrument" >> $config_host_mak
+ QEMU_CFLAGS="-I$instrument $QEMU_CFLAGS"
+ rm -rf *-{linux-user,softmmu}/libinstrument/
+fi
# XXX: suppress that
if [ "$bsd" = "yes" ] ; then
--
1.7.1
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Qemu-devel] [PATCH 05/18] backdoor: [i386] Decode backdoor instructions
2010-10-22 18:53 ` Lluís
` (3 preceding siblings ...)
2010-10-18 18:27 ` [Qemu-devel] [PATCH 08/18] instrument: Handle config-time activation Lluís
@ 2010-10-19 19:14 ` Lluís
2010-10-19 19:22 ` [Qemu-devel] [PATCH 02/18] backdoor: Declare host-side backdoor helpers Lluís
` (12 subsequent siblings)
17 siblings, 0 replies; 33+ messages in thread
From: Lluís @ 2010-10-19 19:14 UTC (permalink / raw)
To: qemu-devel
Decode backdoor instructions following "backdoor/guest.h" and call the
user-defined backdoor helpers.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
target-i386/translate.c | 30 ++++++++++++++++++++++++++++++
1 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 7b6e3c2..b54a823 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -4105,6 +4105,31 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
x86_64_hregs = 0;
#endif
s->rip_offset = 0; /* for relative ip address */
+
+#if defined(CONFIG_BACKDOOR)
+ if (ldub_code(s->pc) == 0x0f && ldub_code(s->pc + 1) == 0x04) {
+ uint8_t type = ldub_code(s->pc + 2);
+ TCGv_i32 cmd;
+ /* TODO: should break TB, but gen_eob generates an infinite loop */
+ switch (type) {
+ case 0x00: /* i8 */
+ cmd = tcg_const_i32((uint32_t)ldub_code(s->pc + 3));
+ gen_helper_backdoor_i8(cmd);
+ break;
+ case 0x01: /* i8 v */
+ cmd = tcg_const_i32(ldub_code(s->pc + 3));
+ gen_helper_backdoor_i8_v(cmd, cpu_regs[R_EAX]);
+ break;
+ default:
+ goto illegal_op;
+ }
+ s->pc += 4;
+ gen_jmp_im(s->pc);
+ gen_eob(s);
+ goto backdoor_done;
+ }
+#endif
+
next_byte:
b = ldub_code(s->pc);
s->pc++;
@@ -7636,6 +7661,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
default:
goto illegal_op;
}
+
+#if defined(CONFIG_BACKDOOR)
+backdoor_done:
+#endif
+
/* lock generation */
if (s->prefix & PREFIX_LOCK)
gen_helper_unlock();
--
1.7.1
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Qemu-devel] [PATCH 02/18] backdoor: Declare host-side backdoor helpers
2010-10-22 18:53 ` Lluís
` (4 preceding siblings ...)
2010-10-19 19:14 ` [Qemu-devel] [PATCH 05/18] backdoor: [i386] Decode backdoor instructions Lluís
@ 2010-10-19 19:22 ` Lluís
2010-10-19 19:33 ` [Qemu-devel] [PATCH 03/18] backdoor: [all] Include backdoor helper declarations Lluís
` (11 subsequent siblings)
17 siblings, 0 replies; 33+ messages in thread
From: Lluís @ 2010-10-19 19:22 UTC (permalink / raw)
To: qemu-devel
These helpers must be implemented by the user on "libbackdoor.a".
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
backdoor/helper.h | 21 +++++++++++++++++++++
1 files changed, 21 insertions(+), 0 deletions(-)
create mode 100644 backdoor/helper.h
diff --git a/backdoor/helper.h b/backdoor/helper.h
new file mode 100644
index 0000000..18b53ac
--- /dev/null
+++ b/backdoor/helper.h
@@ -0,0 +1,21 @@
+/*
+ * Helpers for instruction-based backdoor communication.
+ *
+ * Copyright (c) 2010 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+DEF_HELPER_1(backdoor_i8, void, i32);
+DEF_HELPER_2(backdoor_i8_v, void, i32, tl);
--
1.7.1
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Qemu-devel] [PATCH 03/18] backdoor: [all] Include backdoor helper declarations
2010-10-22 18:53 ` Lluís
` (5 preceding siblings ...)
2010-10-19 19:22 ` [Qemu-devel] [PATCH 02/18] backdoor: Declare host-side backdoor helpers Lluís
@ 2010-10-19 19:33 ` Lluís
2010-10-19 20:05 ` [Qemu-devel] [PATCH 07/18] backdoor: Add a simple example Lluís
` (10 subsequent siblings)
17 siblings, 0 replies; 33+ messages in thread
From: Lluís @ 2010-10-19 19:33 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
target-alpha/helper.h | 4 ++++
target-arm/helper.h | 4 ++++
target-cris/helper.h | 4 ++++
target-i386/helper.h | 4 ++++
target-m68k/helper.h | 4 ++++
target-microblaze/helper.h | 4 ++++
target-mips/helper.h | 4 ++++
target-ppc/helper.h | 4 ++++
target-sh4/helper.h | 4 ++++
target-sparc/helper.h | 4 ++++
10 files changed, 40 insertions(+), 0 deletions(-)
diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index ccf6a2a..d2ec252 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -123,4 +123,8 @@ DEF_HELPER_2(stl_c_raw, i64, i64, i64)
DEF_HELPER_2(stq_c_raw, i64, i64, i64)
#endif
+#if defined(CONFIG_BACKDOOR)
+#include "backdoor/helper.h"
+#endif
+
#include "def-helper.h"
diff --git a/target-arm/helper.h b/target-arm/helper.h
index 0d1bc47..b46f04c 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -447,4 +447,8 @@ DEF_HELPER_3(iwmmxt_muladdswl, i64, i64, i32, i32)
DEF_HELPER_2(set_teecr, void, env, i32)
+#if defined(CONFIG_BACKDOOR)
+#include "backdoor/helper.h"
+#endif
+
#include "def-helper.h"
diff --git a/target-cris/helper.h b/target-cris/helper.h
index 093063a..72fabce 100644
--- a/target-cris/helper.h
+++ b/target-cris/helper.h
@@ -23,4 +23,8 @@ DEF_HELPER_FLAGS_2(evaluate_flags_move_2, TCG_CALL_PURE, i32, i32, i32)
DEF_HELPER_0(evaluate_flags, void)
DEF_HELPER_0(top_evaluate_flags, void)
+#if defined(CONFIG_BACKDOOR)
+#include "backdoor/helper.h"
+#endif
+
#include "def-helper.h"
diff --git a/target-i386/helper.h b/target-i386/helper.h
index 6b518ad..979d94e 100644
--- a/target-i386/helper.h
+++ b/target-i386/helper.h
@@ -217,4 +217,8 @@ DEF_HELPER_2(rclq, tl, tl, tl)
DEF_HELPER_2(rcrq, tl, tl, tl)
#endif
+#if defined(CONFIG_BACKDOOR)
+#include "backdoor/helper.h"
+#endif
+
#include "def-helper.h"
diff --git a/target-m68k/helper.h b/target-m68k/helper.h
index cb8a0c7..06e8a47 100644
--- a/target-m68k/helper.h
+++ b/target-m68k/helper.h
@@ -51,4 +51,8 @@ DEF_HELPER_3(set_mac_extu, void, env, i32, i32)
DEF_HELPER_2(flush_flags, void, env, i32)
DEF_HELPER_1(raise_exception, void, i32)
+#if defined(CONFIG_BACKDOOR)
+#include "backdoor/helper.h"
+#endif
+
#include "def-helper.h"
diff --git a/target-microblaze/helper.h b/target-microblaze/helper.h
index 11ad1b6..473ed78 100644
--- a/target-microblaze/helper.h
+++ b/target-microblaze/helper.h
@@ -34,4 +34,8 @@ DEF_HELPER_2(mmu_write, void, i32, i32)
DEF_HELPER_4(memalign, void, i32, i32, i32, i32)
+#if defined(CONFIG_BACKDOOR)
+#include "backdoor/helper.h"
+#endif
+
#include "def-helper.h"
diff --git a/target-mips/helper.h b/target-mips/helper.h
index cb13fb2..cbee380 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -287,4 +287,8 @@ DEF_HELPER_0(rdhwr_ccres, tl)
DEF_HELPER_1(pmon, void, int)
DEF_HELPER_0(wait, void)
+#if defined(CONFIG_BACKDOOR)
+#include "backdoor/helper.h"
+#endif
+
#include "def-helper.h"
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 2bf9283..eeb7487 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -401,4 +401,8 @@ DEF_HELPER_2(store_601_batl, void, i32, tl)
DEF_HELPER_2(store_601_batu, void, i32, tl)
#endif
+#if defined(CONFIG_BACKDOOR)
+#include "backdoor/helper.h"
+#endif
+
#include "def-helper.h"
diff --git a/target-sh4/helper.h b/target-sh4/helper.h
index 4b2fcdd..dbea9e1 100644
--- a/target-sh4/helper.h
+++ b/target-sh4/helper.h
@@ -50,4 +50,8 @@ DEF_HELPER_1(fsqrt_DT, i64, i64)
DEF_HELPER_1(ftrc_FT, i32, i32)
DEF_HELPER_1(ftrc_DT, i32, i64)
+#if defined(CONFIG_BACKDOOR)
+#include "backdoor/helper.h"
+#endif
+
#include "def-helper.h"
diff --git a/target-sparc/helper.h b/target-sparc/helper.h
index 6f103e7..b88f0ac 100644
--- a/target-sparc/helper.h
+++ b/target-sparc/helper.h
@@ -160,4 +160,8 @@ VIS_CMPHELPER(cmpne);
DEF_HELPER_0(compute_psr, void);
DEF_HELPER_0(compute_C_icc, i32);
+#if defined(CONFIG_BACKDOOR)
+#include "backdoor/helper.h"
+#endif
+
#include "def-helper.h"
--
1.7.1
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Qemu-devel] [PATCH 07/18] backdoor: Add a simple example
2010-10-22 18:53 ` Lluís
` (6 preceding siblings ...)
2010-10-19 19:33 ` [Qemu-devel] [PATCH 03/18] backdoor: [all] Include backdoor helper declarations Lluís
@ 2010-10-19 20:05 ` Lluís
2010-10-19 21:11 ` [Qemu-devel] [PATCH 13/18] instrument: Add FETCH point Lluís
` (9 subsequent siblings)
17 siblings, 0 replies; 33+ messages in thread
From: Lluís @ 2010-10-19 20:05 UTC (permalink / raw)
To: qemu-devel
Provides a guest application that exercices the instruction-based backdoor
communication, as well as a backdoor callback implementation that prints the
guest requests.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
.gitignore | 1 +
backdoor/examples/print/README | 13 +++++++++++
backdoor/examples/print/guest/Makefile | 7 ++++++
backdoor/examples/print/guest/test.c | 33 +++++++++++++++++++++++++++++
backdoor/examples/print/host/Makefile | 13 +++++++++++
backdoor/examples/print/host/printcb.c | 36 ++++++++++++++++++++++++++++++++
6 files changed, 103 insertions(+), 0 deletions(-)
create mode 100644 backdoor/examples/print/README
create mode 100644 backdoor/examples/print/guest/Makefile
create mode 100644 backdoor/examples/print/guest/test.c
create mode 100644 backdoor/examples/print/host/Makefile
create mode 100644 backdoor/examples/print/host/printcb.c
diff --git a/.gitignore b/.gitignore
index a43e4d1..e4a351d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -58,3 +58,4 @@ pc-bios/optionrom/multiboot.bin
pc-bios/optionrom/multiboot.raw
.stgit-*
cscope.*
+backdoor/examples/print/guest/test
diff --git a/backdoor/examples/print/README b/backdoor/examples/print/README
new file mode 100644
index 0000000..0675f16
--- /dev/null
+++ b/backdoor/examples/print/README
@@ -0,0 +1,13 @@
+This example simply defines instruction-based backdoors to print their
+arguments, along with a guest example code that makes use of backdoor
+instructions.
+
+To compile the host (quemu) run:
+ /path/to/qemu/configure --with-backdoor=/path/to/qemu/backdoor/examples/print/host/
+ make
+
+To compile the guest program run:
+ make -C /path/to/qemu/backdoor/examples/print/guest/
+
+Now you can run it with:
+ /path/to/qemu/i386-linux-user/qemu-i386 /path/to/qemu/backdoor/examples/print/guest/test
diff --git a/backdoor/examples/print/guest/Makefile b/backdoor/examples/print/guest/Makefile
new file mode 100644
index 0000000..ea266f2
--- /dev/null
+++ b/backdoor/examples/print/guest/Makefile
@@ -0,0 +1,7 @@
+CFLAGS += -I../../../../
+PROGS = test
+
+all: $(PROGS)
+
+clean:
+ rm -f $(PROGS)
diff --git a/backdoor/examples/print/guest/test.c b/backdoor/examples/print/guest/test.c
new file mode 100644
index 0000000..8146c3d
--- /dev/null
+++ b/backdoor/examples/print/guest/test.c
@@ -0,0 +1,33 @@
+/*
+ * Sample guest program exercising instruction-based backdoor communication.
+ *
+ * Copyright (c) 2010 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+
+#include "backdoor/guest.h"
+
+int main ()
+{
+ int i = 23;
+ printf("i8 1\n");
+ BACKDOOR_i8(0x01);
+ printf("i8_v 1 32\n");
+ BACKDOOR_i8_V(0x01, 32);
+ printf("i8_v 2 i (%d)\n", i);
+ BACKDOOR_i8_V(0x02, i);
+}
diff --git a/backdoor/examples/print/host/Makefile b/backdoor/examples/print/host/Makefile
new file mode 100644
index 0000000..bfd6311
--- /dev/null
+++ b/backdoor/examples/print/host/Makefile
@@ -0,0 +1,13 @@
+# Makefile for user-provided backdoor code
+
+include $(SRC_PATH)/config-host.mak
+include $(SRC_PATH)/rules.mak
+include $(SRC_PATH)/Makefile.objs
+
+objs = printcb.o
+
+libbackdoor.a: $(objs)
+ $(call quiet-command,rm -f $@ && $(AR) rcs $@ $^," AR $(TARGET_DIR)$@")
+
+clean:
+ rm -f libbackdoor.a $(objs)
diff --git a/backdoor/examples/print/host/printcb.c b/backdoor/examples/print/host/printcb.c
new file mode 100644
index 0000000..b267b6c
--- /dev/null
+++ b/backdoor/examples/print/host/printcb.c
@@ -0,0 +1,36 @@
+/*
+ * Sample user-defined callbacks for backdoor communication.
+ *
+ * Copyright (c) 2010 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+
+#include "cpu.h"
+#include "helper.h"
+
+
+void
+helper_backdoor_i8 (uint32_t imm)
+{
+ printf("backdoor_i8: %u\n", imm);
+}
+
+void
+helper_backdoor_i8_v (uint32_t imm, target_ulong value)
+{
+ printf("backdoor_i8_v: %u "TARGET_FMT_ld"\n", imm, value);
+}
--
1.7.1
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Qemu-devel] [PATCH 13/18] instrument: Add FETCH point
2010-10-22 18:53 ` Lluís
` (7 preceding siblings ...)
2010-10-19 20:05 ` [Qemu-devel] [PATCH 07/18] backdoor: Add a simple example Lluís
@ 2010-10-19 21:11 ` Lluís
2010-10-19 21:12 ` [Qemu-devel] [PATCH 15/18] instrument: Add VMEM point Lluís
` (8 subsequent siblings)
17 siblings, 0 replies; 33+ messages in thread
From: Lluís @ 2010-10-19 21:11 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
cpu-all.h | 6 +++
instrument/examples/dynprint/guest/test.c | 10 +++++
instrument/examples/dynprint/host/backdoor.c | 8 ++++
instrument/examples/dynprint/host/helpers.c | 43 ++++++++++++++++++++
.../dynprint/host/instrument-host-helpers.h | 2 +
.../examples/dynprint/host/instrument-host.h | 14 ++++++
instrument/generate.h | 2 +
instrument/host-stub.h | 9 ++++
instrument/types.h | 17 +++++---
9 files changed, 105 insertions(+), 6 deletions(-)
diff --git a/cpu-all.h b/cpu-all.h
index b15253f..88970a2 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -24,11 +24,17 @@
#if defined(CONFIG_INSTRUMENT)
+#define INSTR_REGS_SET(regs, reg) \
+ do { (regs) |= (((typeof(regs)) 1) << (reg)); } while (0)
#include "instrument/types.h"
#include "instrument/generate.h"
#include "instrument/control.h"
#include "instrument/state.h"
+#else /* defined(CONFIG_INSTRUMENT) */
+
+#define INSTR_REGS_SET(regs, reg)
+
#endif /* defined(CONFIG_INSTRUMENT) */
/* some important defines:
diff --git a/instrument/examples/dynprint/guest/test.c b/instrument/examples/dynprint/guest/test.c
index 7ddd5be..b6b5788 100644
--- a/instrument/examples/dynprint/guest/test.c
+++ b/instrument/examples/dynprint/guest/test.c
@@ -20,6 +20,7 @@
#include <stdio.h>
#include "backdoor/guest.h"
+#include "../host/instrument-host.h"
#define TOTAL_ITERS 100
@@ -32,18 +33,27 @@ main ()
BACKDOOR_i8(0x01); /* enable instrumentation */
printf("start\n");
+ BACKDOOR_i8_V(0x01, INSTR_TYPE_PC); /* show executed PCs */
for (i = 0; i < TOTAL_ITERS; i++) {
/* disable an iteration every 10 iterations */
if (i % 10 == 0) {
BACKDOOR_i8(0x00);
}
+ /* be completely verbose on even iterations */
+ if (i % 2 == 0) {
+ BACKDOOR_i8_V(0x01, INSTR_TYPE_ALL);
+ }
printf("iteration\n");
+ if (i % 2 == 0) {
+ BACKDOOR_i8_V(0x00, INSTR_TYPE_ALL);
+ }
if (i % 10 == 0) {
BACKDOOR_i8(0x01);
}
}
+ BACKDOOR_i8_V(0x00, INSTR_TYPE_PC); /* stop showing PCs */
printf("stop\n");
BACKDOOR_i8(0x00); /* disable instrumentation */
diff --git a/instrument/examples/dynprint/host/backdoor.c b/instrument/examples/dynprint/host/backdoor.c
index 27f612b..7c3e4b7 100644
--- a/instrument/examples/dynprint/host/backdoor.c
+++ b/instrument/examples/dynprint/host/backdoor.c
@@ -46,6 +46,14 @@ void
helper_backdoor_i8_v (uint32_t imm, target_ulong value)
{
switch (imm) {
+ case 0:
+ printf("backdoor: -"TARGET_FMT_lu"\n", value);
+ instr_disable_type(value);
+ break;
+ case 1:
+ printf("backdoor: +"TARGET_FMT_lu"\n", value);
+ instr_enable_type(value);
+ break;
default:
printf("Unexpected use of instrumentation backdoor\n");
abort();
diff --git a/instrument/examples/dynprint/host/helpers.c b/instrument/examples/dynprint/host/helpers.c
index 656b716..173d0ec 100644
--- a/instrument/examples/dynprint/host/helpers.c
+++ b/instrument/examples/dynprint/host/helpers.c
@@ -17,3 +17,46 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
+#include <stdio.h>
+
+#include "cpu.h"
+#include "helper.h"
+
+#include "disas.h"
+#include "instrument/types.h"
+
+
+void
+helper_pc (target_ulong addr)
+{
+ printf("-> 0x"TARGET_FMT_lx"\n", addr);
+}
+
+static void
+print_registers (const char * msg, const instr_regs_t regs)
+{
+ int i, count = 0;
+ printf("%s", msg);
+ for (i = 0; i < sizeof(regs) * 8; i++) {
+ if (( ((instr_regs_t)1) << i) & regs) {
+ count++;
+ printf(" r%02d", i);
+ }
+ }
+ if (!count) {
+ printf(" -");
+ }
+ printf("\n");
+}
+
+void
+helper_all_fetch (target_ulong addr, uint32_t size,
+ instr_regs_t used, instr_regs_t defined)
+{
+ printf("F: ");
+ target_disas(stdout, addr, size, 0);
+
+ printf(" size : %d\n", size);
+ print_registers(" used :", used);
+ print_registers(" defined:", defined);
+}
diff --git a/instrument/examples/dynprint/host/instrument-host-helpers.h b/instrument/examples/dynprint/host/instrument-host-helpers.h
index e88738d..947cf57 100644
--- a/instrument/examples/dynprint/host/instrument-host-helpers.h
+++ b/instrument/examples/dynprint/host/instrument-host-helpers.h
@@ -17,3 +17,5 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
+DEF_HELPER_1(pc, void, tl);
+DEF_HELPER_4(all_fetch, void, tl, i32, i64, i64);
diff --git a/instrument/examples/dynprint/host/instrument-host.h b/instrument/examples/dynprint/host/instrument-host.h
index 92a4c14..15911e7 100644
--- a/instrument/examples/dynprint/host/instrument-host.h
+++ b/instrument/examples/dynprint/host/instrument-host.h
@@ -29,7 +29,21 @@ typedef enum {
* global state of tracing is wasteful, but hey, this is
* just an example.
*/
+ INSTR_TYPE_PC, /* Print fetched PC */
+ INSTR_TYPE_ALL, /* Print all instruction information */
INSTR_TYPE_COUNT /* Total number of instrumentation types (mandatory) */
} instr_type_t;
+
+#define INSTR_GEN_FETCH(taddr, addr, tlength, length, \
+ tused, used, tdefined, defined) \
+ do { \
+ if (INSTR_TYPE(ENABLED) && INSTR_TYPE(PC)) { \
+ INSTR_GEN_1(pc, taddr, addr); \
+ } \
+ if (INSTR_TYPE(ENABLED) && INSTR_TYPE(ALL)) { \
+ INSTR_GEN_4(all_fetch, taddr, addr, tlength, length, \
+ tused, used, tdefined, defined); \
+ } \
+ } while (0)
#endif /* INSTRUMENT_HOST_H */
diff --git a/instrument/generate.h b/instrument/generate.h
index 7e4b35c..60f0c31 100644
--- a/instrument/generate.h
+++ b/instrument/generate.h
@@ -102,6 +102,7 @@
#define __INSTR_ARG_TUL_DECL(tcg, value) __INSTR_ARG_I32_DECL(tcg, value)
#define __INSTR_ARG_TCGv_i32_DECL(tcg, value) TCGv_i32 tcg = value
#endif
+#define __INSTR_ARG_REGS_DECL(tcg, value) __INSTR_ARG_I64_DECL(tcg, value)
#define __INSTR_ARG_DECL(tcg, type, value) __INSTR_ARG_ ##type ##_DECL(tcg, value)
@@ -118,6 +119,7 @@
#define __INSTR_ARG_TCGv_i64_FREE(tcg)
#define __INSTR_ARG_TCGv_i32_FREE(tcg)
#define __INSTR_ARG_TCGv_FREE(tcg)
+#define __INSTR_ARG_REGS_FREE(tcg) __INSTR_ARG_I64_FREE(tcg)
#define __INSTR_ARG_FREE(tcg, type) __INSTR_ARG_ ##type ##_FREE(tcg)
diff --git a/instrument/host-stub.h b/instrument/host-stub.h
index 4178559..30d2cba 100644
--- a/instrument/host-stub.h
+++ b/instrument/host-stub.h
@@ -45,4 +45,13 @@ typedef enum {
* On all cases, the use of "instrument/state.h" is supported.
*/
+/** Signal the fetch and decode of a new instruction.
+ * @param addr Virtual address of the instruction (target_ulong)
+ * @param length Length of the instruction in bytes (uint32_t)
+ * @param used Set of used registers (instr_regs_t)
+ * @param defined Set of defined registers (instr_regs_t)
+ */
+#define INSTR_GEN_FETCH(taddr, addr, tlength, length, \
+ tused, used, tdefined, defined)
+
#endif /* INSTRUMENT__HOST_STUB_H */
diff --git a/instrument/types.h b/instrument/types.h
index eb4036b..ba2b0c2 100644
--- a/instrument/types.h
+++ b/instrument/types.h
@@ -22,12 +22,17 @@
/** Instrumentation argument types. */
typedef enum {
- INSTR_ARG_I32, /**< immediate of 32bits */
- INSTR_ARG_I64, /**< immediate of 64bits */
- INSTR_ARG_TUL, /**< immediate target_ulong */
- INSTR_ARG_TCGv_i32, /**< 32-bit TCGv variable */
- INSTR_ARG_TCGv_i64, /**< 64-bit TCGv variable */
- INSTR_ARG_TCGv, /**< target-bit TCGv variable*/
+ INSTR_ARG_I32, /**< immediate of 32bits */
+ INSTR_ARG_I64, /**< immediate of 64bits */
+ INSTR_ARG_TUL, /**< immediate target_ulong */
+ INSTR_ARG_TCGv_i32, /**< 32-bit TCGv variable */
+ INSTR_ARG_TCGv_i64, /**< 64-bit TCGv variable */
+ INSTR_ARG_TCGv, /**< target-bit TCGv variable */
+ INSTR_ARG_REGS, /**< register set (instr_regs_t) */
} instr_arg_type_t;
+
+/** Register set. */
+typedef uint64_t instr_regs_t;
+
#endif /* INSTRUMENT__TYPES_H */
--
1.7.1
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Qemu-devel] [PATCH 15/18] instrument: Add VMEM point
2010-10-22 18:53 ` Lluís
` (8 preceding siblings ...)
2010-10-19 21:11 ` [Qemu-devel] [PATCH 13/18] instrument: Add FETCH point Lluís
@ 2010-10-19 21:12 ` Lluís
2010-10-19 21:36 ` [Qemu-devel] [PATCH 18/18] instrument: [i386] Call PLVL point Lluís
` (7 subsequent siblings)
17 siblings, 0 replies; 33+ messages in thread
From: Lluís @ 2010-10-19 21:12 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
instrument/examples/dynprint/host/helpers.c | 24 ++++++
.../dynprint/host/instrument-host-helpers.h | 1 +
.../examples/dynprint/host/instrument-host.h | 19 ++++
instrument/gen-vmem-wrappers.h | 88 ++++++++++++++++++++
instrument/generate.h | 2 +
instrument/host-stub.h | 17 ++++
instrument/types.h | 6 ++
7 files changed, 157 insertions(+), 0 deletions(-)
create mode 100644 instrument/gen-vmem-wrappers.h
diff --git a/instrument/examples/dynprint/host/helpers.c b/instrument/examples/dynprint/host/helpers.c
index 173d0ec..6355f43 100644
--- a/instrument/examples/dynprint/host/helpers.c
+++ b/instrument/examples/dynprint/host/helpers.c
@@ -60,3 +60,27 @@ helper_all_fetch (target_ulong addr, uint32_t size,
print_registers(" used :", used);
print_registers(" defined:", defined);
}
+
+inline
+void
+helper_all_mem (target_ulong addr, uint32_t size, instr_mem_mode_t mode)
+{
+ char smode;
+ switch (mode) {
+ case INSTR_MEM_RD:
+ smode = 'r';
+ break;
+ case INSTR_MEM_WR:
+ smode = 'w';
+ break;
+ default:
+ smode = '?';
+ }
+ printf("M: [%c] 0x"TARGET_FMT_lx" (%d)\n", smode, addr, size);
+}
+
+void
+helper_all_mem_direct (target_ulong addr, uint32_t size, instr_mem_mode_t mode)
+{
+ helper_all_mem(addr, size, mode);
+}
diff --git a/instrument/examples/dynprint/host/instrument-host-helpers.h b/instrument/examples/dynprint/host/instrument-host-helpers.h
index 947cf57..d0de0a1 100644
--- a/instrument/examples/dynprint/host/instrument-host-helpers.h
+++ b/instrument/examples/dynprint/host/instrument-host-helpers.h
@@ -19,3 +19,4 @@
DEF_HELPER_1(pc, void, tl);
DEF_HELPER_4(all_fetch, void, tl, i32, i64, i64);
+DEF_HELPER_3(all_mem, void, tl, i32, i32);
diff --git a/instrument/examples/dynprint/host/instrument-host.h b/instrument/examples/dynprint/host/instrument-host.h
index 15911e7..30eb7d4 100644
--- a/instrument/examples/dynprint/host/instrument-host.h
+++ b/instrument/examples/dynprint/host/instrument-host.h
@@ -22,6 +22,9 @@
/* See "instrument/host-stub.h" for a description of macro arguments. */
+/* Cannot use helpers in DO macros. */
+void helper_all_mem_direct (target_ulong, uint32_t, uint32_t);
+
/* Instrumentation types */
typedef enum {
INSTR_TYPE_ENABLED, /* Instrumentation enabled.
@@ -46,4 +49,20 @@ typedef enum {
tused, used, tdefined, defined); \
} \
} while (0)
+
+#define INSTR_GEN_VMEM(taddr, addr, tlength, length, tmode, mode) \
+ do { \
+ if (INSTR_TYPE(ENABLED) && INSTR_TYPE(ALL)) { \
+ INSTR_GEN_3(all_mem, taddr, addr, tlength, length, \
+ tmode, mode); \
+ } \
+ } while (0)
+
+#define INSTR_DO_VMEM(cpu, addr, length, mode) \
+ do { \
+ if (INSTR_TYPE(ENABLED) && INSTR_TYPE(ALL)) { \
+ helper_all_mem_direct(addr, length, mode); \
+ } \
+ } while (0)
+
#endif /* INSTRUMENT_HOST_H */
diff --git a/instrument/gen-vmem-wrappers.h b/instrument/gen-vmem-wrappers.h
new file mode 100644
index 0000000..7b376ff
--- /dev/null
+++ b/instrument/gen-vmem-wrappers.h
@@ -0,0 +1,88 @@
+/*
+ * Wrappers for code generation of virtual memory accesses.
+ *
+ * Copyright (c) 2010 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INSTRUMENT__GEN_VMEM_WRAPPERS_H
+#define INSTRUMENT__GEN_VMEM_WRAPPERS_H
+
+/* Capture code generation for virtual memory accesses.
+ *
+ * Assumes that no other lower-level call will be performed by target
+ * architecture disassembly code on TCG instructions.
+ *
+ * TODO: lacks physical accesses (ld/st*_phys ?)
+ * TODO: lacks accesses performed by DMA
+ */
+
+#define tcg_gen_qemu_ld8u(arg, addr, mem_index) \
+ do { \
+ INSTR_GEN_VMEM(TCGv, addr, I32, 1, MEM_MODE, RD); \
+ (tcg_gen_qemu_ld8u)(arg, addr, mem_index); \
+ } while (0)
+#define tcg_gen_qemu_ld8s(arg, addr, mem_index) \
+ do { \
+ INSTR_GEN_VMEM(TCGv, addr, I32, 1, MEM_MODE, RD); \
+ (tcg_gen_qemu_ld8s)(arg, addr, mem_index); \
+ } while (0)
+#define tcg_gen_qemu_ld16u(arg, addr, mem_index) \
+ do { \
+ INSTR_GEN_VMEM(TCGv, addr, I32, 2, MEM_MODE, RD); \
+ (tcg_gen_qemu_ld16u)(arg, addr, mem_index); \
+ } while (0)
+#define tcg_gen_qemu_ld16s(arg, addr, mem_index) \
+ do { \
+ INSTR_GEN_VMEM(TCGv, addr, I32, 2, MEM_MODE, RD); \
+ (tcg_gen_qemu_ld16s)(arg, addr, mem_index); \
+ } while (0)
+#define tcg_gen_qemu_ld32u(arg, addr, mem_index) \
+ do { \
+ INSTR_GEN_VMEM(TCGv, addr, I32, 4, MEM_MODE, RD); \
+ (tcg_gen_qemu_ld32u)(arg, addr, mem_index); \
+ } while (0)
+#define tcg_gen_qemu_ld32s(arg, addr, mem_index) \
+ do { \
+ INSTR_GEN_VMEM(TCGv, addr, I32, 4, MEM_MODE, RD); \
+ (tcg_gen_qemu_ld32s)(arg, addr, mem_index); \
+ } while (0)
+#define tcg_gen_qemu_ld64(arg, addr, mem_index) \
+ do { \
+ INSTR_GEN_VMEM(TCGv, addr, I32, 8, MEM_MODE, RD); \
+ (tcg_gen_qemu_ld64)(arg, addr, mem_index); \
+ } while (0)
+#define tcg_gen_qemu_st8(arg, addr, mem_index) \
+ do { \
+ INSTR_GEN_VMEM(TCGv, addr, I32, 1, MEM_MODE, WR); \
+ (tcg_gen_qemu_st8)(arg, addr, mem_index); \
+ } while (0)
+#define tcg_gen_qemu_st16(arg, addr, mem_index) \
+ do { \
+ INSTR_GEN_VMEM(TCGv, addr, I32, 2, MEM_MODE, WR); \
+ (tcg_gen_qemu_st16)(arg, addr, mem_index); \
+ } while (0)
+#define tcg_gen_qemu_st32(arg, addr, mem_index) \
+ do { \
+ INSTR_GEN_VMEM(TCGv, addr, I32, 4, MEM_MODE, WR); \
+ (tcg_gen_qemu_st32)(arg, addr, mem_index); \
+ } while (0)
+#define tcg_gen_qemu_st64(arg, addr, mem_index) \
+ do { \
+ INSTR_GEN_VMEM(TCGv, addr, I32, 8, MEM_MODE, WR); \
+ (tcg_gen_qemu_st64)(arg, addr, mem_index); \
+ } while (0)
+
+#endif /* INSTRUMEN__GEN_VMEM_WRAPPERS_H */
diff --git a/instrument/generate.h b/instrument/generate.h
index 60f0c31..53b44de 100644
--- a/instrument/generate.h
+++ b/instrument/generate.h
@@ -103,6 +103,7 @@
#define __INSTR_ARG_TCGv_i32_DECL(tcg, value) TCGv_i32 tcg = value
#endif
#define __INSTR_ARG_REGS_DECL(tcg, value) __INSTR_ARG_I64_DECL(tcg, value)
+#define __INSTR_ARG_MEM_MODE_DECL(tcg, value) __INSTR_ARG_I32_DECL(tcg, INSTR_MEM_ ##value)
#define __INSTR_ARG_DECL(tcg, type, value) __INSTR_ARG_ ##type ##_DECL(tcg, value)
@@ -120,6 +121,7 @@
#define __INSTR_ARG_TCGv_i32_FREE(tcg)
#define __INSTR_ARG_TCGv_FREE(tcg)
#define __INSTR_ARG_REGS_FREE(tcg) __INSTR_ARG_I64_FREE(tcg)
+#define __INSTR_ARG_MEM_MODE_FREE(tcg) __INSTR_ARG_I32_FREE(tcg)
#define __INSTR_ARG_FREE(tcg, type) __INSTR_ARG_ ##type ##_FREE(tcg)
diff --git a/instrument/host-stub.h b/instrument/host-stub.h
index 30d2cba..bfe5b06 100644
--- a/instrument/host-stub.h
+++ b/instrument/host-stub.h
@@ -54,4 +54,21 @@ typedef enum {
#define INSTR_GEN_FETCH(taddr, addr, tlength, length, \
tused, used, tdefined, defined)
+/** Signal a virtual memory access.
+ * This is called before checking if the memory access is allowed.
+ * @param addr Address of the memory access (TCGv)
+ * @param length Length of the memory access in bytes (uint32_t)
+ * @param mode Access mode (instr_mem_mode_t)
+ */
+#define INSTR_GEN_VMEM(taddr, addr, tlength, length, tmode, mode)
+
+/** Signal a virtual memory access.
+ * This is called before checking if the memory access is allowed.
+ * @param cpu CPU performing the operation (CPUState*)
+ * @param addr Address of the memory access (target_ulong)
+ * @param length Length of the memory access in bytes (uint32_t)
+ * @param mode Access mode (instr_mem_mode_t)
+ */
+#define INSTR_DO_VMEM(cpu, addr, length, mode)
+
#endif /* INSTRUMENT__HOST_STUB_H */
diff --git a/instrument/types.h b/instrument/types.h
index ba2b0c2..4e5b7a3 100644
--- a/instrument/types.h
+++ b/instrument/types.h
@@ -35,4 +35,10 @@ typedef enum {
/** Register set. */
typedef uint64_t instr_regs_t;
+/** Memory access type. */
+typedef enum {
+ INSTR_MEM_RD, /**< read memory */
+ INSTR_MEM_WR, /**< write memory */
+} instr_mem_mode_t;
+
#endif /* INSTRUMENT__TYPES_H */
--
1.7.1
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Qemu-devel] [PATCH 18/18] instrument: [i386] Call PLVL point
2010-10-22 18:53 ` Lluís
` (9 preceding siblings ...)
2010-10-19 21:12 ` [Qemu-devel] [PATCH 15/18] instrument: Add VMEM point Lluís
@ 2010-10-19 21:36 ` Lluís
2010-10-19 21:36 ` [Qemu-devel] [PATCH 17/18] instrument: Add " Lluís
` (6 subsequent siblings)
17 siblings, 0 replies; 33+ messages in thread
From: Lluís @ 2010-10-19 21:36 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
instrument/host.h | 31 -------------------------------
target-i386/cpu.h | 21 +++++++++++----------
2 files changed, 11 insertions(+), 41 deletions(-)
delete mode 100644 instrument/host.h
diff --git a/instrument/host.h b/instrument/host.h
deleted file mode 100644
index cd120d0..0000000
--- a/instrument/host.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Static instrumentation points.
- *
- * Copyright (c) 2010 Lluís Vilanova <vilanova@ac.upc.edu>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef INSTRUMENT__HOST_H
-#define INSTRUMENT__HOST_H
-
-#if defined(CONFIG_INSTRUMENT)
-/* user-provided definitions */
-#include "instrument-host.h"
-#else
-/* empty stub definitions */
-#include "instrument/host-stub.h"
-#endif
-
-#endif /* INSTRUMENT__HOST_H */
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 1144d4e..e8d3953 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -810,16 +810,6 @@ int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
target_ulong *base, unsigned int *limit,
unsigned int *flags);
-/* wrapper, just in case memory mappings must be changed */
-static inline void cpu_x86_set_cpl(CPUX86State *s, int cpl)
-{
-#if HF_CPL_MASK == 3
- s->hflags = (s->hflags & ~HF_CPL_MASK) | cpl;
-#else
-#error HF_CPL_MASK is hardcoded
-#endif
-}
-
/* op_helper.c */
/* used for debug or cpu save/restore */
void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, CPU86_LDouble f);
@@ -939,6 +929,17 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
#include "hw/apic.h"
#endif
+/* wrapper, just in case memory mappings must be changed */
+static inline void cpu_x86_set_cpl(CPUX86State *s, int cpl)
+{
+ INSTR_DO_PLVL(s, cpl);
+#if HF_CPL_MASK == 3
+ s->hflags = (s->hflags & ~HF_CPL_MASK) | cpl;
+#else
+#error HF_CPL_MASK is hardcoded
+#endif
+}
+
static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
target_ulong *cs_base, int *flags)
{
--
1.7.1
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Qemu-devel] [PATCH 17/18] instrument: Add PLVL point
2010-10-22 18:53 ` Lluís
` (10 preceding siblings ...)
2010-10-19 21:36 ` [Qemu-devel] [PATCH 18/18] instrument: [i386] Call PLVL point Lluís
@ 2010-10-19 21:36 ` Lluís
2010-10-19 21:37 ` [Qemu-devel] [PATCH 10/18] instrument: Dynamic per-CPU state of static instrumentation points Lluís
` (5 subsequent siblings)
17 siblings, 0 replies; 33+ messages in thread
From: Lluís @ 2010-10-19 21:36 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
instrument/examples/dynprint/guest/test.c | 1 +
.../examples/dynprint/host/instrument-host.h | 21 ++++++++++++++++---
instrument/host-stub.h | 7 ++++++
3 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/instrument/examples/dynprint/guest/test.c b/instrument/examples/dynprint/guest/test.c
index b6b5788..ce43a48 100644
--- a/instrument/examples/dynprint/guest/test.c
+++ b/instrument/examples/dynprint/guest/test.c
@@ -31,6 +31,7 @@ main ()
int i;
BACKDOOR_i8(0x01); /* enable instrumentation */
+ BACKDOOR_i8_V(0x01, INSTR_TYPE_USER);
printf("start\n");
BACKDOOR_i8_V(0x01, INSTR_TYPE_PC); /* show executed PCs */
diff --git a/instrument/examples/dynprint/host/instrument-host.h b/instrument/examples/dynprint/host/instrument-host.h
index 30eb7d4..24b6ece 100644
--- a/instrument/examples/dynprint/host/instrument-host.h
+++ b/instrument/examples/dynprint/host/instrument-host.h
@@ -32,6 +32,7 @@ typedef enum {
* global state of tracing is wasteful, but hey, this is
* just an example.
*/
+ INSTR_TYPE_USER, /* Executing at user-level */
INSTR_TYPE_PC, /* Print fetched PC */
INSTR_TYPE_ALL, /* Print all instruction information */
INSTR_TYPE_COUNT /* Total number of instrumentation types (mandatory) */
@@ -41,10 +42,10 @@ typedef enum {
#define INSTR_GEN_FETCH(taddr, addr, tlength, length, \
tused, used, tdefined, defined) \
do { \
- if (INSTR_TYPE(ENABLED) && INSTR_TYPE(PC)) { \
+ if (INSTR_TYPE(ENABLED) && INSTR_TYPE(PC) && INSTR_TYPE(USER)) { \
INSTR_GEN_1(pc, taddr, addr); \
} \
- if (INSTR_TYPE(ENABLED) && INSTR_TYPE(ALL)) { \
+ if (INSTR_TYPE(ENABLED) && INSTR_TYPE(ALL) && INSTR_TYPE(USER)) { \
INSTR_GEN_4(all_fetch, taddr, addr, tlength, length, \
tused, used, tdefined, defined); \
} \
@@ -52,7 +53,7 @@ typedef enum {
#define INSTR_GEN_VMEM(taddr, addr, tlength, length, tmode, mode) \
do { \
- if (INSTR_TYPE(ENABLED) && INSTR_TYPE(ALL)) { \
+ if (INSTR_TYPE(ENABLED) && INSTR_TYPE(ALL) && INSTR_TYPE(USER)) { \
INSTR_GEN_3(all_mem, taddr, addr, tlength, length, \
tmode, mode); \
} \
@@ -60,9 +61,21 @@ typedef enum {
#define INSTR_DO_VMEM(cpu, addr, length, mode) \
do { \
- if (INSTR_TYPE(ENABLED) && INSTR_TYPE(ALL)) { \
+ if (INSTR_TYPE(ENABLED) && INSTR_TYPE(ALL) && INSTR_TYPE(USER)) { \
helper_all_mem_direct(addr, length, mode); \
} \
} while (0)
+#define INSTR_DO_PLVL(cpu, plvl) \
+ do { \
+ if (INSTR_CPU_TYPE(cpu, ENABLED)) { \
+ if (plvl == 0) { \
+ instr_disable_type(INSTR_TYPE_USER); \
+ } \
+ else{ \
+ instr_enable_type(INSTR_TYPE_USER); \
+ } \
+ } \
+ } while (0)
+
#endif /* INSTRUMENT_HOST_H */
diff --git a/instrument/host-stub.h b/instrument/host-stub.h
index bfe5b06..5cba4f2 100644
--- a/instrument/host-stub.h
+++ b/instrument/host-stub.h
@@ -71,4 +71,11 @@ typedef enum {
*/
#define INSTR_DO_VMEM(cpu, addr, length, mode)
+/** Signal a privilege level change.
+ * This is called before actually changing the privilege level.
+ * @param cpu CPU performing the operation (CPUState*)
+ * @param plvl New value for the privilege level (uint32_t)
+ */
+#define INSTR_DO_PLVL(cpu, plvl)
+
#endif /* INSTRUMENT__HOST_STUB_H */
--
1.7.1
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Qemu-devel] [PATCH 10/18] instrument: Dynamic per-CPU state of static instrumentation points
2010-10-22 18:53 ` Lluís
` (11 preceding siblings ...)
2010-10-19 21:36 ` [Qemu-devel] [PATCH 17/18] instrument: Add " Lluís
@ 2010-10-19 21:37 ` Lluís
2010-10-19 21:40 ` [Qemu-devel] [PATCH 14/18] instrument: [i386] Call FETCH point Lluís
` (4 subsequent siblings)
17 siblings, 0 replies; 33+ messages in thread
From: Lluís @ 2010-10-19 21:37 UTC (permalink / raw)
To: qemu-devel
The user-provided implementation for instrumentation points can define and use
"instrumentation types" as the atomic unit of instrumentation point
(de)activation.
The set of "instrumentation types" is named as "instrumentation state" (just a
bitset, one bit per type), which can be independently controlled on each
emulated CPU.
Thus, during guest code translation, instrumentation points execute arbitrary
code, including generating new TCG code, which will be generated only for CPUs
with an instrumentation state that matches the instrumentation type requirements
of the user-provided instrumentation point implementation.
This is efficiently supported by having one translation block table for each
possible instrumentation state, such that code translations can be efficiently
reused even if the CPUs are constantly changing their instrumentation state.
The net effect is similar (in terms of avoiding TB flushes) to that of the
execution of TBs that are marked to be available only under certain CPU
privilege levels.
Note that for simplicity, every CPU state change flushes the virtual translation
block table of the afected CPU ('tb_jmp_cache'), but not the global physical
translation block table ('tb_phys_hash'), which is the one containing one set of
translations for each instrumentation state.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
Makefile.target | 8 ++-
cpu-all.h | 7 ++
cpu-defs.h | 24 ++++++
cpu-exec.c | 8 ++-
cpus.c | 8 ++
exec-all.h | 5 +-
exec.c | 50 +++++++++-----
instrument/control.c | 74 ++++++++++++++++++++
instrument/control.h | 44 ++++++++++++
instrument/examples/dynprint/guest/test.c | 12 +++
instrument/examples/dynprint/host/backdoor.c | 9 +++
.../examples/dynprint/host/instrument-host.h | 5 ++
instrument/host-stub.h | 48 +++++++++++++
instrument/host.h | 31 ++++++++
instrument/state.h | 61 ++++++++++++++++
qemu-common.h | 4 +
target-microblaze/translate.c | 6 ++
17 files changed, 383 insertions(+), 21 deletions(-)
create mode 100644 instrument/control.c
create mode 100644 instrument/control.h
create mode 100644 instrument/host-stub.h
create mode 100644 instrument/host.h
create mode 100644 instrument/state.h
diff --git a/Makefile.target b/Makefile.target
index 90867e7..72849b3 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -353,12 +353,18 @@ endif
#########################################################
# static instrumentation
+obj-$(CONFIG_INSTRUMENT) += instrument/control.o
+
ifdef CONFIG_INSTRUMENT
VPATH := $(VPATH):$(INSTRUMENT_PATH)
+INSTRUMENT_DIR = instrument
LIBINSTRUMENT_LIB = libinstrument/libinstrument.a
LIBINSTRUMENT_CLEAN = libinstrument-clean
+instrument:
+ $(call quiet-command, mkdir -p instrument, " MKDIR $(TARGET_DIR)$@")
+
libinstrument/Makefile:
$(call quiet-command, mkdir -p libinstrument, " CREAT $(TARGET_DIR)$@")
$(call quiet-command, rm -f libinstrument/Makefile)
@@ -376,7 +382,7 @@ libinstrument-clean:
endif
-$(QEMU_PROG)-prepare: $(GENERATED_HEADERS) $(LIBBACKDOOR_LIB) $(LIBINSTRUMENT_LIB) $(QEMU_PROG)
+$(QEMU_PROG)-prepare: $(GENERATED_HEADERS) $(LIBBACKDOOR_LIB) $(INSTRUMENT_DIR) $(LIBINSTRUMENT_LIB) $(QEMU_PROG)
$(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y) $(LIBBACKDOOR_LIB) $(LIBINSTRUMENT_LIB)
$(call LINK,$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)) $(LIBBACKDOOR_LIB) $(LIBINSTRUMENT_LIB)
diff --git a/cpu-all.h b/cpu-all.h
index 67a3266..1be1c60 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -22,6 +22,13 @@
#include "qemu-common.h"
#include "cpu-common.h"
+#if defined(CONFIG_INSTRUMENT)
+
+#include "instrument/control.h"
+#include "instrument/state.h"
+
+#endif /* defined(CONFIG_INSTRUMENT) */
+
/* some important defines:
*
* WORDS_ALIGNED : if defined, the host cpu can only make word aligned
diff --git a/cpu-defs.h b/cpu-defs.h
index 8d4bf86..f896844 100644
--- a/cpu-defs.h
+++ b/cpu-defs.h
@@ -147,6 +147,28 @@ typedef struct CPUWatchpoint {
QTAILQ_ENTRY(CPUWatchpoint) entry;
} CPUWatchpoint;
+
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument-host.h"
+#include "instrument/state.h"
+
+/* Extra attributes for CPUState */
+#define INSTR_CPUState \
+ /** Current instrumentation state. */ \
+ instr_state_t instr_state; \
+ /** Inidcate a pending instrumentation state change. */ \
+ instr_state_t instr_state_request;
+
+#else /* defined(CONFIG_INSTRUMENT) */
+
+#include "instrument/host-stub.h"
+#include "instrument/state.h"
+
+#define INSTR_CPUState
+
+#endif /* defined(CONFIG_INSTRUMENT) */
+
+
#define CPU_TEMP_BUF_NLONGS 128
#define CPU_COMMON \
struct TranslationBlock *current_tb; /* currently executing TB */ \
@@ -166,6 +188,8 @@ typedef struct CPUWatchpoint {
/* buffer for temporaries in the code generator */ \
long temp_buf[CPU_TEMP_BUF_NLONGS]; \
\
+ INSTR_CPUState; \
+ \
int64_t icount_extra; /* Instructions until next timer event. */ \
/* Number of cycles left, with interrupt flag in high bit. \
This allows a single read-compare-cbranch-write sequence to test \
diff --git a/cpu-exec.c b/cpu-exec.c
index dbdfdcc..d925ee9 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -140,7 +140,7 @@ static TranslationBlock *tb_find_slow(target_ulong pc,
phys_page1 = phys_pc & TARGET_PAGE_MASK;
phys_page2 = -1;
h = tb_phys_hash_func(phys_pc);
- ptb1 = &tb_phys_hash[h];
+ ptb1 = &tb_phys_hash[INSTR_CURR_STATE][h];
for(;;) {
tb = *ptb1;
if (!tb)
@@ -553,6 +553,12 @@ int cpu_exec(CPUState *env1)
env->exception_index = EXCP_INTERRUPT;
cpu_loop_exit();
}
+#if defined(CONFIG_INSTRUMENT)
+ if (unlikely(env->instr_state != env->instr_state_request)) {
+ instr_cpu_do_state_change(env);
+ next_tb = 0;
+ }
+#endif
#if defined(DEBUG_DISAS) || defined(CONFIG_DEBUG_EXEC)
if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) {
/* restore flags in standard format */
diff --git a/cpus.c b/cpus.c
index b09f5e3..47dc22d 100644
--- a/cpus.c
+++ b/cpus.c
@@ -256,6 +256,10 @@ void qemu_init_vcpu(void *_env)
{
CPUState *env = _env;
+#if defined(CONFIG_INSTRUMENT)
+ instr_init_vcpu(env);
+#endif
+
env->nr_cores = smp_cores;
env->nr_threads = smp_threads;
if (kvm_enabled())
@@ -700,6 +704,10 @@ void qemu_init_vcpu(void *_env)
{
CPUState *env = _env;
+#if defined(CONFIG_INSTRUMENT)
+ instr_init_vcpu(env);
+#endif
+
env->nr_cores = smp_cores;
env->nr_threads = smp_threads;
if (kvm_enabled())
diff --git a/exec-all.h b/exec-all.h
index 2ae09c5..35d2a57 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -158,6 +158,9 @@ struct TranslationBlock {
struct TranslationBlock *jmp_next[2];
struct TranslationBlock *jmp_first;
uint32_t icount;
+#if defined(CONFIG_INSTRUMENT)
+ instr_state_t instr_state;
+#endif
};
static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc)
@@ -189,7 +192,7 @@ void tb_link_page(TranslationBlock *tb,
tb_page_addr_t phys_pc, tb_page_addr_t phys_page2);
void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
-extern TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
+extern TranslationBlock *tb_phys_hash[INSTR_STATE_COUNT][CODE_GEN_PHYS_HASH_SIZE];
#if defined(USE_DIRECT_JUMP)
diff --git a/exec.c b/exec.c
index 516960a..24ade3c 100644
--- a/exec.c
+++ b/exec.c
@@ -81,7 +81,7 @@
static TranslationBlock *tbs;
static int code_gen_max_blocks;
-TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
+TranslationBlock *tb_phys_hash[INSTR_STATE_COUNT][CODE_GEN_PHYS_HASH_SIZE];
static int nb_tbs;
/* any access to the tbs or the page table must use this lock */
spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
@@ -713,7 +713,8 @@ void tb_flush(CPUState *env1)
tb_flush_jmp_cache(env);
}
- memset (tb_phys_hash, 0, CODE_GEN_PHYS_HASH_SIZE * sizeof (void *));
+ memset (tb_phys_hash, 0,
+ INSTR_STATE_COUNT * CODE_GEN_PHYS_HASH_SIZE * sizeof (void *));
page_flush_tb();
code_gen_ptr = code_gen_buffer;
@@ -727,15 +728,18 @@ void tb_flush(CPUState *env1)
static void tb_invalidate_check(target_ulong address)
{
TranslationBlock *tb;
+ instr_state_t s;
int i;
address &= TARGET_PAGE_MASK;
- for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++) {
- for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
- if (!(address + TARGET_PAGE_SIZE <= tb->pc ||
- address >= tb->pc + tb->size)) {
- printf("ERROR invalidate: address=" TARGET_FMT_lx
- " PC=%08lx size=%04x\n",
- address, (long)tb->pc, tb->size);
+ for (s = 0; s < INSTR_STATE_COUNT; s++) {
+ for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++) {
+ for(tb = tb_phys_hash[s][i]; tb != NULL; tb = tb->phys_hash_next) {
+ if (!(address + TARGET_PAGE_SIZE <= tb->pc ||
+ address >= tb->pc + tb->size)) {
+ printf("ERROR invalidate: address=" TARGET_FMT_lx
+ " PC=%08lx size=%04x\n",
+ address, (long)tb->pc, tb->size);
+ }
}
}
}
@@ -745,15 +749,18 @@ static void tb_invalidate_check(target_ulong address)
static void tb_page_check(void)
{
TranslationBlock *tb;
+ instr_state_t s;
int i, flags1, flags2;
- for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++) {
- for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
- flags1 = page_get_flags(tb->pc);
- flags2 = page_get_flags(tb->pc + tb->size - 1);
- if ((flags1 & PAGE_WRITE) || (flags2 & PAGE_WRITE)) {
- printf("ERROR page flags: PC=%08lx size=%04x f1=%x f2=%x\n",
- (long)tb->pc, tb->size, flags1, flags2);
+ for(s = 0; s < INSTR_STATE_COUNT; s++) {
+ for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++) {
+ for(tb = tb_phys_hash[s][i]; tb != NULL; tb = tb->phys_hash_next) {
+ flags1 = page_get_flags(tb->pc);
+ flags2 = page_get_flags(tb->pc + tb->size - 1);
+ if ((flags1 & PAGE_WRITE) || (flags2 & PAGE_WRITE)) {
+ printf("ERROR page flags: PC=%08lx size=%04x f1=%x f2=%x\n",
+ (long)tb->pc, tb->size, flags1, flags2);
+ }
}
}
}
@@ -839,7 +846,7 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
/* remove the TB from the hash list */
phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
h = tb_phys_hash_func(phys_pc);
- tb_remove(&tb_phys_hash[h], tb,
+ tb_remove(&tb_phys_hash[INSTR_TB_STATE(tb)][h], tb,
offsetof(TranslationBlock, phys_hash_next));
/* remove the TB from the page list */
@@ -964,6 +971,9 @@ TranslationBlock *tb_gen_code(CPUState *env,
tb->cs_base = cs_base;
tb->flags = flags;
tb->cflags = cflags;
+#if defined(CONFIG_INSTRUMENT)
+ tb->instr_state = env->instr_state;
+#endif
cpu_gen_code(env, tb, &code_gen_size);
code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
@@ -1269,7 +1279,7 @@ void tb_link_page(TranslationBlock *tb,
mmap_lock();
/* add in the physical hash table */
h = tb_phys_hash_func(phys_pc);
- ptb = &tb_phys_hash[h];
+ ptb = &tb_phys_hash[INSTR_TB_STATE(tb)][h];
tb->phys_hash_next = *ptb;
*ptb = tb;
@@ -3139,6 +3149,8 @@ static void check_watchpoint(int offset, int len_mask, int flags)
"pc=%p", (void *)env->mem_io_pc);
}
cpu_restore_state(tb, env, env->mem_io_pc, NULL);
+ /* XXX: It is OK to invalidate only this TB (and not for all
+ * states), as this is the one triggering the memory access */
tb_phys_invalidate(tb, -1);
if (wp->flags & BP_STOP_BEFORE_ACCESS) {
env->exception_index = EXCP_DEBUG;
@@ -4079,6 +4091,8 @@ void cpu_io_recompile(CPUState *env, void *retaddr)
pc = tb->pc;
cs_base = tb->cs_base;
flags = tb->flags;
+ /* XXX: It is OK to invalidate only this TB (and not for all states), as
+ * this is the one triggering the memory access */
tb_phys_invalidate(tb, -1);
/* FIXME: In theory this could raise an exception. In practice
we have already translated the block once so it's probably ok. */
diff --git a/instrument/control.c b/instrument/control.c
new file mode 100644
index 0000000..c2c7476
--- /dev/null
+++ b/instrument/control.c
@@ -0,0 +1,74 @@
+/*
+ * Dynamic control of instrumentation states.
+ *
+ * Copyright (c) 2010 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+
+#include "exec-all.h"
+#include "instrument/control.h"
+
+
+void
+instr_enable_type (instr_type_t type)
+{
+ CPUState *cpu;
+ for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+ instr_cpu_enable_type(cpu, type);
+ }
+}
+
+void
+instr_disable_type (instr_type_t type)
+{
+ CPUState *cpu;
+ for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+ instr_cpu_disable_type(cpu, type);
+ }
+}
+
+void
+instr_cpu_enable_type (CPUState * cpu, instr_type_t type)
+{
+ cpu->instr_state_request |= (1 << type);
+}
+
+void
+instr_cpu_disable_type (CPUState * cpu, instr_type_t type)
+{
+ cpu->instr_state_request &= ~(1 << type);
+}
+
+void
+instr_cpu_do_state_change (CPUState * cpu)
+{
+ cpu->instr_state = cpu->instr_state_request;
+ tb_flush_jmp_cache(cpu);
+}
+
+void
+instr_init_vcpu (CPUState * cpu)
+{
+ int bits = sizeof(cpu->instr_state) * 8;
+ if (INSTR_TYPE_COUNT > bits) {
+ fprintf(stderr, "Can only support at most %d instrumentation types\n",
+ bits);
+ abort();
+ }
+ cpu->instr_state = 0;
+ cpu->instr_state_request = cpu->instr_state;
+}
diff --git a/instrument/control.h b/instrument/control.h
new file mode 100644
index 0000000..c4ee12c
--- /dev/null
+++ b/instrument/control.h
@@ -0,0 +1,44 @@
+/*
+ * Dynamic control of instrumentation states.
+ *
+ * Copyright (c) 2010 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INSTRUMENT__CONTROL_H
+#define INSTRUMENT__CONTROL_H
+
+#include "instrument-host.h"
+
+/** Enable instrumentation for given type on all CPUs. */
+void instr_enable_type (instr_type_t type);
+/** Disable instrumentation for given type on all CPUs. */
+void instr_disable_type (instr_type_t type);
+
+/** Enable instrumentation for given type on given CPU. */
+void instr_cpu_enable_type (CPUState * cpu, instr_type_t type);
+/** Disable instrumentation for given type on given CPU. */
+void instr_cpu_disable_type (CPUState * cpu, instr_type_t type);
+
+
+/* Internal API */
+
+/** Apply instrumentation state changes. */
+void instr_cpu_do_state_change (CPUState * cpu);
+
+/** Initialize per-cpu insrumentation variables. */
+void instr_init_vcpu (CPUState * cpu);
+
+#endif /* INSTRUMENT__CONTROL_H */
diff --git a/instrument/examples/dynprint/guest/test.c b/instrument/examples/dynprint/guest/test.c
index 254ebcf..7ddd5be 100644
--- a/instrument/examples/dynprint/guest/test.c
+++ b/instrument/examples/dynprint/guest/test.c
@@ -19,6 +19,8 @@
#include <stdio.h>
+#include "backdoor/guest.h"
+
#define TOTAL_ITERS 100
@@ -27,13 +29,23 @@ main ()
{
int i;
+ BACKDOOR_i8(0x01); /* enable instrumentation */
+
printf("start\n");
for (i = 0; i < TOTAL_ITERS; i++) {
+ /* disable an iteration every 10 iterations */
+ if (i % 10 == 0) {
+ BACKDOOR_i8(0x00);
+ }
printf("iteration\n");
+ if (i % 10 == 0) {
+ BACKDOOR_i8(0x01);
+ }
}
printf("stop\n");
+ BACKDOOR_i8(0x00); /* disable instrumentation */
return 0;
}
diff --git a/instrument/examples/dynprint/host/backdoor.c b/instrument/examples/dynprint/host/backdoor.c
index 7b4e883..27f612b 100644
--- a/instrument/examples/dynprint/host/backdoor.c
+++ b/instrument/examples/dynprint/host/backdoor.c
@@ -21,12 +21,21 @@
#include "cpu.h"
#include "helper.h"
+#include "instrument/control.h"
void
helper_backdoor_i8 (uint32_t imm)
{
switch (imm) {
+ case 0:
+ printf("backdoor: -%d\n", INSTR_TYPE_ENABLED);
+ instr_disable_type(INSTR_TYPE_ENABLED);
+ break;
+ case 1:
+ printf("backdoor: +%d\n", INSTR_TYPE_ENABLED);
+ instr_enable_type(INSTR_TYPE_ENABLED);
+ break;
default:
printf("Unexpected use of instrumentation backdoor\n");
abort();
diff --git a/instrument/examples/dynprint/host/instrument-host.h b/instrument/examples/dynprint/host/instrument-host.h
index 9ede6af..92a4c14 100644
--- a/instrument/examples/dynprint/host/instrument-host.h
+++ b/instrument/examples/dynprint/host/instrument-host.h
@@ -24,6 +24,11 @@
/* Instrumentation types */
typedef enum {
+ INSTR_TYPE_ENABLED, /* Instrumentation enabled.
+ * Using an instrumentation type for identifying a
+ * global state of tracing is wasteful, but hey, this is
+ * just an example.
+ */
INSTR_TYPE_COUNT /* Total number of instrumentation types (mandatory) */
} instr_type_t;
diff --git a/instrument/host-stub.h b/instrument/host-stub.h
new file mode 100644
index 0000000..4178559
--- /dev/null
+++ b/instrument/host-stub.h
@@ -0,0 +1,48 @@
+/*
+ * Stub for empty static instrumentation points.
+ *
+ * Copyright (c) 2010 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INSTRUMENT__HOST_STUB_H
+#define INSTRUMENT__HOST_STUB_H
+
+/** Instrumentation types. */
+typedef enum {
+ INSTR_TYPE_COUNT /**< Total number of instrumentation types (mandatory) */
+} instr_type_t;
+
+/* All instrumentation point macros follow a strict naming scheme:
+ * INSTR_<when>_<point>
+ *
+ * - <point>
+ * A name for a conceptual generic event.
+ *
+ * - <when>
+ * Describes when the instrumentation point is invoked:
+ *
+ * - GEN
+ * Invoked at TB generation time. If information is to be used, it must be
+ * so through the use of "instrument/generate.h".
+ *
+ * - DO
+ * Invoked at instruction emulation time. If information is to be used, it
+ * must be so by simply providing extra code.
+ *
+ * On all cases, the use of "instrument/state.h" is supported.
+ */
+
+#endif /* INSTRUMENT__HOST_STUB_H */
diff --git a/instrument/host.h b/instrument/host.h
new file mode 100644
index 0000000..cd120d0
--- /dev/null
+++ b/instrument/host.h
@@ -0,0 +1,31 @@
+/*
+ * Static instrumentation points.
+ *
+ * Copyright (c) 2010 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INSTRUMENT__HOST_H
+#define INSTRUMENT__HOST_H
+
+#if defined(CONFIG_INSTRUMENT)
+/* user-provided definitions */
+#include "instrument-host.h"
+#else
+/* empty stub definitions */
+#include "instrument/host-stub.h"
+#endif
+
+#endif /* INSTRUMENT__HOST_H */
diff --git a/instrument/state.h b/instrument/state.h
new file mode 100644
index 0000000..60221c1
--- /dev/null
+++ b/instrument/state.h
@@ -0,0 +1,61 @@
+/*
+ * Instrumentation state information.
+ *
+ * Copyright (c) 2010 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INSTRUMENT__STATE_H
+#define INSTRUMENT__STATE_H
+
+/** Instrumentation state. */
+typedef uint16_t instr_state_t;
+
+/** Number of available instrumentation states. */
+#define INSTR_STATE_COUNT (((instr_state_t)1) << INSTR_TYPE_COUNT)
+
+/** Get instrumentation state of current CPU.
+ * This macro will also work when instrumentation is not compiled in.
+ */
+#define INSTR_CURR_STATE INSTR_CPU_STATE(cpu_single_env)
+
+
+#if defined(CONFIG_INSTRUMENT)
+
+/** Check if given instrumentation type is enabled on current CPU. */
+#define INSTR_TYPE(type) (INSTR_CURR_STATE & (1 << INSTR_TYPE_ ##type))
+
+/** Check if given instrumentation type is enabled on given CPU. */
+#define INSTR_CPU_TYPE(cpu, type) \
+ (INSTR_CPU_STATE(cpu) & (1 << INSTR_TYPE_ ##type))
+
+/** Get instrumentation state of given CPU.
+ * This macro will also work when instrumentation is not compiled in.
+ */
+#define INSTR_CPU_STATE(cpu) ((cpu)->instr_state)
+
+/** Get instrumentation state of given TranslationBLock.
+ * This macro will also work when instrumentation is not compiled in.
+ */
+#define INSTR_TB_STATE(tb) ((tb)->instr_state)
+
+#else /* defined(CONFIG_INSTRUMENT) */
+
+#define INSTR_CPU_STATE(cpu) 0
+#define INSTR_TB_STATE(tb) 0
+
+#endif /* defined(CONFIG_INSTRUMENT) */
+
+#endif /* INSTRUMENT__STATE_H */
diff --git a/qemu-common.h b/qemu-common.h
index 81aafa0..e0063a7 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -278,7 +278,11 @@ struct qemu_work_item {
};
#ifdef CONFIG_USER_ONLY
+#if defined(CONFIG_INSTRUMENT)
+#define qemu_init_vcpu(env) do { instr_init_vcpu(env); } while (0)
+#else
#define qemu_init_vcpu(env) do { } while (0)
+#endif
#else
void qemu_init_vcpu(void *env);
#endif
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 38149bb..9dcc78a 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1607,6 +1607,12 @@ CPUState *cpu_mb_init (const char *cpu_model)
offsetof(CPUState, sregs[i]),
special_regnames[i]);
}
+
+#if defined(CONFIG_INSTRUMENT)
+ /* XXX: Here only because qemu_init_vcpu is not called in this target */
+ instr_init_vcpu(env);
+#endif
+
#define GEN_HELPER 2
#include "helper.h"
--
1.7.1
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Qemu-devel] [PATCH 14/18] instrument: [i386] Call FETCH point
2010-10-22 18:53 ` Lluís
` (12 preceding siblings ...)
2010-10-19 21:37 ` [Qemu-devel] [PATCH 10/18] instrument: Dynamic per-CPU state of static instrumentation points Lluís
@ 2010-10-19 21:40 ` Lluís
2010-10-21 14:36 ` [Qemu-devel] [PATCH 11/18] instrument: Code-generation macros Lluís
` (3 subsequent siblings)
17 siblings, 0 replies; 33+ messages in thread
From: Lluís @ 2010-10-19 21:40 UTC (permalink / raw)
To: qemu-devel
Provides an instrumentation point for instruction fetch/decode events.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
target-i386/translate.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 113 insertions(+), 0 deletions(-)
diff --git a/target-i386/translate.c b/target-i386/translate.c
index b54a823..02a93a4 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -32,6 +32,32 @@
#define GEN_HELPER 1
#include "helper.h"
+#if defined(CONFIG_INSTRUMENT)
+static inline void
+mem_exchange (void * tmp, void * start1, size_t size1,
+ void * start2, size_t size2)
+{
+ memcpy(tmp , start2, size2);
+ memcpy(tmp+size2, start1, size1);
+ memcpy(start1 , tmp , size1+size2);
+}
+#endif
+
+
+/* tracking of register usage */
+#if defined(CONFIG_INSTRUMENT)
+struct DisasContext;
+/* Have current context always accessible */
+struct DisasContext * instr_disas = NULL;
+#endif
+
+#define INSTR_REGS_SET_GP(s, r) INSTR_REGS_SET(instr_disas->instr_regs_ ##s, r)
+/* TODO: access to env->regs in helper functions */
+/* TODO: not tracking register sets for: eflags, segments, floating point,
+ * crX, ...
+ */
+
+
#define PREFIX_REPZ 0x01
#define PREFIX_REPNZ 0x02
#define PREFIX_LOCK 0x04
@@ -116,6 +142,11 @@ typedef struct DisasContext {
int cpuid_ext_features;
int cpuid_ext2_features;
int cpuid_ext3_features;
+#if defined(CONFIG_INSTRUMENT)
+ /* temporal vars for FETCH instrumentation */
+ instr_regs_t instr_regs_used;
+ instr_regs_t instr_regs_defined;
+#endif
} DisasContext;
static void gen_eob(DisasContext *s);
@@ -281,9 +312,13 @@ static inline void gen_op_mov_reg_v(int ot, int reg, TCGv t0)
tmp = tcg_temp_new();
tcg_gen_ext8u_tl(tmp, t0);
if (reg < 4 X86_64_DEF( || reg >= 8 || x86_64_hregs)) {
+ INSTR_REGS_SET_GP(used, reg);
+ INSTR_REGS_SET_GP(defined, reg);
tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xff);
tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], tmp);
} else {
+ INSTR_REGS_SET_GP(used, reg - 4);
+ INSTR_REGS_SET_GP(defined, reg - 4);
tcg_gen_shli_tl(tmp, tmp, 8);
tcg_gen_andi_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], ~0xff00);
tcg_gen_or_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], tmp);
@@ -293,6 +328,8 @@ static inline void gen_op_mov_reg_v(int ot, int reg, TCGv t0)
case OT_WORD:
tmp = tcg_temp_new();
tcg_gen_ext16u_tl(tmp, t0);
+ INSTR_REGS_SET_GP(used, reg);
+ INSTR_REGS_SET_GP(defined, reg);
tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xffff);
tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], tmp);
tcg_temp_free(tmp);
@@ -301,10 +338,12 @@ static inline void gen_op_mov_reg_v(int ot, int reg, TCGv t0)
case OT_LONG:
/* For x86_64, this sets the higher half of register to zero.
For i386, this is equivalent to a mov. */
+ INSTR_REGS_SET_GP(defined, reg);
tcg_gen_ext32u_tl(cpu_regs[reg], t0);
break;
#ifdef TARGET_X86_64
case OT_QUAD:
+ INSTR_REGS_SET_GP(defined, reg);
tcg_gen_mov_tl(cpu_regs[reg], t0);
break;
#endif
@@ -329,6 +368,8 @@ static inline void gen_op_mov_reg_A0(int size, int reg)
case 0:
tmp = tcg_temp_new();
tcg_gen_ext16u_tl(tmp, cpu_A0);
+ INSTR_REGS_SET_GP(used, reg);
+ INSTR_REGS_SET_GP(defined, reg);
tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xffff);
tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], tmp);
tcg_temp_free(tmp);
@@ -337,10 +378,12 @@ static inline void gen_op_mov_reg_A0(int size, int reg)
case 1:
/* For x86_64, this sets the higher half of register to zero.
For i386, this is equivalent to a mov. */
+ INSTR_REGS_SET_GP(defined, reg);
tcg_gen_ext32u_tl(cpu_regs[reg], cpu_A0);
break;
#ifdef TARGET_X86_64
case 2:
+ INSTR_REGS_SET_GP(defined, reg);
tcg_gen_mov_tl(cpu_regs[reg], cpu_A0);
break;
#endif
@@ -354,12 +397,14 @@ static inline void gen_op_mov_v_reg(int ot, TCGv t0, int reg)
if (reg < 4 X86_64_DEF( || reg >= 8 || x86_64_hregs)) {
goto std_case;
} else {
+ INSTR_REGS_SET_GP(used, reg - 4);
tcg_gen_shri_tl(t0, cpu_regs[reg - 4], 8);
tcg_gen_ext8u_tl(t0, t0);
}
break;
default:
std_case:
+ INSTR_REGS_SET_GP(used, reg);
tcg_gen_mov_tl(t0, cpu_regs[reg]);
break;
}
@@ -372,6 +417,7 @@ static inline void gen_op_mov_TN_reg(int ot, int t_index, int reg)
static inline void gen_op_movl_A0_reg(int reg)
{
+ INSTR_REGS_SET_GP(used, reg);
tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]);
}
@@ -414,12 +460,16 @@ static inline void gen_op_add_reg_im(int size, int reg, int32_t val)
{
switch(size) {
case 0:
+ INSTR_REGS_SET_GP(used, reg);
+ INSTR_REGS_SET_GP(defined, reg);
tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val);
tcg_gen_ext16u_tl(cpu_tmp0, cpu_tmp0);
tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xffff);
tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0);
break;
case 1:
+ INSTR_REGS_SET_GP(used, reg);
+ INSTR_REGS_SET_GP(defined, reg);
tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val);
/* For x86_64, this sets the higher half of register to zero.
For i386, this is equivalent to a nop. */
@@ -428,6 +478,8 @@ static inline void gen_op_add_reg_im(int size, int reg, int32_t val)
break;
#ifdef TARGET_X86_64
case 2:
+ INSTR_REGS_SET_GP(used, reg);
+ INSTR_REGS_SET_GP(defined, reg);
tcg_gen_addi_tl(cpu_regs[reg], cpu_regs[reg], val);
break;
#endif
@@ -438,12 +490,16 @@ static inline void gen_op_add_reg_T0(int size, int reg)
{
switch(size) {
case 0:
+ INSTR_REGS_SET_GP(used, reg);
+ INSTR_REGS_SET_GP(defined, reg);
tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]);
tcg_gen_ext16u_tl(cpu_tmp0, cpu_tmp0);
tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xffff);
tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0);
break;
case 1:
+ INSTR_REGS_SET_GP(used, reg);
+ INSTR_REGS_SET_GP(defined, reg);
tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]);
/* For x86_64, this sets the higher half of register to zero.
For i386, this is equivalent to a nop. */
@@ -452,6 +508,8 @@ static inline void gen_op_add_reg_T0(int size, int reg)
break;
#ifdef TARGET_X86_64
case 2:
+ INSTR_REGS_SET_GP(used, reg);
+ INSTR_REGS_SET_GP(defined, reg);
tcg_gen_add_tl(cpu_regs[reg], cpu_regs[reg], cpu_T[0]);
break;
#endif
@@ -465,6 +523,7 @@ static inline void gen_op_set_cc_op(int32_t val)
static inline void gen_op_addl_A0_reg_sN(int shift, int reg)
{
+ INSTR_REGS_SET_GP(used, reg);
tcg_gen_mov_tl(cpu_tmp0, cpu_regs[reg]);
if (shift != 0)
tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
@@ -502,11 +561,13 @@ static inline void gen_op_addq_A0_seg(int reg)
static inline void gen_op_movq_A0_reg(int reg)
{
+ INSTR_REGS_SET_GP(used, reg);
tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]);
}
static inline void gen_op_addq_A0_reg_sN(int shift, int reg)
{
+ INSTR_REGS_SET_GP(used, reg);
tcg_gen_mov_tl(cpu_tmp0, cpu_regs[reg]);
if (shift != 0)
tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
@@ -707,6 +768,7 @@ static void gen_exts(int ot, TCGv reg)
static inline void gen_op_jnz_ecx(int size, int label1)
{
+ INSTR_REGS_SET_GP(used, R_ECX);
tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
gen_extu(size + 1, cpu_tmp0);
tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, label1);
@@ -714,6 +776,7 @@ static inline void gen_op_jnz_ecx(int size, int label1)
static inline void gen_op_jz_ecx(int size, int label1)
{
+ INSTR_REGS_SET_GP(used, R_ECX);
tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
gen_extu(size + 1, cpu_tmp0);
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
@@ -4090,6 +4153,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
target_ulong next_eip, tval;
int rex_w, rex_r;
+#if defined(CONFIG_INSTRUMENT)
+ uint16_t * instr_gen_opc_ptr = gen_opc_ptr;
+ TCGArg * instr_gen_opparam_ptr = gen_opparam_ptr;
+#endif
+
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
tcg_gen_debug_insn_start(pc_start);
s->pc = pc_start;
@@ -4105,6 +4173,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
x86_64_hregs = 0;
#endif
s->rip_offset = 0; /* for relative ip address */
+#if defined(CONFIG_INSTRUMENT)
+ s->instr_regs_used = 0;
+ s->instr_regs_defined = 0;
+#endif
#if defined(CONFIG_BACKDOOR)
if (ldub_code(s->pc) == 0x0f && ldub_code(s->pc + 1) == 0x04) {
@@ -4118,6 +4190,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
break;
case 0x01: /* i8 v */
cmd = tcg_const_i32(ldub_code(s->pc + 3));
+ INSTR_REGS_SET_GP(used, R_EAX);
gen_helper_backdoor_i8_v(cmd, cpu_regs[R_EAX]);
break;
default:
@@ -4901,6 +4974,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
rm = 0; /* avoid warning */
}
label1 = gen_new_label();
+ INSTR_REGS_SET_GP(used, R_EAX);
tcg_gen_sub_tl(t2, cpu_regs[R_EAX], t0);
gen_extu(ot, t2);
tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
@@ -5476,6 +5550,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
val = ldub_code(s->pc++);
tcg_gen_movi_tl(cpu_T3, val);
} else {
+ INSTR_REGS_SET_GP(used, R_ECX);
tcg_gen_mov_tl(cpu_T3, cpu_regs[R_ECX]);
}
gen_shiftd_rm_T1_T3(s, ot, opreg, op);
@@ -6386,6 +6461,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
/* XXX: specific Intel behaviour ? */
l1 = gen_new_label();
gen_jcc1(s, s->cc_op, b ^ 1, l1);
+ INSTR_REGS_SET_GP(defined, reg);
tcg_gen_mov_tl(cpu_regs[reg], t0);
gen_set_label(l1);
tcg_gen_ext32u_tl(cpu_regs[reg], cpu_regs[reg]);
@@ -7666,6 +7742,36 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
backdoor_done:
#endif
+#if defined(CONFIG_INSTRUMENT)
+ {
+ uint16_t * old_gen_opc_ptr = gen_opc_ptr;
+ TCGArg * old_gen_opparam_ptr = gen_opparam_ptr;
+
+ INSTR_GEN_FETCH(TUL, pc_start,
+ I32, s->pc - pc_start,
+ REGS, s->instr_regs_used,
+ REGS, s->instr_regs_defined);
+
+ /* Move TCG code generated by instrumentation callback */
+
+ if (old_gen_opc_ptr != gen_opc_ptr) {
+ typeof(*gen_opc_ptr) tmp[OPC_BUF_SIZE];
+ mem_exchange(tmp, instr_gen_opc_ptr,
+ (old_gen_opc_ptr - instr_gen_opc_ptr) * sizeof(*gen_opc_ptr),
+ old_gen_opc_ptr,
+ (gen_opc_ptr - old_gen_opc_ptr) * sizeof(*gen_opc_ptr));
+ }
+
+ if (old_gen_opparam_ptr != gen_opparam_ptr) {
+ typeof(*gen_opparam_ptr) tmp[OPPARAM_BUF_SIZE];
+ mem_exchange(tmp, instr_gen_opparam_ptr,
+ (old_gen_opparam_ptr - instr_gen_opparam_ptr) * sizeof(*gen_opparam_ptr),
+ old_gen_opparam_ptr,
+ (gen_opparam_ptr - old_gen_opparam_ptr) * sizeof(*gen_opparam_ptr));
+ }
+ }
+#endif
+
/* lock generation */
if (s->prefix & PREFIX_LOCK)
gen_helper_unlock();
@@ -7812,6 +7918,9 @@ static inline void gen_intermediate_code_internal(CPUState *env,
|| (flags & HF_SOFTMMU_MASK)
#endif
);
+#if defined(CONFIG_INSTRUMENT)
+ instr_disas = dc;
+#endif
#if 0
/* check addseg logic */
if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
@@ -7930,6 +8039,10 @@ static inline void gen_intermediate_code_internal(CPUState *env,
tb->size = pc_ptr - pc_start;
tb->icount = num_insns;
}
+
+#if defined(CONFIG_INSTRUMENT)
+ instr_disas = NULL;
+#endif
}
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
--
1.7.1
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Qemu-devel] [PATCH 11/18] instrument: Code-generation macros
2010-10-22 18:53 ` Lluís
` (13 preceding siblings ...)
2010-10-19 21:40 ` [Qemu-devel] [PATCH 14/18] instrument: [i386] Call FETCH point Lluís
@ 2010-10-21 14:36 ` Lluís
2010-10-21 17:42 ` [Qemu-devel] [PATCH 09/18] instrument: Add initial instrumentation example Lluís
` (2 subsequent siblings)
17 siblings, 0 replies; 33+ messages in thread
From: Lluís @ 2010-10-21 14:36 UTC (permalink / raw)
To: qemu-devel
Provides some code-generation macros intended to be used by the user when
generating code on instrumentation points.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
cpu-all.h | 2 +
instrument/generate.h | 124 +++++++++++++++++++++++++++++++++++++++++++++++++
instrument/types.h | 33 +++++++++++++
3 files changed, 159 insertions(+), 0 deletions(-)
create mode 100644 instrument/generate.h
create mode 100644 instrument/types.h
diff --git a/cpu-all.h b/cpu-all.h
index 1be1c60..b15253f 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -24,6 +24,8 @@
#if defined(CONFIG_INSTRUMENT)
+#include "instrument/types.h"
+#include "instrument/generate.h"
#include "instrument/control.h"
#include "instrument/state.h"
diff --git a/instrument/generate.h b/instrument/generate.h
new file mode 100644
index 0000000..7e4b35c
--- /dev/null
+++ b/instrument/generate.h
@@ -0,0 +1,124 @@
+/*
+ * User macros for code generation in static instrumentation points.
+ *
+ * Copyright (c) 2010 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INSTRUMENT__GENERATE_H
+#define INSTRUMENT__GENERATE_H
+
+/* Generate calls to code helpers (callback) with the provided arguments.
+ *
+ * Note that each argument comes in pairs: the type (instr_arg_type_t) and the
+ * value.
+ */
+
+#define INSTR_GEN_0(callback) \
+ do { \
+ gen_helper_ ##callback(); \
+ } while(0)
+
+#define INSTR_GEN_1(callback, type1, arg1) \
+ do { \
+ __INSTR_ARG_DECL(tmp1, type1, arg1); \
+ gen_helper_ ##callback (tmp1); \
+ __INSTR_ARG_FREE(tmp1, type1); \
+ } while(0)
+
+#define INSTR_GEN_2(callback, type1, arg1, type2, arg2) \
+ do { \
+ __INSTR_ARG_DECL(tmp1, type1, arg1); \
+ __INSTR_ARG_DECL(tmp2, type2, arg2); \
+ gen_helper_ ##callback (tmp1, tmp2); \
+ __INSTR_ARG_FREE(tmp1, type1); \
+ __INSTR_ARG_FREE(tmp2, type2); \
+ } while(0)
+
+#define INSTR_GEN_3(callback, type1, arg1, type2, arg2, type3, arg3) \
+ do { \
+ __INSTR_ARG_DECL(tmp1, type1, arg1); \
+ __INSTR_ARG_DECL(tmp2, type2, arg2); \
+ __INSTR_ARG_DECL(tmp3, type3, arg3); \
+ gen_helper_ ##callback (tmp1, tmp2, tmp3); \
+ __INSTR_ARG_FREE(tmp1, type1); \
+ __INSTR_ARG_FREE(tmp2, type2); \
+ __INSTR_ARG_FREE(tmp3, type3); \
+ } while(0)
+
+#define INSTR_GEN_4(callback, type1, arg1, type2, arg2, type3, arg3, \
+ type4, arg4) \
+ do { \
+ __INSTR_ARG_DECL(tmp1, type1, arg1); \
+ __INSTR_ARG_DECL(tmp2, type2, arg2); \
+ __INSTR_ARG_DECL(tmp3, type3, arg3); \
+ __INSTR_ARG_DECL(tmp4, type4, arg4); \
+ gen_helper_ ##callback (tmp1, tmp2, tmp3, tmp4); \
+ __INSTR_ARG_FREE(tmp1, type1); \
+ __INSTR_ARG_FREE(tmp2, type2); \
+ __INSTR_ARG_FREE(tmp3, type3); \
+ __INSTR_ARG_FREE(tmp4, type4); \
+ } while(0)
+
+#define INSTR_GEN_5(callback, type1, arg1, type2, arg2, type3, arg3, \
+ type4, arg4, type5, arg5) \
+ do { \
+ __INSTR_ARG_DECL(tmp1, type1, arg1); \
+ __INSTR_ARG_DECL(tmp2, type2, arg2); \
+ __INSTR_ARG_DECL(tmp3, type3, arg3); \
+ __INSTR_ARG_DECL(tmp4, type4, arg4); \
+ __INSTR_ARG_DECL(tmp5, type5, arg5); \
+ gen_helper_ ##callback (tmp1, tmp2, tmp3, tmp4, tmp5); \
+ __INSTR_ARG_FREE(tmp1, type1); \
+ __INSTR_ARG_FREE(tmp2, type2); \
+ __INSTR_ARG_FREE(tmp3, type3); \
+ __INSTR_ARG_FREE(tmp4, type4); \
+ __INSTR_ARG_FREE(tmp5, type5); \
+ } while(0)
+
+
+/* Internal API */
+
+/* Argument type conversion into TCGv temporaries */
+
+#define __INSTR_ARG_I32_DECL(tcg, value) TCGv_i32 tcg = tcg_const_i32((value))
+#define __INSTR_ARG_I64_DECL(tcg, value) TCGv_i64 tcg = tcg_const_i64((value))
+#if TARGET_LONG_BITS == 64
+#define __INSTR_ARG_TUL_DECL(tcg, value) __INSTR_ARG_I64_DECL(tcg, value)
+#define __INSTR_ARG_TCGv_i64_DECL(tcg, value) TCGv_i64 tcg = value
+#else
+#define __INSTR_ARG_TUL_DECL(tcg, value) __INSTR_ARG_I32_DECL(tcg, value)
+#define __INSTR_ARG_TCGv_i32_DECL(tcg, value) TCGv_i32 tcg = value
+#endif
+
+#define __INSTR_ARG_DECL(tcg, type, value) __INSTR_ARG_ ##type ##_DECL(tcg, value)
+
+
+/* Free TCGv temporaries */
+
+#define __INSTR_ARG_I32_FREE(tcg) tcg_temp_free_i32(tcg)
+#define __INSTR_ARG_I64_FREE(tcg) tcg_temp_free_i64(tcg)
+#if TARGET_LONG_BITS == 64
+#define __INSTR_ARG_TUL_FREE(tcg) __INSTR_ARG_I64_FREE(tcg)
+#else
+#define __INSTR_ARG_TUL_FREE(tcg) __INSTR_ARG_I32_FREE(tcg)
+#endif
+#define __INSTR_ARG_TCGv_i64_FREE(tcg)
+#define __INSTR_ARG_TCGv_i32_FREE(tcg)
+#define __INSTR_ARG_TCGv_FREE(tcg)
+
+#define __INSTR_ARG_FREE(tcg, type) __INSTR_ARG_ ##type ##_FREE(tcg)
+
+#endif /* INSTRUMENT__GENERATE_H */
diff --git a/instrument/types.h b/instrument/types.h
new file mode 100644
index 0000000..eb4036b
--- /dev/null
+++ b/instrument/types.h
@@ -0,0 +1,33 @@
+/*
+ * Static instrumentation data types.
+ *
+ * Copyright (c) 2010 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INSTRUMENT__TYPES_H
+#define INSTRUMENT__TYPES_H
+
+/** Instrumentation argument types. */
+typedef enum {
+ INSTR_ARG_I32, /**< immediate of 32bits */
+ INSTR_ARG_I64, /**< immediate of 64bits */
+ INSTR_ARG_TUL, /**< immediate target_ulong */
+ INSTR_ARG_TCGv_i32, /**< 32-bit TCGv variable */
+ INSTR_ARG_TCGv_i64, /**< 64-bit TCGv variable */
+ INSTR_ARG_TCGv, /**< target-bit TCGv variable*/
+} instr_arg_type_t;
+
+#endif /* INSTRUMENT__TYPES_H */
--
1.7.1
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Qemu-devel] [PATCH 09/18] instrument: Add initial instrumentation example
2010-10-22 18:53 ` Lluís
` (14 preceding siblings ...)
2010-10-21 14:36 ` [Qemu-devel] [PATCH 11/18] instrument: Code-generation macros Lluís
@ 2010-10-21 17:42 ` Lluís
2010-10-21 20:55 ` [Qemu-devel] [PATCH 12/18] instrument: [all] Include instrumentation helper declarations Lluís
2010-10-22 14:00 ` [Qemu-devel] [PATCH 16/18] instrument: [all] Call VMEM point Lluís
17 siblings, 0 replies; 33+ messages in thread
From: Lluís @ 2010-10-21 17:42 UTC (permalink / raw)
To: qemu-devel
---
.gitignore | 1 +
instrument/examples/dynprint/README | 16 +++++++
instrument/examples/dynprint/guest/Makefile | 7 +++
instrument/examples/dynprint/guest/test.c | 39 +++++++++++++++++
instrument/examples/dynprint/host/Makefile | 14 ++++++
instrument/examples/dynprint/host/backdoor.c | 44 ++++++++++++++++++++
instrument/examples/dynprint/host/helpers.c | 19 ++++++++
.../dynprint/host/instrument-host-helpers.h | 19 ++++++++
.../examples/dynprint/host/instrument-host.h | 30 +++++++++++++
9 files changed, 189 insertions(+), 0 deletions(-)
create mode 100644 instrument/examples/dynprint/README
create mode 100644 instrument/examples/dynprint/guest/Makefile
create mode 100644 instrument/examples/dynprint/guest/test.c
create mode 100644 instrument/examples/dynprint/host/Makefile
create mode 100644 instrument/examples/dynprint/host/backdoor.c
create mode 100644 instrument/examples/dynprint/host/helpers.c
create mode 100644 instrument/examples/dynprint/host/instrument-host-helpers.h
create mode 100644 instrument/examples/dynprint/host/instrument-host.h
diff --git a/.gitignore b/.gitignore
index e4a351d..7fd5e88 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,3 +59,4 @@ pc-bios/optionrom/multiboot.raw
.stgit-*
cscope.*
backdoor/examples/print/guest/test
+instrument/examples/dynprint/guest/test
diff --git a/instrument/examples/dynprint/README b/instrument/examples/dynprint/README
new file mode 100644
index 0000000..a1aa7f1
--- /dev/null
+++ b/instrument/examples/dynprint/README
@@ -0,0 +1,16 @@
+This example defines two instrumentation states:
+ * one printing the address of each fetched instruction
+ * one printing all the available information of each fetched instruction
+
+along with an instruction-based backdoor to dynamically (de)activate such
+states.
+
+To compile the host (quemu) run:
+ /path/to/qemu/configure --with-backdoor=/path/to/qemu/instrument/examples/dynprint/host/ --with-instrument=/path/to/qemu/instrument/examples/dynprint/host/
+ make
+
+To compile the guest program run:
+ make -C /path/to/qemu/instrument/examples/dynprint/guest/
+
+Now you can run it with:
+ /path/to/qemu/i386-linux-user/qemu-i386 /path/to/qemu/instrument/examples/dynprint/guest/test
diff --git a/instrument/examples/dynprint/guest/Makefile b/instrument/examples/dynprint/guest/Makefile
new file mode 100644
index 0000000..ea266f2
--- /dev/null
+++ b/instrument/examples/dynprint/guest/Makefile
@@ -0,0 +1,7 @@
+CFLAGS += -I../../../../
+PROGS = test
+
+all: $(PROGS)
+
+clean:
+ rm -f $(PROGS)
diff --git a/instrument/examples/dynprint/guest/test.c b/instrument/examples/dynprint/guest/test.c
new file mode 100644
index 0000000..254ebcf
--- /dev/null
+++ b/instrument/examples/dynprint/guest/test.c
@@ -0,0 +1,39 @@
+/*
+ * Sample guest program exercising instruction-based backdoor communication.
+ *
+ * Copyright (c) 2010 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+
+#define TOTAL_ITERS 100
+
+
+int
+main ()
+{
+ int i;
+
+ printf("start\n");
+
+ for (i = 0; i < TOTAL_ITERS; i++) {
+ printf("iteration\n");
+ }
+
+ printf("stop\n");
+
+ return 0;
+}
diff --git a/instrument/examples/dynprint/host/Makefile b/instrument/examples/dynprint/host/Makefile
new file mode 100644
index 0000000..45213d1
--- /dev/null
+++ b/instrument/examples/dynprint/host/Makefile
@@ -0,0 +1,14 @@
+# Makefile for user-provided backdoor and instrumentation code
+
+include $(SRC_PATH)/config-host.mak
+include $(SRC_PATH)/rules.mak
+include $(SRC_PATH)/Makefile.objs
+
+libbackdoor.a: backdoor.o
+ $(call quiet-command,rm -f $@ && $(AR) rcs $@ $^," AR $(TARGET_DIR)$@")
+
+libinstrument.a: helpers.o
+ $(call quiet-command,rm -f $@ && $(AR) rcs $@ $^," AR $(TARGET_DIR)$@")
+
+clean:
+ rm -f libinstrument.a $(objs)
diff --git a/instrument/examples/dynprint/host/backdoor.c b/instrument/examples/dynprint/host/backdoor.c
new file mode 100644
index 0000000..7b4e883
--- /dev/null
+++ b/instrument/examples/dynprint/host/backdoor.c
@@ -0,0 +1,44 @@
+/*
+ * Example of dynamic control of instrumentation states.
+ *
+ * Copyright (c) 2010 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+
+#include "cpu.h"
+#include "helper.h"
+
+
+void
+helper_backdoor_i8 (uint32_t imm)
+{
+ switch (imm) {
+ default:
+ printf("Unexpected use of instrumentation backdoor\n");
+ abort();
+ }
+}
+
+void
+helper_backdoor_i8_v (uint32_t imm, target_ulong value)
+{
+ switch (imm) {
+ default:
+ printf("Unexpected use of instrumentation backdoor\n");
+ abort();
+ }
+}
diff --git a/instrument/examples/dynprint/host/helpers.c b/instrument/examples/dynprint/host/helpers.c
new file mode 100644
index 0000000..656b716
--- /dev/null
+++ b/instrument/examples/dynprint/host/helpers.c
@@ -0,0 +1,19 @@
+/*
+ * Example of static instrumentation point callbacks.
+ *
+ * Copyright (c) 2010 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
diff --git a/instrument/examples/dynprint/host/instrument-host-helpers.h b/instrument/examples/dynprint/host/instrument-host-helpers.h
new file mode 100644
index 0000000..e88738d
--- /dev/null
+++ b/instrument/examples/dynprint/host/instrument-host-helpers.h
@@ -0,0 +1,19 @@
+/*
+ * Example of static instrumentation point callback definitions.
+ *
+ * Copyright (c) 2010 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
diff --git a/instrument/examples/dynprint/host/instrument-host.h b/instrument/examples/dynprint/host/instrument-host.h
new file mode 100644
index 0000000..9ede6af
--- /dev/null
+++ b/instrument/examples/dynprint/host/instrument-host.h
@@ -0,0 +1,30 @@
+/*
+ * Example of static instrumentation points.
+ *
+ * Copyright (c) 2010 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INSTRUMENT_HOST_H
+#define INSTRUMENT_HOST_H
+
+/* See "instrument/host-stub.h" for a description of macro arguments. */
+
+/* Instrumentation types */
+typedef enum {
+ INSTR_TYPE_COUNT /* Total number of instrumentation types (mandatory) */
+} instr_type_t;
+
+#endif /* INSTRUMENT_HOST_H */
--
1.7.1
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Qemu-devel] [PATCH 12/18] instrument: [all] Include instrumentation helper declarations
2010-10-22 18:53 ` Lluís
` (15 preceding siblings ...)
2010-10-21 17:42 ` [Qemu-devel] [PATCH 09/18] instrument: Add initial instrumentation example Lluís
@ 2010-10-21 20:55 ` Lluís
2010-10-22 14:00 ` [Qemu-devel] [PATCH 16/18] instrument: [all] Call VMEM point Lluís
17 siblings, 0 replies; 33+ messages in thread
From: Lluís @ 2010-10-21 20:55 UTC (permalink / raw)
To: qemu-devel
---
target-alpha/helper.h | 4 ++++
target-arm/helper.h | 4 ++++
target-cris/helper.h | 4 ++++
target-i386/helper.h | 4 ++++
target-m68k/helper.h | 4 ++++
target-microblaze/helper.h | 4 ++++
target-mips/helper.h | 4 ++++
target-ppc/helper.h | 4 ++++
target-sh4/helper.h | 4 ++++
target-sparc/helper.h | 4 ++++
10 files changed, 40 insertions(+), 0 deletions(-)
diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index d2ec252..4456205 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -127,4 +127,8 @@ DEF_HELPER_2(stq_c_raw, i64, i64, i64)
#include "backdoor/helper.h"
#endif
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument-host-helpers.h"
+#endif
+
#include "def-helper.h"
diff --git a/target-arm/helper.h b/target-arm/helper.h
index b46f04c..b1d24f7 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -451,4 +451,8 @@ DEF_HELPER_2(set_teecr, void, env, i32)
#include "backdoor/helper.h"
#endif
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument-host-helpers.h"
+#endif
+
#include "def-helper.h"
diff --git a/target-cris/helper.h b/target-cris/helper.h
index 72fabce..8f7e976 100644
--- a/target-cris/helper.h
+++ b/target-cris/helper.h
@@ -27,4 +27,8 @@ DEF_HELPER_0(top_evaluate_flags, void)
#include "backdoor/helper.h"
#endif
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument-host-helpers.h"
+#endif
+
#include "def-helper.h"
diff --git a/target-i386/helper.h b/target-i386/helper.h
index 979d94e..1b8e6e8 100644
--- a/target-i386/helper.h
+++ b/target-i386/helper.h
@@ -221,4 +221,8 @@ DEF_HELPER_2(rcrq, tl, tl, tl)
#include "backdoor/helper.h"
#endif
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument-host-helpers.h"
+#endif
+
#include "def-helper.h"
diff --git a/target-m68k/helper.h b/target-m68k/helper.h
index 06e8a47..523fde2 100644
--- a/target-m68k/helper.h
+++ b/target-m68k/helper.h
@@ -55,4 +55,8 @@ DEF_HELPER_1(raise_exception, void, i32)
#include "backdoor/helper.h"
#endif
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument-host-helpers.h"
+#endif
+
#include "def-helper.h"
diff --git a/target-microblaze/helper.h b/target-microblaze/helper.h
index 473ed78..6f8e274 100644
--- a/target-microblaze/helper.h
+++ b/target-microblaze/helper.h
@@ -38,4 +38,8 @@ DEF_HELPER_4(memalign, void, i32, i32, i32, i32)
#include "backdoor/helper.h"
#endif
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument-host-helpers.h"
+#endif
+
#include "def-helper.h"
diff --git a/target-mips/helper.h b/target-mips/helper.h
index cbee380..0953815 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -291,4 +291,8 @@ DEF_HELPER_0(wait, void)
#include "backdoor/helper.h"
#endif
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument-host-helpers.h"
+#endif
+
#include "def-helper.h"
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index eeb7487..960ba5e 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -405,4 +405,8 @@ DEF_HELPER_2(store_601_batu, void, i32, tl)
#include "backdoor/helper.h"
#endif
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument-host-helpers.h"
+#endif
+
#include "def-helper.h"
diff --git a/target-sh4/helper.h b/target-sh4/helper.h
index dbea9e1..361a15f 100644
--- a/target-sh4/helper.h
+++ b/target-sh4/helper.h
@@ -54,4 +54,8 @@ DEF_HELPER_1(ftrc_DT, i32, i64)
#include "backdoor/helper.h"
#endif
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument-host-helpers.h"
+#endif
+
#include "def-helper.h"
diff --git a/target-sparc/helper.h b/target-sparc/helper.h
index b88f0ac..a1f177c 100644
--- a/target-sparc/helper.h
+++ b/target-sparc/helper.h
@@ -164,4 +164,8 @@ DEF_HELPER_0(compute_C_icc, i32);
#include "backdoor/helper.h"
#endif
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument-host-helpers.h"
+#endif
+
#include "def-helper.h"
--
1.7.1
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Qemu-devel] [PATCH 16/18] instrument: [all] Call VMEM point
2010-10-22 18:53 ` Lluís
` (16 preceding siblings ...)
2010-10-21 20:55 ` [Qemu-devel] [PATCH 12/18] instrument: [all] Include instrumentation helper declarations Lluís
@ 2010-10-22 14:00 ` Lluís
17 siblings, 0 replies; 33+ messages in thread
From: Lluís @ 2010-10-22 14:00 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
cpu-all.h | 59 +++++++++++++++++++++-------------------
exec-all.h | 2 +
linux-user/main.c | 12 ++++++++
| 15 ++++++++++
target-alpha/translate.c | 4 +++
target-arm/translate.c | 4 +++
target-cris/translate.c | 4 +++
target-i386/translate.c | 4 +++
target-m68k/translate.c | 4 +++
target-microblaze/translate.c | 4 +++
target-mips/translate.c | 4 +++
target-ppc/translate.c | 4 +++
target-s390x/translate.c | 4 +++
target-sh4/translate.c | 4 +++
target-sparc/translate.c | 4 +++
15 files changed, 104 insertions(+), 28 deletions(-)
diff --git a/cpu-all.h b/cpu-all.h
index 88970a2..2e666e4 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -697,21 +697,24 @@ extern unsigned long reserved_va;
#if defined(CONFIG_USER_ONLY)
+/* XXX: INSTRUMENT can capture these when enabled. */
+/* TODO: INSTRUMENT might find a NULL 'cpu_single_env', should check... */
+
/* if user mode, no other memory access functions */
-#define ldub(p) ldub_raw(p)
-#define ldsb(p) ldsb_raw(p)
-#define lduw(p) lduw_raw(p)
-#define ldsw(p) ldsw_raw(p)
-#define ldl(p) ldl_raw(p)
-#define ldq(p) ldq_raw(p)
-#define ldfl(p) ldfl_raw(p)
-#define ldfq(p) ldfq_raw(p)
-#define stb(p, v) stb_raw(p, v)
-#define stw(p, v) stw_raw(p, v)
-#define stl(p, v) stl_raw(p, v)
-#define stq(p, v) stq_raw(p, v)
-#define stfl(p, v) stfl_raw(p, v)
-#define stfq(p, v) stfq_raw(p, v)
+#define ldub(p) ({ INSTR_DO_VMEM(cpu_single_env, p, 1, INSTR_MEM_RD); ldub_raw(p); })
+#define ldsb(p) ({ INSTR_DO_VMEM(cpu_single_env, p, 1, INSTR_MEM_RD); ldsb_raw(p); })
+#define lduw(p) ({ INSTR_DO_VMEM(cpu_single_env, p, 2, INSTR_MEM_RD); lduw_raw(p); })
+#define ldsw(p) ({ INSTR_DO_VMEM(cpu_single_env, p, 2, INSTR_MEM_RD); ldsw_raw(p); })
+#define ldl(p) ({ INSTR_DO_VMEM(cpu_single_env, p, 4, INSTR_MEM_RD); ldl_raw(p); })
+#define ldq(p) ({ INSTR_DO_VMEM(cpu_single_env, p, 8, INSTR_MEM_RD); ldq_raw(p); })
+#define ldfl(p) ({ INSTR_DO_VMEM(cpu_single_env, p, 4, INSTR_MEM_RD); ldfl_raw(p); })
+#define ldfq(p) ({ INSTR_DO_VMEM(cpu_single_env, p, 8, INSTR_MEM_RD); ldfq_raw(p); })
+#define stb(p, v) ({ INSTR_DO_VMEM(cpu_single_env, p, 1, INSTR_MEM_WR); stb_raw(p, v); })
+#define stw(p, v) ({ INSTR_DO_VMEM(cpu_single_env, p, 2, INSTR_MEM_WR); stw_raw(p, v); })
+#define stl(p, v) ({ INSTR_DO_VMEM(cpu_single_env, p, 4, INSTR_MEM_WR); stl_raw(p, v); })
+#define stq(p, v) ({ INSTR_DO_VMEM(cpu_single_env, p, 8, INSTR_MEM_WR); stq_raw(p, v); })
+#define stfl(p, v) ({ INSTR_DO_VMEM(cpu_single_env, p, 4, INSTR_MEM_WR); stfl_raw(p, v); })
+#define stfq(p, v) ({ INSTR_DO_VMEM(cpu_single_env, p, 8, INSTR_MEM_WR); stfq_raw(p, v); })
#define ldub_code(p) ldub_raw(p)
#define ldsb_code(p) ldsb_raw(p)
@@ -720,20 +723,20 @@ extern unsigned long reserved_va;
#define ldl_code(p) ldl_raw(p)
#define ldq_code(p) ldq_raw(p)
-#define ldub_kernel(p) ldub_raw(p)
-#define ldsb_kernel(p) ldsb_raw(p)
-#define lduw_kernel(p) lduw_raw(p)
-#define ldsw_kernel(p) ldsw_raw(p)
-#define ldl_kernel(p) ldl_raw(p)
-#define ldq_kernel(p) ldq_raw(p)
-#define ldfl_kernel(p) ldfl_raw(p)
-#define ldfq_kernel(p) ldfq_raw(p)
-#define stb_kernel(p, v) stb_raw(p, v)
-#define stw_kernel(p, v) stw_raw(p, v)
-#define stl_kernel(p, v) stl_raw(p, v)
-#define stq_kernel(p, v) stq_raw(p, v)
-#define stfl_kernel(p, v) stfl_raw(p, v)
-#define stfq_kernel(p, vt) stfq_raw(p, v)
+#define ldub_kernel(p) ({ INSTR_DO_VMEM(cpu_single_env, p, 1, INSTR_MEM_RD); ldub_raw(p); })
+#define ldsb_kernel(p) ({ INSTR_DO_VMEM(cpu_single_env, p, 1, INSTR_MEM_RD); ldsb_raw(p); })
+#define lduw_kernel(p) ({ INSTR_DO_VMEM(cpu_single_env, p, 2, INSTR_MEM_RD); lduw_raw(p); })
+#define ldsw_kernel(p) ({ INSTR_DO_VMEM(cpu_single_env, p, 2, INSTR_MEM_RD); ldsw_raw(p); })
+#define ldl_kernel(p) ({ INSTR_DO_VMEM(cpu_single_env, p, 4, INSTR_MEM_RD); ldl_raw(p); })
+#define ldq_kernel(p) ({ INSTR_DO_VMEM(cpu_single_env, p, 8, INSTR_MEM_RD); ldq_raw(p); })
+#define ldfl_kernel(p) ({ INSTR_DO_VMEM(cpu_single_env, p, 4, INSTR_MEM_RD); ldfl_raw(p); })
+#define ldfq_kernel(p) ({ INSTR_DO_VMEM(cpu_single_env, p, 8, INSTR_MEM_RD); ldfq_raw(p); })
+#define stb_kernel(p, v) ({ INSTR_DO_VMEM(cpu_single_env, p, 1, INSTR_MEM_WR); stb_raw(p, v); })
+#define stw_kernel(p, v) ({ INSTR_DO_VMEM(cpu_single_env, p, 2, INSTR_MEM_WR); stw_raw(p, v); })
+#define stl_kernel(p, v) ({ INSTR_DO_VMEM(cpu_single_env, p, 4, INSTR_MEM_WR); stl_raw(p, v); })
+#define stq_kernel(p, v) ({ INSTR_DO_VMEM(cpu_single_env, p, 8, INSTR_MEM_WR); stq_raw(p, v); })
+#define stfl_kernel(p, v) ({ INSTR_DO_VMEM(cpu_single_env, p, 4, INSTR_MEM_WR); stfl_raw(p, v); })
+#define stfq_kernel(p, vt) ({ INSTR_DO_VMEM(cpu_single_env, p, 8, INSTR_MEM_WR); stfq_raw(p, v); })
#endif /* defined(CONFIG_USER_ONLY) */
diff --git a/exec-all.h b/exec-all.h
index 35d2a57..4c2c1d2 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -288,6 +288,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx,
#include "softmmu_defs.h"
#define ACCESS_TYPE (NB_MMU_MODES + 1)
+#define INSTR_CODE_ACCESSOR 1 /* do not instrument '*_code' accesses */
#define MEMSUFFIX _code
#define env cpu_single_env
@@ -304,6 +305,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx,
#include "softmmu_header.h"
#undef ACCESS_TYPE
+#undef INSTR_CODE_ACCESSOR
#undef MEMSUFFIX
#undef env
diff --git a/linux-user/main.c b/linux-user/main.c
index dbba8be..b82d53c 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2948,6 +2948,12 @@ int main(int argc, char **argv, char **envp)
fprintf(stderr, "Unable to find CPU definition\n");
exit(1);
}
+
+#if defined(CONFIG_INSTRUMENT)
+ /* hack around 'env' vs 'cpu_single_env' */
+ cpu_single_env = env;
+#endif
+
#if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
cpu_reset(env);
#endif
@@ -3369,6 +3375,12 @@ int main(int argc, char **argv, char **envp)
gdbserver_start (gdbstub_port);
gdb_handlesig(env, 0);
}
+
+#if defined(CONFIG_INSTRUMENT)
+ /* hack around 'env' vs 'cpu_single_env' */
+ cpu_single_env = NULL;
+#endif
+
cpu_loop(env);
/* never exits */
return 0;
--git a/softmmu_header.h b/softmmu_header.h
index 2f95c33..b6052f3 100644
--- a/softmmu_header.h
+++ b/softmmu_header.h
@@ -79,6 +79,11 @@ static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
unsigned long physaddr;
int mmu_idx;
+#if !defined(INSTR_CODE_ACCESSOR) /* XXX: kind of hackish, but couldn't
+ * find another way */
+ INSTR_DO_VMEM(env, ptr, DATA_SIZE, INSTR_MEM_RD);
+#endif
+
addr = ptr;
page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
mmu_idx = CPU_MMU_INDEX;
@@ -100,6 +105,11 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
unsigned long physaddr;
int mmu_idx;
+#if !defined(INSTR_CODE_ACCESSOR) /* XXX: kind of hackish, but couldn't
+ * find another way */
+ INSTR_DO_VMEM(env, ptr, DATA_SIZE, INSTR_MEM_RD);
+#endif
+
addr = ptr;
page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
mmu_idx = CPU_MMU_INDEX;
@@ -125,6 +135,11 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE
unsigned long physaddr;
int mmu_idx;
+#if !defined(INSTR_CODE_ACCESSOR) /* XXX: kind of hackish, but couldn't
+ * find another way */
+ INSTR_DO_VMEM(env, ptr, DATA_SIZE, INSTR_MEM_WR);
+#endif
+
addr = ptr;
page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
mmu_idx = CPU_MMU_INDEX;
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 3a1c625..1e7e66b 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -32,6 +32,10 @@
#define GEN_HELPER 1
#include "helper.h"
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument/gen-vmem-wrappers.h"
+#endif
+
#undef ALPHA_DEBUG_DISAS
#define CONFIG_SOFTFLOAT_INLINE
diff --git a/target-arm/translate.c b/target-arm/translate.c
index a9fbe5b..8c47e34 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -34,6 +34,10 @@
#define GEN_HELPER 1
#include "helper.h"
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument/gen-vmem-wrappers.h"
+#endif
+
#define ENABLE_ARCH_5J 0
#define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
#define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
diff --git a/target-cris/translate.c b/target-cris/translate.c
index 8361369..8f43ae5 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -41,6 +41,10 @@
#define GEN_HELPER 1
#include "helper.h"
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument/gen-vmem-wrappers.h"
+#endif
+
#define DISAS_CRIS 0
#if DISAS_CRIS
# define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 02a93a4..aa3b307 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -33,6 +33,10 @@
#include "helper.h"
#if defined(CONFIG_INSTRUMENT)
+#include "instrument/gen-vmem-wrappers.h"
+#endif
+
+#if defined(CONFIG_INSTRUMENT)
static inline void
mem_exchange (void * tmp, void * start1, size_t size1,
void * start2, size_t size2)
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 0c6f0e2..e212392 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -34,6 +34,10 @@
#define GEN_HELPER 1
#include "helper.h"
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument/gen-vmem-wrappers.h"
+#endif
+
//#define DEBUG_DISPATCH 1
/* Fake floating point. */
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 9dcc78a..0adf173 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -35,6 +35,10 @@
#define GEN_HELPER 1
#include "helper.h"
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument/gen-vmem-wrappers.h"
+#endif
+
#define SIM_COMPAT 0
#define DISAS_GNU 1
#define DISAS_MB 1
diff --git a/target-mips/translate.c b/target-mips/translate.c
index d62c615..a92ac7f 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -36,6 +36,10 @@
#define GEN_HELPER 1
#include "helper.h"
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument/gen-vmem-wrappers.h"
+#endif
+
//#define MIPS_DEBUG_DISAS
//#define MIPS_DEBUG_SIGN_EXTENSIONS
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index fd06861..555658c 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -33,6 +33,10 @@
#define GEN_HELPER 1
#include "helper.h"
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument/gen-vmem-wrappers.h"
+#endif
+
#define CPU_SINGLE_STEP 0x1
#define CPU_BRANCH_STEP 0x2
#define GDBSTUB_SINGLE_STEP 0x4
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index 44dfa65..168017f 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -23,6 +23,10 @@
#include "tcg-op.h"
#include "qemu-log.h"
+#ifdef CONFIG_INSTRUMENT
+#include "instrument/gen-vmem-wrappers.h"
+#endif
+
void cpu_dump_state(CPUState *env, FILE *f,
int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
int flags)
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index deee939..5e232e5 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -36,6 +36,10 @@
#define GEN_HELPER 1
#include "helper.h"
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument/gen-vmem-wrappers.h"
+#endif
+
typedef struct DisasContext {
struct TranslationBlock *tb;
target_ulong pc;
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 23f9519..2c2c505 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -33,6 +33,10 @@
#define GEN_HELPER 1
#include "helper.h"
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument/gen-vmem-wrappers.h"
+#endif
+
#define DEBUG_DISAS
#define DYNAMIC_PC 1 /* dynamic pc value */
--
1.7.1
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply related [flat|nested] 33+ messages in thread