translator: inject instrumentation from plugins

Signed-off-by: Emilio G. Cota <cota@braap.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Emilio G. Cota 2018-12-07 17:35:56 -05:00 committed by Alex Bennée
parent 7f93879e44
commit 6ba6f81821

View File

@ -16,6 +16,7 @@
#include "exec/gen-icount.h" #include "exec/gen-icount.h"
#include "exec/log.h" #include "exec/log.h"
#include "exec/translator.h" #include "exec/translator.h"
#include "exec/plugin-gen.h"
/* Pairs with tcg_clear_temp_count. /* Pairs with tcg_clear_temp_count.
To be called by #TranslatorOps.{translate_insn,tb_stop} if To be called by #TranslatorOps.{translate_insn,tb_stop} if
@ -34,6 +35,7 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
CPUState *cpu, TranslationBlock *tb, int max_insns) CPUState *cpu, TranslationBlock *tb, int max_insns)
{ {
int bp_insn = 0; int bp_insn = 0;
bool plugin_enabled;
/* Initialize DisasContext */ /* Initialize DisasContext */
db->tb = tb; db->tb = tb;
@ -55,11 +57,17 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
ops->tb_start(db, cpu); ops->tb_start(db, cpu);
tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */ tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */
plugin_enabled = plugin_gen_tb_start(cpu, tb);
while (true) { while (true) {
db->num_insns++; db->num_insns++;
ops->insn_start(db, cpu); ops->insn_start(db, cpu);
tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */ tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */
if (plugin_enabled) {
plugin_gen_insn_start(cpu, db);
}
/* Pass breakpoint hits to target for further processing */ /* Pass breakpoint hits to target for further processing */
if (!db->singlestep_enabled if (!db->singlestep_enabled
&& unlikely(!QTAILQ_EMPTY(&cpu->breakpoints))) { && unlikely(!QTAILQ_EMPTY(&cpu->breakpoints))) {
@ -99,6 +107,14 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
break; break;
} }
/*
* We can't instrument after instructions that change control
* flow although this only really affects post-load operations.
*/
if (plugin_enabled) {
plugin_gen_insn_end();
}
/* Stop translation if the output buffer is full, /* Stop translation if the output buffer is full,
or we have executed all of the allowed instructions. */ or we have executed all of the allowed instructions. */
if (tcg_op_buf_full() || db->num_insns >= db->max_insns) { if (tcg_op_buf_full() || db->num_insns >= db->max_insns) {
@ -111,6 +127,10 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
ops->tb_stop(db, cpu); ops->tb_stop(db, cpu);
gen_tb_end(db->tb, db->num_insns - bp_insn); gen_tb_end(db->tb, db->num_insns - bp_insn);
if (plugin_enabled) {
plugin_gen_tb_end(cpu);
}
/* The disas_log hook may use these values rather than recompute. */ /* The disas_log hook may use these values rather than recompute. */
db->tb->size = db->pc_next - db->pc_first; db->tb->size = db->pc_next - db->pc_first;
db->tb->icount = db->num_insns; db->tb->icount = db->num_insns;