Patchwork [15/18] instrument: Add VMEM point

login
register
mail settings
Submitter =?utf-8?Q?Llu=C3=ADs?=
Date Oct. 19, 2010, 9:12 p.m.
Message ID <44dc887a06affece6eae1acd2bbb39753a52c415.1287772676.git.vilanova@ac.upc.edu>
Download mbox | patch
Permalink /patch/68945/
State New
Headers show

Comments

=?utf-8?Q?Llu=C3=ADs?= - Oct. 19, 2010, 9:12 p.m.
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

Patch

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 */