qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 13/18] instrument: Add FETCH point


From: Lluís
Subject: [Qemu-devel] [PATCH 13/18] instrument: Add FETCH point
Date: Tue, 19 Oct 2010 23:11:16 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux)

Signed-off-by: Lluís Vilanova <address@hidden>
---
 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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]