Add a match similar to the afilter address match, but for data addresses. When an address is specified with '-dfilter=0x12345' only load/stores to/from address 0x12345 are printed. All other instructions are hidden.
Signed-off-by: Sven Schnelle <sv...@stackframe.org> --- contrib/plugins/execlog.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/contrib/plugins/execlog.c b/contrib/plugins/execlog.c index b4b5ba113c..33fef9bfc6 100644 --- a/contrib/plugins/execlog.c +++ b/contrib/plugins/execlog.c @@ -23,9 +23,11 @@ static GRWLock expand_array_lock; static GPtrArray *imatches; static GArray *amatches; +static GArray *dmatches; struct execlog_ctx { GString *s; + bool log; }; /* @@ -45,6 +47,17 @@ static void expand_last_exec(int cpu_index) g_rw_lock_writer_unlock(&expand_array_lock); } +static bool match_vaddr(struct execlog_ctx *ctx, uint64_t vaddr) +{ + for (int i = 0; i < dmatches->len; i++) { + uint64_t v = g_array_index(dmatches, uint64_t, i); + if (v == vaddr) { + ctx->log = true; + return true; + } + } + return false; +} /** * Add memory read or write information to current instruction log */ @@ -57,6 +70,9 @@ static void vcpu_mem(unsigned int cpu_index, qemu_plugin_meminfo_t info, struct execlog_ctx *ctx = g_ptr_array_index(last_exec, cpu_index); g_rw_lock_reader_unlock(&expand_array_lock); + if (dmatches && !match_vaddr(ctx, vaddr)) { + return; + } GString *s = ctx->s; /* Indicate type of memory access */ if (qemu_plugin_mem_is_store(info)) { @@ -93,7 +109,7 @@ static void vcpu_insn_exec(unsigned int cpu_index, void *udata) GString *s = ctx->s; /* Print previous instruction in cache */ - if (s->len) { + if (ctx->log && s->len) { qemu_plugin_outs(s->str); qemu_plugin_outs("\n"); } @@ -102,6 +118,7 @@ static void vcpu_insn_exec(unsigned int cpu_index, void *udata) /* vcpu_mem will add memory access information to last_exec */ g_string_printf(s, "%u, ", cpu_index); g_string_append(s, (char *)udata); + ctx->log = dmatches ? false : true; } /** @@ -190,7 +207,7 @@ static void plugin_exit(qemu_plugin_id_t id, void *p) for (i = 0; i < last_exec->len; i++) { struct execlog_ctx *ctx = g_ptr_array_index(last_exec, i); GString *s = ctx->s; - if (s->str) { + if (ctx->log && s->str) { qemu_plugin_outs(s->str); qemu_plugin_outs("\n"); } @@ -240,6 +257,8 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id, parse_insn_match(tokens[1]); } else if (g_strcmp0(tokens[0], "afilter") == 0) { parse_vaddr_match(&amatches, tokens[1]); + } else if (g_strcmp0(tokens[0], "dfilter") == 0) { + parse_vaddr_match(&dmatches, tokens[1]); } else { fprintf(stderr, "option parsing failed: %s\n", opt); return -1; -- 2.43.2