@@ -243,21 +243,23 @@ extern unsigned long reserved_va;
#if defined(CONFIG_USER_ONLY)
+#include "trace.h"
+
/* 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) ({ trace_vmem(p, 1, 0); ldub_raw(p); })
+#define ldsb(p) ({ trace_vmem(p, 1, 0); ldsb_raw(p); })
+#define lduw(p) ({ trace_vmem(p, 2, 0); lduw_raw(p); })
+#define ldsw(p) ({ trace_vmem(p, 2, 0); ldsw_raw(p); })
+#define ldl(p) ({ trace_vmem(p, 4, 0); ldl_raw(p); })
+#define ldq(p) ({ trace_vmem(p, 8, 0); ldq_raw(p); })
+#define ldfl(p) ({ trace_vmem(p, 4, 0); ldfl_raw(p); })
+#define ldfq(p) ({ trace_vmem(p, 8, 0); ldfq_raw(p); })
+#define stb(p, v) ({ trace_vmem(p, 1, 1); stb_raw(p, v); })
+#define stw(p, v) ({ trace_vmem(p, 2, 1); stw_raw(p, v); })
+#define stl(p, v) ({ trace_vmem(p, 4, 1); stl_raw(p, v); })
+#define stq(p, v) ({ trace_vmem(p, 8, 1); stq_raw(p, v); })
+#define stfl(p, v) ({ trace_vmem(p, 4, 1); stfl_raw(p, v); })
+#define stfq(p, v) ({ trace_vmem(p, 8, 1); stfq_raw(p, v); })
#define ldub_code(p) ldub_raw(p)
#define ldsb_code(p) ldsb_raw(p)
@@ -266,20 +268,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) ({ trace_vmem(p, 1, 0); ldub_raw(p); })
+#define ldsb_kernel(p) ({ trace_vmem(p, 1, 0); ldsb_raw(p); })
+#define lduw_kernel(p) ({ trace_vmem(p, 2, 0); lduw_raw(p); })
+#define ldsw_kernel(p) ({ trace_vmem(p, 2, 0); ldsw_raw(p); })
+#define ldl_kernel(p) ({ trace_vmem(p, 4, 0); ldl_raw(p); })
+#define ldq_kernel(p) ({ trace_vmem(p, 8, 0); ldq_raw(p); })
+#define ldfl_kernel(p) ({ trace_vmem(p, 4, 0); ldfl_raw(p); })
+#define ldfq_kernel(p) ({ trace_vmem(p, 8, 0); ldfq_raw(p); })
+#define stb_kernel(p, v) ({ trace_vmem(p, 1, 1); stb_raw(p, v); })
+#define stw_kernel(p, v) ({ trace_vmem(p, 2, 1); stw_raw(p, v); })
+#define stl_kernel(p, v) ({ trace_vmem(p, 4, 1); stl_raw(p, v); })
+#define stq_kernel(p, v) ({ trace_vmem(p, 8, 1); stq_raw(p, v); })
+#define stfl_kernel(p, v) ({ trace_vmem(p, 4, 1); stfl_raw(p, v); })
+#define stfq_kernel(p, vt) ({ trace_vmem(p, 8, 1); stfq_raw(p, v); })
#endif /* defined(CONFIG_USER_ONLY) */
@@ -309,6 +309,8 @@ void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx,
#include "softmmu_defs.h"
#define ACCESS_TYPE (NB_MMU_MODES + 1)
+/* do not trace '*_code' accesses during instruction disassembly */
+#define TRACE_TCG_CODE_ACCESSOR 1
#define MEMSUFFIX _code
#define env cpu_single_env
@@ -325,6 +327,7 @@ void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx,
#include "softmmu_header.h"
#undef ACCESS_TYPE
+#undef TRACE_TCG_CODE_ACCESSOR
#undef MEMSUFFIX
#undef env
@@ -25,6 +25,9 @@
* 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 "trace.h"
+
#if DATA_SIZE == 8
#define SUFFIX q
#define USUFFIX q
@@ -88,6 +91,10 @@ static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
unsigned long physaddr;
int mmu_idx;
+#if !defined(TRACE_TCG_CODE_ACCESSOR)
+ trace_vmem(ptr, DATA_SIZE, 0);
+#endif
+
addr = ptr;
page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
mmu_idx = CPU_MMU_INDEX;
@@ -109,6 +116,10 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
unsigned long physaddr;
int mmu_idx;
+#if !defined(TRACE_TCG_CODE_ACCESSOR)
+ trace_vmem(ptr, DATA_SIZE, 0);
+#endif
+
addr = ptr;
page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
mmu_idx = CPU_MMU_INDEX;
@@ -134,6 +145,10 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE
unsigned long physaddr;
int mmu_idx;
+#if !defined(TRACE_TCG_CODE_ACCESSOR)
+ trace_vmem(ptr, DATA_SIZE, 1);
+#endif
+
addr = ptr;
page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
mmu_idx = CPU_MMU_INDEX;
@@ -2522,3 +2522,9 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv addr, int mem_index)
TCGV_PTR_TO_NAT(A), (B))
#define tcg_gen_ext_i32_ptr(R, A) tcg_gen_ext_i32_i64(TCGV_PTR_TO_NAT(R), (A))
#endif /* TCG_TARGET_REG_BITS != 32 */
+
+/* To avoid a circular dependency with helper.h, overload tcg_gen_qemu_*
+ * routines with preprocessor macros to insert TCG virtual memory access
+ * tracing.
+ */
+#include "trace/tcg-op-internal.h"
@@ -660,3 +660,12 @@ disable tcg vbbl(uint64_t vaddr) "vaddr=0x%016"PRIx64
#
# vaddr : instruction's virtual address
disable tcg vfetch(uint64_t vaddr) "vaddr=0x%016"PRIx64
+
+# Start virtual memory access (before any potential access violation)
+#
+# Targets: all
+#
+# vaddr : access' virtual address
+# size : access' size (bytes)
+# write : whether the access is a write
+disable tcg vmem(TCGv vaddr, uint8_t size, uint8_t write) "vaddr=0x%016"PRIx64" size=%d write=%d"
new file mode 100644
@@ -0,0 +1,74 @@
+/* -*- mode: c -*-
+ * Copyright (c) 2011 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+/**
+ * @file Capture TCG code generation for virtual memory accesses.
+ *
+ * Assumes that no other lower-level call will be performed by target
+ * architecture disassembly code on TCG instructions for accessing memory.
+ */
+
+#ifndef TRACE__TCG_OP_INTERNAL_H
+#define TRACE__TCG_OP_INTERNAL_H
+
+#define tcg_gen_qemu_ld8u(arg, addr, mem_index) \
+ do { \
+ gen_helper_trace_vmem(addr, 1, 0); \
+ (tcg_gen_qemu_ld8u)(arg, addr, mem_index); \
+ } while (0)
+#define tcg_gen_qemu_ld8s(arg, addr, mem_index) \
+ do { \
+ gen_helper_trace_vmem(addr, 1, 0); \
+ (tcg_gen_qemu_ld8s)(arg, addr, mem_index); \
+ } while (0)
+#define tcg_gen_qemu_ld16u(arg, addr, mem_index) \
+ do { \
+ gen_helper_trace_vmem(addr, 2, 0); \
+ (tcg_gen_qemu_ld16u)(arg, addr, mem_index); \
+ } while (0)
+#define tcg_gen_qemu_ld16s(arg, addr, mem_index) \
+ do { \
+ gen_helper_trace_vmem(addr, 2, 0); \
+ (tcg_gen_qemu_ld16s)(arg, addr, mem_index); \
+ } while (0)
+#define tcg_gen_qemu_ld32u(arg, addr, mem_index) \
+ do { \
+ gen_helper_trace_vmem(addr, 4, 0); \
+ (tcg_gen_qemu_ld32u)(arg, addr, mem_index); \
+ } while (0)
+#define tcg_gen_qemu_ld32s(arg, addr, mem_index) \
+ do { \
+ gen_helper_trace_vmem(addr, 4, 0); \
+ (tcg_gen_qemu_ld32s)(arg, addr, mem_index); \
+ } while (0)
+#define tcg_gen_qemu_ld64(arg, addr, mem_index) \
+ do { \
+ gen_helper_trace_vmem(addr, 8, 0); \
+ (tcg_gen_qemu_ld64)(arg, addr, mem_index); \
+ } while (0)
+#define tcg_gen_qemu_st8(arg, addr, mem_index) \
+ do { \
+ gen_helper_trace_vmem(addr, 1, 1); \
+ (tcg_gen_qemu_st8)(arg, addr, mem_index); \
+ } while (0)
+#define tcg_gen_qemu_st16(arg, addr, mem_index) \
+ do { \
+ gen_helper_trace_vmem(addr, 2, 1); \
+ (tcg_gen_qemu_st16)(arg, addr, mem_index); \
+ } while (0)
+#define tcg_gen_qemu_st32(arg, addr, mem_index) \
+ do { \
+ gen_helper_trace_vmem(addr, 4, 1); \
+ (tcg_gen_qemu_st32)(arg, addr, mem_index); \
+ } while (0)
+#define tcg_gen_qemu_st64(arg, addr, mem_index) \
+ do { \
+ gen_helper_trace_vmem(addr, 8, 1); \
+ (tcg_gen_qemu_st64)(arg, addr, mem_index); \
+ } while (0)
+
+#endif /* TRACE__TCG_OP_INTERNAL_H */
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu> --- cpu-all.h | 58 +++++++++++++++++++------------------ exec-all.h | 3 ++ softmmu_header.h | 15 ++++++++++ tcg/tcg-op.h | 6 ++++ trace-events | 9 ++++++ trace/tcg-op-internal.h | 74 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 137 insertions(+), 28 deletions(-) create mode 100644 trace/tcg-op-internal.h