@@ -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:
@@ -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 */
@@ -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();
@@ -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);
+}
@@ -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);
@@ -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 */
@@ -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)
@@ -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 */
@@ -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 */
Signed-off-by: LluĂs Vilanova <vilanova@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(-)