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