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